authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-06-15 16:10:53-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-07-07 22:59:52-04:00
log525f341f33af9b8aad53931fd5511f00a82cb090
treecec3280498c1122858580946ac5e31f8feb807ce
parent8f20e81b8816aadd8ceb1b04bd3727cc1d124464

Zcu: introduce `PerThread` and pass to all the functions


56 files changed, 11266 insertions(+), 9961 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/Thread/Pool.zig+86-10
...@@ -9,17 +9,19 @@ run_queue: RunQueue = .{},...@@ -9,17 +9,19 @@ run_queue: RunQueue = .{},
9is_running: bool = true,9is_running: bool = true,
10allocator: std.mem.Allocator,10allocator: std.mem.Allocator,
11threads: []std.Thread,11threads: []std.Thread,
12ids: std.AutoArrayHashMapUnmanaged(std.Thread.Id, void),
1213
13const RunQueue = std.SinglyLinkedList(Runnable);14const RunQueue = std.SinglyLinkedList(Runnable);
14const Runnable = struct {15const Runnable = struct {
15 runFn: RunProto,16 runFn: RunProto,
16};17};
1718
18const RunProto = *const fn (*Runnable) void;19const RunProto = *const fn (*Runnable, id: ?usize) void;
1920
20pub const Options = struct {21pub const Options = struct {
21 allocator: std.mem.Allocator,22 allocator: std.mem.Allocator,
22 n_jobs: ?u32 = null,23 n_jobs: ?u32 = null,
24 track_ids: bool = false,
23};25};
2426
25pub fn init(pool: *Pool, options: Options) !void {27pub fn init(pool: *Pool, options: Options) !void {
...@@ -28,6 +30,7 @@ pub fn init(pool: *Pool, options: Options) !void {...@@ -28,6 +30,7 @@ pub fn init(pool: *Pool, options: Options) !void {
28 pool.* = .{30 pool.* = .{
29 .allocator = allocator,31 .allocator = allocator,
30 .threads = &[_]std.Thread{},32 .threads = &[_]std.Thread{},
33 .ids = .{},
31 };34 };
3235
33 if (builtin.single_threaded) {36 if (builtin.single_threaded) {
...@@ -35,6 +38,10 @@ pub fn init(pool: *Pool, options: Options) !void {...@@ -35,6 +38,10 @@ pub fn init(pool: *Pool, options: Options) !void {
35 }38 }
3639
37 const thread_count = options.n_jobs orelse @max(1, std.Thread.getCpuCount() catch 1);40 const thread_count = options.n_jobs orelse @max(1, std.Thread.getCpuCount() catch 1);
41 if (options.track_ids) {
42 try pool.ids.ensureTotalCapacity(allocator, 1 + thread_count);
43 pool.ids.putAssumeCapacityNoClobber(std.Thread.getCurrentId(), {});
44 }
3845
39 // kill and join any threads we spawned and free memory on error.46 // kill and join any threads we spawned and free memory on error.
40 pool.threads = try allocator.alloc(std.Thread, thread_count);47 pool.threads = try allocator.alloc(std.Thread, thread_count);
...@@ -49,6 +56,7 @@ pub fn init(pool: *Pool, options: Options) !void {...@@ -49,6 +56,7 @@ pub fn init(pool: *Pool, options: Options) !void {
4956
50pub fn deinit(pool: *Pool) void {57pub fn deinit(pool: *Pool) void {
51 pool.join(pool.threads.len); // kill and join all threads.58 pool.join(pool.threads.len); // kill and join all threads.
59 pool.ids.deinit(pool.allocator);
52 pool.* = undefined;60 pool.* = undefined;
53}61}
5462
...@@ -96,7 +104,7 @@ pub fn spawnWg(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args...@@ -96,7 +104,7 @@ pub fn spawnWg(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args
96 run_node: RunQueue.Node = .{ .data = .{ .runFn = runFn } },104 run_node: RunQueue.Node = .{ .data = .{ .runFn = runFn } },
97 wait_group: *WaitGroup,105 wait_group: *WaitGroup,
98106
99 fn runFn(runnable: *Runnable) void {107 fn runFn(runnable: *Runnable, _: ?usize) void {
100 const run_node: *RunQueue.Node = @fieldParentPtr("data", runnable);108 const run_node: *RunQueue.Node = @fieldParentPtr("data", runnable);
101 const closure: *@This() = @alignCast(@fieldParentPtr("run_node", run_node));109 const closure: *@This() = @alignCast(@fieldParentPtr("run_node", run_node));
102 @call(.auto, func, closure.arguments);110 @call(.auto, func, closure.arguments);
...@@ -134,6 +142,70 @@ pub fn spawnWg(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args...@@ -134,6 +142,70 @@ pub fn spawnWg(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args
134 pool.cond.signal();142 pool.cond.signal();
135}143}
136144
145/// Runs `func` in the thread pool, calling `WaitGroup.start` beforehand, and
146/// `WaitGroup.finish` after it returns.
147///
148/// The first argument passed to `func` is a dense `usize` thread id, the rest
149/// of the arguments are passed from `args`. Requires the pool to have been
150/// initialized with `.track_ids = true`.
151///
152/// In the case that queuing the function call fails to allocate memory, or the
153/// target is single-threaded, the function is called directly.
154pub fn spawnWgId(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args: anytype) void {
155 wait_group.start();
156
157 if (builtin.single_threaded) {
158 @call(.auto, func, .{0} ++ args);
159 wait_group.finish();
160 return;
161 }
162
163 const Args = @TypeOf(args);
164 const Closure = struct {
165 arguments: Args,
166 pool: *Pool,
167 run_node: RunQueue.Node = .{ .data = .{ .runFn = runFn } },
168 wait_group: *WaitGroup,
169
170 fn runFn(runnable: *Runnable, id: ?usize) void {
171 const run_node: *RunQueue.Node = @fieldParentPtr("data", runnable);
172 const closure: *@This() = @alignCast(@fieldParentPtr("run_node", run_node));
173 @call(.auto, func, .{id.?} ++ closure.arguments);
174 closure.wait_group.finish();
175
176 // The thread pool's allocator is protected by the mutex.
177 const mutex = &closure.pool.mutex;
178 mutex.lock();
179 defer mutex.unlock();
180
181 closure.pool.allocator.destroy(closure);
182 }
183 };
184
185 {
186 pool.mutex.lock();
187
188 const closure = pool.allocator.create(Closure) catch {
189 const id = pool.ids.getIndex(std.Thread.getCurrentId());
190 pool.mutex.unlock();
191 @call(.auto, func, .{id.?} ++ args);
192 wait_group.finish();
193 return;
194 };
195 closure.* = .{
196 .arguments = args,
197 .pool = pool,
198 .wait_group = wait_group,
199 };
200
201 pool.run_queue.prepend(&closure.run_node);
202 pool.mutex.unlock();
203 }
204
205 // Notify waiting threads outside the lock to try and keep the critical section small.
206 pool.cond.signal();
207}
208
137pub fn spawn(pool: *Pool, comptime func: anytype, args: anytype) !void {209pub fn spawn(pool: *Pool, comptime func: anytype, args: anytype) !void {
138 if (builtin.single_threaded) {210 if (builtin.single_threaded) {
139 @call(.auto, func, args);211 @call(.auto, func, args);
...@@ -181,14 +253,16 @@ fn worker(pool: *Pool) void {...@@ -181,14 +253,16 @@ fn worker(pool: *Pool) void {
181 pool.mutex.lock();253 pool.mutex.lock();
182 defer pool.mutex.unlock();254 defer pool.mutex.unlock();
183255
256 const id = if (pool.ids.count() > 0) pool.ids.count() else null;
257 if (id) |_| pool.ids.putAssumeCapacityNoClobber(std.Thread.getCurrentId(), {});
258
184 while (true) {259 while (true) {
185 while (pool.run_queue.popFirst()) |run_node| {260 while (pool.run_queue.popFirst()) |run_node| {
186 // Temporarily unlock the mutex in order to execute the run_node261 // Temporarily unlock the mutex in order to execute the run_node
187 pool.mutex.unlock();262 pool.mutex.unlock();
188 defer pool.mutex.lock();263 defer pool.mutex.lock();
189264
190 const runFn = run_node.data.runFn;265 run_node.data.runFn(&run_node.data, id);
191 runFn(&run_node.data);
192 }266 }
193267
194 // Stop executing instead of waiting if the thread pool is no longer running.268 // Stop executing instead of waiting if the thread pool is no longer running.
...@@ -201,16 +275,18 @@ fn worker(pool: *Pool) void {...@@ -201,16 +275,18 @@ fn worker(pool: *Pool) void {
201}275}
202276
203pub fn waitAndWork(pool: *Pool, wait_group: *WaitGroup) void {277pub fn waitAndWork(pool: *Pool, wait_group: *WaitGroup) void {
278 var id: ?usize = null;
279
204 while (!wait_group.isDone()) {280 while (!wait_group.isDone()) {
205 if (blk: {281 pool.mutex.lock();
206 pool.mutex.lock();282 if (pool.run_queue.popFirst()) |run_node| {
207 defer pool.mutex.unlock();283 id = id orelse pool.ids.getIndex(std.Thread.getCurrentId());
208 break :blk pool.run_queue.popFirst();284 pool.mutex.unlock();
209 }) |run_node| {285 run_node.data.runFn(&run_node.data, id);
210 run_node.data.runFn(&run_node.data);
211 continue;286 continue;
212 }287 }
213288
289 pool.mutex.unlock();
214 wait_group.wait();290 wait_group.wait();
215 return;291 return;
216 }292 }
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+31-29
...@@ -2146,6 +2146,8 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2146,6 +2146,8 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2146 try comp.performAllTheWork(main_progress_node);2146 try comp.performAllTheWork(main_progress_node);
21472147
2148 if (comp.module) |zcu| {2148 if (comp.module) |zcu| {
2149 const pt: Zcu.PerThread = .{ .zcu = zcu, .tid = .main };
2150
2149 if (build_options.enable_debug_extensions and comp.verbose_intern_pool) {2151 if (build_options.enable_debug_extensions and comp.verbose_intern_pool) {
2150 std.debug.print("intern pool stats for '{s}':\n", .{2152 std.debug.print("intern pool stats for '{s}':\n", .{
2151 comp.root_name,2153 comp.root_name,
...@@ -2165,10 +2167,10 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2165,10 +2167,10 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2165 // The `test_functions` decl has been intentionally postponed until now,2167 // The `test_functions` decl has been intentionally postponed until now,
2166 // at which point we must populate it with the list of test functions that2168 // at which point we must populate it with the list of test functions that
2167 // have been discovered and not filtered out.2169 // have been discovered and not filtered out.
2168 try zcu.populateTestFunctions(main_progress_node);2170 try pt.populateTestFunctions(main_progress_node);
2169 }2171 }
21702172
2171 try zcu.processExports();2173 try pt.processExports();
2172 }2174 }
21732175
2174 if (comp.totalErrorCount() != 0) {2176 if (comp.totalErrorCount() != 0) {
...@@ -2247,7 +2249,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2247,7 +2249,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2247 }2249 }
2248 }2250 }
22492251
2250 try flush(comp, arena, main_progress_node);2252 try flush(comp, arena, .main, main_progress_node);
2251 if (comp.totalErrorCount() != 0) return;2253 if (comp.totalErrorCount() != 0) return;
22522254
2253 // Failure here only means an unnecessary cache miss.2255 // Failure here only means an unnecessary cache miss.
...@@ -2264,16 +2266,16 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2264,16 +2266,16 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2264 whole.lock = man.toOwnedLock();2266 whole.lock = man.toOwnedLock();
2265 },2267 },
2266 .incremental => {2268 .incremental => {
2267 try flush(comp, arena, main_progress_node);2269 try flush(comp, arena, .main, main_progress_node);
2268 if (comp.totalErrorCount() != 0) return;2270 if (comp.totalErrorCount() != 0) return;
2269 },2271 },
2270 }2272 }
2271}2273}
22722274
2273fn flush(comp: *Compilation, arena: Allocator, prog_node: std.Progress.Node) !void {2275fn flush(comp: *Compilation, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void {
2274 if (comp.bin_file) |lf| {2276 if (comp.bin_file) |lf| {
2275 // This is needed before reading the error flags.2277 // This is needed before reading the error flags.
2276 lf.flush(arena, prog_node) catch |err| switch (err) {2278 lf.flush(arena, tid, prog_node) catch |err| switch (err) {
2277 error.FlushFailure => {}, // error reported through link_error_flags2279 error.FlushFailure => {}, // error reported through link_error_flags
2278 error.LLDReportedFailure => {}, // error reported via lockAndParseLldStderr2280 error.LLDReportedFailure => {}, // error reported via lockAndParseLldStderr
2279 else => |e| return e,2281 else => |e| return e,
...@@ -3419,7 +3421,7 @@ pub fn performAllTheWork(...@@ -3419,7 +3421,7 @@ pub fn performAllTheWork(
34193421
3420 while (true) {3422 while (true) {
3421 if (comp.work_queue.readItem()) |work_item| {3423 if (comp.work_queue.readItem()) |work_item| {
3422 try processOneJob(comp, work_item, main_progress_node);3424 try processOneJob(0, comp, work_item, main_progress_node);
3423 continue;3425 continue;
3424 }3426 }
3425 if (comp.module) |zcu| {3427 if (comp.module) |zcu| {
...@@ -3447,11 +3449,11 @@ pub fn performAllTheWork(...@@ -3447,11 +3449,11 @@ pub fn performAllTheWork(
3447 }3449 }
3448}3450}
34493451
3450fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !void {3452fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progress.Node) !void {
3451 switch (job) {3453 switch (job) {
3452 .codegen_decl => |decl_index| {3454 .codegen_decl => |decl_index| {
3453 const zcu = comp.module.?;3455 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
3454 const decl = zcu.declPtr(decl_index);3456 const decl = pt.zcu.declPtr(decl_index);
34553457
3456 switch (decl.analysis) {3458 switch (decl.analysis) {
3457 .unreferenced => unreachable,3459 .unreferenced => unreachable,
...@@ -3469,7 +3471,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo...@@ -3469,7 +3471,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo
34693471
3470 assert(decl.has_tv);3472 assert(decl.has_tv);
34713473
3472 try zcu.linkerUpdateDecl(decl_index);3474 try pt.linkerUpdateDecl(decl_index);
3473 return;3475 return;
3474 },3476 },
3475 }3477 }
...@@ -3478,16 +3480,16 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo...@@ -3478,16 +3480,16 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo
3478 const named_frame = tracy.namedFrame("codegen_func");3480 const named_frame = tracy.namedFrame("codegen_func");
3479 defer named_frame.end();3481 defer named_frame.end();
34803482
3481 const zcu = comp.module.?;3483 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
3482 // This call takes ownership of `func.air`.3484 // This call takes ownership of `func.air`.
3483 try zcu.linkerUpdateFunc(func.func, func.air);3485 try pt.linkerUpdateFunc(func.func, func.air);
3484 },3486 },
3485 .analyze_func => |func| {3487 .analyze_func => |func| {
3486 const named_frame = tracy.namedFrame("analyze_func");3488 const named_frame = tracy.namedFrame("analyze_func");
3487 defer named_frame.end();3489 defer named_frame.end();
34883490
3489 const zcu = comp.module.?;3491 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
3490 zcu.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {3492 pt.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
3491 error.OutOfMemory => return error.OutOfMemory,3493 error.OutOfMemory => return error.OutOfMemory,
3492 error.AnalysisFail => return,3494 error.AnalysisFail => return,
3493 };3495 };
...@@ -3496,8 +3498,8 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo...@@ -3496,8 +3498,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, " ++3498 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");3499 "not decl analysis, which is too early to know about @export calls");
34983500
3499 const zcu = comp.module.?;3501 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
3500 const decl = zcu.declPtr(decl_index);3502 const decl = pt.zcu.declPtr(decl_index);
35013503
3502 switch (decl.analysis) {3504 switch (decl.analysis) {
3503 .unreferenced => unreachable,3505 .unreferenced => unreachable,
...@@ -3515,7 +3517,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo...@@ -3515,7 +3517,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo
3515 defer named_frame.end();3517 defer named_frame.end();
35163518
3517 const gpa = comp.gpa;3519 const gpa = comp.gpa;
3518 const emit_h = zcu.emit_h.?;3520 const emit_h = pt.zcu.emit_h.?;
3519 _ = try emit_h.decl_table.getOrPut(gpa, decl_index);3521 _ = try emit_h.decl_table.getOrPut(gpa, decl_index);
3520 const decl_emit_h = emit_h.declPtr(decl_index);3522 const decl_emit_h = emit_h.declPtr(decl_index);
3521 const fwd_decl = &decl_emit_h.fwd_decl;3523 const fwd_decl = &decl_emit_h.fwd_decl;
...@@ -3523,11 +3525,11 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo...@@ -3523,11 +3525,11 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo
3523 var ctypes_arena = std.heap.ArenaAllocator.init(gpa);3525 var ctypes_arena = std.heap.ArenaAllocator.init(gpa);
3524 defer ctypes_arena.deinit();3526 defer ctypes_arena.deinit();
35253527
3526 const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu);3528 const file_scope = pt.zcu.namespacePtr(decl.src_namespace).fileScope(pt.zcu);
35273529
3528 var dg: c_codegen.DeclGen = .{3530 var dg: c_codegen.DeclGen = .{
3529 .gpa = gpa,3531 .gpa = gpa,
3530 .zcu = zcu,3532 .pt = pt,
3531 .mod = file_scope.mod,3533 .mod = file_scope.mod,
3532 .error_msg = null,3534 .error_msg = null,
3533 .pass = .{ .decl = decl_index },3535 .pass = .{ .decl = decl_index },
...@@ -3557,25 +3559,25 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo...@@ -3557,25 +3559,25 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo
3557 }3559 }
3558 },3560 },
3559 .analyze_decl => |decl_index| {3561 .analyze_decl => |decl_index| {
3560 const zcu = comp.module.?;3562 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
3561 zcu.ensureDeclAnalyzed(decl_index) catch |err| switch (err) {3563 pt.ensureDeclAnalyzed(decl_index) catch |err| switch (err) {
3562 error.OutOfMemory => return error.OutOfMemory,3564 error.OutOfMemory => return error.OutOfMemory,
3563 error.AnalysisFail => return,3565 error.AnalysisFail => return,
3564 };3566 };
3565 const decl = zcu.declPtr(decl_index);3567 const decl = pt.zcu.declPtr(decl_index);
3566 if (decl.kind == .@"test" and comp.config.is_test) {3568 if (decl.kind == .@"test" and comp.config.is_test) {
3567 // Tests are always emitted in test binaries. The decl_refs are created by3569 // Tests are always emitted in test binaries. The decl_refs are created by
3568 // Zcu.populateTestFunctions, but this will not queue body analysis, so do3570 // Zcu.populateTestFunctions, but this will not queue body analysis, so do
3569 // that now.3571 // that now.
3570 try zcu.ensureFuncBodyAnalysisQueued(decl.val.toIntern());3572 try pt.zcu.ensureFuncBodyAnalysisQueued(decl.val.toIntern());
3571 }3573 }
3572 },3574 },
3573 .resolve_type_fully => |ty| {3575 .resolve_type_fully => |ty| {
3574 const named_frame = tracy.namedFrame("resolve_type_fully");3576 const named_frame = tracy.namedFrame("resolve_type_fully");
3575 defer named_frame.end();3577 defer named_frame.end();
35763578
3577 const zcu = comp.module.?;3579 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
3578 Type.fromInterned(ty).resolveFully(zcu) catch |err| switch (err) {3580 Type.fromInterned(ty).resolveFully(pt) catch |err| switch (err) {
3579 error.OutOfMemory => return error.OutOfMemory,3581 error.OutOfMemory => return error.OutOfMemory,
3580 error.AnalysisFail => return,3582 error.AnalysisFail => return,
3581 };3583 };
...@@ -3603,12 +3605,12 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo...@@ -3603,12 +3605,12 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo
3603 try zcu.retryable_failures.append(gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));3605 try zcu.retryable_failures.append(gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));
3604 };3606 };
3605 },3607 },
3606 .analyze_mod => |pkg| {3608 .analyze_mod => |mod| {
3607 const named_frame = tracy.namedFrame("analyze_mod");3609 const named_frame = tracy.namedFrame("analyze_mod");
3608 defer named_frame.end();3610 defer named_frame.end();
36093611
3610 const zcu = comp.module.?;3612 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
3611 zcu.semaPkg(pkg) catch |err| switch (err) {3613 pt.semaPkg(mod) catch |err| switch (err) {
3612 error.OutOfMemory => return error.OutOfMemory,3614 error.OutOfMemory => return error.OutOfMemory,
3613 error.AnalysisFail => return,3615 error.AnalysisFail => return,
3614 };3616 };
src/InternPool.zig+156-86
...@@ -4548,17 +4548,14 @@ pub fn init(ip: *InternPool, gpa: Allocator) !void {...@@ -4548,17 +4548,14 @@ pub fn init(ip: *InternPool, gpa: Allocator) !void {
45484548
4549 // This inserts all the statically-known values into the intern pool in the4549 // This inserts all the statically-known values into the intern pool in the
4550 // order expected.4550 // order expected.
4551 for (static_keys[0..@intFromEnum(Index.empty_struct_type)]) |key| {4551 for (&static_keys, 0..) |key, key_index| switch (@as(Index, @enumFromInt(key_index))) {
4552 _ = ip.get(gpa, key) catch unreachable;4552 .empty_struct_type => assert(try ip.getAnonStructType(gpa, .main, .{
4553 }4553 .types = &.{},
4554 _ = ip.getAnonStructType(gpa, .{4554 .names = &.{},
4555 .types = &.{},4555 .values = &.{},
4556 .names = &.{},4556 }) == .empty_struct_type),
4557 .values = &.{},4557 else => |expected_index| assert(try ip.get(gpa, .main, key) == expected_index),
4558 }) catch unreachable;4558 };
4559 for (static_keys[@intFromEnum(Index.empty_struct_type) + 1 ..]) |key| {
4560 _ = ip.get(gpa, key) catch unreachable;
4561 }
45624559
4563 if (std.debug.runtime_safety) {4560 if (std.debug.runtime_safety) {
4564 // Sanity check.4561 // Sanity check.
...@@ -5242,7 +5239,7 @@ fn indexToKeyBigInt(ip: *const InternPool, limb_index: u32, positive: bool) Key...@@ -5242,7 +5239,7 @@ fn indexToKeyBigInt(ip: *const InternPool, limb_index: u32, positive: bool) Key
5242 } };5239 } };
5243}5240}
52445241
5245pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {5242pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) Allocator.Error!Index {
5246 const adapter: KeyAdapter = .{ .intern_pool = ip };5243 const adapter: KeyAdapter = .{ .intern_pool = ip };
5247 const gop = try ip.map.getOrPutAdapted(gpa, key, adapter);5244 const gop = try ip.map.getOrPutAdapted(gpa, key, adapter);
5248 if (gop.found_existing) return @enumFromInt(gop.index);5245 if (gop.found_existing) return @enumFromInt(gop.index);
...@@ -5266,8 +5263,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5266,8 +5263,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5266 _ = ip.map.pop();5263 _ = ip.map.pop();
5267 var new_key = key;5264 var new_key = key;
5268 new_key.ptr_type.flags.size = .Many;5265 new_key.ptr_type.flags.size = .Many;
5269 const ptr_type_index = try ip.get(gpa, new_key);5266 const ptr_type_index = try ip.get(gpa, tid, new_key);
5270 assert(!(try ip.map.getOrPutAdapted(gpa, key, adapter)).found_existing);5267 assert(!(try ip.map.getOrPutAdapted(gpa, key, adapter)).found_existing);
5268
5271 try ip.items.ensureUnusedCapacity(gpa, 1);5269 try ip.items.ensureUnusedCapacity(gpa, 1);
5272 ip.items.appendAssumeCapacity(.{5270 ip.items.appendAssumeCapacity(.{
5273 .tag = .type_slice,5271 .tag = .type_slice,
...@@ -5519,7 +5517,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5519,7 +5517,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5519 else => unreachable,5517 else => unreachable,
5520 }5518 }
5521 _ = ip.map.pop();5519 _ = ip.map.pop();
5522 const index_index = try ip.get(gpa, .{ .int = .{5520 const index_index = try ip.get(gpa, tid, .{ .int = .{
5523 .ty = .usize_type,5521 .ty = .usize_type,
5524 .storage = .{ .u64 = base_index.index },5522 .storage = .{ .u64 = base_index.index },
5525 } });5523 } });
...@@ -5932,7 +5930,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5932,7 +5930,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5932 const elem = switch (aggregate.storage) {5930 const elem = switch (aggregate.storage) {
5933 .bytes => |bytes| elem: {5931 .bytes => |bytes| elem: {
5934 _ = ip.map.pop();5932 _ = ip.map.pop();
5935 const elem = try ip.get(gpa, .{ .int = .{5933 const elem = try ip.get(gpa, tid, .{ .int = .{
5936 .ty = .u8_type,5934 .ty = .u8_type,
5937 .storage = .{ .u64 = bytes.at(0, ip) },5935 .storage = .{ .u64 = bytes.at(0, ip) },
5938 } });5936 } });
...@@ -6074,7 +6072,12 @@ pub const UnionTypeInit = struct {...@@ -6074,7 +6072,12 @@ pub const UnionTypeInit = struct {
6074 },6072 },
6075};6073};
60766074
6077pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocator.Error!WipNamespaceType.Result {6075pub fn getUnionType(
6076 ip: *InternPool,
6077 gpa: Allocator,
6078 _: Zcu.PerThread.Id,
6079 ini: UnionTypeInit,
6080) Allocator.Error!WipNamespaceType.Result {
6078 const adapter: KeyAdapter = .{ .intern_pool = ip };6081 const adapter: KeyAdapter = .{ .intern_pool = ip };
6079 const gop = try ip.map.getOrPutAdapted(gpa, Key{ .union_type = switch (ini.key) {6082 const gop = try ip.map.getOrPutAdapted(gpa, Key{ .union_type = switch (ini.key) {
6080 .declared => |d| .{ .declared = .{6083 .declared => |d| .{ .declared = .{
...@@ -6221,6 +6224,7 @@ pub const StructTypeInit = struct {...@@ -6221,6 +6224,7 @@ pub const StructTypeInit = struct {
6221pub fn getStructType(6224pub fn getStructType(
6222 ip: *InternPool,6225 ip: *InternPool,
6223 gpa: Allocator,6226 gpa: Allocator,
6227 _: Zcu.PerThread.Id,
6224 ini: StructTypeInit,6228 ini: StructTypeInit,
6225) Allocator.Error!WipNamespaceType.Result {6229) Allocator.Error!WipNamespaceType.Result {
6226 const adapter: KeyAdapter = .{ .intern_pool = ip };6230 const adapter: KeyAdapter = .{ .intern_pool = ip };
...@@ -6396,7 +6400,12 @@ pub const AnonStructTypeInit = struct {...@@ -6396,7 +6400,12 @@ pub const AnonStructTypeInit = struct {
6396 values: []const Index,6400 values: []const Index,
6397};6401};
63986402
6399pub fn getAnonStructType(ip: *InternPool, gpa: Allocator, ini: AnonStructTypeInit) Allocator.Error!Index {6403pub fn getAnonStructType(
6404 ip: *InternPool,
6405 gpa: Allocator,
6406 _: Zcu.PerThread.Id,
6407 ini: AnonStructTypeInit,
6408) Allocator.Error!Index {
6400 assert(ini.types.len == ini.values.len);6409 assert(ini.types.len == ini.values.len);
6401 for (ini.types) |elem| assert(elem != .none);6410 for (ini.types) |elem| assert(elem != .none);
64026411
...@@ -6450,7 +6459,12 @@ pub const GetFuncTypeKey = struct {...@@ -6450,7 +6459,12 @@ pub const GetFuncTypeKey = struct {
6450 addrspace_is_generic: bool = false,6459 addrspace_is_generic: bool = false,
6451};6460};
64526461
6453pub fn getFuncType(ip: *InternPool, gpa: Allocator, key: GetFuncTypeKey) Allocator.Error!Index {6462pub fn getFuncType(
6463 ip: *InternPool,
6464 gpa: Allocator,
6465 _: Zcu.PerThread.Id,
6466 key: GetFuncTypeKey,
6467) Allocator.Error!Index {
6454 // Validate input parameters.6468 // Validate input parameters.
6455 assert(key.return_type != .none);6469 assert(key.return_type != .none);
6456 for (key.param_types) |param_type| assert(param_type != .none);6470 for (key.param_types) |param_type| assert(param_type != .none);
...@@ -6503,7 +6517,12 @@ pub fn getFuncType(ip: *InternPool, gpa: Allocator, key: GetFuncTypeKey) Allocat...@@ -6503,7 +6517,12 @@ pub fn getFuncType(ip: *InternPool, gpa: Allocator, key: GetFuncTypeKey) Allocat
6503 return @enumFromInt(ip.items.len - 1);6517 return @enumFromInt(ip.items.len - 1);
6504}6518}
65056519
6506pub fn getExternFunc(ip: *InternPool, gpa: Allocator, key: Key.ExternFunc) Allocator.Error!Index {6520pub fn getExternFunc(
6521 ip: *InternPool,
6522 gpa: Allocator,
6523 _: Zcu.PerThread.Id,
6524 key: Key.ExternFunc,
6525) Allocator.Error!Index {
6507 const adapter: KeyAdapter = .{ .intern_pool = ip };6526 const adapter: KeyAdapter = .{ .intern_pool = ip };
6508 const gop = try ip.map.getOrPutAdapted(gpa, Key{ .extern_func = key }, adapter);6527 const gop = try ip.map.getOrPutAdapted(gpa, Key{ .extern_func = key }, adapter);
6509 if (gop.found_existing) return @enumFromInt(gop.index);6528 if (gop.found_existing) return @enumFromInt(gop.index);
...@@ -6531,7 +6550,12 @@ pub const GetFuncDeclKey = struct {...@@ -6531,7 +6550,12 @@ pub const GetFuncDeclKey = struct {
6531 is_noinline: bool,6550 is_noinline: bool,
6532};6551};
65336552
6534pub fn getFuncDecl(ip: *InternPool, gpa: Allocator, key: GetFuncDeclKey) Allocator.Error!Index {6553pub fn getFuncDecl(
6554 ip: *InternPool,
6555 gpa: Allocator,
6556 _: Zcu.PerThread.Id,
6557 key: GetFuncDeclKey,
6558) Allocator.Error!Index {
6535 // The strategy here is to add the function type unconditionally, then to6559 // 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 mutated6560 // ask if it already exists, and if so, revert the lengths of the mutated
6537 // arrays. This is similar to what `getOrPutTrailingString` does.6561 // arrays. This is similar to what `getOrPutTrailingString` does.
...@@ -6598,7 +6622,12 @@ pub const GetFuncDeclIesKey = struct {...@@ -6598,7 +6622,12 @@ pub const GetFuncDeclIesKey = struct {
6598 rbrace_column: u32,6622 rbrace_column: u32,
6599};6623};
66006624
6601pub fn getFuncDeclIes(ip: *InternPool, gpa: Allocator, key: GetFuncDeclIesKey) Allocator.Error!Index {6625pub fn getFuncDeclIes(
6626 ip: *InternPool,
6627 gpa: Allocator,
6628 _: Zcu.PerThread.Id,
6629 key: GetFuncDeclIesKey,
6630) Allocator.Error!Index {
6602 // Validate input parameters.6631 // Validate input parameters.
6603 assert(key.bare_return_type != .none);6632 assert(key.bare_return_type != .none);
6604 for (key.param_types) |param_type| assert(param_type != .none);6633 for (key.param_types) |param_type| assert(param_type != .none);
...@@ -6707,6 +6736,7 @@ pub fn getFuncDeclIes(ip: *InternPool, gpa: Allocator, key: GetFuncDeclIesKey) A...@@ -6707,6 +6736,7 @@ pub fn getFuncDeclIes(ip: *InternPool, gpa: Allocator, key: GetFuncDeclIesKey) A
6707pub fn getErrorSetType(6736pub fn getErrorSetType(
6708 ip: *InternPool,6737 ip: *InternPool,
6709 gpa: Allocator,6738 gpa: Allocator,
6739 _: Zcu.PerThread.Id,
6710 names: []const NullTerminatedString,6740 names: []const NullTerminatedString,
6711) Allocator.Error!Index {6741) Allocator.Error!Index {
6712 assert(std.sort.isSorted(NullTerminatedString, names, {}, NullTerminatedString.indexLessThan));6742 assert(std.sort.isSorted(NullTerminatedString, names, {}, NullTerminatedString.indexLessThan));
...@@ -6770,11 +6800,16 @@ pub const GetFuncInstanceKey = struct {...@@ -6770,11 +6800,16 @@ pub const GetFuncInstanceKey = struct {
6770 inferred_error_set: bool,6800 inferred_error_set: bool,
6771};6801};
67726802
6773pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey) Allocator.Error!Index {6803pub fn getFuncInstance(
6804 ip: *InternPool,
6805 gpa: Allocator,
6806 tid: Zcu.PerThread.Id,
6807 arg: GetFuncInstanceKey,
6808) Allocator.Error!Index {
6774 if (arg.inferred_error_set)6809 if (arg.inferred_error_set)
6775 return getFuncInstanceIes(ip, gpa, arg);6810 return getFuncInstanceIes(ip, gpa, tid, arg);
67766811
6777 const func_ty = try ip.getFuncType(gpa, .{6812 const func_ty = try ip.getFuncType(gpa, tid, .{
6778 .param_types = arg.param_types,6813 .param_types = arg.param_types,
6779 .return_type = arg.bare_return_type,6814 .return_type = arg.bare_return_type,
6780 .noalias_bits = arg.noalias_bits,6815 .noalias_bits = arg.noalias_bits,
...@@ -6844,6 +6879,7 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey)...@@ -6844,6 +6879,7 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey)
6844pub fn getFuncInstanceIes(6879pub fn getFuncInstanceIes(
6845 ip: *InternPool,6880 ip: *InternPool,
6846 gpa: Allocator,6881 gpa: Allocator,
6882 _: Zcu.PerThread.Id,
6847 arg: GetFuncInstanceKey,6883 arg: GetFuncInstanceKey,
6848) Allocator.Error!Index {6884) Allocator.Error!Index {
6849 // Validate input parameters.6885 // Validate input parameters.
...@@ -6955,7 +6991,6 @@ pub fn getFuncInstanceIes(...@@ -6955,7 +6991,6 @@ pub fn getFuncInstanceIes(
6955 assert(!ip.map.getOrPutAssumeCapacityAdapted(Key{6991 assert(!ip.map.getOrPutAssumeCapacityAdapted(Key{
6956 .func_type = extraFuncType(ip, func_type_extra_index),6992 .func_type = extraFuncType(ip, func_type_extra_index),
6957 }, adapter).found_existing);6993 }, adapter).found_existing);
6958
6959 return finishFuncInstance(6994 return finishFuncInstance(
6960 ip,6995 ip,
6961 gpa,6996 gpa,
...@@ -7096,6 +7131,7 @@ pub const WipEnumType = struct {...@@ -7096,6 +7131,7 @@ pub const WipEnumType = struct {
7096pub fn getEnumType(7131pub fn getEnumType(
7097 ip: *InternPool,7132 ip: *InternPool,
7098 gpa: Allocator,7133 gpa: Allocator,
7134 _: Zcu.PerThread.Id,
7099 ini: EnumTypeInit,7135 ini: EnumTypeInit,
7100) Allocator.Error!WipEnumType.Result {7136) Allocator.Error!WipEnumType.Result {
7101 const adapter: KeyAdapter = .{ .intern_pool = ip };7137 const adapter: KeyAdapter = .{ .intern_pool = ip };
...@@ -7172,7 +7208,7 @@ pub fn getEnumType(...@@ -7172,7 +7208,7 @@ pub fn getEnumType(
7172 break :m values_map.toOptional();7208 break :m values_map.toOptional();
7173 };7209 };
7174 errdefer if (ini.has_values) {7210 errdefer if (ini.has_values) {
7175 _ = ip.map.pop();7211 _ = ip.maps.pop();
7176 };7212 };
71777213
7178 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumExplicit).Struct.fields.len +7214 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumExplicit).Struct.fields.len +
...@@ -7245,7 +7281,12 @@ const GeneratedTagEnumTypeInit = struct {...@@ -7245,7 +7281,12 @@ const GeneratedTagEnumTypeInit = struct {
7245/// Creates an enum type which was automatically-generated as the tag type of a7281/// 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 union7282/// `union` with no explicit tag type. Since this is only called once per union
7247/// type, it asserts that no matching type yet exists.7283/// type, it asserts that no matching type yet exists.
7248pub fn getGeneratedTagEnumType(ip: *InternPool, gpa: Allocator, ini: GeneratedTagEnumTypeInit) Allocator.Error!Index {7284pub fn getGeneratedTagEnumType(
7285 ip: *InternPool,
7286 gpa: Allocator,
7287 _: Zcu.PerThread.Id,
7288 ini: GeneratedTagEnumTypeInit,
7289) Allocator.Error!Index {
7249 assert(ip.isUnion(ini.owner_union_ty));7290 assert(ip.isUnion(ini.owner_union_ty));
7250 assert(ip.isIntegerType(ini.tag_ty));7291 assert(ip.isIntegerType(ini.tag_ty));
7251 for (ini.values) |val| assert(ip.typeOf(val) == ini.tag_ty);7292 for (ini.values) |val| assert(ip.typeOf(val) == ini.tag_ty);
...@@ -7342,7 +7383,12 @@ pub const OpaqueTypeInit = struct {...@@ -7342,7 +7383,12 @@ pub const OpaqueTypeInit = struct {
7342 },7383 },
7343};7384};
73447385
7345pub fn getOpaqueType(ip: *InternPool, gpa: Allocator, ini: OpaqueTypeInit) Allocator.Error!WipNamespaceType.Result {7386pub fn getOpaqueType(
7387 ip: *InternPool,
7388 gpa: Allocator,
7389 _: Zcu.PerThread.Id,
7390 ini: OpaqueTypeInit,
7391) Allocator.Error!WipNamespaceType.Result {
7346 const adapter: KeyAdapter = .{ .intern_pool = ip };7392 const adapter: KeyAdapter = .{ .intern_pool = ip };
7347 const gop = try ip.map.getOrPutAdapted(gpa, Key{ .opaque_type = switch (ini.key) {7393 const gop = try ip.map.getOrPutAdapted(gpa, Key{ .opaque_type = switch (ini.key) {
7348 .declared => |d| .{ .declared = .{7394 .declared => |d| .{ .declared = .{
...@@ -7680,23 +7726,23 @@ test "basic usage" {...@@ -7680,23 +7726,23 @@ test "basic usage" {
7680 var ip: InternPool = .{};7726 var ip: InternPool = .{};
7681 defer ip.deinit(gpa);7727 defer ip.deinit(gpa);
76827728
7683 const i32_type = try ip.get(gpa, .{ .int_type = .{7729 const i32_type = try ip.get(gpa, .main, .{ .int_type = .{
7684 .signedness = .signed,7730 .signedness = .signed,
7685 .bits = 32,7731 .bits = 32,
7686 } });7732 } });
7687 const array_i32 = try ip.get(gpa, .{ .array_type = .{7733 const array_i32 = try ip.get(gpa, .main, .{ .array_type = .{
7688 .len = 10,7734 .len = 10,
7689 .child = i32_type,7735 .child = i32_type,
7690 .sentinel = .none,7736 .sentinel = .none,
7691 } });7737 } });
76927738
7693 const another_i32_type = try ip.get(gpa, .{ .int_type = .{7739 const another_i32_type = try ip.get(gpa, .main, .{ .int_type = .{
7694 .signedness = .signed,7740 .signedness = .signed,
7695 .bits = 32,7741 .bits = 32,
7696 } });7742 } });
7697 try std.testing.expect(another_i32_type == i32_type);7743 try std.testing.expect(another_i32_type == i32_type);
76987744
7699 const another_array_i32 = try ip.get(gpa, .{ .array_type = .{7745 const another_array_i32 = try ip.get(gpa, .main, .{ .array_type = .{
7700 .len = 10,7746 .len = 10,
7701 .child = i32_type,7747 .child = i32_type,
7702 .sentinel = .none,7748 .sentinel = .none,
...@@ -7766,48 +7812,54 @@ pub fn sliceLen(ip: *const InternPool, i: Index) Index {...@@ -7766,48 +7812,54 @@ pub fn sliceLen(ip: *const InternPool, i: Index) Index {
7766/// * payload => error union7812/// * payload => error union
7767/// * fn <=> fn7813/// * fn <=> fn
7768/// * aggregate <=> aggregate (where children can also be coerced)7814/// * aggregate <=> aggregate (where children can also be coerced)
7769pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index {7815pub fn getCoerced(
7816 ip: *InternPool,
7817 gpa: Allocator,
7818 tid: Zcu.PerThread.Id,
7819 val: Index,
7820 new_ty: Index,
7821) Allocator.Error!Index {
7770 const old_ty = ip.typeOf(val);7822 const old_ty = ip.typeOf(val);
7771 if (old_ty == new_ty) return val;7823 if (old_ty == new_ty) return val;
77727824
7773 const tags = ip.items.items(.tag);7825 const tags = ip.items.items(.tag);
77747826
7775 switch (val) {7827 switch (val) {
7776 .undef => return ip.get(gpa, .{ .undef = new_ty }),7828 .undef => return ip.get(gpa, tid, .{ .undef = new_ty }),
7777 .null_value => {7829 .null_value => {
7778 if (ip.isOptionalType(new_ty)) return ip.get(gpa, .{ .opt = .{7830 if (ip.isOptionalType(new_ty)) return ip.get(gpa, tid, .{ .opt = .{
7779 .ty = new_ty,7831 .ty = new_ty,
7780 .val = .none,7832 .val = .none,
7781 } });7833 } });
77827834
7783 if (ip.isPointerType(new_ty)) switch (ip.indexToKey(new_ty).ptr_type.flags.size) {7835 if (ip.isPointerType(new_ty)) switch (ip.indexToKey(new_ty).ptr_type.flags.size) {
7784 .One, .Many, .C => return ip.get(gpa, .{ .ptr = .{7836 .One, .Many, .C => return ip.get(gpa, tid, .{ .ptr = .{
7785 .ty = new_ty,7837 .ty = new_ty,
7786 .base_addr = .int,7838 .base_addr = .int,
7787 .byte_offset = 0,7839 .byte_offset = 0,
7788 } }),7840 } }),
7789 .Slice => return ip.get(gpa, .{ .slice = .{7841 .Slice => return ip.get(gpa, tid, .{ .slice = .{
7790 .ty = new_ty,7842 .ty = new_ty,
7791 .ptr = try ip.get(gpa, .{ .ptr = .{7843 .ptr = try ip.get(gpa, tid, .{ .ptr = .{
7792 .ty = ip.slicePtrType(new_ty),7844 .ty = ip.slicePtrType(new_ty),
7793 .base_addr = .int,7845 .base_addr = .int,
7794 .byte_offset = 0,7846 .byte_offset = 0,
7795 } }),7847 } }),
7796 .len = try ip.get(gpa, .{ .undef = .usize_type }),7848 .len = try ip.get(gpa, tid, .{ .undef = .usize_type }),
7797 } }),7849 } }),
7798 };7850 };
7799 },7851 },
7800 else => switch (tags[@intFromEnum(val)]) {7852 else => switch (tags[@intFromEnum(val)]) {
7801 .func_decl => return getCoercedFuncDecl(ip, gpa, val, new_ty),7853 .func_decl => return getCoercedFuncDecl(ip, gpa, tid, val, new_ty),
7802 .func_instance => return getCoercedFuncInstance(ip, gpa, val, new_ty),7854 .func_instance => return getCoercedFuncInstance(ip, gpa, tid, val, new_ty),
7803 .func_coerced => {7855 .func_coerced => {
7804 const extra_index = ip.items.items(.data)[@intFromEnum(val)];7856 const extra_index = ip.items.items(.data)[@intFromEnum(val)];
7805 const func: Index = @enumFromInt(7857 const func: Index = @enumFromInt(
7806 ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncCoerced, "func").?],7858 ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncCoerced, "func").?],
7807 );7859 );
7808 switch (tags[@intFromEnum(func)]) {7860 switch (tags[@intFromEnum(func)]) {
7809 .func_decl => return getCoercedFuncDecl(ip, gpa, val, new_ty),7861 .func_decl => return getCoercedFuncDecl(ip, gpa, tid, val, new_ty),
7810 .func_instance => return getCoercedFuncInstance(ip, gpa, val, new_ty),7862 .func_instance => return getCoercedFuncInstance(ip, gpa, tid, val, new_ty),
7811 else => unreachable,7863 else => unreachable,
7812 }7864 }
7813 },7865 },
...@@ -7816,9 +7868,9 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -7816,9 +7868,9 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
7816 }7868 }
78177869
7818 switch (ip.indexToKey(val)) {7870 switch (ip.indexToKey(val)) {
7819 .undef => return ip.get(gpa, .{ .undef = new_ty }),7871 .undef => return ip.get(gpa, tid, .{ .undef = new_ty }),
7820 .extern_func => |extern_func| if (ip.isFunctionType(new_ty))7872 .extern_func => |extern_func| if (ip.isFunctionType(new_ty))
7821 return ip.get(gpa, .{ .extern_func = .{7873 return ip.get(gpa, tid, .{ .extern_func = .{
7822 .ty = new_ty,7874 .ty = new_ty,
7823 .decl = extern_func.decl,7875 .decl = extern_func.decl,
7824 .lib_name = extern_func.lib_name,7876 .lib_name = extern_func.lib_name,
...@@ -7827,12 +7879,12 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -7827,12 +7879,12 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
7827 .func => unreachable,7879 .func => unreachable,
78287880
7829 .int => |int| switch (ip.indexToKey(new_ty)) {7881 .int => |int| switch (ip.indexToKey(new_ty)) {
7830 .enum_type => return ip.get(gpa, .{ .enum_tag = .{7882 .enum_type => return ip.get(gpa, tid, .{ .enum_tag = .{
7831 .ty = new_ty,7883 .ty = new_ty,
7832 .int = try ip.getCoerced(gpa, val, ip.loadEnumType(new_ty).tag_ty),7884 .int = try ip.getCoerced(gpa, tid, val, ip.loadEnumType(new_ty).tag_ty),
7833 } }),7885 } }),
7834 .ptr_type => switch (int.storage) {7886 .ptr_type => switch (int.storage) {
7835 inline .u64, .i64 => |int_val| return ip.get(gpa, .{ .ptr = .{7887 inline .u64, .i64 => |int_val| return ip.get(gpa, tid, .{ .ptr = .{
7836 .ty = new_ty,7888 .ty = new_ty,
7837 .base_addr = .int,7889 .base_addr = .int,
7838 .byte_offset = @intCast(int_val),7890 .byte_offset = @intCast(int_val),
...@@ -7841,7 +7893,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -7841,7 +7893,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
7841 .lazy_align, .lazy_size => {},7893 .lazy_align, .lazy_size => {},
7842 },7894 },
7843 else => if (ip.isIntegerType(new_ty))7895 else => if (ip.isIntegerType(new_ty))
7844 return getCoercedInts(ip, gpa, int, new_ty),7896 return ip.getCoercedInts(gpa, tid, int, new_ty),
7845 },7897 },
7846 .float => |float| switch (ip.indexToKey(new_ty)) {7898 .float => |float| switch (ip.indexToKey(new_ty)) {
7847 .simple_type => |simple| switch (simple) {7899 .simple_type => |simple| switch (simple) {
...@@ -7852,7 +7904,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -7852,7 +7904,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
7852 .f128,7904 .f128,
7853 .c_longdouble,7905 .c_longdouble,
7854 .comptime_float,7906 .comptime_float,
7855 => return ip.get(gpa, .{ .float = .{7907 => return ip.get(gpa, tid, .{ .float = .{
7856 .ty = new_ty,7908 .ty = new_ty,
7857 .storage = float.storage,7909 .storage = float.storage,
7858 } }),7910 } }),
...@@ -7861,17 +7913,17 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -7861,17 +7913,17 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
7861 else => {},7913 else => {},
7862 },7914 },
7863 .enum_tag => |enum_tag| if (ip.isIntegerType(new_ty))7915 .enum_tag => |enum_tag| if (ip.isIntegerType(new_ty))
7864 return getCoercedInts(ip, gpa, ip.indexToKey(enum_tag.int).int, new_ty),7916 return ip.getCoercedInts(gpa, tid, ip.indexToKey(enum_tag.int).int, new_ty),
7865 .enum_literal => |enum_literal| switch (ip.indexToKey(new_ty)) {7917 .enum_literal => |enum_literal| switch (ip.indexToKey(new_ty)) {
7866 .enum_type => {7918 .enum_type => {
7867 const enum_type = ip.loadEnumType(new_ty);7919 const enum_type = ip.loadEnumType(new_ty);
7868 const index = enum_type.nameIndex(ip, enum_literal).?;7920 const index = enum_type.nameIndex(ip, enum_literal).?;
7869 return ip.get(gpa, .{ .enum_tag = .{7921 return ip.get(gpa, tid, .{ .enum_tag = .{
7870 .ty = new_ty,7922 .ty = new_ty,
7871 .int = if (enum_type.values.len != 0)7923 .int = if (enum_type.values.len != 0)
7872 enum_type.values.get(ip)[index]7924 enum_type.values.get(ip)[index]
7873 else7925 else
7874 try ip.get(gpa, .{ .int = .{7926 try ip.get(gpa, tid, .{ .int = .{
7875 .ty = enum_type.tag_ty,7927 .ty = enum_type.tag_ty,
7876 .storage = .{ .u64 = index },7928 .storage = .{ .u64 = index },
7877 } }),7929 } }),
...@@ -7880,22 +7932,22 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -7880,22 +7932,22 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
7880 else => {},7932 else => {},
7881 },7933 },
7882 .slice => |slice| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size == .Slice)7934 .slice => |slice| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size == .Slice)
7883 return ip.get(gpa, .{ .slice = .{7935 return ip.get(gpa, tid, .{ .slice = .{
7884 .ty = new_ty,7936 .ty = new_ty,
7885 .ptr = try ip.getCoerced(gpa, slice.ptr, ip.slicePtrType(new_ty)),7937 .ptr = try ip.getCoerced(gpa, tid, slice.ptr, ip.slicePtrType(new_ty)),
7886 .len = slice.len,7938 .len = slice.len,
7887 } })7939 } })
7888 else if (ip.isIntegerType(new_ty))7940 else if (ip.isIntegerType(new_ty))
7889 return ip.getCoerced(gpa, slice.ptr, new_ty),7941 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)7942 .ptr => |ptr| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size != .Slice)
7891 return ip.get(gpa, .{ .ptr = .{7943 return ip.get(gpa, tid, .{ .ptr = .{
7892 .ty = new_ty,7944 .ty = new_ty,
7893 .base_addr = ptr.base_addr,7945 .base_addr = ptr.base_addr,
7894 .byte_offset = ptr.byte_offset,7946 .byte_offset = ptr.byte_offset,
7895 } })7947 } })
7896 else if (ip.isIntegerType(new_ty))7948 else if (ip.isIntegerType(new_ty))
7897 switch (ptr.base_addr) {7949 switch (ptr.base_addr) {
7898 .int => return ip.get(gpa, .{ .int = .{7950 .int => return ip.get(gpa, tid, .{ .int = .{
7899 .ty = .usize_type,7951 .ty = .usize_type,
7900 .storage = .{ .u64 = @intCast(ptr.byte_offset) },7952 .storage = .{ .u64 = @intCast(ptr.byte_offset) },
7901 } }),7953 } }),
...@@ -7904,44 +7956,44 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -7904,44 +7956,44 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
7904 .opt => |opt| switch (ip.indexToKey(new_ty)) {7956 .opt => |opt| switch (ip.indexToKey(new_ty)) {
7905 .ptr_type => |ptr_type| return switch (opt.val) {7957 .ptr_type => |ptr_type| return switch (opt.val) {
7906 .none => switch (ptr_type.flags.size) {7958 .none => switch (ptr_type.flags.size) {
7907 .One, .Many, .C => try ip.get(gpa, .{ .ptr = .{7959 .One, .Many, .C => try ip.get(gpa, tid, .{ .ptr = .{
7908 .ty = new_ty,7960 .ty = new_ty,
7909 .base_addr = .int,7961 .base_addr = .int,
7910 .byte_offset = 0,7962 .byte_offset = 0,
7911 } }),7963 } }),
7912 .Slice => try ip.get(gpa, .{ .slice = .{7964 .Slice => try ip.get(gpa, tid, .{ .slice = .{
7913 .ty = new_ty,7965 .ty = new_ty,
7914 .ptr = try ip.get(gpa, .{ .ptr = .{7966 .ptr = try ip.get(gpa, tid, .{ .ptr = .{
7915 .ty = ip.slicePtrType(new_ty),7967 .ty = ip.slicePtrType(new_ty),
7916 .base_addr = .int,7968 .base_addr = .int,
7917 .byte_offset = 0,7969 .byte_offset = 0,
7918 } }),7970 } }),
7919 .len = try ip.get(gpa, .{ .undef = .usize_type }),7971 .len = try ip.get(gpa, tid, .{ .undef = .usize_type }),
7920 } }),7972 } }),
7921 },7973 },
7922 else => |payload| try ip.getCoerced(gpa, payload, new_ty),7974 else => |payload| try ip.getCoerced(gpa, tid, payload, new_ty),
7923 },7975 },
7924 .opt_type => |child_type| return try ip.get(gpa, .{ .opt = .{7976 .opt_type => |child_type| return try ip.get(gpa, tid, .{ .opt = .{
7925 .ty = new_ty,7977 .ty = new_ty,
7926 .val = switch (opt.val) {7978 .val = switch (opt.val) {
7927 .none => .none,7979 .none => .none,
7928 else => try ip.getCoerced(gpa, opt.val, child_type),7980 else => try ip.getCoerced(gpa, tid, opt.val, child_type),
7929 },7981 },
7930 } }),7982 } }),
7931 else => {},7983 else => {},
7932 },7984 },
7933 .err => |err| if (ip.isErrorSetType(new_ty))7985 .err => |err| if (ip.isErrorSetType(new_ty))
7934 return ip.get(gpa, .{ .err = .{7986 return ip.get(gpa, tid, .{ .err = .{
7935 .ty = new_ty,7987 .ty = new_ty,
7936 .name = err.name,7988 .name = err.name,
7937 } })7989 } })
7938 else if (ip.isErrorUnionType(new_ty))7990 else if (ip.isErrorUnionType(new_ty))
7939 return ip.get(gpa, .{ .error_union = .{7991 return ip.get(gpa, tid, .{ .error_union = .{
7940 .ty = new_ty,7992 .ty = new_ty,
7941 .val = .{ .err_name = err.name },7993 .val = .{ .err_name = err.name },
7942 } }),7994 } }),
7943 .error_union => |error_union| if (ip.isErrorUnionType(new_ty))7995 .error_union => |error_union| if (ip.isErrorUnionType(new_ty))
7944 return ip.get(gpa, .{ .error_union = .{7996 return ip.get(gpa, tid, .{ .error_union = .{
7945 .ty = new_ty,7997 .ty = new_ty,
7946 .val = error_union.val,7998 .val = error_union.val,
7947 } }),7999 } }),
...@@ -7960,20 +8012,20 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -7960,20 +8012,20 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
7960 };8012 };
7961 if (old_ty_child != new_ty_child) break :direct;8013 if (old_ty_child != new_ty_child) break :direct;
7962 switch (aggregate.storage) {8014 switch (aggregate.storage) {
7963 .bytes => |bytes| return ip.get(gpa, .{ .aggregate = .{8015 .bytes => |bytes| return ip.get(gpa, tid, .{ .aggregate = .{
7964 .ty = new_ty,8016 .ty = new_ty,
7965 .storage = .{ .bytes = bytes },8017 .storage = .{ .bytes = bytes },
7966 } }),8018 } }),
7967 .elems => |elems| {8019 .elems => |elems| {
7968 const elems_copy = try gpa.dupe(Index, elems[0..new_len]);8020 const elems_copy = try gpa.dupe(Index, elems[0..new_len]);
7969 defer gpa.free(elems_copy);8021 defer gpa.free(elems_copy);
7970 return ip.get(gpa, .{ .aggregate = .{8022 return ip.get(gpa, tid, .{ .aggregate = .{
7971 .ty = new_ty,8023 .ty = new_ty,
7972 .storage = .{ .elems = elems_copy },8024 .storage = .{ .elems = elems_copy },
7973 } });8025 } });
7974 },8026 },
7975 .repeated_elem => |elem| {8027 .repeated_elem => |elem| {
7976 return ip.get(gpa, .{ .aggregate = .{8028 return ip.get(gpa, tid, .{ .aggregate = .{
7977 .ty = new_ty,8029 .ty = new_ty,
7978 .storage = .{ .repeated_elem = elem },8030 .storage = .{ .repeated_elem = elem },
7979 } });8031 } });
...@@ -7991,7 +8043,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -7991,7 +8043,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 avoid8043 // We have to intern each value here, so unfortunately we can't easily avoid
7992 // the repeated indexToKey calls.8044 // the repeated indexToKey calls.
7993 for (agg_elems, 0..) |*elem, index| {8045 for (agg_elems, 0..) |*elem, index| {
7994 elem.* = try ip.get(gpa, .{ .int = .{8046 elem.* = try ip.get(gpa, tid, .{ .int = .{
7995 .ty = .u8_type,8047 .ty = .u8_type,
7996 .storage = .{ .u64 = bytes.at(index, ip) },8048 .storage = .{ .u64 = bytes.at(index, ip) },
7997 } });8049 } });
...@@ -8008,27 +8060,27 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -8008,27 +8060,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],8060 .struct_type => ip.loadStructType(new_ty).field_types.get(ip)[i],
8009 else => unreachable,8061 else => unreachable,
8010 };8062 };
8011 elem.* = try ip.getCoerced(gpa, elem.*, new_elem_ty);8063 elem.* = try ip.getCoerced(gpa, tid, elem.*, new_elem_ty);
8012 }8064 }
8013 return ip.get(gpa, .{ .aggregate = .{ .ty = new_ty, .storage = .{ .elems = agg_elems } } });8065 return ip.get(gpa, tid, .{ .aggregate = .{ .ty = new_ty, .storage = .{ .elems = agg_elems } } });
8014 },8066 },
8015 else => {},8067 else => {},
8016 }8068 }
80178069
8018 switch (ip.indexToKey(new_ty)) {8070 switch (ip.indexToKey(new_ty)) {
8019 .opt_type => |child_type| switch (val) {8071 .opt_type => |child_type| switch (val) {
8020 .null_value => return ip.get(gpa, .{ .opt = .{8072 .null_value => return ip.get(gpa, tid, .{ .opt = .{
8021 .ty = new_ty,8073 .ty = new_ty,
8022 .val = .none,8074 .val = .none,
8023 } }),8075 } }),
8024 else => return ip.get(gpa, .{ .opt = .{8076 else => return ip.get(gpa, tid, .{ .opt = .{
8025 .ty = new_ty,8077 .ty = new_ty,
8026 .val = try ip.getCoerced(gpa, val, child_type),8078 .val = try ip.getCoerced(gpa, tid, val, child_type),
8027 } }),8079 } }),
8028 },8080 },
8029 .error_union_type => |error_union_type| return ip.get(gpa, .{ .error_union = .{8081 .error_union_type => |error_union_type| return ip.get(gpa, tid, .{ .error_union = .{
8030 .ty = new_ty,8082 .ty = new_ty,
8031 .val = .{ .payload = try ip.getCoerced(gpa, val, error_union_type.payload_type) },8083 .val = .{ .payload = try ip.getCoerced(gpa, tid, val, error_union_type.payload_type) },
8032 } }),8084 } }),
8033 else => {},8085 else => {},
8034 }8086 }
...@@ -8042,27 +8094,45 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -8042,27 +8094,45 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
8042 unreachable;8094 unreachable;
8043}8095}
80448096
8045fn getCoercedFuncDecl(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index {8097fn getCoercedFuncDecl(
8098 ip: *InternPool,
8099 gpa: Allocator,
8100 tid: Zcu.PerThread.Id,
8101 val: Index,
8102 new_ty: Index,
8103) Allocator.Error!Index {
8046 const datas = ip.items.items(.data);8104 const datas = ip.items.items(.data);
8047 const extra_index = datas[@intFromEnum(val)];8105 const extra_index = datas[@intFromEnum(val)];
8048 const prev_ty: Index = @enumFromInt(8106 const prev_ty: Index = @enumFromInt(
8049 ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncDecl, "ty").?],8107 ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncDecl, "ty").?],
8050 );8108 );
8051 if (new_ty == prev_ty) return val;8109 if (new_ty == prev_ty) return val;
8052 return getCoercedFunc(ip, gpa, val, new_ty);8110 return getCoercedFunc(ip, gpa, tid, val, new_ty);
8053}8111}
80548112
8055fn getCoercedFuncInstance(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index {8113fn getCoercedFuncInstance(
8114 ip: *InternPool,
8115 gpa: Allocator,
8116 tid: Zcu.PerThread.Id,
8117 val: Index,
8118 new_ty: Index,
8119) Allocator.Error!Index {
8056 const datas = ip.items.items(.data);8120 const datas = ip.items.items(.data);
8057 const extra_index = datas[@intFromEnum(val)];8121 const extra_index = datas[@intFromEnum(val)];
8058 const prev_ty: Index = @enumFromInt(8122 const prev_ty: Index = @enumFromInt(
8059 ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "ty").?],8123 ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "ty").?],
8060 );8124 );
8061 if (new_ty == prev_ty) return val;8125 if (new_ty == prev_ty) return val;
8062 return getCoercedFunc(ip, gpa, val, new_ty);8126 return getCoercedFunc(ip, gpa, tid, val, new_ty);
8063}8127}
80648128
8065fn getCoercedFunc(ip: *InternPool, gpa: Allocator, func: Index, ty: Index) Allocator.Error!Index {8129fn getCoercedFunc(
8130 ip: *InternPool,
8131 gpa: Allocator,
8132 _: Zcu.PerThread.Id,
8133 func: Index,
8134 ty: Index,
8135) Allocator.Error!Index {
8066 const prev_extra_len = ip.extra.items.len;8136 const prev_extra_len = ip.extra.items.len;
8067 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncCoerced).Struct.fields.len);8137 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncCoerced).Struct.fields.len);
8068 try ip.items.ensureUnusedCapacity(gpa, 1);8138 try ip.items.ensureUnusedCapacity(gpa, 1);
...@@ -8092,7 +8162,7 @@ fn getCoercedFunc(ip: *InternPool, gpa: Allocator, func: Index, ty: Index) Alloc...@@ -8092,7 +8162,7 @@ fn getCoercedFunc(ip: *InternPool, gpa: Allocator, func: Index, ty: Index) Alloc
80928162
8093/// Asserts `val` has an integer type.8163/// Asserts `val` has an integer type.
8094/// Assumes `new_ty` is an integer type.8164/// Assumes `new_ty` is an integer type.
8095pub fn getCoercedInts(ip: *InternPool, gpa: Allocator, int: Key.Int, new_ty: Index) Allocator.Error!Index {8165pub 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 of8166 // The key cannot be passed directly to `get`, otherwise in the case of
8097 // big_int storage, the limbs would be invalidated before they are read.8167 // 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` will8168 // Here we pre-reserve the limbs to ensure that the logic in `addInt` will
...@@ -8111,7 +8181,7 @@ pub fn getCoercedInts(ip: *InternPool, gpa: Allocator, int: Key.Int, new_ty: Ind...@@ -8111,7 +8181,7 @@ pub fn getCoercedInts(ip: *InternPool, gpa: Allocator, int: Key.Int, new_ty: Ind
8111 } };8181 } };
8112 },8182 },
8113 };8183 };
8114 return ip.get(gpa, .{ .int = .{8184 return ip.get(gpa, tid, .{ .int = .{
8115 .ty = new_ty,8185 .ty = new_ty,
8116 .storage = new_storage,8186 .storage = new_storage,
8117 } });8187 } });
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+2671-2297
...@@ -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,16 +2081,16 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)...@@ -2076,16 +2081,16 @@ 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, "instruction_addresses", .no_embedded_nulls);
...@@ -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
...@@ -2706,7 +2718,7 @@ fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) {...@@ -2706,7 +2718,7 @@ fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) {
2706 if (sema.builtin_type_target_index == .none) return wip_ty;2718 if (sema.builtin_type_target_index == .none) return wip_ty;
2707 var new = wip_ty;2719 var new = wip_ty;
2708 new.index = sema.builtin_type_target_index;2720 new.index = sema.builtin_type_target_index;
2709 sema.mod.intern_pool.resolveBuiltinType(new.index, wip_ty.index);2721 sema.pt.zcu.intern_pool.resolveBuiltinType(new.index, wip_ty.index);
2710 return new;2722 return new;
2711}2723}
27122724
...@@ -2714,7 +2726,8 @@ fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) {...@@ -2714,7 +2726,8 @@ fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) {
2714/// considered outdated on this update. If so, remove it from the pool2726/// considered outdated on this update. If so, remove it from the pool
2715/// and return `true`.2727/// and return `true`.
2716fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool {2728fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool {
2717 const zcu = sema.mod;2729 const pt = sema.pt;
2730 const zcu = pt.zcu;
27182731
2719 if (!zcu.comp.debug_incremental) return false;2732 if (!zcu.comp.debug_incremental) return false;
27202733
...@@ -2737,7 +2750,8 @@ fn zirStructDecl(...@@ -2737,7 +2750,8 @@ fn zirStructDecl(
2737 extended: Zir.Inst.Extended.InstData,2750 extended: Zir.Inst.Extended.InstData,
2738 inst: Zir.Inst.Index,2751 inst: Zir.Inst.Index,
2739) CompileError!Air.Inst.Ref {2752) CompileError!Air.Inst.Ref {
2740 const mod = sema.mod;2753 const pt = sema.pt;
2754 const mod = pt.zcu;
2741 const gpa = sema.gpa;2755 const gpa = sema.gpa;
2742 const ip = &mod.intern_pool;2756 const ip = &mod.intern_pool;
2743 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);2757 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
...@@ -2796,10 +2810,10 @@ fn zirStructDecl(...@@ -2796,10 +2810,10 @@ fn zirStructDecl(
2796 .captures = captures,2810 .captures = captures,
2797 } },2811 } },
2798 };2812 };
2799 const wip_ty = sema.wrapWipTy(switch (try ip.getStructType(gpa, struct_init)) {2813 const wip_ty = sema.wrapWipTy(switch (try ip.getStructType(gpa, pt.tid, struct_init)) {
2800 .existing => |ty| wip: {2814 .existing => |ty| wip: {
2801 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);2815 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);
2802 break :wip (try ip.getStructType(gpa, struct_init)).wip;2816 break :wip (try ip.getStructType(gpa, pt.tid, struct_init)).wip;
2803 },2817 },
2804 .wip => |wip| wip,2818 .wip => |wip| wip,
2805 });2819 });
...@@ -2815,7 +2829,7 @@ fn zirStructDecl(...@@ -2815,7 +2829,7 @@ fn zirStructDecl(
2815 mod.declPtr(new_decl_index).owns_tv = true;2829 mod.declPtr(new_decl_index).owns_tv = true;
2816 errdefer mod.abortAnonDecl(new_decl_index);2830 errdefer mod.abortAnonDecl(new_decl_index);
28172831
2818 if (sema.mod.comp.debug_incremental) {2832 if (pt.zcu.comp.debug_incremental) {
2819 try ip.addDependency(2833 try ip.addDependency(
2820 sema.gpa,2834 sema.gpa,
2821 AnalUnit.wrap(.{ .decl = new_decl_index }),2835 AnalUnit.wrap(.{ .decl = new_decl_index }),
...@@ -2836,7 +2850,7 @@ fn zirStructDecl(...@@ -2836,7 +2850,7 @@ fn zirStructDecl(
2836 try mod.scanNamespace(ns, decls, mod.declPtr(new_decl_index));2850 try mod.scanNamespace(ns, decls, mod.declPtr(new_decl_index));
2837 }2851 }
28382852
2839 try mod.finalizeAnonDecl(new_decl_index);2853 try pt.finalizeAnonDecl(new_decl_index);
2840 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });2854 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
2841 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));2855 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));
2842 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));2856 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));
...@@ -2850,7 +2864,8 @@ fn createAnonymousDeclTypeNamed(...@@ -2850,7 +2864,8 @@ fn createAnonymousDeclTypeNamed(
2850 anon_prefix: []const u8,2864 anon_prefix: []const u8,
2851 inst: ?Zir.Inst.Index,2865 inst: ?Zir.Inst.Index,
2852) !InternPool.DeclIndex {2866) !InternPool.DeclIndex {
2853 const zcu = sema.mod;2867 const pt = sema.pt;
2868 const zcu = pt.zcu;
2854 const ip = &zcu.intern_pool;2869 const ip = &zcu.intern_pool;
2855 const gpa = sema.gpa;2870 const gpa = sema.gpa;
2856 const namespace = block.namespace;2871 const namespace = block.namespace;
...@@ -2892,7 +2907,7 @@ fn createAnonymousDeclTypeNamed(...@@ -2892,7 +2907,7 @@ fn createAnonymousDeclTypeNamed(
2892 // some tooling may not support very long symbol names.2907 // some tooling may not support very long symbol names.
2893 try writer.print("{}", .{Value.fmtValueFull(.{2908 try writer.print("{}", .{Value.fmtValueFull(.{
2894 .val = arg_val,2909 .val = arg_val,
2895 .mod = zcu,2910 .pt = pt,
2896 .opt_sema = sema,2911 .opt_sema = sema,
2897 .depth = 1,2912 .depth = 1,
2898 })});2913 })});
...@@ -2953,7 +2968,8 @@ fn zirEnumDecl(...@@ -2953,7 +2968,8 @@ fn zirEnumDecl(
2953 const tracy = trace(@src());2968 const tracy = trace(@src());
2954 defer tracy.end();2969 defer tracy.end();
29552970
2956 const mod = sema.mod;2971 const pt = sema.pt;
2972 const mod = pt.zcu;
2957 const gpa = sema.gpa;2973 const gpa = sema.gpa;
2958 const ip = &mod.intern_pool;2974 const ip = &mod.intern_pool;
2959 const small: Zir.Inst.EnumDecl.Small = @bitCast(extended.small);2975 const small: Zir.Inst.EnumDecl.Small = @bitCast(extended.small);
...@@ -3026,10 +3042,10 @@ fn zirEnumDecl(...@@ -3026,10 +3042,10 @@ fn zirEnumDecl(
3026 .captures = captures,3042 .captures = captures,
3027 } },3043 } },
3028 };3044 };
3029 const wip_ty = sema.wrapWipTy(switch (try ip.getEnumType(gpa, enum_init)) {3045 const wip_ty = sema.wrapWipTy(switch (try ip.getEnumType(gpa, pt.tid, enum_init)) {
3030 .existing => |ty| wip: {3046 .existing => |ty| wip: {
3031 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);3047 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);
3032 break :wip (try ip.getEnumType(gpa, enum_init)).wip;3048 break :wip (try ip.getEnumType(gpa, pt.tid, enum_init)).wip;
3033 },3049 },
3034 .wip => |wip| wip,3050 .wip => |wip| wip,
3035 });3051 });
...@@ -3051,7 +3067,7 @@ fn zirEnumDecl(...@@ -3051,7 +3067,7 @@ fn zirEnumDecl(
3051 new_decl.owns_tv = true;3067 new_decl.owns_tv = true;
3052 errdefer if (!done) mod.abortAnonDecl(new_decl_index);3068 errdefer if (!done) mod.abortAnonDecl(new_decl_index);
30533069
3054 if (sema.mod.comp.debug_incremental) {3070 if (pt.zcu.comp.debug_incremental) {
3055 try mod.intern_pool.addDependency(3071 try mod.intern_pool.addDependency(
3056 gpa,3072 gpa,
3057 AnalUnit.wrap(.{ .decl = new_decl_index }),3073 AnalUnit.wrap(.{ .decl = new_decl_index }),
...@@ -3118,21 +3134,21 @@ fn zirEnumDecl(...@@ -3118,21 +3134,21 @@ fn zirEnumDecl(
3118 if (tag_type_ref != .none) {3134 if (tag_type_ref != .none) {
3119 const ty = try sema.resolveType(&enum_block, tag_ty_src, tag_type_ref);3135 const ty = try sema.resolveType(&enum_block, tag_ty_src, tag_type_ref);
3120 if (ty.zigTypeTag(mod) != .Int and ty.zigTypeTag(mod) != .ComptimeInt) {3136 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)});3137 return sema.fail(&enum_block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(pt)});
3122 }3138 }
3123 break :ty ty;3139 break :ty ty;
3124 } else if (fields_len == 0) {3140 } else if (fields_len == 0) {
3125 break :ty try mod.intType(.unsigned, 0);3141 break :ty try pt.intType(.unsigned, 0);
3126 } else {3142 } else {
3127 const bits = std.math.log2_int_ceil(usize, fields_len);3143 const bits = std.math.log2_int_ceil(usize, fields_len);
3128 break :ty try mod.intType(.unsigned, bits);3144 break :ty try pt.intType(.unsigned, bits);
3129 }3145 }
3130 };3146 };
31313147
3132 wip_ty.setTagTy(ip, int_tag_ty.toIntern());3148 wip_ty.setTagTy(ip, int_tag_ty.toIntern());
31333149
3134 if (small.nonexhaustive and int_tag_ty.toIntern() != .comptime_int_type) {3150 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)) {3151 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", .{});3152 return sema.fail(block, src, "non-exhaustive enum specifies every value", .{});
3137 }3153 }
3138 }3154 }
...@@ -3171,7 +3187,7 @@ fn zirEnumDecl(...@@ -3171,7 +3187,7 @@ fn zirEnumDecl(
3171 .needed_comptime_reason = "enum tag value must be comptime-known",3187 .needed_comptime_reason = "enum tag value must be comptime-known",
3172 });3188 });
3173 if (!(try sema.intFitsInType(last_tag_val.?, int_tag_ty, null))) break :overflow true;3189 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);3190 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| {3191 if (wip_ty.nextField(&mod.intern_pool, field_name, last_tag_val.?.toIntern())) |conflict| {
3176 assert(conflict.kind == .value); // AstGen validated names are unique3192 assert(conflict.kind == .value); // AstGen validated names are unique
3177 const other_field_src: LazySrcLoc = .{3193 const other_field_src: LazySrcLoc = .{
...@@ -3179,7 +3195,7 @@ fn zirEnumDecl(...@@ -3179,7 +3195,7 @@ fn zirEnumDecl(
3179 .offset = .{ .container_field_value = conflict.prev_field_idx },3195 .offset = .{ .container_field_value = conflict.prev_field_idx },
3180 };3196 };
3181 const msg = msg: {3197 const msg = msg: {
3182 const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(sema.mod, sema)});3198 const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(pt, sema)});
3183 errdefer msg.destroy(gpa);3199 errdefer msg.destroy(gpa);
3184 try sema.errNote(other_field_src, msg, "other occurrence here", .{});3200 try sema.errNote(other_field_src, msg, "other occurrence here", .{});
3185 break :msg msg;3201 break :msg msg;
...@@ -3190,9 +3206,9 @@ fn zirEnumDecl(...@@ -3190,9 +3206,9 @@ fn zirEnumDecl(
3190 } else if (any_values) overflow: {3206 } else if (any_values) overflow: {
3191 var overflow: ?usize = null;3207 var overflow: ?usize = null;
3192 last_tag_val = if (last_tag_val) |val|3208 last_tag_val = if (last_tag_val) |val|
3193 try sema.intAdd(val, try mod.intValue(int_tag_ty, 1), int_tag_ty, &overflow)3209 try sema.intAdd(val, try pt.intValue(int_tag_ty, 1), int_tag_ty, &overflow)
3194 else3210 else
3195 try mod.intValue(int_tag_ty, 0);3211 try pt.intValue(int_tag_ty, 0);
3196 if (overflow != null) break :overflow true;3212 if (overflow != null) break :overflow true;
3197 if (wip_ty.nextField(&mod.intern_pool, field_name, last_tag_val.?.toIntern())) |conflict| {3213 if (wip_ty.nextField(&mod.intern_pool, field_name, last_tag_val.?.toIntern())) |conflict| {
3198 assert(conflict.kind == .value); // AstGen validated names are unique3214 assert(conflict.kind == .value); // AstGen validated names are unique
...@@ -3201,7 +3217,7 @@ fn zirEnumDecl(...@@ -3201,7 +3217,7 @@ fn zirEnumDecl(
3201 .offset = .{ .container_field_value = conflict.prev_field_idx },3217 .offset = .{ .container_field_value = conflict.prev_field_idx },
3202 };3218 };
3203 const msg = msg: {3219 const msg = msg: {
3204 const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(sema.mod, sema)});3220 const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(pt, sema)});
3205 errdefer msg.destroy(gpa);3221 errdefer msg.destroy(gpa);
3206 try sema.errNote(other_field_src, msg, "other occurrence here", .{});3222 try sema.errNote(other_field_src, msg, "other occurrence here", .{});
3207 break :msg msg;3223 break :msg msg;
...@@ -3211,21 +3227,21 @@ fn zirEnumDecl(...@@ -3211,21 +3227,21 @@ fn zirEnumDecl(
3211 break :overflow false;3227 break :overflow false;
3212 } else overflow: {3228 } else overflow: {
3213 assert(wip_ty.nextField(&mod.intern_pool, field_name, .none) == null);3229 assert(wip_ty.nextField(&mod.intern_pool, field_name, .none) == null);
3214 last_tag_val = try mod.intValue(Type.comptime_int, field_i);3230 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;3231 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);3232 last_tag_val = try pt.getCoerced(last_tag_val.?, int_tag_ty);
3217 break :overflow false;3233 break :overflow false;
3218 };3234 };
32193235
3220 if (tag_overflow) {3236 if (tag_overflow) {
3221 const msg = try sema.errMsg(value_src, "enumeration value '{}' too large for type '{}'", .{3237 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),3238 last_tag_val.?.fmtValue(pt, sema), int_tag_ty.fmt(pt),
3223 });3239 });
3224 return sema.failWithOwnedErrorMsg(block, msg);3240 return sema.failWithOwnedErrorMsg(block, msg);
3225 }3241 }
3226 }3242 }
32273243
3228 try mod.finalizeAnonDecl(new_decl_index);3244 try pt.finalizeAnonDecl(new_decl_index);
3229 return Air.internedToRef(wip_ty.index);3245 return Air.internedToRef(wip_ty.index);
3230}3246}
32313247
...@@ -3238,7 +3254,8 @@ fn zirUnionDecl(...@@ -3238,7 +3254,8 @@ fn zirUnionDecl(
3238 const tracy = trace(@src());3254 const tracy = trace(@src());
3239 defer tracy.end();3255 defer tracy.end();
32403256
3241 const mod = sema.mod;3257 const pt = sema.pt;
3258 const mod = pt.zcu;
3242 const gpa = sema.gpa;3259 const gpa = sema.gpa;
3243 const ip = &mod.intern_pool;3260 const ip = &mod.intern_pool;
3244 const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small);3261 const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small);
...@@ -3298,10 +3315,10 @@ fn zirUnionDecl(...@@ -3298,10 +3315,10 @@ fn zirUnionDecl(
3298 .captures = captures,3315 .captures = captures,
3299 } },3316 } },
3300 };3317 };
3301 const wip_ty = sema.wrapWipTy(switch (try ip.getUnionType(gpa, union_init)) {3318 const wip_ty = sema.wrapWipTy(switch (try ip.getUnionType(gpa, pt.tid, union_init)) {
3302 .existing => |ty| wip: {3319 .existing => |ty| wip: {
3303 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);3320 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);
3304 break :wip (try ip.getUnionType(gpa, union_init)).wip;3321 break :wip (try ip.getUnionType(gpa, pt.tid, union_init)).wip;
3305 },3322 },
3306 .wip => |wip| wip,3323 .wip => |wip| wip,
3307 });3324 });
...@@ -3317,7 +3334,7 @@ fn zirUnionDecl(...@@ -3317,7 +3334,7 @@ fn zirUnionDecl(
3317 mod.declPtr(new_decl_index).owns_tv = true;3334 mod.declPtr(new_decl_index).owns_tv = true;
3318 errdefer mod.abortAnonDecl(new_decl_index);3335 errdefer mod.abortAnonDecl(new_decl_index);
33193336
3320 if (sema.mod.comp.debug_incremental) {3337 if (pt.zcu.comp.debug_incremental) {
3321 try mod.intern_pool.addDependency(3338 try mod.intern_pool.addDependency(
3322 gpa,3339 gpa,
3323 AnalUnit.wrap(.{ .decl = new_decl_index }),3340 AnalUnit.wrap(.{ .decl = new_decl_index }),
...@@ -3338,7 +3355,7 @@ fn zirUnionDecl(...@@ -3338,7 +3355,7 @@ fn zirUnionDecl(
3338 try mod.scanNamespace(ns, decls, mod.declPtr(new_decl_index));3355 try mod.scanNamespace(ns, decls, mod.declPtr(new_decl_index));
3339 }3356 }
33403357
3341 try mod.finalizeAnonDecl(new_decl_index);3358 try pt.finalizeAnonDecl(new_decl_index);
3342 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });3359 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
3343 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));3360 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));
3344 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));3361 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));
...@@ -3353,7 +3370,8 @@ fn zirOpaqueDecl(...@@ -3353,7 +3370,8 @@ fn zirOpaqueDecl(
3353 const tracy = trace(@src());3370 const tracy = trace(@src());
3354 defer tracy.end();3371 defer tracy.end();
33553372
3356 const mod = sema.mod;3373 const pt = sema.pt;
3374 const mod = pt.zcu;
3357 const gpa = sema.gpa;3375 const gpa = sema.gpa;
3358 const ip = &mod.intern_pool;3376 const ip = &mod.intern_pool;
33593377
...@@ -3387,10 +3405,10 @@ fn zirOpaqueDecl(...@@ -3387,10 +3405,10 @@ fn zirOpaqueDecl(
3387 } },3405 } },
3388 };3406 };
3389 // No `wrapWipTy` needed as no std.builtin types are opaque.3407 // No `wrapWipTy` needed as no std.builtin types are opaque.
3390 const wip_ty = switch (try ip.getOpaqueType(gpa, opaque_init)) {3408 const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, opaque_init)) {
3391 .existing => |ty| wip: {3409 .existing => |ty| wip: {
3392 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);3410 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);
3393 break :wip (try ip.getOpaqueType(gpa, opaque_init)).wip;3411 break :wip (try ip.getOpaqueType(gpa, pt.tid, opaque_init)).wip;
3394 },3412 },
3395 .wip => |wip| wip,3413 .wip => |wip| wip,
3396 };3414 };
...@@ -3406,7 +3424,7 @@ fn zirOpaqueDecl(...@@ -3406,7 +3424,7 @@ fn zirOpaqueDecl(
3406 mod.declPtr(new_decl_index).owns_tv = true;3424 mod.declPtr(new_decl_index).owns_tv = true;
3407 errdefer mod.abortAnonDecl(new_decl_index);3425 errdefer mod.abortAnonDecl(new_decl_index);
34083426
3409 if (sema.mod.comp.debug_incremental) {3427 if (pt.zcu.comp.debug_incremental) {
3410 try ip.addDependency(3428 try ip.addDependency(
3411 gpa,3429 gpa,
3412 AnalUnit.wrap(.{ .decl = new_decl_index }),3430 AnalUnit.wrap(.{ .decl = new_decl_index }),
...@@ -3426,7 +3444,7 @@ fn zirOpaqueDecl(...@@ -3426,7 +3444,7 @@ fn zirOpaqueDecl(
3426 try mod.scanNamespace(ns, decls, mod.declPtr(new_decl_index));3444 try mod.scanNamespace(ns, decls, mod.declPtr(new_decl_index));
3427 }3445 }
34283446
3429 try mod.finalizeAnonDecl(new_decl_index);3447 try pt.finalizeAnonDecl(new_decl_index);
34303448
3431 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));3449 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));
3432}3450}
...@@ -3438,7 +3456,8 @@ fn zirErrorSetDecl(...@@ -3438,7 +3456,8 @@ fn zirErrorSetDecl(
3438 const tracy = trace(@src());3456 const tracy = trace(@src());
3439 defer tracy.end();3457 defer tracy.end();
34403458
3441 const mod = sema.mod;3459 const pt = sema.pt;
3460 const mod = pt.zcu;
3442 const gpa = sema.gpa;3461 const gpa = sema.gpa;
3443 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;3462 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);3463 const extra = sema.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index);
...@@ -3457,20 +3476,22 @@ fn zirErrorSetDecl(...@@ -3457,20 +3476,22 @@ fn zirErrorSetDecl(
3457 assert(!result.found_existing); // verified in AstGen3476 assert(!result.found_existing); // verified in AstGen
3458 }3477 }
34593478
3460 return Air.internedToRef((try mod.errorSetFromUnsortedNames(names.keys())).toIntern());3479 return Air.internedToRef((try pt.errorSetFromUnsortedNames(names.keys())).toIntern());
3461}3480}
34623481
3463fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {3482fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
3464 const tracy = trace(@src());3483 const tracy = trace(@src());
3465 defer tracy.end();3484 defer tracy.end();
34663485
3486 const pt = sema.pt;
3487
3467 if (block.is_comptime or try sema.typeRequiresComptime(sema.fn_ret_ty)) {3488 if (block.is_comptime or try sema.typeRequiresComptime(sema.fn_ret_ty)) {
3468 try sema.fn_ret_ty.resolveFields(sema.mod);3489 try sema.fn_ret_ty.resolveFields(pt);
3469 return sema.analyzeComptimeAlloc(block, sema.fn_ret_ty, .none);3490 return sema.analyzeComptimeAlloc(block, sema.fn_ret_ty, .none);
3470 }3491 }
34713492
3472 const target = sema.mod.getTarget();3493 const target = pt.zcu.getTarget();
3473 const ptr_type = try sema.mod.ptrTypeSema(.{3494 const ptr_type = try pt.ptrTypeSema(.{
3474 .child = sema.fn_ret_ty.toIntern(),3495 .child = sema.fn_ret_ty.toIntern(),
3475 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },3496 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
3476 });3497 });
...@@ -3511,7 +3532,8 @@ fn ensureResultUsed(...@@ -3511,7 +3532,8 @@ fn ensureResultUsed(
3511 ty: Type,3532 ty: Type,
3512 src: LazySrcLoc,3533 src: LazySrcLoc,
3513) CompileError!void {3534) CompileError!void {
3514 const mod = sema.mod;3535 const pt = sema.pt;
3536 const mod = pt.zcu;
3515 switch (ty.zigTypeTag(mod)) {3537 switch (ty.zigTypeTag(mod)) {
3516 .Void, .NoReturn => return,3538 .Void, .NoReturn => return,
3517 .ErrorSet => return sema.fail(block, src, "error set is ignored", .{}),3539 .ErrorSet => return sema.fail(block, src, "error set is ignored", .{}),
...@@ -3526,7 +3548,7 @@ fn ensureResultUsed(...@@ -3526,7 +3548,7 @@ fn ensureResultUsed(
3526 },3548 },
3527 else => {3549 else => {
3528 const msg = msg: {3550 const msg = msg: {
3529 const msg = try sema.errMsg(src, "value of type '{}' ignored", .{ty.fmt(sema.mod)});3551 const msg = try sema.errMsg(src, "value of type '{}' ignored", .{ty.fmt(pt)});
3530 errdefer msg.destroy(sema.gpa);3552 errdefer msg.destroy(sema.gpa);
3531 try sema.errNote(src, msg, "all non-void values must be used", .{});3553 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 '_'", .{});3554 try sema.errNote(src, msg, "to discard the value, assign it to '_'", .{});
...@@ -3541,7 +3563,8 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -3541,7 +3563,8 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
3541 const tracy = trace(@src());3563 const tracy = trace(@src());
3542 defer tracy.end();3564 defer tracy.end();
35433565
3544 const mod = sema.mod;3566 const pt = sema.pt;
3567 const mod = pt.zcu;
3545 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;3568 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3546 const operand = try sema.resolveInst(inst_data.operand);3569 const operand = try sema.resolveInst(inst_data.operand);
3547 const src = block.nodeOffset(inst_data.src_node);3570 const src = block.nodeOffset(inst_data.src_node);
...@@ -3565,7 +3588,8 @@ fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index...@@ -3565,7 +3588,8 @@ fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index
3565 const tracy = trace(@src());3588 const tracy = trace(@src());
3566 defer tracy.end();3589 defer tracy.end();
35673590
3568 const mod = sema.mod;3591 const pt = sema.pt;
3592 const mod = pt.zcu;
3569 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;3593 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3570 const src = block.nodeOffset(inst_data.src_node);3594 const src = block.nodeOffset(inst_data.src_node);
3571 const operand = try sema.resolveInst(inst_data.operand);3595 const operand = try sema.resolveInst(inst_data.operand);
...@@ -3604,7 +3628,8 @@ fn indexablePtrLen(...@@ -3604,7 +3628,8 @@ fn indexablePtrLen(
3604 src: LazySrcLoc,3628 src: LazySrcLoc,
3605 object: Air.Inst.Ref,3629 object: Air.Inst.Ref,
3606) CompileError!Air.Inst.Ref {3630) CompileError!Air.Inst.Ref {
3607 const mod = sema.mod;3631 const pt = sema.pt;
3632 const mod = pt.zcu;
3608 const object_ty = sema.typeOf(object);3633 const object_ty = sema.typeOf(object);
3609 const is_pointer_to = object_ty.isSinglePointer(mod);3634 const is_pointer_to = object_ty.isSinglePointer(mod);
3610 const indexable_ty = if (is_pointer_to) object_ty.childType(mod) else object_ty;3635 const indexable_ty = if (is_pointer_to) object_ty.childType(mod) else object_ty;
...@@ -3619,7 +3644,8 @@ fn indexablePtrLenOrNone(...@@ -3619,7 +3644,8 @@ fn indexablePtrLenOrNone(
3619 src: LazySrcLoc,3644 src: LazySrcLoc,
3620 operand: Air.Inst.Ref,3645 operand: Air.Inst.Ref,
3621) CompileError!Air.Inst.Ref {3646) CompileError!Air.Inst.Ref {
3622 const mod = sema.mod;3647 const pt = sema.pt;
3648 const mod = pt.zcu;
3623 const operand_ty = sema.typeOf(operand);3649 const operand_ty = sema.typeOf(operand);
3624 try checkMemOperand(sema, block, src, operand_ty);3650 try checkMemOperand(sema, block, src, operand_ty);
3625 if (operand_ty.ptrSize(mod) == .Many) return .none;3651 if (operand_ty.ptrSize(mod) == .Many) return .none;
...@@ -3632,6 +3658,7 @@ fn zirAllocExtended(...@@ -3632,6 +3658,7 @@ fn zirAllocExtended(
3632 block: *Block,3658 block: *Block,
3633 extended: Zir.Inst.Extended.InstData,3659 extended: Zir.Inst.Extended.InstData,
3634) CompileError!Air.Inst.Ref {3660) CompileError!Air.Inst.Ref {
3661 const pt = sema.pt;
3635 const gpa = sema.gpa;3662 const gpa = sema.gpa;
3636 const extra = sema.code.extraData(Zir.Inst.AllocExtended, extended.operand);3663 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 });3664 const ty_src = block.src(.{ .node_offset_var_decl_ty = extra.data.src_node });
...@@ -3673,9 +3700,9 @@ fn zirAllocExtended(...@@ -3673,9 +3700,9 @@ fn zirAllocExtended(
3673 if (!small.is_const) {3700 if (!small.is_const) {
3674 try sema.validateVarType(block, ty_src, var_ty, false);3701 try sema.validateVarType(block, ty_src, var_ty, false);
3675 }3702 }
3676 const target = sema.mod.getTarget();3703 const target = pt.zcu.getTarget();
3677 try var_ty.resolveLayout(sema.mod);3704 try var_ty.resolveLayout(pt);
3678 const ptr_type = try sema.mod.ptrTypeSema(.{3705 const ptr_type = try sema.pt.ptrTypeSema(.{
3679 .child = var_ty.toIntern(),3706 .child = var_ty.toIntern(),
3680 .flags = .{3707 .flags = .{
3681 .alignment = alignment,3708 .alignment = alignment,
...@@ -3717,7 +3744,8 @@ fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -3717,7 +3744,8 @@ fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
3717}3744}
37183745
3719fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {3746fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
3720 const mod = sema.mod;3747 const pt = sema.pt;
3748 const mod = pt.zcu;
3721 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;3749 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3722 const alloc = try sema.resolveInst(inst_data.operand);3750 const alloc = try sema.resolveInst(inst_data.operand);
3723 const alloc_ty = sema.typeOf(alloc);3751 const alloc_ty = sema.typeOf(alloc);
...@@ -3749,7 +3777,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3749,7 +3777,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
3749 assert(ptr.byte_offset == 0);3777 assert(ptr.byte_offset == 0);
3750 const alloc_index = ptr.base_addr.comptime_alloc;3778 const alloc_index = ptr.base_addr.comptime_alloc;
3751 const ct_alloc = sema.getComptimeAlloc(alloc_index);3779 const ct_alloc = sema.getComptimeAlloc(alloc_index);
3752 const interned = try ct_alloc.val.intern(mod, sema.arena);3780 const interned = try ct_alloc.val.intern(pt, sema.arena);
3753 if (interned.canMutateComptimeVarState(mod)) {3781 if (interned.canMutateComptimeVarState(mod)) {
3754 // Preserve the comptime alloc, just make the pointer const.3782 // Preserve the comptime alloc, just make the pointer const.
3755 ct_alloc.val = .{ .interned = interned.toIntern() };3783 ct_alloc.val = .{ .interned = interned.toIntern() };
...@@ -3757,7 +3785,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3757,7 +3785,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
3757 return sema.makePtrConst(block, alloc);3785 return sema.makePtrConst(block, alloc);
3758 } else {3786 } else {
3759 // Promote the constant to an anon decl.3787 // Promote the constant to an anon decl.
3760 const new_mut_ptr = Air.internedToRef(try mod.intern(.{ .ptr = .{3788 const new_mut_ptr = Air.internedToRef(try pt.intern(.{ .ptr = .{
3761 .ty = alloc_ty.toIntern(),3789 .ty = alloc_ty.toIntern(),
3762 .base_addr = .{ .anon_decl = .{3790 .base_addr = .{ .anon_decl = .{
3763 .val = interned.toIntern(),3791 .val = interned.toIntern(),
...@@ -3778,7 +3806,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3778,7 +3806,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.3806 // The value was initialized through RLS, so we didn't detect the runtime condition earlier.
3779 // TODO: source location of runtime control flow3807 // TODO: source location of runtime control flow
3780 const init_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });3808 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)});3809 return sema.fail(block, init_src, "value with comptime-only type '{}' depends on runtime control flow", .{elem_ty.fmt(pt)});
3782 }3810 }
37833811
3784 // This is a runtime value.3812 // This is a runtime value.
...@@ -3788,7 +3816,8 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3788,7 +3816,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 resolved3816/// 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`.3817/// 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 {3818fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref, resolved_alloc_ty: ?Type) CompileError!?InternPool.Index {
3791 const zcu = sema.mod;3819 const pt = sema.pt;
3820 const zcu = pt.zcu;
37923821
3793 const alloc_ty = resolved_alloc_ty orelse sema.typeOf(alloc);3822 const alloc_ty = resolved_alloc_ty orelse sema.typeOf(alloc);
3794 const ptr_info = alloc_ty.ptrInfo(zcu);3823 const ptr_info = alloc_ty.ptrInfo(zcu);
...@@ -3831,7 +3860,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,...@@ -3831,7 +3860,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
38313860
3832 const ct_alloc = try sema.newComptimeAlloc(block, elem_ty, ptr_info.flags.alignment);3861 const ct_alloc = try sema.newComptimeAlloc(block, elem_ty, ptr_info.flags.alignment);
38333862
3834 const alloc_ptr = try zcu.intern(.{ .ptr = .{3863 const alloc_ptr = try pt.intern(.{ .ptr = .{
3835 .ty = alloc_ty.toIntern(),3864 .ty = alloc_ty.toIntern(),
3836 .base_addr = .{ .comptime_alloc = ct_alloc },3865 .base_addr = .{ .comptime_alloc = ct_alloc },
3837 .byte_offset = 0,3866 .byte_offset = 0,
...@@ -3909,7 +3938,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,...@@ -3909,7 +3938,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
3909 const idx_val = (try sema.resolveValue(data.rhs)).?;3938 const idx_val = (try sema.resolveValue(data.rhs)).?;
3910 break :blk .{3939 break :blk .{
3911 data.lhs,3940 data.lhs,
3912 .{ .elem = try idx_val.toUnsignedIntSema(zcu) },3941 .{ .elem = try idx_val.toUnsignedIntSema(pt) },
3913 };3942 };
3914 },3943 },
3915 .bitcast => .{3944 .bitcast => .{
...@@ -3935,32 +3964,32 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,...@@ -3935,32 +3964,32 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
3935 };3964 };
3936 const new_ptr_ty = tmp_air.typeOfIndex(air_ptr, &zcu.intern_pool).toIntern();3965 const new_ptr_ty = tmp_air.typeOfIndex(air_ptr, &zcu.intern_pool).toIntern();
3937 const new_ptr = switch (method) {3966 const new_ptr = switch (method) {
3938 .same_addr => try zcu.intern_pool.getCoerced(sema.gpa, decl_parent_ptr, new_ptr_ty),3967 .same_addr => try zcu.intern_pool.getCoerced(sema.gpa, pt.tid, decl_parent_ptr, new_ptr_ty),
3939 .opt_payload => ptr: {3968 .opt_payload => ptr: {
3940 // Set the optional to non-null at comptime.3969 // Set the optional to non-null at comptime.
3941 // If the payload is OPV, we must use that value instead of undef.3970 // 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);3971 const opt_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu);
3943 const payload_ty = opt_ty.optionalChild(zcu);3972 const payload_ty = opt_ty.optionalChild(zcu);
3944 const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try zcu.undefValue(payload_ty);3973 const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try pt.undefValue(payload_ty);
3945 const opt_val = try zcu.intern(.{ .opt = .{3974 const opt_val = try pt.intern(.{ .opt = .{
3946 .ty = opt_ty.toIntern(),3975 .ty = opt_ty.toIntern(),
3947 .val = payload_val.toIntern(),3976 .val = payload_val.toIntern(),
3948 } });3977 } });
3949 try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), Value.fromInterned(opt_val), opt_ty);3978 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();3979 break :ptr (try Value.fromInterned(decl_parent_ptr).ptrOptPayload(pt)).toIntern();
3951 },3980 },
3952 .eu_payload => ptr: {3981 .eu_payload => ptr: {
3953 // Set the error union to non-error at comptime.3982 // Set the error union to non-error at comptime.
3954 // If the payload is OPV, we must use that value instead of undef.3983 // 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);3984 const eu_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu);
3956 const payload_ty = eu_ty.errorUnionPayload(zcu);3985 const payload_ty = eu_ty.errorUnionPayload(zcu);
3957 const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try zcu.undefValue(payload_ty);3986 const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try pt.undefValue(payload_ty);
3958 const eu_val = try zcu.intern(.{ .error_union = .{3987 const eu_val = try pt.intern(.{ .error_union = .{
3959 .ty = eu_ty.toIntern(),3988 .ty = eu_ty.toIntern(),
3960 .val = .{ .payload = payload_val.toIntern() },3989 .val = .{ .payload = payload_val.toIntern() },
3961 } });3990 } });
3962 try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), Value.fromInterned(eu_val), eu_ty);3991 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();3992 break :ptr (try Value.fromInterned(decl_parent_ptr).ptrEuPayload(pt)).toIntern();
3964 },3993 },
3965 .field => |idx| ptr: {3994 .field => |idx| ptr: {
3966 const maybe_union_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu);3995 const maybe_union_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu);
...@@ -3969,14 +3998,14 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,...@@ -3969,14 +3998,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.3998 // 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.3999 // 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]);4000 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);4001 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);4002 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);4003 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);4004 try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), store_val, maybe_union_ty);
3976 }4005 }
3977 break :ptr (try Value.fromInterned(decl_parent_ptr).ptrField(idx, zcu)).toIntern();4006 break :ptr (try Value.fromInterned(decl_parent_ptr).ptrField(idx, pt)).toIntern();
3978 },4007 },
3979 .elem => |idx| (try Value.fromInterned(decl_parent_ptr).ptrElem(idx, zcu)).toIntern(),4008 .elem => |idx| (try Value.fromInterned(decl_parent_ptr).ptrElem(idx, pt)).toIntern(),
3980 };4009 };
3981 try ptr_mapping.put(air_ptr, new_ptr);4010 try ptr_mapping.put(air_ptr, new_ptr);
3982 }4011 }
...@@ -4020,7 +4049,8 @@ fn finishResolveComptimeKnownAllocPtr(...@@ -4020,7 +4049,8 @@ fn finishResolveComptimeKnownAllocPtr(
4020 alloc_inst: Air.Inst.Index,4049 alloc_inst: Air.Inst.Index,
4021 comptime_info: MaybeComptimeAlloc,4050 comptime_info: MaybeComptimeAlloc,
4022) CompileError!?InternPool.Index {4051) CompileError!?InternPool.Index {
4023 const zcu = sema.mod;4052 const pt = sema.pt;
4053 const zcu = pt.zcu;
40244054
4025 // We're almost done - we have the resolved comptime value. We just need to4055 // We're almost done - we have the resolved comptime value. We just need to
4026 // eliminate the now-dead runtime instructions.4056 // eliminate the now-dead runtime instructions.
...@@ -4041,19 +4071,19 @@ fn finishResolveComptimeKnownAllocPtr(...@@ -4041,19 +4071,19 @@ fn finishResolveComptimeKnownAllocPtr(
40414071
4042 if (Value.fromInterned(result_val).canMutateComptimeVarState(zcu)) {4072 if (Value.fromInterned(result_val).canMutateComptimeVarState(zcu)) {
4043 const alloc_index = existing_comptime_alloc orelse a: {4073 const alloc_index = existing_comptime_alloc orelse a: {
4044 const idx = try sema.newComptimeAlloc(block, alloc_ty.childType(zcu), alloc_ty.ptrAlignment(zcu));4074 const idx = try sema.newComptimeAlloc(block, alloc_ty.childType(zcu), alloc_ty.ptrAlignment(pt));
4045 const alloc = sema.getComptimeAlloc(idx);4075 const alloc = sema.getComptimeAlloc(idx);
4046 alloc.val = .{ .interned = result_val };4076 alloc.val = .{ .interned = result_val };
4047 break :a idx;4077 break :a idx;
4048 };4078 };
4049 sema.getComptimeAlloc(alloc_index).is_const = true;4079 sema.getComptimeAlloc(alloc_index).is_const = true;
4050 return try zcu.intern(.{ .ptr = .{4080 return try pt.intern(.{ .ptr = .{
4051 .ty = alloc_ty.toIntern(),4081 .ty = alloc_ty.toIntern(),
4052 .base_addr = .{ .comptime_alloc = alloc_index },4082 .base_addr = .{ .comptime_alloc = alloc_index },
4053 .byte_offset = 0,4083 .byte_offset = 0,
4054 } });4084 } });
4055 } else {4085 } else {
4056 return try zcu.intern(.{ .ptr = .{4086 return try pt.intern(.{ .ptr = .{
4057 .ty = alloc_ty.toIntern(),4087 .ty = alloc_ty.toIntern(),
4058 .base_addr = .{ .anon_decl = .{4088 .base_addr = .{ .anon_decl = .{
4059 .orig_ty = alloc_ty.toIntern(),4089 .orig_ty = alloc_ty.toIntern(),
...@@ -4065,9 +4095,9 @@ fn finishResolveComptimeKnownAllocPtr(...@@ -4065,9 +4095,9 @@ fn finishResolveComptimeKnownAllocPtr(
4065}4095}
40664096
4067fn makePtrTyConst(sema: *Sema, ptr_ty: Type) CompileError!Type {4097fn makePtrTyConst(sema: *Sema, ptr_ty: Type) CompileError!Type {
4068 var ptr_info = ptr_ty.ptrInfo(sema.mod);4098 var ptr_info = ptr_ty.ptrInfo(sema.pt.zcu);
4069 ptr_info.flags.is_const = true;4099 ptr_info.flags.is_const = true;
4070 return sema.mod.ptrTypeSema(ptr_info);4100 return sema.pt.ptrTypeSema(ptr_info);
4071}4101}
40724102
4073fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Air.Inst.Ref {4103fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Air.Inst.Ref {
...@@ -4076,7 +4106,7 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai...@@ -4076,7 +4106,7 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai
40764106
4077 // Detect if a comptime value simply needs to have its type changed.4107 // Detect if a comptime value simply needs to have its type changed.
4078 if (try sema.resolveValue(alloc)) |val| {4108 if (try sema.resolveValue(alloc)) |val| {
4079 return Air.internedToRef((try sema.mod.getCoerced(val, const_ptr_ty)).toIntern());4109 return Air.internedToRef((try sema.pt.getCoerced(val, const_ptr_ty)).toIntern());
4080 }4110 }
40814111
4082 return block.addBitCast(const_ptr_ty, alloc);4112 return block.addBitCast(const_ptr_ty, alloc);
...@@ -4103,14 +4133,16 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -4103,14 +4133,16 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
4103 const tracy = trace(@src());4133 const tracy = trace(@src());
4104 defer tracy.end();4134 defer tracy.end();
41054135
4136 const pt = sema.pt;
4137
4106 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;4138 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 });4139 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);4140 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
4109 if (block.is_comptime) {4141 if (block.is_comptime) {
4110 return sema.analyzeComptimeAlloc(block, var_ty, .none);4142 return sema.analyzeComptimeAlloc(block, var_ty, .none);
4111 }4143 }
4112 const target = sema.mod.getTarget();4144 const target = pt.zcu.getTarget();
4113 const ptr_type = try sema.mod.ptrTypeSema(.{4145 const ptr_type = try pt.ptrTypeSema(.{
4114 .child = var_ty.toIntern(),4146 .child = var_ty.toIntern(),
4115 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },4147 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
4116 });4148 });
...@@ -4125,6 +4157,8 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -4125,6 +4157,8 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
4125 const tracy = trace(@src());4157 const tracy = trace(@src());
4126 defer tracy.end();4158 defer tracy.end();
41274159
4160 const pt = sema.pt;
4161
4128 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;4162 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 });4163 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);4164 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
...@@ -4132,8 +4166,8 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -4132,8 +4166,8 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
4132 return sema.analyzeComptimeAlloc(block, var_ty, .none);4166 return sema.analyzeComptimeAlloc(block, var_ty, .none);
4133 }4167 }
4134 try sema.validateVarType(block, ty_src, var_ty, false);4168 try sema.validateVarType(block, ty_src, var_ty, false);
4135 const target = sema.mod.getTarget();4169 const target = pt.zcu.getTarget();
4136 const ptr_type = try sema.mod.ptrTypeSema(.{4170 const ptr_type = try pt.ptrTypeSema(.{
4137 .child = var_ty.toIntern(),4171 .child = var_ty.toIntern(),
4138 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },4172 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
4139 });4173 });
...@@ -4181,7 +4215,8 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4181,7 +4215,8 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4181 const tracy = trace(@src());4215 const tracy = trace(@src());
4182 defer tracy.end();4216 defer tracy.end();
41834217
4184 const mod = sema.mod;4218 const pt = sema.pt;
4219 const mod = pt.zcu;
4185 const gpa = sema.gpa;4220 const gpa = sema.gpa;
4186 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;4221 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
4187 const src = block.nodeOffset(inst_data.src_node);4222 const src = block.nodeOffset(inst_data.src_node);
...@@ -4206,7 +4241,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4206,7 +4241,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4206 .anon_decl => |a| a.val,4241 .anon_decl => |a| a.val,
4207 .comptime_alloc => |i| val: {4242 .comptime_alloc => |i| val: {
4208 const alloc = sema.getComptimeAlloc(i);4243 const alloc = sema.getComptimeAlloc(i);
4209 break :val (try alloc.val.intern(mod, sema.arena)).toIntern();4244 break :val (try alloc.val.intern(pt, sema.arena)).toIntern();
4210 },4245 },
4211 else => unreachable,4246 else => unreachable,
4212 };4247 };
...@@ -4232,7 +4267,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4232,7 +4267,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4232 }4267 }
4233 const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_vals, .none);4268 const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_vals, .none);
42344269
4235 const final_ptr_ty = try mod.ptrTypeSema(.{4270 const final_ptr_ty = try pt.ptrTypeSema(.{
4236 .child = final_elem_ty.toIntern(),4271 .child = final_elem_ty.toIntern(),
4237 .flags = .{4272 .flags = .{
4238 .alignment = ia1.alignment,4273 .alignment = ia1.alignment,
...@@ -4244,7 +4279,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4244,7 +4279,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4244 try sema.validateVarType(block, ty_src, final_elem_ty, false);4279 try sema.validateVarType(block, ty_src, final_elem_ty, false);
4245 } else if (try sema.resolveComptimeKnownAllocPtr(block, ptr, final_ptr_ty)) |ptr_val| {4280 } else if (try sema.resolveComptimeKnownAllocPtr(block, ptr, final_ptr_ty)) |ptr_val| {
4246 const const_ptr_ty = try sema.makePtrTyConst(final_ptr_ty);4281 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);4282 const new_const_ptr = try pt.getCoerced(Value.fromInterned(ptr_val), const_ptr_ty);
42484283
4249 // Remap the ZIR operand to the resolved pointer value4284 // Remap the ZIR operand to the resolved pointer value
4250 sema.inst_map.putAssumeCapacity(inst_data.operand.toIndex().?, Air.internedToRef(new_const_ptr.toIntern()));4285 sema.inst_map.putAssumeCapacity(inst_data.operand.toIndex().?, Air.internedToRef(new_const_ptr.toIntern()));
...@@ -4252,7 +4287,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4252,7 +4287,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4252 // Unless the block is comptime, `alloc_inferred` always produces4287 // Unless the block is comptime, `alloc_inferred` always produces
4253 // a runtime constant. The final inferred type needs to be4288 // a runtime constant. The final inferred type needs to be
4254 // fully resolved so it can be lowered in codegen.4289 // fully resolved so it can be lowered in codegen.
4255 try final_elem_ty.resolveFully(mod);4290 try final_elem_ty.resolveFully(pt);
42564291
4257 return;4292 return;
4258 }4293 }
...@@ -4261,7 +4296,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4261,7 +4296,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4261 // The alloc wasn't comptime-known per the above logic, so the4296 // The alloc wasn't comptime-known per the above logic, so the
4262 // type cannot be comptime-only.4297 // type cannot be comptime-only.
4263 // TODO: source location of runtime control flow4298 // 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)});4299 return sema.fail(block, src, "value with comptime-only type '{}' depends on runtime control flow", .{final_elem_ty.fmt(pt)});
4265 }4300 }
42664301
4267 // Change it to a normal alloc.4302 // Change it to a normal alloc.
...@@ -4318,7 +4353,8 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4318,7 +4353,8 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4318}4353}
43194354
4320fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {4355fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
4321 const mod = sema.mod;4356 const pt = sema.pt;
4357 const mod = pt.zcu;
4322 const gpa = sema.gpa;4358 const gpa = sema.gpa;
4323 const ip = &mod.intern_pool;4359 const ip = &mod.intern_pool;
4324 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;4360 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
...@@ -4355,7 +4391,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -4355,7 +4391,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
4355 if (!object_ty.isIndexable(mod)) {4391 if (!object_ty.isIndexable(mod)) {
4356 // Instead of using checkIndexable we customize this error.4392 // Instead of using checkIndexable we customize this error.
4357 const msg = msg: {4393 const msg = msg: {
4358 const msg = try sema.errMsg(arg_src, "type '{}' is not indexable and not a range", .{object_ty.fmt(sema.mod)});4394 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);4395 errdefer msg.destroy(sema.gpa);
4360 try sema.errNote(arg_src, msg, "for loop operand must be a range, array, slice, tuple, or vector", .{});4396 try sema.errNote(arg_src, msg, "for loop operand must be a range, array, slice, tuple, or vector", .{});
43614397
...@@ -4387,10 +4423,10 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -4387,10 +4423,10 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
4387 .input_index = len_idx,4423 .input_index = len_idx,
4388 } });4424 } });
4389 try sema.errNote(a_src, msg, "length {} here", .{4425 try sema.errNote(a_src, msg, "length {} here", .{
4390 v.fmtValue(sema.mod, sema),4426 v.fmtValue(pt, sema),
4391 });4427 });
4392 try sema.errNote(arg_src, msg, "length {} here", .{4428 try sema.errNote(arg_src, msg, "length {} here", .{
4393 arg_val.fmtValue(sema.mod, sema),4429 arg_val.fmtValue(pt, sema),
4394 });4430 });
4395 break :msg msg;4431 break :msg msg;
4396 };4432 };
...@@ -4427,7 +4463,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -4427,7 +4463,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
4427 .input_index = i,4463 .input_index = i,
4428 } });4464 } });
4429 try sema.errNote(arg_src, msg, "type '{}' has no upper bound", .{4465 try sema.errNote(arg_src, msg, "type '{}' has no upper bound", .{
4430 object_ty.fmt(sema.mod),4466 object_ty.fmt(pt),
4431 });4467 });
4432 }4468 }
4433 break :msg msg;4469 break :msg msg;
...@@ -4453,7 +4489,8 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -4453,7 +4489,8 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
4453/// Given a `*E!?T`, returns a (valid) `*T`.4489/// Given a `*E!?T`, returns a (valid) `*T`.
4454/// May invalidate already-stored payload data.4490/// May invalidate already-stored payload data.
4455fn optEuBasePtrInit(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, src: LazySrcLoc) CompileError!Air.Inst.Ref {4491fn optEuBasePtrInit(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, src: LazySrcLoc) CompileError!Air.Inst.Ref {
4456 const mod = sema.mod;4492 const pt = sema.pt;
4493 const mod = pt.zcu;
4457 var base_ptr = ptr;4494 var base_ptr = ptr;
4458 while (true) switch (sema.typeOf(base_ptr).childType(mod).zigTypeTag(mod)) {4495 while (true) switch (sema.typeOf(base_ptr).childType(mod).zigTypeTag(mod)) {
4459 .ErrorUnion => base_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, base_ptr, false, true),4496 .ErrorUnion => base_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, base_ptr, false, true),
...@@ -4471,7 +4508,8 @@ fn zirOptEuBasePtrInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile...@@ -4471,7 +4508,8 @@ fn zirOptEuBasePtrInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile
4471}4508}
44724509
4473fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {4510fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
4474 const mod = sema.mod;4511 const pt = sema.pt;
4512 const mod = pt.zcu;
4475 const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;4513 const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
4476 const src = block.nodeOffset(pl_node.src_node);4514 const src = block.nodeOffset(pl_node.src_node);
4477 const extra = sema.code.extraData(Zir.Inst.Bin, pl_node.payload_index).data;4515 const extra = sema.code.extraData(Zir.Inst.Bin, pl_node.payload_index).data;
...@@ -4503,10 +4541,10 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -4503,10 +4541,10 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
4503 switch (val_ty.zigTypeTag(mod)) {4541 switch (val_ty.zigTypeTag(mod)) {
4504 .Array, .Vector => {},4542 .Array, .Vector => {},
4505 else => if (!val_ty.isTuple(mod)) {4543 else => if (!val_ty.isTuple(mod)) {
4506 return sema.fail(block, src, "expected array of '{}', found '{}'", .{ elem_ty.fmt(mod), val_ty.fmt(mod) });4544 return sema.fail(block, src, "expected array of '{}', found '{}'", .{ elem_ty.fmt(pt), val_ty.fmt(pt) });
4507 },4545 },
4508 }4546 }
4509 const want_ty = try mod.arrayType(.{4547 const want_ty = try pt.arrayType(.{
4510 .len = val_ty.arrayLen(mod),4548 .len = val_ty.arrayLen(mod),
4511 .child = elem_ty.toIntern(),4549 .child = elem_ty.toIntern(),
4512 .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,4550 .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,
...@@ -4522,7 +4560,8 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -4522,7 +4560,8 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
4522}4560}
45234561
4524fn zirValidateRefTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {4562fn zirValidateRefTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
4525 const mod = sema.mod;4563 const pt = sema.pt;
4564 const mod = pt.zcu;
4526 const un_tok = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok;4565 const un_tok = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok;
4527 const src = block.tokenOffset(un_tok.src_tok);4566 const src = block.tokenOffset(un_tok.src_tok);
4528 // In case of GenericPoison, we don't actually have a type, so this will be4567 // In case of GenericPoison, we don't actually have a type, so this will be
...@@ -4538,7 +4577,7 @@ fn zirValidateRefTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -4538,7 +4577,7 @@ fn zirValidateRefTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
4538 if (ty_operand.isGenericPoison()) return;4577 if (ty_operand.isGenericPoison()) return;
4539 if (ty_operand.optEuBaseType(mod).zigTypeTag(mod) != .Pointer) {4578 if (ty_operand.optEuBaseType(mod).zigTypeTag(mod) != .Pointer) {
4540 return sema.failWithOwnedErrorMsg(block, msg: {4579 return sema.failWithOwnedErrorMsg(block, msg: {
4541 const msg = try sema.errMsg(src, "expected type '{}', found pointer", .{ty_operand.fmt(mod)});4580 const msg = try sema.errMsg(src, "expected type '{}', found pointer", .{ty_operand.fmt(pt)});
4542 errdefer msg.destroy(sema.gpa);4581 errdefer msg.destroy(sema.gpa);
4543 try sema.errNote(src, msg, "address-of operator always returns a pointer", .{});4582 try sema.errNote(src, msg, "address-of operator always returns a pointer", .{});
4544 break :msg msg;4583 break :msg msg;
...@@ -4551,7 +4590,8 @@ fn zirValidateArrayInitRefTy(...@@ -4551,7 +4590,8 @@ fn zirValidateArrayInitRefTy(
4551 block: *Block,4590 block: *Block,
4552 inst: Zir.Inst.Index,4591 inst: Zir.Inst.Index,
4553) CompileError!Air.Inst.Ref {4592) CompileError!Air.Inst.Ref {
4554 const mod = sema.mod;4593 const pt = sema.pt;
4594 const mod = pt.zcu;
4555 const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;4595 const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
4556 const src = block.nodeOffset(pl_node.src_node);4596 const src = block.nodeOffset(pl_node.src_node);
4557 const extra = sema.code.extraData(Zir.Inst.ArrayInitRefTy, pl_node.payload_index).data;4597 const extra = sema.code.extraData(Zir.Inst.ArrayInitRefTy, pl_node.payload_index).data;
...@@ -4565,7 +4605,7 @@ fn zirValidateArrayInitRefTy(...@@ -4565,7 +4605,7 @@ fn zirValidateArrayInitRefTy(
4565 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {4605 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
4566 .Slice, .Many => {4606 .Slice, .Many => {
4567 // Use array of correct length4607 // Use array of correct length
4568 const arr_ty = try mod.arrayType(.{4608 const arr_ty = try pt.arrayType(.{
4569 .len = extra.elem_count,4609 .len = extra.elem_count,
4570 .child = ptr_ty.childType(mod).toIntern(),4610 .child = ptr_ty.childType(mod).toIntern(),
4571 .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,4611 .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,
...@@ -4593,7 +4633,8 @@ fn zirValidateArrayInitTy(...@@ -4593,7 +4633,8 @@ fn zirValidateArrayInitTy(
4593 inst: Zir.Inst.Index,4633 inst: Zir.Inst.Index,
4594 is_result_ty: bool,4634 is_result_ty: bool,
4595) CompileError!void {4635) CompileError!void {
4596 const mod = sema.mod;4636 const pt = sema.pt;
4637 const mod = pt.zcu;
4597 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;4638 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
4598 const src = block.nodeOffset(inst_data.src_node);4639 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 });4640 const ty_src: LazySrcLoc = if (is_result_ty) src else block.src(.{ .node_offset_init_ty = inst_data.src_node });
...@@ -4615,7 +4656,8 @@ fn validateArrayInitTy(...@@ -4615,7 +4656,8 @@ fn validateArrayInitTy(
4615 init_count: u32,4656 init_count: u32,
4616 ty: Type,4657 ty: Type,
4617) CompileError!void {4658) CompileError!void {
4618 const mod = sema.mod;4659 const pt = sema.pt;
4660 const mod = pt.zcu;
4619 switch (ty.zigTypeTag(mod)) {4661 switch (ty.zigTypeTag(mod)) {
4620 .Array => {4662 .Array => {
4621 const array_len = ty.arrayLen(mod);4663 const array_len = ty.arrayLen(mod);
...@@ -4636,7 +4678,7 @@ fn validateArrayInitTy(...@@ -4636,7 +4678,7 @@ fn validateArrayInitTy(
4636 return;4678 return;
4637 },4679 },
4638 .Struct => if (ty.isTuple(mod)) {4680 .Struct => if (ty.isTuple(mod)) {
4639 try ty.resolveFields(mod);4681 try ty.resolveFields(pt);
4640 const array_len = ty.arrayLen(mod);4682 const array_len = ty.arrayLen(mod);
4641 if (init_count > array_len) {4683 if (init_count > array_len) {
4642 return sema.fail(block, src, "expected at most {d} tuple fields; found {d}", .{4684 return sema.fail(block, src, "expected at most {d} tuple fields; found {d}", .{
...@@ -4656,7 +4698,8 @@ fn zirValidateStructInitTy(...@@ -4656,7 +4698,8 @@ fn zirValidateStructInitTy(
4656 inst: Zir.Inst.Index,4698 inst: Zir.Inst.Index,
4657 is_result_ty: bool,4699 is_result_ty: bool,
4658) CompileError!void {4700) CompileError!void {
4659 const mod = sema.mod;4701 const pt = sema.pt;
4702 const mod = pt.zcu;
4660 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;4703 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
4661 const src = block.nodeOffset(inst_data.src_node);4704 const src = block.nodeOffset(inst_data.src_node);
4662 const ty = sema.resolveType(block, src, inst_data.operand) catch |err| switch (err) {4705 const ty = sema.resolveType(block, src, inst_data.operand) catch |err| switch (err) {
...@@ -4681,7 +4724,8 @@ fn zirValidatePtrStructInit(...@@ -4681,7 +4724,8 @@ fn zirValidatePtrStructInit(
4681 const tracy = trace(@src());4724 const tracy = trace(@src());
4682 defer tracy.end();4725 defer tracy.end();
46834726
4684 const mod = sema.mod;4727 const pt = sema.pt;
4728 const mod = pt.zcu;
4685 const validate_inst = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;4729 const validate_inst = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
4686 const init_src = block.nodeOffset(validate_inst.src_node);4730 const init_src = block.nodeOffset(validate_inst.src_node);
4687 const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index);4731 const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index);
...@@ -4716,7 +4760,8 @@ fn validateUnionInit(...@@ -4716,7 +4760,8 @@ fn validateUnionInit(
4716 instrs: []const Zir.Inst.Index,4760 instrs: []const Zir.Inst.Index,
4717 union_ptr: Air.Inst.Ref,4761 union_ptr: Air.Inst.Ref,
4718) CompileError!void {4762) CompileError!void {
4719 const mod = sema.mod;4763 const pt = sema.pt;
4764 const mod = pt.zcu;
4720 const gpa = sema.gpa;4765 const gpa = sema.gpa;
47214766
4722 if (instrs.len != 1) {4767 if (instrs.len != 1) {
...@@ -4814,7 +4859,7 @@ fn validateUnionInit(...@@ -4814,7 +4859,7 @@ fn validateUnionInit(
4814 }4859 }
48154860
4816 const tag_ty = union_ty.unionTagTypeHypothetical(mod);4861 const tag_ty = union_ty.unionTagTypeHypothetical(mod);
4817 const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index);4862 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);
4818 const field_type = union_ty.unionFieldType(tag_val, mod).?;4863 const field_type = union_ty.unionFieldType(tag_val, mod).?;
48194864
4820 if (try sema.typeHasOnePossibleValue(field_type)) |field_only_value| {4865 if (try sema.typeHasOnePossibleValue(field_type)) |field_only_value| {
...@@ -4848,7 +4893,7 @@ fn validateUnionInit(...@@ -4848,7 +4893,7 @@ fn validateUnionInit(
4848 }4893 }
4849 block.instructions.shrinkRetainingCapacity(block_index);4894 block.instructions.shrinkRetainingCapacity(block_index);
48504895
4851 const union_val = try mod.intern(.{ .un = .{4896 const union_val = try pt.intern(.{ .un = .{
4852 .ty = union_ty.toIntern(),4897 .ty = union_ty.toIntern(),
4853 .tag = tag_val.toIntern(),4898 .tag = tag_val.toIntern(),
4854 .val = val.toIntern(),4899 .val = val.toIntern(),
...@@ -4875,7 +4920,8 @@ fn validateStructInit(...@@ -4875,7 +4920,8 @@ fn validateStructInit(
4875 init_src: LazySrcLoc,4920 init_src: LazySrcLoc,
4876 instrs: []const Zir.Inst.Index,4921 instrs: []const Zir.Inst.Index,
4877) CompileError!void {4922) CompileError!void {
4878 const mod = sema.mod;4923 const pt = sema.pt;
4924 const mod = pt.zcu;
4879 const gpa = sema.gpa;4925 const gpa = sema.gpa;
4880 const ip = &mod.intern_pool;4926 const ip = &mod.intern_pool;
48814927
...@@ -4914,7 +4960,7 @@ fn validateStructInit(...@@ -4914,7 +4960,7 @@ fn validateStructInit(
4914 if (block.is_comptime and4960 if (block.is_comptime and
4915 (try sema.resolveDefinedValue(block, init_src, struct_ptr)) != null)4961 (try sema.resolveDefinedValue(block, init_src, struct_ptr)) != null)
4916 {4962 {
4917 try struct_ty.resolveLayout(mod);4963 try struct_ty.resolveLayout(pt);
4918 // In this case the only thing we need to do is evaluate the implicit4964 // 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.4965 // 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.4966 // Avoid the cost of the extra machinery for detecting a comptime struct init value.
...@@ -4922,7 +4968,7 @@ fn validateStructInit(...@@ -4922,7 +4968,7 @@ fn validateStructInit(
4922 const i: u32 = @intCast(i_usize);4968 const i: u32 = @intCast(i_usize);
4923 if (field_ptr != .none) continue;4969 if (field_ptr != .none) continue;
49244970
4925 try struct_ty.resolveStructFieldInits(mod);4971 try struct_ty.resolveStructFieldInits(pt);
4926 const default_val = struct_ty.structFieldDefaultValue(i, mod);4972 const default_val = struct_ty.structFieldDefaultValue(i, mod);
4927 if (default_val.toIntern() == .unreachable_value) {4973 if (default_val.toIntern() == .unreachable_value) {
4928 const field_name = struct_ty.structFieldName(i, mod).unwrap() orelse {4974 const field_name = struct_ty.structFieldName(i, mod).unwrap() orelse {
...@@ -4971,7 +5017,7 @@ fn validateStructInit(...@@ -4971,7 +5017,7 @@ fn validateStructInit(
4971 const air_tags = sema.air_instructions.items(.tag);5017 const air_tags = sema.air_instructions.items(.tag);
4972 const air_datas = sema.air_instructions.items(.data);5018 const air_datas = sema.air_instructions.items(.data);
49735019
4974 try struct_ty.resolveStructFieldInits(mod);5020 try struct_ty.resolveStructFieldInits(pt);
49755021
4976 // We collect the comptime field values in case the struct initialization5022 // We collect the comptime field values in case the struct initialization
4977 // ends up being comptime-known.5023 // ends up being comptime-known.
...@@ -5094,7 +5140,7 @@ fn validateStructInit(...@@ -5094,7 +5140,7 @@ fn validateStructInit(
5094 for (block.instructions.items[first_block_index..]) |cur_inst| {5140 for (block.instructions.items[first_block_index..]) |cur_inst| {
5095 while (field_ptr_ref == .none and init_index < instrs.len) : (init_index += 1) {5141 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);5142 const field_ty = struct_ty.structFieldType(field_indices[init_index], mod);
5097 if (try field_ty.onePossibleValue(mod)) |_| continue;5143 if (try field_ty.onePossibleValue(pt)) |_| continue;
5098 field_ptr_ref = sema.inst_map.get(instrs[init_index]).?;5144 field_ptr_ref = sema.inst_map.get(instrs[init_index]).?;
5099 }5145 }
5100 switch (air_tags[@intFromEnum(cur_inst)]) {5146 switch (air_tags[@intFromEnum(cur_inst)]) {
...@@ -5122,7 +5168,7 @@ fn validateStructInit(...@@ -5122,7 +5168,7 @@ fn validateStructInit(
5122 }5168 }
5123 block.instructions.shrinkRetainingCapacity(block_index);5169 block.instructions.shrinkRetainingCapacity(block_index);
51245170
5125 const struct_val = try mod.intern(.{ .aggregate = .{5171 const struct_val = try pt.intern(.{ .aggregate = .{
5126 .ty = struct_ty.toIntern(),5172 .ty = struct_ty.toIntern(),
5127 .storage = .{ .elems = field_values },5173 .storage = .{ .elems = field_values },
5128 } });5174 } });
...@@ -5130,7 +5176,7 @@ fn validateStructInit(...@@ -5130,7 +5176,7 @@ fn validateStructInit(
5130 try sema.storePtr2(block, init_src, struct_ptr, init_src, struct_init, init_src, .store);5176 try sema.storePtr2(block, init_src, struct_ptr, init_src, struct_init, init_src, .store);
5131 return;5177 return;
5132 }5178 }
5133 try struct_ty.resolveLayout(mod);5179 try struct_ty.resolveLayout(pt);
51345180
5135 // Our task is to insert `store` instructions for all the default field values.5181 // Our task is to insert `store` instructions for all the default field values.
5136 for (found_fields, 0..) |field_ptr, i| {5182 for (found_fields, 0..) |field_ptr, i| {
...@@ -5152,7 +5198,8 @@ fn zirValidatePtrArrayInit(...@@ -5152,7 +5198,8 @@ fn zirValidatePtrArrayInit(
5152 block: *Block,5198 block: *Block,
5153 inst: Zir.Inst.Index,5199 inst: Zir.Inst.Index,
5154) CompileError!void {5200) CompileError!void {
5155 const mod = sema.mod;5201 const pt = sema.pt;
5202 const mod = pt.zcu;
5156 const validate_inst = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;5203 const validate_inst = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
5157 const init_src = block.nodeOffset(validate_inst.src_node);5204 const init_src = block.nodeOffset(validate_inst.src_node);
5158 const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index);5205 const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index);
...@@ -5175,7 +5222,7 @@ fn zirValidatePtrArrayInit(...@@ -5175,7 +5222,7 @@ fn zirValidatePtrArrayInit(
5175 var root_msg: ?*Module.ErrorMsg = null;5222 var root_msg: ?*Module.ErrorMsg = null;
5176 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);5223 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);
51775224
5178 try array_ty.resolveStructFieldInits(mod);5225 try array_ty.resolveStructFieldInits(pt);
5179 var i = instrs.len;5226 var i = instrs.len;
5180 while (i < array_len) : (i += 1) {5227 while (i < array_len) : (i += 1) {
5181 const default_val = array_ty.structFieldDefaultValue(i, mod).toIntern();5228 const default_val = array_ty.structFieldDefaultValue(i, mod).toIntern();
...@@ -5218,7 +5265,7 @@ fn zirValidatePtrArrayInit(...@@ -5218,7 +5265,7 @@ fn zirValidatePtrArrayInit(
5218 // sentinel-terminated array, the sentinel will not have been populated by5265 // sentinel-terminated array, the sentinel will not have been populated by
5219 // any ZIR instructions at comptime; we need to do that here.5266 // any ZIR instructions at comptime; we need to do that here.
5220 if (array_ty.sentinel(mod)) |sentinel_val| {5267 if (array_ty.sentinel(mod)) |sentinel_val| {
5221 const array_len_ref = try mod.intRef(Type.usize, array_len);5268 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);5269 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());5270 const sentinel = Air.internedToRef(sentinel_val.toIntern());
5224 try sema.storePtr2(block, init_src, sentinel_ptr, init_src, sentinel, init_src, .store);5271 try sema.storePtr2(block, init_src, sentinel_ptr, init_src, sentinel, init_src, .store);
...@@ -5244,8 +5291,8 @@ fn zirValidatePtrArrayInit(...@@ -5244,8 +5291,8 @@ fn zirValidatePtrArrayInit(
52445291
5245 if (array_ty.isTuple(mod)) {5292 if (array_ty.isTuple(mod)) {
5246 if (array_ty.structFieldIsComptime(i, mod))5293 if (array_ty.structFieldIsComptime(i, mod))
5247 try array_ty.resolveStructFieldInits(mod);5294 try array_ty.resolveStructFieldInits(pt);
5248 if (try array_ty.structFieldValueComptime(mod, i)) |opv| {5295 if (try array_ty.structFieldValueComptime(pt, i)) |opv| {
5249 element_vals[i] = opv.toIntern();5296 element_vals[i] = opv.toIntern();
5250 continue;5297 continue;
5251 }5298 }
...@@ -5347,7 +5394,7 @@ fn zirValidatePtrArrayInit(...@@ -5347,7 +5394,7 @@ fn zirValidatePtrArrayInit(
5347 }5394 }
5348 block.instructions.shrinkRetainingCapacity(block_index);5395 block.instructions.shrinkRetainingCapacity(block_index);
53495396
5350 const array_val = try mod.intern(.{ .aggregate = .{5397 const array_val = try pt.intern(.{ .aggregate = .{
5351 .ty = array_ty.toIntern(),5398 .ty = array_ty.toIntern(),
5352 .storage = .{ .elems = element_vals },5399 .storage = .{ .elems = element_vals },
5353 } });5400 } });
...@@ -5357,18 +5404,19 @@ fn zirValidatePtrArrayInit(...@@ -5357,18 +5404,19 @@ fn zirValidatePtrArrayInit(
5357}5404}
53585405
5359fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {5406fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
5360 const mod = sema.mod;5407 const pt = sema.pt;
5408 const mod = pt.zcu;
5361 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;5409 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
5362 const src = block.nodeOffset(inst_data.src_node);5410 const src = block.nodeOffset(inst_data.src_node);
5363 const operand = try sema.resolveInst(inst_data.operand);5411 const operand = try sema.resolveInst(inst_data.operand);
5364 const operand_ty = sema.typeOf(operand);5412 const operand_ty = sema.typeOf(operand);
53655413
5366 if (operand_ty.zigTypeTag(mod) != .Pointer) {5414 if (operand_ty.zigTypeTag(mod) != .Pointer) {
5367 return sema.fail(block, src, "cannot dereference non-pointer type '{}'", .{operand_ty.fmt(mod)});5415 return sema.fail(block, src, "cannot dereference non-pointer type '{}'", .{operand_ty.fmt(pt)});
5368 } else switch (operand_ty.ptrSize(mod)) {5416 } else switch (operand_ty.ptrSize(mod)) {
5369 .One, .C => {},5417 .One, .C => {},
5370 .Many => return sema.fail(block, src, "index syntax required for unknown-length pointer type '{}'", .{operand_ty.fmt(mod)}),5418 .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)}),5419 .Slice => return sema.fail(block, src, "index syntax required for slice type '{}'", .{operand_ty.fmt(pt)}),
5372 }5420 }
53735421
5374 if ((try sema.typeHasOnePossibleValue(operand_ty.childType(mod))) != null) {5422 if ((try sema.typeHasOnePossibleValue(operand_ty.childType(mod))) != null) {
...@@ -5386,7 +5434,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -5386,7 +5434,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
5386 const msg = try sema.errMsg(5434 const msg = try sema.errMsg(
5387 src,5435 src,
5388 "values of type '{}' must be comptime-known, but operand value is runtime-known",5436 "values of type '{}' must be comptime-known, but operand value is runtime-known",
5389 .{elem_ty.fmt(mod)},5437 .{elem_ty.fmt(pt)},
5390 );5438 );
5391 errdefer msg.destroy(sema.gpa);5439 errdefer msg.destroy(sema.gpa);
53925440
...@@ -5398,7 +5446,8 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -5398,7 +5446,8 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
5398}5446}
53995447
5400fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {5448fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
5401 const mod = sema.mod;5449 const pt = sema.pt;
5450 const mod = pt.zcu;
5402 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;5451 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;5452 const extra = sema.code.extraData(Zir.Inst.ValidateDestructure, inst_data.payload_index).data;
5404 const src = block.nodeOffset(inst_data.src_node);5453 const src = block.nodeOffset(inst_data.src_node);
...@@ -5414,7 +5463,7 @@ fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp...@@ -5414,7 +5463,7 @@ fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
54145463
5415 if (!can_destructure) {5464 if (!can_destructure) {
5416 return sema.failWithOwnedErrorMsg(block, msg: {5465 return sema.failWithOwnedErrorMsg(block, msg: {
5417 const msg = try sema.errMsg(src, "type '{}' cannot be destructured", .{operand_ty.fmt(mod)});5466 const msg = try sema.errMsg(src, "type '{}' cannot be destructured", .{operand_ty.fmt(pt)});
5418 errdefer msg.destroy(sema.gpa);5467 errdefer msg.destroy(sema.gpa);
5419 try sema.errNote(destructure_src, msg, "result destructured here", .{});5468 try sema.errNote(destructure_src, msg, "result destructured here", .{});
5420 break :msg msg;5469 break :msg msg;
...@@ -5441,7 +5490,8 @@ fn failWithBadMemberAccess(...@@ -5441,7 +5490,8 @@ fn failWithBadMemberAccess(
5441 field_src: LazySrcLoc,5490 field_src: LazySrcLoc,
5442 field_name: InternPool.NullTerminatedString,5491 field_name: InternPool.NullTerminatedString,
5443) CompileError {5492) CompileError {
5444 const mod = sema.mod;5493 const pt = sema.pt;
5494 const mod = pt.zcu;
5445 const kw_name = switch (agg_ty.zigTypeTag(mod)) {5495 const kw_name = switch (agg_ty.zigTypeTag(mod)) {
5446 .Union => "union",5496 .Union => "union",
5447 .Struct => "struct",5497 .Struct => "struct",
...@@ -5451,12 +5501,12 @@ fn failWithBadMemberAccess(...@@ -5451,12 +5501,12 @@ fn failWithBadMemberAccess(
5451 };5501 };
5452 if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (mod.declIsRoot(some)) {5502 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 '{}'", .{5503 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),5504 agg_ty.fmt(pt), field_name.fmt(&mod.intern_pool),
5455 });5505 });
5456 };5506 };
54575507
5458 return sema.fail(block, field_src, "{s} '{}' has no member named '{}'", .{5508 return sema.fail(block, field_src, "{s} '{}' has no member named '{}'", .{
5459 kw_name, agg_ty.fmt(mod), field_name.fmt(&mod.intern_pool),5509 kw_name, agg_ty.fmt(pt), field_name.fmt(&mod.intern_pool),
5460 });5510 });
5461}5511}
54625512
...@@ -5468,8 +5518,8 @@ fn failWithBadStructFieldAccess(...@@ -5468,8 +5518,8 @@ fn failWithBadStructFieldAccess(
5468 field_src: LazySrcLoc,5518 field_src: LazySrcLoc,
5469 field_name: InternPool.NullTerminatedString,5519 field_name: InternPool.NullTerminatedString,
5470) CompileError {5520) CompileError {
5471 const zcu = sema.mod;5521 const zcu = sema.pt.zcu;
5472 const gpa = sema.gpa;5522 const ip = &zcu.intern_pool;
5473 const decl = zcu.declPtr(struct_type.decl.unwrap().?);5523 const decl = zcu.declPtr(struct_type.decl.unwrap().?);
5474 const fqn = try decl.fullyQualifiedName(zcu);5524 const fqn = try decl.fullyQualifiedName(zcu);
54755525
...@@ -5477,9 +5527,9 @@ fn failWithBadStructFieldAccess(...@@ -5477,9 +5527,9 @@ fn failWithBadStructFieldAccess(
5477 const msg = try sema.errMsg(5527 const msg = try sema.errMsg(
5478 field_src,5528 field_src,
5479 "no field named '{}' in struct '{}'",5529 "no field named '{}' in struct '{}'",
5480 .{ field_name.fmt(&zcu.intern_pool), fqn.fmt(&zcu.intern_pool) },5530 .{ field_name.fmt(ip), fqn.fmt(ip) },
5481 );5531 );
5482 errdefer msg.destroy(gpa);5532 errdefer msg.destroy(sema.gpa);
5483 try sema.errNote(struct_ty.srcLoc(zcu), msg, "struct declared here", .{});5533 try sema.errNote(struct_ty.srcLoc(zcu), msg, "struct declared here", .{});
5484 break :msg msg;5534 break :msg msg;
5485 };5535 };
...@@ -5494,7 +5544,8 @@ fn failWithBadUnionFieldAccess(...@@ -5494,7 +5544,8 @@ fn failWithBadUnionFieldAccess(
5494 field_src: LazySrcLoc,5544 field_src: LazySrcLoc,
5495 field_name: InternPool.NullTerminatedString,5545 field_name: InternPool.NullTerminatedString,
5496) CompileError {5546) CompileError {
5497 const zcu = sema.mod;5547 const zcu = sema.pt.zcu;
5548 const ip = &zcu.intern_pool;
5498 const gpa = sema.gpa;5549 const gpa = sema.gpa;
54995550
5500 const decl = zcu.declPtr(union_obj.decl);5551 const decl = zcu.declPtr(union_obj.decl);
...@@ -5504,7 +5555,7 @@ fn failWithBadUnionFieldAccess(...@@ -5504,7 +5555,7 @@ fn failWithBadUnionFieldAccess(
5504 const msg = try sema.errMsg(5555 const msg = try sema.errMsg(
5505 field_src,5556 field_src,
5506 "no field named '{}' in union '{}'",5557 "no field named '{}' in union '{}'",
5507 .{ field_name.fmt(&zcu.intern_pool), fqn.fmt(&zcu.intern_pool) },5558 .{ field_name.fmt(ip), fqn.fmt(ip) },
5508 );5559 );
5509 errdefer msg.destroy(gpa);5560 errdefer msg.destroy(gpa);
5510 try sema.errNote(union_ty.srcLoc(zcu), msg, "union declared here", .{});5561 try sema.errNote(union_ty.srcLoc(zcu), msg, "union declared here", .{});
...@@ -5514,9 +5565,9 @@ fn failWithBadUnionFieldAccess(...@@ -5514,9 +5565,9 @@ fn failWithBadUnionFieldAccess(
5514}5565}
55155566
5516fn addDeclaredHereNote(sema: *Sema, parent: *Module.ErrorMsg, decl_ty: Type) !void {5567fn addDeclaredHereNote(sema: *Sema, parent: *Module.ErrorMsg, decl_ty: Type) !void {
5517 const mod = sema.mod;5568 const zcu = sema.pt.zcu;
5518 const src_loc = decl_ty.srcLocOrNull(mod) orelse return;5569 const src_loc = decl_ty.srcLocOrNull(zcu) orelse return;
5519 const category = switch (decl_ty.zigTypeTag(mod)) {5570 const category = switch (decl_ty.zigTypeTag(zcu)) {
5520 .Union => "union",5571 .Union => "union",
5521 .Struct => "struct",5572 .Struct => "struct",
5522 .Enum => "enum",5573 .Enum => "enum",
...@@ -5575,7 +5626,8 @@ fn storeToInferredAllocComptime(...@@ -5575,7 +5626,8 @@ fn storeToInferredAllocComptime(
5575 operand: Air.Inst.Ref,5626 operand: Air.Inst.Ref,
5576 iac: *Air.Inst.Data.InferredAllocComptime,5627 iac: *Air.Inst.Data.InferredAllocComptime,
5577) CompileError!void {5628) CompileError!void {
5578 const zcu = sema.mod;5629 const pt = sema.pt;
5630 const zcu = pt.zcu;
5579 const operand_ty = sema.typeOf(operand);5631 const operand_ty = sema.typeOf(operand);
5580 // There will be only one store_to_inferred_ptr because we are running at comptime.5632 // 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.5633 // The alloc will turn into a Decl or a ComptimeAlloc.
...@@ -5584,7 +5636,7 @@ fn storeToInferredAllocComptime(...@@ -5584,7 +5636,7 @@ fn storeToInferredAllocComptime(
5584 .needed_comptime_reason = "value being stored to a comptime variable must be comptime-known",5636 .needed_comptime_reason = "value being stored to a comptime variable must be comptime-known",
5585 });5637 });
5586 };5638 };
5587 const alloc_ty = try zcu.ptrTypeSema(.{5639 const alloc_ty = try pt.ptrTypeSema(.{
5588 .child = operand_ty.toIntern(),5640 .child = operand_ty.toIntern(),
5589 .flags = .{5641 .flags = .{
5590 .alignment = iac.alignment,5642 .alignment = iac.alignment,
...@@ -5592,7 +5644,7 @@ fn storeToInferredAllocComptime(...@@ -5592,7 +5644,7 @@ fn storeToInferredAllocComptime(
5592 },5644 },
5593 });5645 });
5594 if (iac.is_const and !operand_val.canMutateComptimeVarState(zcu)) {5646 if (iac.is_const and !operand_val.canMutateComptimeVarState(zcu)) {
5595 iac.ptr = try zcu.intern(.{ .ptr = .{5647 iac.ptr = try pt.intern(.{ .ptr = .{
5596 .ty = alloc_ty.toIntern(),5648 .ty = alloc_ty.toIntern(),
5597 .base_addr = .{ .anon_decl = .{5649 .base_addr = .{ .anon_decl = .{
5598 .val = operand_val.toIntern(),5650 .val = operand_val.toIntern(),
...@@ -5603,7 +5655,7 @@ fn storeToInferredAllocComptime(...@@ -5603,7 +5655,7 @@ fn storeToInferredAllocComptime(
5603 } else {5655 } else {
5604 const alloc_index = try sema.newComptimeAlloc(block, operand_ty, iac.alignment);5656 const alloc_index = try sema.newComptimeAlloc(block, operand_ty, iac.alignment);
5605 sema.getComptimeAlloc(alloc_index).val = .{ .interned = operand_val.toIntern() };5657 sema.getComptimeAlloc(alloc_index).val = .{ .interned = operand_val.toIntern() };
5606 iac.ptr = try zcu.intern(.{ .ptr = .{5658 iac.ptr = try pt.intern(.{ .ptr = .{
5607 .ty = alloc_ty.toIntern(),5659 .ty = alloc_ty.toIntern(),
5608 .base_addr = .{ .comptime_alloc = alloc_index },5660 .base_addr = .{ .comptime_alloc = alloc_index },
5609 .byte_offset = 0,5661 .byte_offset = 0,
...@@ -5624,7 +5676,8 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v...@@ -5624,7 +5676,8 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v
5624 const tracy = trace(@src());5676 const tracy = trace(@src());
5625 defer tracy.end();5677 defer tracy.end();
56265678
5627 const mod = sema.mod;5679 const pt = sema.pt;
5680 const mod = pt.zcu;
5628 const zir_tags = sema.code.instructions.items(.tag);5681 const zir_tags = sema.code.instructions.items(.tag);
5629 const zir_datas = sema.code.instructions.items(.data);5682 const zir_datas = sema.code.instructions.items(.data);
5630 const inst_data = zir_datas[@intFromEnum(inst)].pl_node;5683 const inst_data = zir_datas[@intFromEnum(inst)].pl_node;
...@@ -5662,23 +5715,23 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v...@@ -5662,23 +5715,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 {5715fn 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);5716 const bytes = sema.code.instructions.items(.data)[@intFromEnum(inst)].str.get(sema.code);
5664 return sema.addStrLit(5717 return sema.addStrLit(
5665 try sema.mod.intern_pool.getOrPutString(sema.gpa, bytes, .maybe_embedded_nulls),5718 try sema.pt.zcu.intern_pool.getOrPutString(sema.gpa, bytes, .maybe_embedded_nulls),
5666 bytes.len,5719 bytes.len,
5667 );5720 );
5668}5721}
56695722
5670fn addNullTerminatedStrLit(sema: *Sema, string: InternPool.NullTerminatedString) CompileError!Air.Inst.Ref {5723fn addNullTerminatedStrLit(sema: *Sema, string: InternPool.NullTerminatedString) CompileError!Air.Inst.Ref {
5671 return sema.addStrLit(string.toString(), string.length(&sema.mod.intern_pool));5724 return sema.addStrLit(string.toString(), string.length(&sema.pt.zcu.intern_pool));
5672}5725}
56735726
5674fn addStrLit(sema: *Sema, string: InternPool.String, len: u64) CompileError!Air.Inst.Ref {5727fn addStrLit(sema: *Sema, string: InternPool.String, len: u64) CompileError!Air.Inst.Ref {
5675 const mod = sema.mod;5728 const pt = sema.pt;
5676 const array_ty = try mod.arrayType(.{5729 const array_ty = try pt.arrayType(.{
5677 .len = len,5730 .len = len,
5678 .sentinel = .zero_u8,5731 .sentinel = .zero_u8,
5679 .child = .u8_type,5732 .child = .u8_type,
5680 });5733 });
5681 const val = try mod.intern(.{ .aggregate = .{5734 const val = try pt.intern(.{ .aggregate = .{
5682 .ty = array_ty.toIntern(),5735 .ty = array_ty.toIntern(),
5683 .storage = .{ .bytes = string },5736 .storage = .{ .bytes = string },
5684 } });5737 } });
...@@ -5690,16 +5743,16 @@ fn anonDeclRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {...@@ -5690,16 +5743,16 @@ fn anonDeclRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {
5690}5743}
56915744
5692fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {5745fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {
5693 const mod = sema.mod;5746 const pt = sema.pt;
5694 const ptr_ty = (try mod.ptrTypeSema(.{5747 const ptr_ty = (try pt.ptrTypeSema(.{
5695 .child = mod.intern_pool.typeOf(val),5748 .child = pt.zcu.intern_pool.typeOf(val),
5696 .flags = .{5749 .flags = .{
5697 .alignment = .none,5750 .alignment = .none,
5698 .is_const = true,5751 .is_const = true,
5699 .address_space = .generic,5752 .address_space = .generic,
5700 },5753 },
5701 })).toIntern();5754 })).toIntern();
5702 return mod.intern(.{ .ptr = .{5755 return pt.intern(.{ .ptr = .{
5703 .ty = ptr_ty,5756 .ty = ptr_ty,
5704 .base_addr = .{ .anon_decl = .{5757 .base_addr = .{ .anon_decl = .{
5705 .val = val,5758 .val = val,
...@@ -5715,7 +5768,7 @@ fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -5715,7 +5768,7 @@ fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
5715 defer tracy.end();5768 defer tracy.end();
57165769
5717 const int = sema.code.instructions.items(.data)[@intFromEnum(inst)].int;5770 const int = sema.code.instructions.items(.data)[@intFromEnum(inst)].int;
5718 return sema.mod.intRef(Type.comptime_int, int);5771 return sema.pt.intRef(Type.comptime_int, int);
5719}5772}
57205773
5721fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5774fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -5723,7 +5776,6 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -5723,7 +5776,6 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
5723 const tracy = trace(@src());5776 const tracy = trace(@src());
5724 defer tracy.end();5777 defer tracy.end();
57255778
5726 const mod = sema.mod;
5727 const int = sema.code.instructions.items(.data)[@intFromEnum(inst)].str;5779 const int = sema.code.instructions.items(.data)[@intFromEnum(inst)].str;
5728 const byte_count = int.len * @sizeOf(std.math.big.Limb);5780 const byte_count = int.len * @sizeOf(std.math.big.Limb);
5729 const limb_bytes = sema.code.string_bytes[@intFromEnum(int.start)..][0..byte_count];5781 const limb_bytes = sema.code.string_bytes[@intFromEnum(int.start)..][0..byte_count];
...@@ -5734,7 +5786,7 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -5734,7 +5786,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);5786 const limbs = try sema.arena.alloc(std.math.big.Limb, int.len);
5735 @memcpy(mem.sliceAsBytes(limbs), limb_bytes);5787 @memcpy(mem.sliceAsBytes(limbs), limb_bytes);
57365788
5737 return Air.internedToRef((try mod.intValue_big(Type.comptime_int, .{5789 return Air.internedToRef((try sema.pt.intValue_big(Type.comptime_int, .{
5738 .limbs = limbs,5790 .limbs = limbs,
5739 .positive = true,5791 .positive = true,
5740 })).toIntern());5792 })).toIntern());
...@@ -5743,7 +5795,7 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -5743,7 +5795,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 {5795fn zirFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
5744 _ = block;5796 _ = block;
5745 const number = sema.code.instructions.items(.data)[@intFromEnum(inst)].float;5797 const number = sema.code.instructions.items(.data)[@intFromEnum(inst)].float;
5746 return Air.internedToRef((try sema.mod.floatValue(5798 return Air.internedToRef((try sema.pt.floatValue(
5747 Type.comptime_float,5799 Type.comptime_float,
5748 number,5800 number,
5749 )).toIntern());5801 )).toIntern());
...@@ -5754,7 +5806,7 @@ fn zirFloat128(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -5754,7 +5806,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;5806 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;5807 const extra = sema.code.extraData(Zir.Inst.Float128, inst_data.payload_index).data;
5756 const number = extra.get();5808 const number = extra.get();
5757 return Air.internedToRef((try sema.mod.floatValue(Type.comptime_float, number)).toIntern());5809 return Air.internedToRef((try sema.pt.floatValue(Type.comptime_float, number)).toIntern());
5758}5810}
57595811
5760fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {5812fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
...@@ -5775,10 +5827,11 @@ fn zirCompileLog(...@@ -5775,10 +5827,11 @@ fn zirCompileLog(
5775 block: *Block,5827 block: *Block,
5776 extended: Zir.Inst.Extended.InstData,5828 extended: Zir.Inst.Extended.InstData,
5777) CompileError!Air.Inst.Ref {5829) CompileError!Air.Inst.Ref {
5778 const mod = sema.mod;5830 const pt = sema.pt;
5831 const mod = pt.zcu;
57795832
5780 var managed = mod.compile_log_text.toManaged(sema.gpa);5833 var managed = mod.compile_log_text.toManaged(sema.gpa);
5781 defer sema.mod.compile_log_text = managed.moveToUnmanaged();5834 defer pt.zcu.compile_log_text = managed.moveToUnmanaged();
5782 const writer = managed.writer();5835 const writer = managed.writer();
57835836
5784 const extra = sema.code.extraData(Zir.Inst.NodeMultiOp, extended.operand);5837 const extra = sema.code.extraData(Zir.Inst.NodeMultiOp, extended.operand);
...@@ -5792,10 +5845,10 @@ fn zirCompileLog(...@@ -5792,10 +5845,10 @@ fn zirCompileLog(
5792 const arg_ty = sema.typeOf(arg);5845 const arg_ty = sema.typeOf(arg);
5793 if (try sema.resolveValueResolveLazy(arg)) |val| {5846 if (try sema.resolveValueResolveLazy(arg)) |val| {
5794 try writer.print("@as({}, {})", .{5847 try writer.print("@as({}, {})", .{
5795 arg_ty.fmt(mod), val.fmtValue(mod, sema),5848 arg_ty.fmt(pt), val.fmtValue(pt, sema),
5796 });5849 });
5797 } else {5850 } else {
5798 try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(mod)});5851 try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(pt)});
5799 }5852 }
5800 }5853 }
5801 try writer.print("\n", .{});5854 try writer.print("\n", .{});
...@@ -5835,7 +5888,8 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError...@@ -5835,7 +5888,8 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
5835 const tracy = trace(@src());5888 const tracy = trace(@src());
5836 defer tracy.end();5889 defer tracy.end();
58375890
5838 const mod = sema.mod;5891 const pt = sema.pt;
5892 const mod = pt.zcu;
5839 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;5893 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
5840 const src = parent_block.nodeOffset(inst_data.src_node);5894 const src = parent_block.nodeOffset(inst_data.src_node);
5841 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);5895 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);
...@@ -5906,7 +5960,8 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -5906,7 +5960,8 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
5906 const tracy = trace(@src());5960 const tracy = trace(@src());
5907 defer tracy.end();5961 defer tracy.end();
59085962
5909 const zcu = sema.mod;5963 const pt = sema.pt;
5964 const zcu = pt.zcu;
5910 const comp = zcu.comp;5965 const comp = zcu.comp;
5911 const gpa = sema.gpa;5966 const gpa = sema.gpa;
5912 const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;5967 const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
...@@ -6005,7 +6060,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -6005,7 +6060,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
6005 zcu.astGenFile(result.file, result.file_index, path_digest, root_decl) catch |err|6060 zcu.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)});6061 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
60076062
6008 try zcu.ensureFileAnalyzed(result.file_index);6063 try pt.ensureFileAnalyzed(result.file_index);
6009 const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?;6064 const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?;
6010 return sema.analyzeDeclVal(parent_block, src, file_root_decl_index);6065 return sema.analyzeDeclVal(parent_block, src, file_root_decl_index);
6011}6066}
...@@ -6147,7 +6202,8 @@ fn resolveAnalyzedBlock(...@@ -6147,7 +6202,8 @@ fn resolveAnalyzedBlock(
6147 defer tracy.end();6202 defer tracy.end();
61486203
6149 const gpa = sema.gpa;6204 const gpa = sema.gpa;
6150 const mod = sema.mod;6205 const pt = sema.pt;
6206 const mod = pt.zcu;
61516207
6152 // Blocks must terminate with noreturn instruction.6208 // Blocks must terminate with noreturn instruction.
6153 assert(child_block.instructions.items.len != 0);6209 assert(child_block.instructions.items.len != 0);
...@@ -6258,7 +6314,7 @@ fn resolveAnalyzedBlock(...@@ -6258,7 +6314,7 @@ fn resolveAnalyzedBlock(
6258 const type_src = src; // TODO: better source location6314 const type_src = src; // TODO: better source location
6259 if (try sema.typeRequiresComptime(resolved_ty)) {6315 if (try sema.typeRequiresComptime(resolved_ty)) {
6260 const msg = msg: {6316 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)});6317 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);6318 errdefer msg.destroy(sema.gpa);
62636319
6264 const runtime_src = child_block.runtime_cond orelse child_block.runtime_loop.?;6320 const runtime_src = child_block.runtime_cond orelse child_block.runtime_loop.?;
...@@ -6353,7 +6409,8 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -6353,7 +6409,8 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
6353 const tracy = trace(@src());6409 const tracy = trace(@src());
6354 defer tracy.end();6410 defer tracy.end();
63556411
6356 const mod = sema.mod;6412 const pt = sema.pt;
6413 const mod = pt.zcu;
6357 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;6414 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;6415 const extra = sema.code.extraData(Zir.Inst.Export, inst_data.payload_index).data;
6359 const src = block.nodeOffset(inst_data.src_node);6416 const src = block.nodeOffset(inst_data.src_node);
...@@ -6388,7 +6445,8 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -6388,7 +6445,8 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
6388 const tracy = trace(@src());6445 const tracy = trace(@src());
6389 defer tracy.end();6446 defer tracy.end();
63906447
6391 const mod = sema.mod;6448 const pt = sema.pt;
6449 const mod = pt.zcu;
6392 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;6450 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;6451 const extra = sema.code.extraData(Zir.Inst.ExportValue, inst_data.payload_index).data;
6394 const src = block.nodeOffset(inst_data.src_node);6452 const src = block.nodeOffset(inst_data.src_node);
...@@ -6421,7 +6479,8 @@ pub fn analyzeExport(...@@ -6421,7 +6479,8 @@ pub fn analyzeExport(
6421 exported_decl_index: InternPool.DeclIndex,6479 exported_decl_index: InternPool.DeclIndex,
6422) !void {6480) !void {
6423 const gpa = sema.gpa;6481 const gpa = sema.gpa;
6424 const mod = sema.mod;6482 const pt = sema.pt;
6483 const mod = pt.zcu;
64256484
6426 if (options.linkage == .internal)6485 if (options.linkage == .internal)
6427 return;6486 return;
...@@ -6433,7 +6492,7 @@ pub fn analyzeExport(...@@ -6433,7 +6492,7 @@ pub fn analyzeExport(
64336492
6434 if (!try sema.validateExternType(export_ty, .other)) {6493 if (!try sema.validateExternType(export_ty, .other)) {
6435 const msg = msg: {6494 const msg = msg: {
6436 const msg = try sema.errMsg(src, "unable to export type '{}'", .{export_ty.fmt(mod)});6495 const msg = try sema.errMsg(src, "unable to export type '{}'", .{export_ty.fmt(pt)});
6437 errdefer msg.destroy(gpa);6496 errdefer msg.destroy(gpa);
64386497
6439 try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other);6498 try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other);
...@@ -6460,7 +6519,8 @@ pub fn analyzeExport(...@@ -6460,7 +6519,8 @@ pub fn analyzeExport(
6460}6519}
64616520
6462fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {6521fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
6463 const mod = sema.mod;6522 const pt = sema.pt;
6523 const mod = pt.zcu;
6464 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;6524 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
6465 const operand_src = block.builtinCallArgSrc(extra.node, 0);6525 const operand_src = block.builtinCallArgSrc(extra.node, 0);
6466 const src = block.nodeOffset(extra.node);6526 const src = block.nodeOffset(extra.node);
...@@ -6502,7 +6562,8 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst...@@ -6502,7 +6562,8 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
6502}6562}
65036563
6504fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {6564fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
6505 const mod = sema.mod;6565 const pt = sema.pt;
6566 const mod = pt.zcu;
6506 const ip = &mod.intern_pool;6567 const ip = &mod.intern_pool;
6507 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;6568 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
6508 const operand_src = block.builtinCallArgSrc(extra.node, 0);6569 const operand_src = block.builtinCallArgSrc(extra.node, 0);
...@@ -6628,7 +6689,8 @@ fn addDbgVar(...@@ -6628,7 +6689,8 @@ fn addDbgVar(
6628) CompileError!void {6689) CompileError!void {
6629 if (block.is_comptime or block.ownerModule().strip) return;6690 if (block.is_comptime or block.ownerModule().strip) return;
66306691
6631 const mod = sema.mod;6692 const pt = sema.pt;
6693 const mod = pt.zcu;
6632 const operand_ty = sema.typeOf(operand);6694 const operand_ty = sema.typeOf(operand);
6633 const val_ty = switch (air_tag) {6695 const val_ty = switch (air_tag) {
6634 .dbg_var_ptr => operand_ty.childType(mod),6696 .dbg_var_ptr => operand_ty.childType(mod),
...@@ -6669,7 +6731,8 @@ fn addDbgVar(...@@ -6669,7 +6731,8 @@ fn addDbgVar(
6669}6731}
66706732
6671fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {6733fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
6672 const mod = sema.mod;6734 const pt = sema.pt;
6735 const mod = pt.zcu;
6673 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;6736 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
6674 const src = block.tokenOffset(inst_data.src_tok);6737 const src = block.tokenOffset(inst_data.src_tok);
6675 const decl_name = try mod.intern_pool.getOrPutString(6738 const decl_name = try mod.intern_pool.getOrPutString(
...@@ -6682,7 +6745,8 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -6682,7 +6745,8 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
6682}6745}
66836746
6684fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {6747fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
6685 const mod = sema.mod;6748 const pt = sema.pt;
6749 const mod = pt.zcu;
6686 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;6750 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
6687 const src = block.tokenOffset(inst_data.src_tok);6751 const src = block.tokenOffset(inst_data.src_tok);
6688 const decl_name = try mod.intern_pool.getOrPutString(6752 const decl_name = try mod.intern_pool.getOrPutString(
...@@ -6695,7 +6759,8 @@ fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -6695,7 +6759,8 @@ fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
6695}6759}
66966760
6697fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPool.NullTerminatedString) !InternPool.DeclIndex {6761fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPool.NullTerminatedString) !InternPool.DeclIndex {
6698 const mod = sema.mod;6762 const pt = sema.pt;
6763 const mod = pt.zcu;
6699 var namespace = block.namespace;6764 var namespace = block.namespace;
6700 while (true) {6765 while (true) {
6701 if (try sema.lookupInNamespace(block, src, namespace.toOptional(), name, false)) |decl_index| {6766 if (try sema.lookupInNamespace(block, src, namespace.toOptional(), name, false)) |decl_index| {
...@@ -6716,7 +6781,8 @@ fn lookupInNamespace(...@@ -6716,7 +6781,8 @@ fn lookupInNamespace(
6716 ident_name: InternPool.NullTerminatedString,6781 ident_name: InternPool.NullTerminatedString,
6717 observe_usingnamespace: bool,6782 observe_usingnamespace: bool,
6718) CompileError!?InternPool.DeclIndex {6783) CompileError!?InternPool.DeclIndex {
6719 const mod = sema.mod;6784 const pt = sema.pt;
6785 const mod = pt.zcu;
67206786
6721 const namespace_index = opt_namespace_index.unwrap() orelse return null;6787 const namespace_index = opt_namespace_index.unwrap() orelse return null;
6722 const namespace = mod.namespacePtr(namespace_index);6788 const namespace = mod.namespacePtr(namespace_index);
...@@ -6811,7 +6877,8 @@ fn lookupInNamespace(...@@ -6811,7 +6877,8 @@ fn lookupInNamespace(
6811}6877}
68126878
6813fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {6879fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {
6814 const mod = sema.mod;6880 const pt = sema.pt;
6881 const mod = pt.zcu;
6815 const func_val = (try sema.resolveValue(func_inst)) orelse return null;6882 const func_val = (try sema.resolveValue(func_inst)) orelse return null;
6816 if (func_val.isUndef(mod)) return null;6883 if (func_val.isUndef(mod)) return null;
6817 const owner_decl_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) {6884 const owner_decl_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) {
...@@ -6827,18 +6894,19 @@ fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {...@@ -6827,18 +6894,19 @@ fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {
6827}6894}
68286895
6829pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref {6896pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref {
6830 const mod = sema.mod;6897 const pt = sema.pt;
6898 const mod = pt.zcu;
6831 const gpa = sema.gpa;6899 const gpa = sema.gpa;
68326900
6833 if (block.is_comptime or block.is_typeof) {6901 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);6902 const index_val = try pt.intValue_u64(Type.usize, sema.comptime_err_ret_trace.items.len);
6835 return Air.internedToRef(index_val.toIntern());6903 return Air.internedToRef(index_val.toIntern());
6836 }6904 }
68376905
6838 if (!block.ownerModule().error_tracing) return .none;6906 if (!block.ownerModule().error_tracing) return .none;
68396907
6840 const stack_trace_ty = try mod.getBuiltinType("StackTrace");6908 const stack_trace_ty = try pt.getBuiltinType("StackTrace");
6841 try stack_trace_ty.resolveFields(mod);6909 try stack_trace_ty.resolveFields(pt);
6842 const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls);6910 const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls);
6843 const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) {6911 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"),6912 error.AnalysisFail => @panic("std.builtin.StackTrace is corrupt"),
...@@ -6864,7 +6932,8 @@ fn popErrorReturnTrace(...@@ -6864,7 +6932,8 @@ fn popErrorReturnTrace(
6864 operand: Air.Inst.Ref,6932 operand: Air.Inst.Ref,
6865 saved_error_trace_index: Air.Inst.Ref,6933 saved_error_trace_index: Air.Inst.Ref,
6866) CompileError!void {6934) CompileError!void {
6867 const mod = sema.mod;6935 const pt = sema.pt;
6936 const mod = pt.zcu;
6868 const gpa = sema.gpa;6937 const gpa = sema.gpa;
6869 var is_non_error: ?bool = null;6938 var is_non_error: ?bool = null;
6870 var is_non_error_inst: Air.Inst.Ref = undefined;6939 var is_non_error_inst: Air.Inst.Ref = undefined;
...@@ -6878,9 +6947,9 @@ fn popErrorReturnTrace(...@@ -6878,9 +6947,9 @@ fn popErrorReturnTrace(
6878 // AstGen determined this result does not go to an error-handling expr (try/catch/return etc.), or6947 // 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.6948 // the result is comptime-known to be a non-error. Either way, pop unconditionally.
68806949
6881 const stack_trace_ty = try mod.getBuiltinType("StackTrace");6950 const stack_trace_ty = try pt.getBuiltinType("StackTrace");
6882 try stack_trace_ty.resolveFields(mod);6951 try stack_trace_ty.resolveFields(pt);
6883 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);6952 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);6953 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);6954 const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls);
6886 const field_ptr = try sema.structFieldPtr(block, src, err_return_trace, field_name, src, stack_trace_ty, true);6955 const field_ptr = try sema.structFieldPtr(block, src, err_return_trace, field_name, src, stack_trace_ty, true);
...@@ -6904,9 +6973,9 @@ fn popErrorReturnTrace(...@@ -6904,9 +6973,9 @@ fn popErrorReturnTrace(
6904 defer then_block.instructions.deinit(gpa);6973 defer then_block.instructions.deinit(gpa);
69056974
6906 // If non-error, then pop the error return trace by restoring the index.6975 // If non-error, then pop the error return trace by restoring the index.
6907 const stack_trace_ty = try mod.getBuiltinType("StackTrace");6976 const stack_trace_ty = try pt.getBuiltinType("StackTrace");
6908 try stack_trace_ty.resolveFields(mod);6977 try stack_trace_ty.resolveFields(pt);
6909 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);6978 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);6979 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);6980 const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls);
6912 const field_ptr = try sema.structFieldPtr(&then_block, src, err_return_trace, field_name, src, stack_trace_ty, true);6981 const field_ptr = try sema.structFieldPtr(&then_block, src, err_return_trace, field_name, src, stack_trace_ty, true);
...@@ -6947,7 +7016,8 @@ fn zirCall(...@@ -6947,7 +7016,8 @@ fn zirCall(
6947 const tracy = trace(@src());7016 const tracy = trace(@src());
6948 defer tracy.end();7017 defer tracy.end();
69497018
6950 const mod = sema.mod;7019 const pt = sema.pt;
7020 const mod = pt.zcu;
6951 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;7021 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 });7022 const callee_src = block.src(.{ .node_offset_call_func = inst_data.src_node });
6953 const call_src = block.nodeOffset(inst_data.src_node);7023 const call_src = block.nodeOffset(inst_data.src_node);
...@@ -7031,8 +7101,8 @@ fn zirCall(...@@ -7031,8 +7101,8 @@ fn zirCall(
7031 // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only7101 // 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.7102 // 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))) {7103 if (input_is_error or (pop_error_return_trace and return_ty.isError(mod))) {
7034 const stack_trace_ty = try mod.getBuiltinType("StackTrace");7104 const stack_trace_ty = try pt.getBuiltinType("StackTrace");
7035 try stack_trace_ty.resolveFields(mod);7105 try stack_trace_ty.resolveFields(pt);
7036 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "index", .no_embedded_nulls);7106 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "index", .no_embedded_nulls);
7037 const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src);7107 const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src);
70387108
...@@ -7065,7 +7135,8 @@ fn checkCallArgumentCount(...@@ -7065,7 +7135,8 @@ fn checkCallArgumentCount(
7065 total_args: usize,7135 total_args: usize,
7066 member_fn: bool,7136 member_fn: bool,
7067) !Type {7137) !Type {
7068 const mod = sema.mod;7138 const pt = sema.pt;
7139 const mod = pt.zcu;
7069 const func_ty = func_ty: {7140 const func_ty = func_ty: {
7070 switch (callee_ty.zigTypeTag(mod)) {7141 switch (callee_ty.zigTypeTag(mod)) {
7071 .Fn => break :func_ty callee_ty,7142 .Fn => break :func_ty callee_ty,
...@@ -7082,7 +7153,7 @@ fn checkCallArgumentCount(...@@ -7082,7 +7153,7 @@ fn checkCallArgumentCount(
7082 {7153 {
7083 const msg = msg: {7154 const msg = msg: {
7084 const msg = try sema.errMsg(func_src, "cannot call optional type '{}'", .{7155 const msg = try sema.errMsg(func_src, "cannot call optional type '{}'", .{
7085 callee_ty.fmt(mod),7156 callee_ty.fmt(pt),
7086 });7157 });
7087 errdefer msg.destroy(sema.gpa);7158 errdefer msg.destroy(sema.gpa);
7088 try sema.errNote(func_src, msg, "consider using '.?', 'orelse' or 'if'", .{});7159 try sema.errNote(func_src, msg, "consider using '.?', 'orelse' or 'if'", .{});
...@@ -7093,7 +7164,7 @@ fn checkCallArgumentCount(...@@ -7093,7 +7164,7 @@ fn checkCallArgumentCount(
7093 },7164 },
7094 else => {},7165 else => {},
7095 }7166 }
7096 return sema.fail(block, func_src, "type '{}' not a function", .{callee_ty.fmt(mod)});7167 return sema.fail(block, func_src, "type '{}' not a function", .{callee_ty.fmt(pt)});
7097 };7168 };
70987169
7099 const func_ty_info = mod.typeToFunc(func_ty).?;7170 const func_ty_info = mod.typeToFunc(func_ty).?;
...@@ -7142,7 +7213,8 @@ fn callBuiltin(...@@ -7142,7 +7213,8 @@ fn callBuiltin(
7142 args: []const Air.Inst.Ref,7213 args: []const Air.Inst.Ref,
7143 operation: CallOperation,7214 operation: CallOperation,
7144) !void {7215) !void {
7145 const mod = sema.mod;7216 const pt = sema.pt;
7217 const mod = pt.zcu;
7146 const callee_ty = sema.typeOf(builtin_fn);7218 const callee_ty = sema.typeOf(builtin_fn);
7147 const func_ty = func_ty: {7219 const func_ty = func_ty: {
7148 switch (callee_ty.zigTypeTag(mod)) {7220 switch (callee_ty.zigTypeTag(mod)) {
...@@ -7155,7 +7227,7 @@ fn callBuiltin(...@@ -7155,7 +7227,7 @@ fn callBuiltin(
7155 },7227 },
7156 else => {},7228 else => {},
7157 }7229 }
7158 std.debug.panic("type '{}' is not a function calling builtin fn", .{callee_ty.fmt(mod)});7230 std.debug.panic("type '{}' is not a function calling builtin fn", .{callee_ty.fmt(pt)});
7159 };7231 };
71607232
7161 const func_ty_info = mod.typeToFunc(func_ty).?;7233 const func_ty_info = mod.typeToFunc(func_ty).?;
...@@ -7261,7 +7333,8 @@ const CallArgsInfo = union(enum) {...@@ -7261,7 +7333,8 @@ const CallArgsInfo = union(enum) {
7261 func_ty_info: InternPool.Key.FuncType,7333 func_ty_info: InternPool.Key.FuncType,
7262 func_inst: Air.Inst.Ref,7334 func_inst: Air.Inst.Ref,
7263 ) CompileError!Air.Inst.Ref {7335 ) CompileError!Air.Inst.Ref {
7264 const mod = sema.mod;7336 const pt = sema.pt;
7337 const mod = pt.zcu;
7265 const param_count = func_ty_info.param_types.len;7338 const param_count = func_ty_info.param_types.len;
7266 const uncoerced_arg: Air.Inst.Ref = switch (cai) {7339 const uncoerced_arg: Air.Inst.Ref = switch (cai) {
7267 inline .resolved, .call_builtin => |resolved| resolved.args[arg_index],7340 inline .resolved, .call_builtin => |resolved| resolved.args[arg_index],
...@@ -7438,7 +7511,8 @@ fn analyzeCall(...@@ -7438,7 +7511,8 @@ fn analyzeCall(
7438 call_dbg_node: ?Zir.Inst.Index,7511 call_dbg_node: ?Zir.Inst.Index,
7439 operation: CallOperation,7512 operation: CallOperation,
7440) CompileError!Air.Inst.Ref {7513) CompileError!Air.Inst.Ref {
7441 const mod = sema.mod;7514 const pt = sema.pt;
7515 const mod = pt.zcu;
7442 const ip = &mod.intern_pool;7516 const ip = &mod.intern_pool;
74437517
7444 const callee_ty = sema.typeOf(func);7518 const callee_ty = sema.typeOf(func);
...@@ -7741,10 +7815,10 @@ fn analyzeCall(...@@ -7741,10 +7815,10 @@ fn analyzeCall(
7741 const ies = try sema.arena.create(InferredErrorSet);7815 const ies = try sema.arena.create(InferredErrorSet);
7742 ies.* = .{ .func = .none };7816 ies.* = .{ .func = .none };
7743 sema.fn_ret_ty_ies = ies;7817 sema.fn_ret_ty_ies = ies;
7744 sema.fn_ret_ty = Type.fromInterned((try ip.get(gpa, .{ .error_union_type = .{7818 sema.fn_ret_ty = Type.fromInterned(try pt.intern(.{ .error_union_type = .{
7745 .error_set_type = .adhoc_inferred_error_set_type,7819 .error_set_type = .adhoc_inferred_error_set_type,
7746 .payload_type = sema.fn_ret_ty.toIntern(),7820 .payload_type = sema.fn_ret_ty.toIntern(),
7747 } })));7821 } }));
7748 }7822 }
77497823
7750 // This `res2` is here instead of directly breaking from `res` due to a stage17824 // This `res2` is here instead of directly breaking from `res` due to a stage1
...@@ -7816,7 +7890,7 @@ fn analyzeCall(...@@ -7816,7 +7890,7 @@ fn analyzeCall(
7816 // TODO: check whether any external comptime memory was mutated by the7890 // TODO: check whether any external comptime memory was mutated by the
7817 // comptime function call. If so, then do not memoize the call here.7891 // comptime function call. If so, then do not memoize the call here.
7818 if (should_memoize and !Value.fromInterned(result_interned).canMutateComptimeVarState(mod)) {7892 if (should_memoize and !Value.fromInterned(result_interned).canMutateComptimeVarState(mod)) {
7819 _ = try mod.intern(.{ .memoized_call = .{7893 _ = try pt.intern(.{ .memoized_call = .{
7820 .func = module_fn_index,7894 .func = module_fn_index,
7821 .arg_values = memoized_arg_values,7895 .arg_values = memoized_arg_values,
7822 .result = result_transformed,7896 .result = result_transformed,
...@@ -7921,7 +7995,8 @@ fn analyzeCall(...@@ -7921,7 +7995,8 @@ fn analyzeCall(
7921}7995}
79227996
7923fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref {7997fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref {
7924 const mod = sema.mod;7998 const pt = sema.pt;
7999 const mod = pt.zcu;
7925 const target = mod.getTarget();8000 const target = mod.getTarget();
7926 const backend = mod.comp.getZigBackend();8001 const backend = mod.comp.getZigBackend();
7927 if (!target_util.supportsTailCall(target, backend)) {8002 if (!target_util.supportsTailCall(target, backend)) {
...@@ -7932,7 +8007,7 @@ fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Typ...@@ -7932,7 +8007,7 @@ fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Typ
7932 const func_decl = mod.funcOwnerDeclPtr(sema.owner_func_index);8007 const func_decl = mod.funcOwnerDeclPtr(sema.owner_func_index);
7933 if (!func_ty.eql(func_decl.typeOf(mod), mod)) {8008 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 '{}'", .{8009 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),8010 func_ty.fmt(pt), func_decl.typeOf(mod).fmt(pt),
7936 });8011 });
7937 }8012 }
7938 _ = try block.addUnOp(.ret, result);8013 _ = try block.addUnOp(.ret, result);
...@@ -7954,7 +8029,7 @@ fn analyzeInlineCallArg(...@@ -7954,7 +8029,7 @@ fn analyzeInlineCallArg(
7954 func_ty_info: InternPool.Key.FuncType,8029 func_ty_info: InternPool.Key.FuncType,
7955 func_inst: Air.Inst.Ref,8030 func_inst: Air.Inst.Ref,
7956) !?Air.Inst.Ref {8031) !?Air.Inst.Ref {
7957 const mod = ics.sema.mod;8032 const mod = ics.sema.pt.zcu;
7958 const ip = &mod.intern_pool;8033 const ip = &mod.intern_pool;
7959 const zir_tags = ics.callee().code.instructions.items(.tag);8034 const zir_tags = ics.callee().code.instructions.items(.tag);
7960 switch (zir_tags[@intFromEnum(inst)]) {8035 switch (zir_tags[@intFromEnum(inst)]) {
...@@ -8084,7 +8159,8 @@ fn instantiateGenericCall(...@@ -8084,7 +8159,8 @@ fn instantiateGenericCall(
8084 call_tag: Air.Inst.Tag,8159 call_tag: Air.Inst.Tag,
8085 call_dbg_node: ?Zir.Inst.Index,8160 call_dbg_node: ?Zir.Inst.Index,
8086) CompileError!Air.Inst.Ref {8161) CompileError!Air.Inst.Ref {
8087 const zcu = sema.mod;8162 const pt = sema.pt;
8163 const zcu = pt.zcu;
8088 const gpa = sema.gpa;8164 const gpa = sema.gpa;
8089 const ip = &zcu.intern_pool;8165 const ip = &zcu.intern_pool;
80908166
...@@ -8127,7 +8203,7 @@ fn instantiateGenericCall(...@@ -8127,7 +8203,7 @@ fn instantiateGenericCall(
8127 // `param_anytype_comptime` ZIR instructions to be ignored, resulting in a8203 // `param_anytype_comptime` ZIR instructions to be ignored, resulting in a
8128 // new, monomorphized function, with the comptime parameters elided.8204 // new, monomorphized function, with the comptime parameters elided.
8129 var child_sema: Sema = .{8205 var child_sema: Sema = .{
8130 .mod = zcu,8206 .pt = pt,
8131 .gpa = gpa,8207 .gpa = gpa,
8132 .arena = sema.arena,8208 .arena = sema.arena,
8133 .code = fn_zir,8209 .code = fn_zir,
...@@ -8358,7 +8434,8 @@ fn instantiateGenericCall(...@@ -8358,7 +8434,8 @@ fn instantiateGenericCall(
8358}8434}
83598435
8360fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {8436fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
8361 const mod = sema.mod;8437 const pt = sema.pt;
8438 const mod = pt.zcu;
8362 const ip = &mod.intern_pool;8439 const ip = &mod.intern_pool;
8363 const tuple = switch (ip.indexToKey(ty.toIntern())) {8440 const tuple = switch (ip.indexToKey(ty.toIntern())) {
8364 .anon_struct_type => |tuple| tuple,8441 .anon_struct_type => |tuple| tuple,
...@@ -8373,9 +8450,8 @@ fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type)...@@ -8373,9 +8450,8 @@ fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type)
8373}8450}
83748451
8375fn zirIntType(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8452fn 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;8453 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);8454 const ty = try sema.pt.intType(int_type.signedness, int_type.bit_count);
8379 return Air.internedToRef(ty.toIntern());8455 return Air.internedToRef(ty.toIntern());
8380}8456}
83818457
...@@ -8383,22 +8459,24 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -8383,22 +8459,24 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
8383 const tracy = trace(@src());8459 const tracy = trace(@src());
8384 defer tracy.end();8460 defer tracy.end();
83858461
8386 const mod = sema.mod;8462 const pt = sema.pt;
8463 const mod = pt.zcu;
8387 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;8464 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 });8465 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);8466 const child_type = try sema.resolveType(block, operand_src, inst_data.operand);
8390 if (child_type.zigTypeTag(mod) == .Opaque) {8467 if (child_type.zigTypeTag(mod) == .Opaque) {
8391 return sema.fail(block, operand_src, "opaque type '{}' cannot be optional", .{child_type.fmt(mod)});8468 return sema.fail(block, operand_src, "opaque type '{}' cannot be optional", .{child_type.fmt(pt)});
8392 } else if (child_type.zigTypeTag(mod) == .Null) {8469 } else if (child_type.zigTypeTag(mod) == .Null) {
8393 return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(mod)});8470 return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(pt)});
8394 }8471 }
8395 const opt_type = try mod.optionalType(child_type.toIntern());8472 const opt_type = try pt.optionalType(child_type.toIntern());
83968473
8397 return Air.internedToRef(opt_type.toIntern());8474 return Air.internedToRef(opt_type.toIntern());
8398}8475}
83998476
8400fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8477fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8401 const mod = sema.mod;8478 const pt = sema.pt;
8479 const mod = pt.zcu;
8402 const bin = sema.code.instructions.items(.data)[@intFromEnum(inst)].bin;8480 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) {8481 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, encountering8482 // Since this is a ZIR instruction that returns a type, encountering
...@@ -8409,7 +8487,7 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -8409,7 +8487,7 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
8409 else => |e| return e,8487 else => |e| return e,
8410 };8488 };
8411 const indexable_ty = maybe_wrapped_indexable_ty.optEuBaseType(mod);8489 const indexable_ty = maybe_wrapped_indexable_ty.optEuBaseType(mod);
8412 try indexable_ty.resolveFields(mod);8490 try indexable_ty.resolveFields(pt);
8413 assert(indexable_ty.isIndexable(mod)); // validated by a previous instruction8491 assert(indexable_ty.isIndexable(mod)); // validated by a previous instruction
8414 if (indexable_ty.zigTypeTag(mod) == .Struct) {8492 if (indexable_ty.zigTypeTag(mod) == .Struct) {
8415 const elem_type = indexable_ty.structFieldType(@intFromEnum(bin.rhs), mod);8493 const elem_type = indexable_ty.structFieldType(@intFromEnum(bin.rhs), mod);
...@@ -8421,7 +8499,8 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -8421,7 +8499,8 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
8421}8499}
84228500
8423fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8501fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8424 const mod = sema.mod;8502 const pt = sema.pt;
8503 const mod = pt.zcu;
8425 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;8504 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) {8505 const maybe_wrapped_ptr_ty = sema.resolveType(block, LazySrcLoc.unneeded, un_node.operand) catch |err| switch (err) {
8427 error.GenericPoison => return .generic_poison_type,8506 error.GenericPoison => return .generic_poison_type,
...@@ -8439,7 +8518,8 @@ fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -8439,7 +8518,8 @@ fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
8439}8518}
84408519
8441fn zirIndexablePtrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8520fn zirIndexablePtrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8442 const mod = sema.mod;8521 const pt = sema.pt;
8522 const mod = pt.zcu;
8443 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;8523 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
8444 const src = block.nodeOffset(un_node.src_node);8524 const src = block.nodeOffset(un_node.src_node);
8445 const ptr_ty = sema.resolveType(block, src, un_node.operand) catch |err| switch (err) {8525 const ptr_ty = sema.resolveType(block, src, un_node.operand) catch |err| switch (err) {
...@@ -8455,7 +8535,8 @@ fn zirIndexablePtrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -8455,7 +8535,8 @@ fn zirIndexablePtrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
8455}8535}
84568536
8457fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8537fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8458 const mod = sema.mod;8538 const pt = sema.pt;
8539 const mod = pt.zcu;
8459 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;8540 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) {8541 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, encountering8542 // Since this is a ZIR instruction that returns a type, encountering
...@@ -8466,13 +8547,12 @@ fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -8466,13 +8547,12 @@ fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
8466 else => |e| return e,8547 else => |e| return e,
8467 };8548 };
8468 if (!vec_ty.isVector(mod)) {8549 if (!vec_ty.isVector(mod)) {
8469 return sema.fail(block, block.nodeOffset(un_node.src_node), "expected vector type, found '{}'", .{vec_ty.fmt(mod)});8550 return sema.fail(block, block.nodeOffset(un_node.src_node), "expected vector type, found '{}'", .{vec_ty.fmt(pt)});
8470 }8551 }
8471 return Air.internedToRef(vec_ty.childType(mod).toIntern());8552 return Air.internedToRef(vec_ty.childType(mod).toIntern());
8472}8553}
84738554
8474fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8555fn 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;8556 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
8477 const len_src = block.builtinCallArgSrc(inst_data.src_node, 0);8557 const len_src = block.builtinCallArgSrc(inst_data.src_node, 0);
8478 const elem_type_src = block.builtinCallArgSrc(inst_data.src_node, 1);8558 const elem_type_src = block.builtinCallArgSrc(inst_data.src_node, 1);
...@@ -8482,7 +8562,7 @@ fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -8482,7 +8562,7 @@ fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
8482 }));8562 }));
8483 const elem_type = try sema.resolveType(block, elem_type_src, extra.rhs);8563 const elem_type = try sema.resolveType(block, elem_type_src, extra.rhs);
8484 try sema.checkVectorElemType(block, elem_type_src, elem_type);8564 try sema.checkVectorElemType(block, elem_type_src, elem_type);
8485 const vector_type = try mod.vectorType(.{8565 const vector_type = try sema.pt.vectorType(.{
8486 .len = len,8566 .len = len,
8487 .child = elem_type.toIntern(),8567 .child = elem_type.toIntern(),
8488 });8568 });
...@@ -8502,7 +8582,7 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -8502,7 +8582,7 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
8502 });8582 });
8503 const elem_type = try sema.resolveType(block, elem_src, extra.rhs);8583 const elem_type = try sema.resolveType(block, elem_src, extra.rhs);
8504 try sema.validateArrayElemType(block, elem_type, elem_src);8584 try sema.validateArrayElemType(block, elem_type, elem_src);
8505 const array_ty = try sema.mod.arrayType(.{8585 const array_ty = try sema.pt.arrayType(.{
8506 .len = len,8586 .len = len,
8507 .child = elem_type.toIntern(),8587 .child = elem_type.toIntern(),
8508 });8588 });
...@@ -8529,7 +8609,7 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -8529,7 +8609,7 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
8529 const sentinel_val = try sema.resolveConstDefinedValue(block, sentinel_src, sentinel, .{8609 const sentinel_val = try sema.resolveConstDefinedValue(block, sentinel_src, sentinel, .{
8530 .needed_comptime_reason = "array sentinel value must be comptime-known",8610 .needed_comptime_reason = "array sentinel value must be comptime-known",
8531 });8611 });
8532 const array_ty = try sema.mod.arrayType(.{8612 const array_ty = try sema.pt.arrayType(.{
8533 .len = len,8613 .len = len,
8534 .sentinel = sentinel_val.toIntern(),8614 .sentinel = sentinel_val.toIntern(),
8535 .child = elem_type.toIntern(),8615 .child = elem_type.toIntern(),
...@@ -8539,9 +8619,10 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -8539,9 +8619,10 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
8539}8619}
85408620
8541fn validateArrayElemType(sema: *Sema, block: *Block, elem_type: Type, elem_src: LazySrcLoc) !void {8621fn validateArrayElemType(sema: *Sema, block: *Block, elem_type: Type, elem_src: LazySrcLoc) !void {
8542 const mod = sema.mod;8622 const pt = sema.pt;
8623 const mod = pt.zcu;
8543 if (elem_type.zigTypeTag(mod) == .Opaque) {8624 if (elem_type.zigTypeTag(mod) == .Opaque) {
8544 return sema.fail(block, elem_src, "array of opaque type '{}' not allowed", .{elem_type.fmt(mod)});8625 return sema.fail(block, elem_src, "array of opaque type '{}' not allowed", .{elem_type.fmt(pt)});
8545 } else if (elem_type.zigTypeTag(mod) == .NoReturn) {8626 } else if (elem_type.zigTypeTag(mod) == .NoReturn) {
8546 return sema.fail(block, elem_src, "array of 'noreturn' not allowed", .{});8627 return sema.fail(block, elem_src, "array of 'noreturn' not allowed", .{});
8547 }8628 }
...@@ -8567,7 +8648,8 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -8567,7 +8648,8 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
8567 const tracy = trace(@src());8648 const tracy = trace(@src());
8568 defer tracy.end();8649 defer tracy.end();
85698650
8570 const mod = sema.mod;8651 const pt = sema.pt;
8652 const mod = pt.zcu;
8571 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;8653 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;8654 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 });8655 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -8577,40 +8659,41 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -8577,40 +8659,41 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
85778659
8578 if (error_set.zigTypeTag(mod) != .ErrorSet) {8660 if (error_set.zigTypeTag(mod) != .ErrorSet) {
8579 return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{8661 return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{
8580 error_set.fmt(mod),8662 error_set.fmt(pt),
8581 });8663 });
8582 }8664 }
8583 try sema.validateErrorUnionPayloadType(block, payload, rhs_src);8665 try sema.validateErrorUnionPayloadType(block, payload, rhs_src);
8584 const err_union_ty = try mod.errorUnionType(error_set, payload);8666 const err_union_ty = try pt.errorUnionType(error_set, payload);
8585 return Air.internedToRef(err_union_ty.toIntern());8667 return Air.internedToRef(err_union_ty.toIntern());
8586}8668}
85878669
8588fn validateErrorUnionPayloadType(sema: *Sema, block: *Block, payload_ty: Type, payload_src: LazySrcLoc) !void {8670fn validateErrorUnionPayloadType(sema: *Sema, block: *Block, payload_ty: Type, payload_src: LazySrcLoc) !void {
8589 const mod = sema.mod;8671 const pt = sema.pt;
8672 const mod = pt.zcu;
8590 if (payload_ty.zigTypeTag(mod) == .Opaque) {8673 if (payload_ty.zigTypeTag(mod) == .Opaque) {
8591 return sema.fail(block, payload_src, "error union with payload of opaque type '{}' not allowed", .{8674 return sema.fail(block, payload_src, "error union with payload of opaque type '{}' not allowed", .{
8592 payload_ty.fmt(mod),8675 payload_ty.fmt(pt),
8593 });8676 });
8594 } else if (payload_ty.zigTypeTag(mod) == .ErrorSet) {8677 } else if (payload_ty.zigTypeTag(mod) == .ErrorSet) {
8595 return sema.fail(block, payload_src, "error union with payload of error set type '{}' not allowed", .{8678 return sema.fail(block, payload_src, "error union with payload of error set type '{}' not allowed", .{
8596 payload_ty.fmt(mod),8679 payload_ty.fmt(pt),
8597 });8680 });
8598 }8681 }
8599}8682}
86008683
8601fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8684fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8602 _ = block;8685 _ = block;
8603 const mod = sema.mod;8686 const pt = sema.pt;
8604 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;8687 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
8605 const name = try mod.intern_pool.getOrPutString(8688 const name = try pt.zcu.intern_pool.getOrPutString(
8606 sema.gpa,8689 sema.gpa,
8607 inst_data.get(sema.code),8690 inst_data.get(sema.code),
8608 .no_embedded_nulls,8691 .no_embedded_nulls,
8609 );8692 );
8610 _ = try mod.getErrorValue(name);8693 _ = try pt.zcu.getErrorValue(name);
8611 // Create an error set type with only this error value, and return the value.8694 // Create an error set type with only this error value, and return the value.
8612 const error_set_type = try mod.singleErrorSetType(name);8695 const error_set_type = try pt.singleErrorSetType(name);
8613 return Air.internedToRef((try mod.intern(.{ .err = .{8696 return Air.internedToRef((try pt.intern(.{ .err = .{
8614 .ty = error_set_type.toIntern(),8697 .ty = error_set_type.toIntern(),
8615 .name = name,8698 .name = name,
8616 } })));8699 } })));
...@@ -8620,21 +8703,22 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -8620,21 +8703,22 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
8620 const tracy = trace(@src());8703 const tracy = trace(@src());
8621 defer tracy.end();8704 defer tracy.end();
86228705
8623 const mod = sema.mod;8706 const pt = sema.pt;
8707 const mod = pt.zcu;
8624 const ip = &mod.intern_pool;8708 const ip = &mod.intern_pool;
8625 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;8709 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
8626 const src = block.nodeOffset(extra.node);8710 const src = block.nodeOffset(extra.node);
8627 const operand_src = block.builtinCallArgSrc(extra.node, 0);8711 const operand_src = block.builtinCallArgSrc(extra.node, 0);
8628 const uncasted_operand = try sema.resolveInst(extra.operand);8712 const uncasted_operand = try sema.resolveInst(extra.operand);
8629 const operand = try sema.coerce(block, Type.anyerror, uncasted_operand, operand_src);8713 const operand = try sema.coerce(block, Type.anyerror, uncasted_operand, operand_src);
8630 const err_int_ty = try mod.errorIntType();8714 const err_int_ty = try pt.errorIntType();
86318715
8632 if (try sema.resolveValue(operand)) |val| {8716 if (try sema.resolveValue(operand)) |val| {
8633 if (val.isUndef(mod)) {8717 if (val.isUndef(mod)) {
8634 return mod.undefRef(err_int_ty);8718 return pt.undefRef(err_int_ty);
8635 }8719 }
8636 const err_name = ip.indexToKey(val.toIntern()).err.name;8720 const err_name = ip.indexToKey(val.toIntern()).err.name;
8637 return Air.internedToRef((try mod.intValue(8721 return Air.internedToRef((try pt.intValue(
8638 err_int_ty,8722 err_int_ty,
8639 try mod.getErrorValue(err_name),8723 try mod.getErrorValue(err_name),
8640 )).toIntern());8724 )).toIntern());
...@@ -8646,10 +8730,10 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -8646,10 +8730,10 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
8646 else => |err_set_ty_index| {8730 else => |err_set_ty_index| {
8647 const names = ip.indexToKey(err_set_ty_index).error_set_type.names;8731 const names = ip.indexToKey(err_set_ty_index).error_set_type.names;
8648 switch (names.len) {8732 switch (names.len) {
8649 0 => return Air.internedToRef((try mod.intValue(err_int_ty, 0)).toIntern()),8733 0 => return Air.internedToRef((try pt.intValue(err_int_ty, 0)).toIntern()),
8650 1 => {8734 1 => {
8651 const int: Module.ErrorInt = @intCast(mod.global_error_set.getIndex(names.get(ip)[0]).?);8735 const int: Module.ErrorInt = @intCast(mod.global_error_set.getIndex(names.get(ip)[0]).?);
8652 return mod.intRef(err_int_ty, int);8736 return pt.intRef(err_int_ty, int);
8653 },8737 },
8654 else => {},8738 else => {},
8655 }8739 }
...@@ -8664,19 +8748,20 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -8664,19 +8748,20 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
8664 const tracy = trace(@src());8748 const tracy = trace(@src());
8665 defer tracy.end();8749 defer tracy.end();
86668750
8667 const mod = sema.mod;8751 const pt = sema.pt;
8752 const mod = pt.zcu;
8668 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;8753 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
8669 const src = block.nodeOffset(extra.node);8754 const src = block.nodeOffset(extra.node);
8670 const operand_src = block.builtinCallArgSrc(extra.node, 0);8755 const operand_src = block.builtinCallArgSrc(extra.node, 0);
8671 const uncasted_operand = try sema.resolveInst(extra.operand);8756 const uncasted_operand = try sema.resolveInst(extra.operand);
8672 const err_int_ty = try mod.errorIntType();8757 const err_int_ty = try pt.errorIntType();
8673 const operand = try sema.coerce(block, err_int_ty, uncasted_operand, operand_src);8758 const operand = try sema.coerce(block, err_int_ty, uncasted_operand, operand_src);
86748759
8675 if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {8760 if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {
8676 const int = try sema.usizeCast(block, operand_src, try value.toUnsignedIntSema(mod));8761 const int = try sema.usizeCast(block, operand_src, try value.toUnsignedIntSema(pt));
8677 if (int > mod.global_error_set.count() or int == 0)8762 if (int > mod.global_error_set.count() or int == 0)
8678 return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});8763 return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});
8679 return Air.internedToRef((try mod.intern(.{ .err = .{8764 return Air.internedToRef((try pt.intern(.{ .err = .{
8680 .ty = .anyerror_type,8765 .ty = .anyerror_type,
8681 .name = mod.global_error_set.keys()[int],8766 .name = mod.global_error_set.keys()[int],
8682 } })));8767 } })));
...@@ -8684,7 +8769,7 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -8684,7 +8769,7 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
8684 try sema.requireRuntimeBlock(block, src, operand_src);8769 try sema.requireRuntimeBlock(block, src, operand_src);
8685 if (block.wantSafety()) {8770 if (block.wantSafety()) {
8686 const is_lt_len = try block.addUnOp(.cmp_lt_errors_len, operand);8771 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());8772 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);8773 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);8774 const ok = try block.addBinOp(.bool_and, is_lt_len, is_non_zero);
8690 try sema.addSafetyCheck(block, src, ok, .invalid_error_code);8775 try sema.addSafetyCheck(block, src, ok, .invalid_error_code);
...@@ -8702,7 +8787,8 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -8702,7 +8787,8 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
8702 const tracy = trace(@src());8787 const tracy = trace(@src());
8703 defer tracy.end();8788 defer tracy.end();
87048789
8705 const mod = sema.mod;8790 const pt = sema.pt;
8791 const mod = pt.zcu;
8706 const ip = &mod.intern_pool;8792 const ip = &mod.intern_pool;
8707 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;8793 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;8794 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
...@@ -8723,9 +8809,9 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -8723,9 +8809,9 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
8723 const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs);8809 const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs);
8724 const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs);8810 const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs);
8725 if (lhs_ty.zigTypeTag(mod) != .ErrorSet)8811 if (lhs_ty.zigTypeTag(mod) != .ErrorSet)
8726 return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{lhs_ty.fmt(mod)});8812 return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{lhs_ty.fmt(pt)});
8727 if (rhs_ty.zigTypeTag(mod) != .ErrorSet)8813 if (rhs_ty.zigTypeTag(mod) != .ErrorSet)
8728 return sema.fail(block, rhs_src, "expected error set type, found '{}'", .{rhs_ty.fmt(mod)});8814 return sema.fail(block, rhs_src, "expected error set type, found '{}'", .{rhs_ty.fmt(pt)});
87298815
8730 // Anything merged with anyerror is anyerror.8816 // Anything merged with anyerror is anyerror.
8731 if (lhs_ty.toIntern() == .anyerror_type or rhs_ty.toIntern() == .anyerror_type) {8817 if (lhs_ty.toIntern() == .anyerror_type or rhs_ty.toIntern() == .anyerror_type) {
...@@ -8758,16 +8844,18 @@ fn zirEnumLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8758,16 +8844,18 @@ fn zirEnumLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8758 const tracy = trace(@src());8844 const tracy = trace(@src());
8759 defer tracy.end();8845 defer tracy.end();
87608846
8761 const mod = sema.mod;8847 const pt = sema.pt;
8848 const mod = pt.zcu;
8762 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;8849 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
8763 const name = inst_data.get(sema.code);8850 const name = inst_data.get(sema.code);
8764 return Air.internedToRef((try mod.intern(.{8851 return Air.internedToRef((try pt.intern(.{
8765 .enum_literal = try mod.intern_pool.getOrPutString(sema.gpa, name, .no_embedded_nulls),8852 .enum_literal = try mod.intern_pool.getOrPutString(sema.gpa, name, .no_embedded_nulls),
8766 })));8853 })));
8767}8854}
87688855
8769fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8856fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8770 const mod = sema.mod;8857 const pt = sema.pt;
8858 const mod = pt.zcu;
8771 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;8859 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
8772 const src = block.nodeOffset(inst_data.src_node);8860 const src = block.nodeOffset(inst_data.src_node);
8773 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);8861 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
...@@ -8777,7 +8865,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8777,7 +8865,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8777 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag(mod)) {8865 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag(mod)) {
8778 .Enum => operand,8866 .Enum => operand,
8779 .Union => blk: {8867 .Union => blk: {
8780 try operand_ty.resolveFields(mod);8868 try operand_ty.resolveFields(pt);
8781 const tag_ty = operand_ty.unionTagType(mod) orelse {8869 const tag_ty = operand_ty.unionTagType(mod) orelse {
8782 return sema.fail(8870 return sema.fail(
8783 block,8871 block,
...@@ -8791,7 +8879,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8791,7 +8879,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8791 },8879 },
8792 else => {8880 else => {
8793 return sema.fail(block, operand_src, "expected enum or tagged union, found '{}'", .{8881 return sema.fail(block, operand_src, "expected enum or tagged union, found '{}'", .{
8794 operand_ty.fmt(mod),8882 operand_ty.fmt(pt),
8795 });8883 });
8796 },8884 },
8797 };8885 };
...@@ -8802,20 +8890,20 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8802,20 +8890,20 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8802 // https://github.com/ziglang/zig/issues/159098890 // https://github.com/ziglang/zig/issues/15909
8803 if (enum_tag_ty.enumFieldCount(mod) == 0 and !enum_tag_ty.isNonexhaustiveEnum(mod)) {8891 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 '{}'", .{8892 return sema.fail(block, operand_src, "cannot use @intFromEnum on empty enum '{}'", .{
8805 enum_tag_ty.fmt(mod),8893 enum_tag_ty.fmt(pt),
8806 });8894 });
8807 }8895 }
88088896
8809 if (try sema.typeHasOnePossibleValue(enum_tag_ty)) |opv| {8897 if (try sema.typeHasOnePossibleValue(enum_tag_ty)) |opv| {
8810 return Air.internedToRef((try mod.getCoerced(opv, int_tag_ty)).toIntern());8898 return Air.internedToRef((try pt.getCoerced(opv, int_tag_ty)).toIntern());
8811 }8899 }
88128900
8813 if (try sema.resolveValue(enum_tag)) |enum_tag_val| {8901 if (try sema.resolveValue(enum_tag)) |enum_tag_val| {
8814 if (enum_tag_val.isUndef(mod)) {8902 if (enum_tag_val.isUndef(mod)) {
8815 return mod.undefRef(int_tag_ty);8903 return pt.undefRef(int_tag_ty);
8816 }8904 }
88178905
8818 const val = try enum_tag_val.intFromEnum(enum_tag_ty, mod);8906 const val = try enum_tag_val.intFromEnum(enum_tag_ty, pt);
8819 return Air.internedToRef(val.toIntern());8907 return Air.internedToRef(val.toIntern());
8820 }8908 }
88218909
...@@ -8824,7 +8912,8 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8824,7 +8912,8 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8824}8912}
88258913
8826fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8914fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8827 const mod = sema.mod;8915 const pt = sema.pt;
8916 const mod = pt.zcu;
8828 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;8917 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;8918 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
8830 const src = block.nodeOffset(inst_data.src_node);8919 const src = block.nodeOffset(inst_data.src_node);
...@@ -8833,7 +8922,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8833,7 +8922,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8833 const operand = try sema.resolveInst(extra.rhs);8922 const operand = try sema.resolveInst(extra.rhs);
88348923
8835 if (dest_ty.zigTypeTag(mod) != .Enum) {8924 if (dest_ty.zigTypeTag(mod) != .Enum) {
8836 return sema.fail(block, src, "expected enum, found '{}'", .{dest_ty.fmt(mod)});8925 return sema.fail(block, src, "expected enum, found '{}'", .{dest_ty.fmt(pt)});
8837 }8926 }
8838 _ = try sema.checkIntType(block, operand_src, sema.typeOf(operand));8927 _ = try sema.checkIntType(block, operand_src, sema.typeOf(operand));
88398928
...@@ -8841,10 +8930,10 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8841,10 +8930,10 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8841 if (dest_ty.isNonexhaustiveEnum(mod)) {8930 if (dest_ty.isNonexhaustiveEnum(mod)) {
8842 const int_tag_ty = dest_ty.intTagType(mod);8931 const int_tag_ty = dest_ty.intTagType(mod);
8843 if (try sema.intFitsInType(int_val, int_tag_ty, null)) {8932 if (try sema.intFitsInType(int_val, int_tag_ty, null)) {
8844 return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern());8933 return Air.internedToRef((try pt.getCoerced(int_val, dest_ty)).toIntern());
8845 }8934 }
8846 return sema.fail(block, src, "int value '{}' out of range of non-exhaustive enum '{}'", .{8935 return sema.fail(block, src, "int value '{}' out of range of non-exhaustive enum '{}'", .{
8847 int_val.fmtValue(mod, sema), dest_ty.fmt(mod),8936 int_val.fmtValue(pt, sema), dest_ty.fmt(pt),
8848 });8937 });
8849 }8938 }
8850 if (int_val.isUndef(mod)) {8939 if (int_val.isUndef(mod)) {
...@@ -8852,10 +8941,10 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8852,10 +8941,10 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8852 }8941 }
8853 if (!(try sema.enumHasInt(dest_ty, int_val))) {8942 if (!(try sema.enumHasInt(dest_ty, int_val))) {
8854 return sema.fail(block, src, "enum '{}' has no tag with value '{}'", .{8943 return sema.fail(block, src, "enum '{}' has no tag with value '{}'", .{
8855 dest_ty.fmt(mod), int_val.fmtValue(mod, sema),8944 dest_ty.fmt(pt), int_val.fmtValue(pt, sema),
8856 });8945 });
8857 }8946 }
8858 return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern());8947 return Air.internedToRef((try pt.getCoerced(int_val, dest_ty)).toIntern());
8859 }8948 }
88608949
8861 if (dest_ty.intTagType(mod).zigTypeTag(mod) == .ComptimeInt) {8950 if (dest_ty.intTagType(mod).zigTypeTag(mod) == .ComptimeInt) {
...@@ -8909,7 +8998,8 @@ fn analyzeOptionalPayloadPtr(...@@ -8909,7 +8998,8 @@ fn analyzeOptionalPayloadPtr(
8909 safety_check: bool,8998 safety_check: bool,
8910 initializing: bool,8999 initializing: bool,
8911) CompileError!Air.Inst.Ref {9000) CompileError!Air.Inst.Ref {
8912 const zcu = sema.mod;9001 const pt = sema.pt;
9002 const zcu = pt.zcu;
8913 const optional_ptr_ty = sema.typeOf(optional_ptr);9003 const optional_ptr_ty = sema.typeOf(optional_ptr);
8914 assert(optional_ptr_ty.zigTypeTag(zcu) == .Pointer);9004 assert(optional_ptr_ty.zigTypeTag(zcu) == .Pointer);
89159005
...@@ -8919,7 +9009,7 @@ fn analyzeOptionalPayloadPtr(...@@ -8919,7 +9009,7 @@ fn analyzeOptionalPayloadPtr(
8919 }9009 }
89209010
8921 const child_type = opt_type.optionalChild(zcu);9011 const child_type = opt_type.optionalChild(zcu);
8922 const child_pointer = try zcu.ptrTypeSema(.{9012 const child_pointer = try pt.ptrTypeSema(.{
8923 .child = child_type.toIntern(),9013 .child = child_type.toIntern(),
8924 .flags = .{9014 .flags = .{
8925 .is_const = optional_ptr_ty.isConstPtr(zcu),9015 .is_const = optional_ptr_ty.isConstPtr(zcu),
...@@ -8932,8 +9022,8 @@ fn analyzeOptionalPayloadPtr(...@@ -8932,8 +9022,8 @@ fn analyzeOptionalPayloadPtr(
8932 if (sema.isComptimeMutablePtr(ptr_val)) {9022 if (sema.isComptimeMutablePtr(ptr_val)) {
8933 // Set the optional to non-null at comptime.9023 // Set the optional to non-null at comptime.
8934 // If the payload is OPV, we must use that value instead of undef.9024 // 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);9025 const payload_val = try sema.typeHasOnePossibleValue(child_type) orelse try pt.undefValue(child_type);
8936 const opt_val = try zcu.intern(.{ .opt = .{9026 const opt_val = try pt.intern(.{ .opt = .{
8937 .ty = opt_type.toIntern(),9027 .ty = opt_type.toIntern(),
8938 .val = payload_val.toIntern(),9028 .val = payload_val.toIntern(),
8939 } });9029 } });
...@@ -8943,13 +9033,13 @@ fn analyzeOptionalPayloadPtr(...@@ -8943,13 +9033,13 @@ fn analyzeOptionalPayloadPtr(
8943 const opt_payload_ptr = try block.addTyOp(.optional_payload_ptr_set, child_pointer, optional_ptr);9033 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);9034 try sema.checkKnownAllocPtr(block, optional_ptr, opt_payload_ptr);
8945 }9035 }
8946 return Air.internedToRef((try ptr_val.ptrOptPayload(zcu)).toIntern());9036 return Air.internedToRef((try ptr_val.ptrOptPayload(pt)).toIntern());
8947 }9037 }
8948 if (try sema.pointerDeref(block, src, ptr_val, optional_ptr_ty)) |val| {9038 if (try sema.pointerDeref(block, src, ptr_val, optional_ptr_ty)) |val| {
8949 if (val.isNull(zcu)) {9039 if (val.isNull(zcu)) {
8950 return sema.fail(block, src, "unable to unwrap null", .{});9040 return sema.fail(block, src, "unable to unwrap null", .{});
8951 }9041 }
8952 return Air.internedToRef((try ptr_val.ptrOptPayload(zcu)).toIntern());9042 return Air.internedToRef((try ptr_val.ptrOptPayload(pt)).toIntern());
8953 }9043 }
8954 }9044 }
89559045
...@@ -8978,7 +9068,8 @@ fn zirOptionalPayload(...@@ -8978,7 +9068,8 @@ fn zirOptionalPayload(
8978 const tracy = trace(@src());9068 const tracy = trace(@src());
8979 defer tracy.end();9069 defer tracy.end();
89809070
8981 const mod = sema.mod;9071 const pt = sema.pt;
9072 const mod = pt.zcu;
8982 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;9073 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
8983 const src = block.nodeOffset(inst_data.src_node);9074 const src = block.nodeOffset(inst_data.src_node);
8984 const operand = try sema.resolveInst(inst_data.operand);9075 const operand = try sema.resolveInst(inst_data.operand);
...@@ -8992,7 +9083,7 @@ fn zirOptionalPayload(...@@ -8992,7 +9083,7 @@ fn zirOptionalPayload(
8992 // TODO https://github.com/ziglang/zig/issues/65979083 // TODO https://github.com/ziglang/zig/issues/6597
8993 if (true) break :t operand_ty;9084 if (true) break :t operand_ty;
8994 const ptr_info = operand_ty.ptrInfo(mod);9085 const ptr_info = operand_ty.ptrInfo(mod);
8995 break :t try mod.ptrTypeSema(.{9086 break :t try pt.ptrTypeSema(.{
8996 .child = ptr_info.child,9087 .child = ptr_info.child,
8997 .flags = .{9088 .flags = .{
8998 .alignment = ptr_info.flags.alignment,9089 .alignment = ptr_info.flags.alignment,
...@@ -9030,7 +9121,8 @@ fn zirErrUnionPayload(...@@ -9030,7 +9121,8 @@ fn zirErrUnionPayload(
9030 const tracy = trace(@src());9121 const tracy = trace(@src());
9031 defer tracy.end();9122 defer tracy.end();
90329123
9033 const mod = sema.mod;9124 const pt = sema.pt;
9125 const mod = pt.zcu;
9034 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;9126 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
9035 const src = block.nodeOffset(inst_data.src_node);9127 const src = block.nodeOffset(inst_data.src_node);
9036 const operand = try sema.resolveInst(inst_data.operand);9128 const operand = try sema.resolveInst(inst_data.operand);
...@@ -9038,7 +9130,7 @@ fn zirErrUnionPayload(...@@ -9038,7 +9130,7 @@ fn zirErrUnionPayload(
9038 const err_union_ty = sema.typeOf(operand);9130 const err_union_ty = sema.typeOf(operand);
9039 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) {9131 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) {
9040 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{9132 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{
9041 err_union_ty.fmt(mod),9133 err_union_ty.fmt(pt),
9042 });9134 });
9043 }9135 }
9044 return sema.analyzeErrUnionPayload(block, src, err_union_ty, operand, operand_src, false);9136 return sema.analyzeErrUnionPayload(block, src, err_union_ty, operand, operand_src, false);
...@@ -9053,7 +9145,8 @@ fn analyzeErrUnionPayload(...@@ -9053,7 +9145,8 @@ fn analyzeErrUnionPayload(
9053 operand_src: LazySrcLoc,9145 operand_src: LazySrcLoc,
9054 safety_check: bool,9146 safety_check: bool,
9055) CompileError!Air.Inst.Ref {9147) CompileError!Air.Inst.Ref {
9056 const mod = sema.mod;9148 const pt = sema.pt;
9149 const mod = pt.zcu;
9057 const payload_ty = err_union_ty.errorUnionPayload(mod);9150 const payload_ty = err_union_ty.errorUnionPayload(mod);
9058 if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {9151 if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {
9059 if (val.getErrorName(mod).unwrap()) |name| {9152 if (val.getErrorName(mod).unwrap()) |name| {
...@@ -9098,19 +9191,20 @@ fn analyzeErrUnionPayloadPtr(...@@ -9098,19 +9191,20 @@ fn analyzeErrUnionPayloadPtr(
9098 safety_check: bool,9191 safety_check: bool,
9099 initializing: bool,9192 initializing: bool,
9100) CompileError!Air.Inst.Ref {9193) CompileError!Air.Inst.Ref {
9101 const zcu = sema.mod;9194 const pt = sema.pt;
9195 const zcu = pt.zcu;
9102 const operand_ty = sema.typeOf(operand);9196 const operand_ty = sema.typeOf(operand);
9103 assert(operand_ty.zigTypeTag(zcu) == .Pointer);9197 assert(operand_ty.zigTypeTag(zcu) == .Pointer);
91049198
9105 if (operand_ty.childType(zcu).zigTypeTag(zcu) != .ErrorUnion) {9199 if (operand_ty.childType(zcu).zigTypeTag(zcu) != .ErrorUnion) {
9106 return sema.fail(block, src, "expected error union type, found '{}'", .{9200 return sema.fail(block, src, "expected error union type, found '{}'", .{
9107 operand_ty.childType(zcu).fmt(zcu),9201 operand_ty.childType(zcu).fmt(pt),
9108 });9202 });
9109 }9203 }
91109204
9111 const err_union_ty = operand_ty.childType(zcu);9205 const err_union_ty = operand_ty.childType(zcu);
9112 const payload_ty = err_union_ty.errorUnionPayload(zcu);9206 const payload_ty = err_union_ty.errorUnionPayload(zcu);
9113 const operand_pointer_ty = try zcu.ptrTypeSema(.{9207 const operand_pointer_ty = try pt.ptrTypeSema(.{
9114 .child = payload_ty.toIntern(),9208 .child = payload_ty.toIntern(),
9115 .flags = .{9209 .flags = .{
9116 .is_const = operand_ty.isConstPtr(zcu),9210 .is_const = operand_ty.isConstPtr(zcu),
...@@ -9123,8 +9217,8 @@ fn analyzeErrUnionPayloadPtr(...@@ -9123,8 +9217,8 @@ fn analyzeErrUnionPayloadPtr(
9123 if (sema.isComptimeMutablePtr(ptr_val)) {9217 if (sema.isComptimeMutablePtr(ptr_val)) {
9124 // Set the error union to non-error at comptime.9218 // Set the error union to non-error at comptime.
9125 // If the payload is OPV, we must use that value instead of undef.9219 // 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);9220 const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try pt.undefValue(payload_ty);
9127 const eu_val = try zcu.intern(.{ .error_union = .{9221 const eu_val = try pt.intern(.{ .error_union = .{
9128 .ty = err_union_ty.toIntern(),9222 .ty = err_union_ty.toIntern(),
9129 .val = .{ .payload = payload_val.toIntern() },9223 .val = .{ .payload = payload_val.toIntern() },
9130 } });9224 } });
...@@ -9135,13 +9229,13 @@ fn analyzeErrUnionPayloadPtr(...@@ -9135,13 +9229,13 @@ fn analyzeErrUnionPayloadPtr(
9135 const eu_payload_ptr = try block.addTyOp(.errunion_payload_ptr_set, operand_pointer_ty, operand);9229 const eu_payload_ptr = try block.addTyOp(.errunion_payload_ptr_set, operand_pointer_ty, operand);
9136 try sema.checkKnownAllocPtr(block, operand, eu_payload_ptr);9230 try sema.checkKnownAllocPtr(block, operand, eu_payload_ptr);
9137 }9231 }
9138 return Air.internedToRef((try ptr_val.ptrEuPayload(zcu)).toIntern());9232 return Air.internedToRef((try ptr_val.ptrEuPayload(pt)).toIntern());
9139 }9233 }
9140 if (try sema.pointerDeref(block, src, ptr_val, operand_ty)) |val| {9234 if (try sema.pointerDeref(block, src, ptr_val, operand_ty)) |val| {
9141 if (val.getErrorName(zcu).unwrap()) |name| {9235 if (val.getErrorName(zcu).unwrap()) |name| {
9142 return sema.failWithComptimeErrorRetTrace(block, src, name);9236 return sema.failWithComptimeErrorRetTrace(block, src, name);
9143 }9237 }
9144 return Air.internedToRef((try ptr_val.ptrEuPayload(zcu)).toIntern());9238 return Air.internedToRef((try ptr_val.ptrEuPayload(pt)).toIntern());
9145 }9239 }
9146 }9240 }
91479241
...@@ -9175,18 +9269,19 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -9175,18 +9269,19 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
9175}9269}
91769270
9177fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) CompileError!Air.Inst.Ref {9271fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) CompileError!Air.Inst.Ref {
9178 const mod = sema.mod;9272 const pt = sema.pt;
9273 const mod = pt.zcu;
9179 const operand_ty = sema.typeOf(operand);9274 const operand_ty = sema.typeOf(operand);
9180 if (operand_ty.zigTypeTag(mod) != .ErrorUnion) {9275 if (operand_ty.zigTypeTag(mod) != .ErrorUnion) {
9181 return sema.fail(block, src, "expected error union type, found '{}'", .{9276 return sema.fail(block, src, "expected error union type, found '{}'", .{
9182 operand_ty.fmt(mod),9277 operand_ty.fmt(pt),
9183 });9278 });
9184 }9279 }
91859280
9186 const result_ty = operand_ty.errorUnionSet(mod);9281 const result_ty = operand_ty.errorUnionSet(mod);
91879282
9188 if (try sema.resolveDefinedValue(block, src, operand)) |val| {9283 if (try sema.resolveDefinedValue(block, src, operand)) |val| {
9189 return Air.internedToRef((try mod.intern(.{ .err = .{9284 return Air.internedToRef((try pt.intern(.{ .err = .{
9190 .ty = result_ty.toIntern(),9285 .ty = result_ty.toIntern(),
9191 .name = mod.intern_pool.indexToKey(val.toIntern()).error_union.val.err_name,9286 .name = mod.intern_pool.indexToKey(val.toIntern()).error_union.val.err_name,
9192 } })));9287 } })));
...@@ -9208,13 +9303,14 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -9208,13 +9303,14 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
9208}9303}
92099304
9210fn analyzeErrUnionCodePtr(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) CompileError!Air.Inst.Ref {9305fn analyzeErrUnionCodePtr(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) CompileError!Air.Inst.Ref {
9211 const mod = sema.mod;9306 const pt = sema.pt;
9307 const mod = pt.zcu;
9212 const operand_ty = sema.typeOf(operand);9308 const operand_ty = sema.typeOf(operand);
9213 assert(operand_ty.zigTypeTag(mod) == .Pointer);9309 assert(operand_ty.zigTypeTag(mod) == .Pointer);
92149310
9215 if (operand_ty.childType(mod).zigTypeTag(mod) != .ErrorUnion) {9311 if (operand_ty.childType(mod).zigTypeTag(mod) != .ErrorUnion) {
9216 return sema.fail(block, src, "expected error union type, found '{}'", .{9312 return sema.fail(block, src, "expected error union type, found '{}'", .{
9217 operand_ty.childType(mod).fmt(mod),9313 operand_ty.childType(mod).fmt(pt),
9218 });9314 });
9219 }9315 }
92209316
...@@ -9223,7 +9319,7 @@ fn analyzeErrUnionCodePtr(sema: *Sema, block: *Block, src: LazySrcLoc, operand:...@@ -9223,7 +9319,7 @@ fn analyzeErrUnionCodePtr(sema: *Sema, block: *Block, src: LazySrcLoc, operand:
9223 if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| {9319 if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| {
9224 if (try sema.pointerDeref(block, src, pointer_val, operand_ty)) |val| {9320 if (try sema.pointerDeref(block, src, pointer_val, operand_ty)) |val| {
9225 assert(val.getErrorName(mod) != .none);9321 assert(val.getErrorName(mod) != .none);
9226 return Air.internedToRef((try mod.intern(.{ .err = .{9322 return Air.internedToRef((try pt.intern(.{ .err = .{
9227 .ty = result_ty.toIntern(),9323 .ty = result_ty.toIntern(),
9228 .name = mod.intern_pool.indexToKey(val.toIntern()).error_union.val.err_name,9324 .name = mod.intern_pool.indexToKey(val.toIntern()).error_union.val.err_name,
9229 } })));9325 } })));
...@@ -9240,10 +9336,11 @@ fn zirFunc(...@@ -9240,10 +9336,11 @@ fn zirFunc(
9240 inst: Zir.Inst.Index,9336 inst: Zir.Inst.Index,
9241 inferred_error_set: bool,9337 inferred_error_set: bool,
9242) CompileError!Air.Inst.Ref {9338) CompileError!Air.Inst.Ref {
9243 const mod = sema.mod;9339 const pt = sema.pt;
9340 const mod = pt.zcu;
9244 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;9341 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);9342 const extra = sema.code.extraData(Zir.Inst.Func, inst_data.payload_index);
9246 const target = sema.mod.getTarget();9343 const target = mod.getTarget();
9247 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node });9344 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node });
92489345
9249 var extra_index = extra.end;9346 var extra_index = extra.end;
...@@ -9372,7 +9469,8 @@ fn handleExternLibName(...@@ -9372,7 +9469,8 @@ fn handleExternLibName(
9372 lib_name: []const u8,9469 lib_name: []const u8,
9373) CompileError!void {9470) CompileError!void {
9374 blk: {9471 blk: {
9375 const mod = sema.mod;9472 const pt = sema.pt;
9473 const mod = pt.zcu;
9376 const comp = mod.comp;9474 const comp = mod.comp;
9377 const target = mod.getTarget();9475 const target = mod.getTarget();
9378 log.debug("extern fn symbol expected in lib '{s}'", .{lib_name});9476 log.debug("extern fn symbol expected in lib '{s}'", .{lib_name});
...@@ -9485,7 +9583,8 @@ fn funcCommon(...@@ -9485,7 +9583,8 @@ fn funcCommon(
9485 noalias_bits: u32,9583 noalias_bits: u32,
9486 is_noinline: bool,9584 is_noinline: bool,
9487) CompileError!Air.Inst.Ref {9585) CompileError!Air.Inst.Ref {
9488 const mod = sema.mod;9586 const pt = sema.pt;
9587 const mod = pt.zcu;
9489 const gpa = sema.gpa;9588 const gpa = sema.gpa;
9490 const target = mod.getTarget();9589 const target = mod.getTarget();
9491 const ip = &mod.intern_pool;9590 const ip = &mod.intern_pool;
...@@ -9539,13 +9638,13 @@ fn funcCommon(...@@ -9539,13 +9638,13 @@ fn funcCommon(
9539 if (!param_ty.isValidParamType(mod)) {9638 if (!param_ty.isValidParamType(mod)) {
9540 const opaque_str = if (param_ty.zigTypeTag(mod) == .Opaque) "opaque " else "";9639 const opaque_str = if (param_ty.zigTypeTag(mod) == .Opaque) "opaque " else "";
9541 return sema.fail(block, param_src, "parameter of {s}type '{}' not allowed", .{9640 return sema.fail(block, param_src, "parameter of {s}type '{}' not allowed", .{
9542 opaque_str, param_ty.fmt(mod),9641 opaque_str, param_ty.fmt(pt),
9543 });9642 });
9544 }9643 }
9545 if (!this_generic and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and !try sema.validateExternType(param_ty, .param_ty)) {9644 if (!this_generic and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and !try sema.validateExternType(param_ty, .param_ty)) {
9546 const msg = msg: {9645 const msg = msg: {
9547 const msg = try sema.errMsg(param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{9646 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),9647 param_ty.fmt(pt), @tagName(cc_resolved),
9549 });9648 });
9550 errdefer msg.destroy(sema.gpa);9649 errdefer msg.destroy(sema.gpa);
95519650
...@@ -9559,7 +9658,7 @@ fn funcCommon(...@@ -9559,7 +9658,7 @@ fn funcCommon(
9559 if (is_source_decl and requires_comptime and !param_is_comptime and has_body and !block.is_comptime) {9658 if (is_source_decl and requires_comptime and !param_is_comptime and has_body and !block.is_comptime) {
9560 const msg = msg: {9659 const msg = msg: {
9561 const msg = try sema.errMsg(param_src, "parameter of type '{}' must be declared comptime", .{9660 const msg = try sema.errMsg(param_src, "parameter of type '{}' must be declared comptime", .{
9562 param_ty.fmt(mod),9661 param_ty.fmt(pt),
9563 });9662 });
9564 errdefer msg.destroy(sema.gpa);9663 errdefer msg.destroy(sema.gpa);
95659664
...@@ -9580,7 +9679,7 @@ fn funcCommon(...@@ -9580,7 +9679,7 @@ fn funcCommon(
9580 const err_code_size = target.ptrBitWidth();9679 const err_code_size = target.ptrBitWidth();
9581 switch (i) {9680 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", .{}),9681 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}),9682 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}),9683 else => return sema.fail(block, param_src, "'Interrupt' calling convention supports up to 2 parameters, found {d}", .{i + 1}),
9585 }9684 }
9586 } else return sema.fail(block, param_src, "parameters are not allowed with 'Interrupt' calling convention", .{}),9685 } else return sema.fail(block, param_src, "parameters are not allowed with 'Interrupt' calling convention", .{}),
...@@ -9606,7 +9705,7 @@ fn funcCommon(...@@ -9606,7 +9705,7 @@ fn funcCommon(
9606 if (inferred_error_set) {9705 if (inferred_error_set) {
9607 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);9706 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);
9608 }9707 }
9609 const func_index = try ip.getFuncInstance(gpa, .{9708 const func_index = try ip.getFuncInstance(gpa, pt.tid, .{
9610 .param_types = param_types,9709 .param_types = param_types,
9611 .noalias_bits = noalias_bits,9710 .noalias_bits = noalias_bits,
9612 .bare_return_type = bare_return_type.toIntern(),9711 .bare_return_type = bare_return_type.toIntern(),
...@@ -9655,7 +9754,7 @@ fn funcCommon(...@@ -9655,7 +9754,7 @@ fn funcCommon(
9655 assert(has_body);9754 assert(has_body);
9656 if (!ret_poison)9755 if (!ret_poison)
9657 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);9756 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);
9658 const func_index = try ip.getFuncDeclIes(gpa, .{9757 const func_index = try ip.getFuncDeclIes(gpa, pt.tid, .{
9659 .owner_decl = sema.owner_decl_index,9758 .owner_decl = sema.owner_decl_index,
96609759
9661 .param_types = param_types,9760 .param_types = param_types,
...@@ -9695,7 +9794,7 @@ fn funcCommon(...@@ -9695,7 +9794,7 @@ fn funcCommon(
9695 );9794 );
9696 }9795 }
96979796
9698 const func_ty = try ip.getFuncType(gpa, .{9797 const func_ty = try ip.getFuncType(gpa, pt.tid, .{
9699 .param_types = param_types,9798 .param_types = param_types,
9700 .noalias_bits = noalias_bits,9799 .noalias_bits = noalias_bits,
9701 .comptime_bits = comptime_bits,9800 .comptime_bits = comptime_bits,
...@@ -9718,7 +9817,7 @@ fn funcCommon(...@@ -9718,7 +9817,7 @@ fn funcCommon(
9718 if (opt_lib_name) |lib_name| try sema.handleExternLibName(block, block.src(.{9817 if (opt_lib_name) |lib_name| try sema.handleExternLibName(block, block.src(.{
9719 .node_offset_lib_name = src_node_offset,9818 .node_offset_lib_name = src_node_offset,
9720 }), lib_name);9819 }), lib_name);
9721 const func_index = try ip.getExternFunc(gpa, .{9820 const func_index = try ip.getExternFunc(gpa, pt.tid, .{
9722 .ty = func_ty,9821 .ty = func_ty,
9723 .decl = sema.owner_decl_index,9822 .decl = sema.owner_decl_index,
9724 .lib_name = try mod.intern_pool.getOrPutStringOpt(gpa, opt_lib_name, .no_embedded_nulls),9823 .lib_name = try mod.intern_pool.getOrPutStringOpt(gpa, opt_lib_name, .no_embedded_nulls),
...@@ -9743,7 +9842,7 @@ fn funcCommon(...@@ -9743,7 +9842,7 @@ fn funcCommon(
9743 }9842 }
97449843
9745 if (has_body) {9844 if (has_body) {
9746 const func_index = try ip.getFuncDecl(gpa, .{9845 const func_index = try ip.getFuncDecl(gpa, pt.tid, .{
9747 .owner_decl = sema.owner_decl_index,9846 .owner_decl = sema.owner_decl_index,
9748 .ty = func_ty,9847 .ty = func_ty,
9749 .cc = cc,9848 .cc = cc,
...@@ -9809,7 +9908,8 @@ fn finishFunc(...@@ -9809,7 +9908,8 @@ fn finishFunc(
9809 is_generic: bool,9908 is_generic: bool,
9810 final_is_generic: bool,9909 final_is_generic: bool,
9811) CompileError!Air.Inst.Ref {9910) CompileError!Air.Inst.Ref {
9812 const mod = sema.mod;9911 const pt = sema.pt;
9912 const mod = pt.zcu;
9813 const ip = &mod.intern_pool;9913 const ip = &mod.intern_pool;
9814 const gpa = sema.gpa;9914 const gpa = sema.gpa;
9815 const target = mod.getTarget();9915 const target = mod.getTarget();
...@@ -9822,7 +9922,7 @@ fn finishFunc(...@@ -9822,7 +9922,7 @@ fn finishFunc(
9822 if (!return_type.isValidReturnType(mod)) {9922 if (!return_type.isValidReturnType(mod)) {
9823 const opaque_str = if (return_type.zigTypeTag(mod) == .Opaque) "opaque " else "";9923 const opaque_str = if (return_type.zigTypeTag(mod) == .Opaque) "opaque " else "";
9824 return sema.fail(block, ret_ty_src, "{s}return type '{}' not allowed", .{9924 return sema.fail(block, ret_ty_src, "{s}return type '{}' not allowed", .{
9825 opaque_str, return_type.fmt(mod),9925 opaque_str, return_type.fmt(pt),
9826 });9926 });
9827 }9927 }
9828 if (!ret_poison and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and9928 if (!ret_poison and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and
...@@ -9830,7 +9930,7 @@ fn finishFunc(...@@ -9830,7 +9930,7 @@ fn finishFunc(
9830 {9930 {
9831 const msg = msg: {9931 const msg = msg: {
9832 const msg = try sema.errMsg(ret_ty_src, "return type '{}' not allowed in function with calling convention '{s}'", .{9932 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),9933 return_type.fmt(pt), @tagName(cc_resolved),
9834 });9934 });
9835 errdefer msg.destroy(gpa);9935 errdefer msg.destroy(gpa);
98369936
...@@ -9852,7 +9952,7 @@ fn finishFunc(...@@ -9852,7 +9952,7 @@ fn finishFunc(
9852 const msg = try sema.errMsg(9952 const msg = try sema.errMsg(
9853 ret_ty_src,9953 ret_ty_src,
9854 "function with comptime-only return type '{}' requires all parameters to be comptime",9954 "function with comptime-only return type '{}' requires all parameters to be comptime",
9855 .{return_type.fmt(mod)},9955 .{return_type.fmt(pt)},
9856 );9956 );
9857 try sema.explainWhyTypeIsComptime(msg, ret_ty_src, return_type);9957 try sema.explainWhyTypeIsComptime(msg, ret_ty_src, return_type);
98589958
...@@ -9938,8 +10038,8 @@ fn finishFunc(...@@ -9938,8 +10038,8 @@ fn finishFunc(
9938 if (!final_is_generic and sema.wantErrorReturnTracing(return_type)) {10038 if (!final_is_generic and sema.wantErrorReturnTracing(return_type)) {
9939 // Make sure that StackTrace's fields are resolved so that the backend can10039 // Make sure that StackTrace's fields are resolved so that the backend can
9940 // lower this fn type.10040 // lower this fn type.
9941 const unresolved_stack_trace_ty = try mod.getBuiltinType("StackTrace");10041 const unresolved_stack_trace_ty = try pt.getBuiltinType("StackTrace");
9942 try unresolved_stack_trace_ty.resolveFields(mod);10042 try unresolved_stack_trace_ty.resolveFields(pt);
9943 }10043 }
994410044
9945 return Air.internedToRef(if (opt_func_index != .none) opt_func_index else func_ty);10045 return Air.internedToRef(if (opt_func_index != .none) opt_func_index else func_ty);
...@@ -10068,7 +10168,8 @@ fn analyzeAs(...@@ -10068,7 +10168,8 @@ fn analyzeAs(
10068 zir_operand: Zir.Inst.Ref,10168 zir_operand: Zir.Inst.Ref,
10069 no_cast_to_comptime_int: bool,10169 no_cast_to_comptime_int: bool,
10070) CompileError!Air.Inst.Ref {10170) CompileError!Air.Inst.Ref {
10071 const mod = sema.mod;10171 const pt = sema.pt;
10172 const mod = pt.zcu;
10072 const operand = try sema.resolveInst(zir_operand);10173 const operand = try sema.resolveInst(zir_operand);
10073 const operand_air_inst = sema.resolveInst(zir_dest_type) catch |err| switch (err) {10174 const operand_air_inst = sema.resolveInst(zir_dest_type) catch |err| switch (err) {
10074 error.GenericPoison => return operand,10175 error.GenericPoison => return operand,
...@@ -10098,7 +10199,8 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -10098,7 +10199,8 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
10098 const tracy = trace(@src());10199 const tracy = trace(@src());
10099 defer tracy.end();10200 defer tracy.end();
1010010201
10101 const zcu = sema.mod;10202 const pt = sema.pt;
10203 const zcu = pt.zcu;
10102 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;10204 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
10103 const ptr_src = block.builtinCallArgSrc(inst_data.src_node, 0);10205 const ptr_src = block.builtinCallArgSrc(inst_data.src_node, 0);
10104 const operand = try sema.resolveInst(inst_data.operand);10206 const operand = try sema.resolveInst(inst_data.operand);
...@@ -10106,12 +10208,12 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -10106,12 +10208,12 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
10106 const ptr_ty = operand_ty.scalarType(zcu);10208 const ptr_ty = operand_ty.scalarType(zcu);
10107 const is_vector = operand_ty.zigTypeTag(zcu) == .Vector;10209 const is_vector = operand_ty.zigTypeTag(zcu) == .Vector;
10108 if (!ptr_ty.isPtrAtRuntime(zcu)) {10210 if (!ptr_ty.isPtrAtRuntime(zcu)) {
10109 return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(zcu)});10211 return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(pt)});
10110 }10212 }
10111 const pointee_ty = ptr_ty.childType(zcu);10213 const pointee_ty = ptr_ty.childType(zcu);
10112 if (try sema.typeRequiresComptime(ptr_ty)) {10214 if (try sema.typeRequiresComptime(ptr_ty)) {
10113 const msg = msg: {10215 const msg = msg: {
10114 const msg = try sema.errMsg(ptr_src, "comptime-only type '{}' has no pointer address", .{pointee_ty.fmt(zcu)});10216 const msg = try sema.errMsg(ptr_src, "comptime-only type '{}' has no pointer address", .{pointee_ty.fmt(pt)});
10115 errdefer msg.destroy(sema.gpa);10217 errdefer msg.destroy(sema.gpa);
10116 try sema.explainWhyTypeIsComptime(msg, ptr_src, pointee_ty);10218 try sema.explainWhyTypeIsComptime(msg, ptr_src, pointee_ty);
10117 break :msg msg;10219 break :msg msg;
...@@ -10121,32 +10223,32 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -10121,32 +10223,32 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
10121 if (try sema.resolveValueIntable(operand)) |operand_val| ct: {10223 if (try sema.resolveValueIntable(operand)) |operand_val| ct: {
10122 if (!is_vector) {10224 if (!is_vector) {
10123 if (operand_val.isUndef(zcu)) {10225 if (operand_val.isUndef(zcu)) {
10124 return Air.internedToRef((try zcu.undefValue(Type.usize)).toIntern());10226 return Air.internedToRef((try pt.undefValue(Type.usize)).toIntern());
10125 }10227 }
10126 return Air.internedToRef((try zcu.intValue(10228 return Air.internedToRef((try pt.intValue(
10127 Type.usize,10229 Type.usize,
10128 (try operand_val.getUnsignedIntAdvanced(zcu, .sema)).?,10230 (try operand_val.getUnsignedIntAdvanced(pt, .sema)).?,
10129 )).toIntern());10231 )).toIntern());
10130 }10232 }
10131 const len = operand_ty.vectorLen(zcu);10233 const len = operand_ty.vectorLen(zcu);
10132 const dest_ty = try zcu.vectorType(.{ .child = .usize_type, .len = len });10234 const dest_ty = try pt.vectorType(.{ .child = .usize_type, .len = len });
10133 const new_elems = try sema.arena.alloc(InternPool.Index, len);10235 const new_elems = try sema.arena.alloc(InternPool.Index, len);
10134 for (new_elems, 0..) |*new_elem, i| {10236 for (new_elems, 0..) |*new_elem, i| {
10135 const ptr_val = try operand_val.elemValue(zcu, i);10237 const ptr_val = try operand_val.elemValue(pt, i);
10136 if (ptr_val.isUndef(zcu)) {10238 if (ptr_val.isUndef(zcu)) {
10137 new_elem.* = (try zcu.undefValue(Type.usize)).toIntern();10239 new_elem.* = (try pt.undefValue(Type.usize)).toIntern();
10138 continue;10240 continue;
10139 }10241 }
10140 const addr = try ptr_val.getUnsignedIntAdvanced(zcu, .sema) orelse {10242 const addr = try ptr_val.getUnsignedIntAdvanced(pt, .sema) orelse {
10141 // A vector element wasn't an integer pointer. This is a runtime operation.10243 // A vector element wasn't an integer pointer. This is a runtime operation.
10142 break :ct;10244 break :ct;
10143 };10245 };
10144 new_elem.* = (try zcu.intValue(10246 new_elem.* = (try pt.intValue(
10145 Type.usize,10247 Type.usize,
10146 addr,10248 addr,
10147 )).toIntern();10249 )).toIntern();
10148 }10250 }
10149 return Air.internedToRef(try zcu.intern(.{ .aggregate = .{10251 return Air.internedToRef(try pt.intern(.{ .aggregate = .{
10150 .ty = dest_ty.toIntern(),10252 .ty = dest_ty.toIntern(),
10151 .storage = .{ .elems = new_elems },10253 .storage = .{ .elems = new_elems },
10152 } }));10254 } }));
...@@ -10157,10 +10259,10 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -10157,10 +10259,10 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
10157 return block.addUnOp(.int_from_ptr, operand);10259 return block.addUnOp(.int_from_ptr, operand);
10158 }10260 }
10159 const len = operand_ty.vectorLen(zcu);10261 const len = operand_ty.vectorLen(zcu);
10160 const dest_ty = try zcu.vectorType(.{ .child = .usize_type, .len = len });10262 const dest_ty = try pt.vectorType(.{ .child = .usize_type, .len = len });
10161 const new_elems = try sema.arena.alloc(Air.Inst.Ref, len);10263 const new_elems = try sema.arena.alloc(Air.Inst.Ref, len);
10162 for (new_elems, 0..) |*new_elem, i| {10264 for (new_elems, 0..) |*new_elem, i| {
10163 const idx_ref = try zcu.intRef(Type.usize, i);10265 const idx_ref = try pt.intRef(Type.usize, i);
10164 const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref);10266 const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref);
10165 new_elem.* = try block.addUnOp(.int_from_ptr, old_elem);10267 new_elem.* = try block.addUnOp(.int_from_ptr, old_elem);
10166 }10268 }
...@@ -10171,7 +10273,8 @@ fn zirFieldVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -10171,7 +10273,8 @@ fn zirFieldVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
10171 const tracy = trace(@src());10273 const tracy = trace(@src());
10172 defer tracy.end();10274 defer tracy.end();
1017310275
10174 const mod = sema.mod;10276 const pt = sema.pt;
10277 const mod = pt.zcu;
10175 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;10278 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10176 const src = block.nodeOffset(inst_data.src_node);10279 const src = block.nodeOffset(inst_data.src_node);
10177 const field_name_src = block.src(.{ .node_offset_field_name = inst_data.src_node });10280 const field_name_src = block.src(.{ .node_offset_field_name = inst_data.src_node });
...@@ -10189,7 +10292,8 @@ fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -10189,7 +10292,8 @@ fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
10189 const tracy = trace(@src());10292 const tracy = trace(@src());
10190 defer tracy.end();10293 defer tracy.end();
1019110294
10192 const mod = sema.mod;10295 const pt = sema.pt;
10296 const mod = pt.zcu;
10193 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;10297 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10194 const src = block.nodeOffset(inst_data.src_node);10298 const src = block.nodeOffset(inst_data.src_node);
10195 const field_name_src = block.src(.{ .node_offset_field_name = inst_data.src_node });10299 const field_name_src = block.src(.{ .node_offset_field_name = inst_data.src_node });
...@@ -10207,7 +10311,8 @@ fn zirStructInitFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi...@@ -10207,7 +10311,8 @@ fn zirStructInitFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi
10207 const tracy = trace(@src());10311 const tracy = trace(@src());
10208 defer tracy.end();10312 defer tracy.end();
1020910313
10210 const mod = sema.mod;10314 const pt = sema.pt;
10315 const mod = pt.zcu;
10211 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;10316 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10212 const src = block.nodeOffset(inst_data.src_node);10317 const src = block.nodeOffset(inst_data.src_node);
10213 const field_name_src = block.src(.{ .node_offset_field_name_init = inst_data.src_node });10318 const field_name_src = block.src(.{ .node_offset_field_name_init = inst_data.src_node });
...@@ -10284,7 +10389,8 @@ fn intCast(...@@ -10284,7 +10389,8 @@ fn intCast(
10284 operand_src: LazySrcLoc,10389 operand_src: LazySrcLoc,
10285 runtime_safety: bool,10390 runtime_safety: bool,
10286) CompileError!Air.Inst.Ref {10391) CompileError!Air.Inst.Ref {
10287 const mod = sema.mod;10392 const pt = sema.pt;
10393 const mod = pt.zcu;
10288 const operand_ty = sema.typeOf(operand);10394 const operand_ty = sema.typeOf(operand);
10289 const dest_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, dest_ty, dest_ty_src);10395 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);10396 const operand_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, operand_ty, operand_src);
...@@ -10307,7 +10413,7 @@ fn intCast(...@@ -10307,7 +10413,7 @@ fn intCast(
1030710413
10308 if (wanted_bits == 0) {10414 if (wanted_bits == 0) {
10309 const ok = if (is_vector) ok: {10415 const ok = if (is_vector) ok: {
10310 const zeros = try sema.splat(operand_ty, try mod.intValue(operand_scalar_ty, 0));10416 const zeros = try sema.splat(operand_ty, try pt.intValue(operand_scalar_ty, 0));
10311 const zero_inst = Air.internedToRef(zeros.toIntern());10417 const zero_inst = Air.internedToRef(zeros.toIntern());
10312 const is_in_range = try block.addCmpVector(operand, zero_inst, .eq);10418 const is_in_range = try block.addCmpVector(operand, zero_inst, .eq);
10313 const all_in_range = try block.addInst(.{10419 const all_in_range = try block.addInst(.{
...@@ -10316,7 +10422,7 @@ fn intCast(...@@ -10316,7 +10422,7 @@ fn intCast(
10316 });10422 });
10317 break :ok all_in_range;10423 break :ok all_in_range;
10318 } else ok: {10424 } else ok: {
10319 const zero_inst = Air.internedToRef((try mod.intValue(operand_ty, 0)).toIntern());10425 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);10426 const is_in_range = try block.addBinOp(.cmp_lte, operand, zero_inst);
10321 break :ok is_in_range;10427 break :ok is_in_range;
10322 };10428 };
...@@ -10339,7 +10445,7 @@ fn intCast(...@@ -10339,7 +10445,7 @@ fn intCast(
10339 // range shrinkage10445 // range shrinkage
10340 // requirement: int value fits into target type10446 // requirement: int value fits into target type
10341 if (wanted_value_bits < actual_value_bits) {10447 if (wanted_value_bits < actual_value_bits) {
10342 const dest_max_val_scalar = try dest_scalar_ty.maxIntScalar(mod, operand_scalar_ty);10448 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);10449 const dest_max_val = try sema.splat(operand_ty, dest_max_val_scalar);
10344 const dest_max = Air.internedToRef(dest_max_val.toIntern());10450 const dest_max = Air.internedToRef(dest_max_val.toIntern());
1034510451
...@@ -10348,8 +10454,8 @@ fn intCast(...@@ -10348,8 +10454,8 @@ fn intCast(
1034810454
10349 // Reinterpret the sign-bit as part of the value. This will make10455 // Reinterpret the sign-bit as part of the value. This will make
10350 // negative differences (`operand` > `dest_max`) appear too big.10456 // negative differences (`operand` > `dest_max`) appear too big.
10351 const unsigned_scalar_operand_ty = try mod.intType(.unsigned, actual_bits);10457 const unsigned_scalar_operand_ty = try pt.intType(.unsigned, actual_bits);
10352 const unsigned_operand_ty = if (is_vector) try mod.vectorType(.{10458 const unsigned_operand_ty = if (is_vector) try pt.vectorType(.{
10353 .len = dest_ty.vectorLen(mod),10459 .len = dest_ty.vectorLen(mod),
10354 .child = unsigned_scalar_operand_ty.toIntern(),10460 .child = unsigned_scalar_operand_ty.toIntern(),
10355 }) else unsigned_scalar_operand_ty;10461 }) else unsigned_scalar_operand_ty;
...@@ -10358,14 +10464,14 @@ fn intCast(...@@ -10358,14 +10464,14 @@ fn intCast(
10358 // If the destination type is signed, then we need to double its10464 // If the destination type is signed, then we need to double its
10359 // range to account for negative values.10465 // range to account for negative values.
10360 const dest_range_val = if (wanted_info.signedness == .signed) range_val: {10466 const dest_range_val = if (wanted_info.signedness == .signed) range_val: {
10361 const one_scalar = try mod.intValue(unsigned_scalar_operand_ty, 1);10467 const one_scalar = try pt.intValue(unsigned_scalar_operand_ty, 1);
10362 const one = if (is_vector) Value.fromInterned((try mod.intern(.{ .aggregate = .{10468 const one = if (is_vector) Value.fromInterned(try pt.intern(.{ .aggregate = .{
10363 .ty = unsigned_operand_ty.toIntern(),10469 .ty = unsigned_operand_ty.toIntern(),
10364 .storage = .{ .repeated_elem = one_scalar.toIntern() },10470 .storage = .{ .repeated_elem = one_scalar.toIntern() },
10365 } }))) else one_scalar;10471 } })) else one_scalar;
10366 const range_minus_one = try dest_max_val.shl(one, unsigned_operand_ty, sema.arena, mod);10472 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);10473 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);10474 } else try pt.getCoerced(dest_max_val, unsigned_operand_ty);
10369 const dest_range = Air.internedToRef(dest_range_val.toIntern());10475 const dest_range = Air.internedToRef(dest_range_val.toIntern());
1037010476
10371 const ok = if (is_vector) ok: {10477 const ok = if (is_vector) ok: {
...@@ -10405,7 +10511,7 @@ fn intCast(...@@ -10405,7 +10511,7 @@ fn intCast(
10405 // no shrinkage, yes sign loss10511 // no shrinkage, yes sign loss
10406 // requirement: signed to unsigned >= 010512 // requirement: signed to unsigned >= 0
10407 const ok = if (is_vector) ok: {10513 const ok = if (is_vector) ok: {
10408 const scalar_zero = try mod.intValue(operand_scalar_ty, 0);10514 const scalar_zero = try pt.intValue(operand_scalar_ty, 0);
10409 const zero_val = try sema.splat(operand_ty, scalar_zero);10515 const zero_val = try sema.splat(operand_ty, scalar_zero);
10410 const zero_inst = Air.internedToRef(zero_val.toIntern());10516 const zero_inst = Air.internedToRef(zero_val.toIntern());
10411 const is_in_range = try block.addCmpVector(operand, zero_inst, .gte);10517 const is_in_range = try block.addCmpVector(operand, zero_inst, .gte);
...@@ -10418,7 +10524,7 @@ fn intCast(...@@ -10418,7 +10524,7 @@ fn intCast(
10418 });10524 });
10419 break :ok all_in_range;10525 break :ok all_in_range;
10420 } else ok: {10526 } else ok: {
10421 const zero_inst = Air.internedToRef((try mod.intValue(operand_ty, 0)).toIntern());10527 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);10528 const is_in_range = try block.addBinOp(.cmp_gte, operand, zero_inst);
10423 break :ok is_in_range;10529 break :ok is_in_range;
10424 };10530 };
...@@ -10432,7 +10538,8 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10432,7 +10538,8 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10432 const tracy = trace(@src());10538 const tracy = trace(@src());
10433 defer tracy.end();10539 defer tracy.end();
1043410540
10435 const mod = sema.mod;10541 const pt = sema.pt;
10542 const mod = pt.zcu;
10436 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;10543 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10437 const src = block.nodeOffset(inst_data.src_node);10544 const src = block.nodeOffset(inst_data.src_node);
10438 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);10545 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
...@@ -10457,14 +10564,14 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10457,14 +10564,14 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10457 .Type,10564 .Type,
10458 .Undefined,10565 .Undefined,
10459 .Void,10566 .Void,
10460 => return sema.fail(block, src, "cannot @bitCast to '{}'", .{dest_ty.fmt(mod)}),10567 => return sema.fail(block, src, "cannot @bitCast to '{}'", .{dest_ty.fmt(pt)}),
1046110568
10462 .Enum => {10569 .Enum => {
10463 const msg = msg: {10570 const msg = msg: {
10464 const msg = try sema.errMsg(src, "cannot @bitCast to '{}'", .{dest_ty.fmt(mod)});10571 const msg = try sema.errMsg(src, "cannot @bitCast to '{}'", .{dest_ty.fmt(pt)});
10465 errdefer msg.destroy(sema.gpa);10572 errdefer msg.destroy(sema.gpa);
10466 switch (operand_ty.zigTypeTag(mod)) {10573 switch (operand_ty.zigTypeTag(mod)) {
10467 .Int, .ComptimeInt => try sema.errNote(src, msg, "use @enumFromInt to cast from '{}'", .{operand_ty.fmt(mod)}),10574 .Int, .ComptimeInt => try sema.errNote(src, msg, "use @enumFromInt to cast from '{}'", .{operand_ty.fmt(pt)}),
10468 else => {},10575 else => {},
10469 }10576 }
1047010577
...@@ -10475,11 +10582,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10475,11 +10582,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1047510582
10476 .Pointer => {10583 .Pointer => {
10477 const msg = msg: {10584 const msg = msg: {
10478 const msg = try sema.errMsg(src, "cannot @bitCast to '{}'", .{dest_ty.fmt(mod)});10585 const msg = try sema.errMsg(src, "cannot @bitCast to '{}'", .{dest_ty.fmt(pt)});
10479 errdefer msg.destroy(sema.gpa);10586 errdefer msg.destroy(sema.gpa);
10480 switch (operand_ty.zigTypeTag(mod)) {10587 switch (operand_ty.zigTypeTag(mod)) {
10481 .Int, .ComptimeInt => try sema.errNote(src, msg, "use @ptrFromInt to cast from '{}'", .{operand_ty.fmt(mod)}),10588 .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)}),10589 .Pointer => try sema.errNote(src, msg, "use @ptrCast to cast from '{}'", .{operand_ty.fmt(pt)}),
10483 else => {},10590 else => {},
10484 }10591 }
1048510592
...@@ -10494,7 +10601,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10494,7 +10601,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10494 else => unreachable,10601 else => unreachable,
10495 };10602 };
10496 return sema.fail(block, src, "cannot @bitCast to '{}'; {s} does not have a guaranteed in-memory layout", .{10603 return sema.fail(block, src, "cannot @bitCast to '{}'; {s} does not have a guaranteed in-memory layout", .{
10497 dest_ty.fmt(mod), container,10604 dest_ty.fmt(pt), container,
10498 });10605 });
10499 },10606 },
1050010607
...@@ -10521,14 +10628,14 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10521,14 +10628,14 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10521 .Type,10628 .Type,
10522 .Undefined,10629 .Undefined,
10523 .Void,10630 .Void,
10524 => return sema.fail(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(mod)}),10631 => return sema.fail(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(pt)}),
1052510632
10526 .Enum => {10633 .Enum => {
10527 const msg = msg: {10634 const msg = msg: {
10528 const msg = try sema.errMsg(operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(mod)});10635 const msg = try sema.errMsg(operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(pt)});
10529 errdefer msg.destroy(sema.gpa);10636 errdefer msg.destroy(sema.gpa);
10530 switch (dest_ty.zigTypeTag(mod)) {10637 switch (dest_ty.zigTypeTag(mod)) {
10531 .Int, .ComptimeInt => try sema.errNote(operand_src, msg, "use @intFromEnum to cast to '{}'", .{dest_ty.fmt(mod)}),10638 .Int, .ComptimeInt => try sema.errNote(operand_src, msg, "use @intFromEnum to cast to '{}'", .{dest_ty.fmt(pt)}),
10532 else => {},10639 else => {},
10533 }10640 }
1053410641
...@@ -10538,11 +10645,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10538,11 +10645,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10538 },10645 },
10539 .Pointer => {10646 .Pointer => {
10540 const msg = msg: {10647 const msg = msg: {
10541 const msg = try sema.errMsg(operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(mod)});10648 const msg = try sema.errMsg(operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(pt)});
10542 errdefer msg.destroy(sema.gpa);10649 errdefer msg.destroy(sema.gpa);
10543 switch (dest_ty.zigTypeTag(mod)) {10650 switch (dest_ty.zigTypeTag(mod)) {
10544 .Int, .ComptimeInt => try sema.errNote(operand_src, msg, "use @intFromPtr to cast to '{}'", .{dest_ty.fmt(mod)}),10651 .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)}),10652 .Pointer => try sema.errNote(operand_src, msg, "use @ptrCast to cast to '{}'", .{dest_ty.fmt(pt)}),
10546 else => {},10653 else => {},
10547 }10654 }
1054810655
...@@ -10557,7 +10664,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10557,7 +10664,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10557 else => unreachable,10664 else => unreachable,
10558 };10665 };
10559 return sema.fail(block, operand_src, "cannot @bitCast from '{}'; {s} does not have a guaranteed in-memory layout", .{10666 return sema.fail(block, operand_src, "cannot @bitCast from '{}'; {s} does not have a guaranteed in-memory layout", .{
10560 operand_ty.fmt(mod), container,10667 operand_ty.fmt(pt), container,
10561 });10668 });
10562 },10669 },
1056310670
...@@ -10575,7 +10682,8 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -10575,7 +10682,8 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
10575 const tracy = trace(@src());10682 const tracy = trace(@src());
10576 defer tracy.end();10683 defer tracy.end();
1057710684
10578 const mod = sema.mod;10685 const pt = sema.pt;
10686 const mod = pt.zcu;
10579 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;10687 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10580 const src = block.nodeOffset(inst_data.src_node);10688 const src = block.nodeOffset(inst_data.src_node);
10581 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);10689 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
...@@ -10599,7 +10707,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -10599,7 +10707,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
10599 block,10707 block,
10600 src,10708 src,
10601 "expected float or vector type, found '{}'",10709 "expected float or vector type, found '{}'",
10602 .{dest_ty.fmt(mod)},10710 .{dest_ty.fmt(pt)},
10603 ),10711 ),
10604 };10712 };
1060510713
...@@ -10609,21 +10717,21 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -10609,21 +10717,21 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
10609 block,10717 block,
10610 operand_src,10718 operand_src,
10611 "expected float or vector type, found '{}'",10719 "expected float or vector type, found '{}'",
10612 .{operand_ty.fmt(mod)},10720 .{operand_ty.fmt(pt)},
10613 ),10721 ),
10614 }10722 }
1061510723
10616 if (try sema.resolveValue(operand)) |operand_val| {10724 if (try sema.resolveValue(operand)) |operand_val| {
10617 if (!is_vector) {10725 if (!is_vector) {
10618 return Air.internedToRef((try operand_val.floatCast(dest_ty, mod)).toIntern());10726 return Air.internedToRef((try operand_val.floatCast(dest_ty, pt)).toIntern());
10619 }10727 }
10620 const vec_len = operand_ty.vectorLen(mod);10728 const vec_len = operand_ty.vectorLen(mod);
10621 const new_elems = try sema.arena.alloc(InternPool.Index, vec_len);10729 const new_elems = try sema.arena.alloc(InternPool.Index, vec_len);
10622 for (new_elems, 0..) |*new_elem, i| {10730 for (new_elems, 0..) |*new_elem, i| {
10623 const old_elem = try operand_val.elemValue(mod, i);10731 const old_elem = try operand_val.elemValue(pt, i);
10624 new_elem.* = (try old_elem.floatCast(dest_scalar_ty, mod)).toIntern();10732 new_elem.* = (try old_elem.floatCast(dest_scalar_ty, pt)).toIntern();
10625 }10733 }
10626 return Air.internedToRef(try mod.intern(.{ .aggregate = .{10734 return Air.internedToRef(try pt.intern(.{ .aggregate = .{
10627 .ty = dest_ty.toIntern(),10735 .ty = dest_ty.toIntern(),
10628 .storage = .{ .elems = new_elems },10736 .storage = .{ .elems = new_elems },
10629 } }));10737 } }));
...@@ -10644,7 +10752,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -10644,7 +10752,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
10644 const vec_len = operand_ty.vectorLen(mod);10752 const vec_len = operand_ty.vectorLen(mod);
10645 const new_elems = try sema.arena.alloc(Air.Inst.Ref, vec_len);10753 const new_elems = try sema.arena.alloc(Air.Inst.Ref, vec_len);
10646 for (new_elems, 0..) |*new_elem, i| {10754 for (new_elems, 0..) |*new_elem, i| {
10647 const idx_ref = try mod.intRef(Type.usize, i);10755 const idx_ref = try pt.intRef(Type.usize, i);
10648 const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref);10756 const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref);
10649 new_elem.* = try block.addTyOp(.fptrunc, dest_scalar_ty, old_elem);10757 new_elem.* = try block.addTyOp(.fptrunc, dest_scalar_ty, old_elem);
10650 }10758 }
...@@ -10681,10 +10789,9 @@ fn zirElemValImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -10681,10 +10789,9 @@ fn zirElemValImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
10681 const tracy = trace(@src());10789 const tracy = trace(@src());
10682 defer tracy.end();10790 defer tracy.end();
1068310791
10684 const mod = sema.mod;
10685 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].elem_val_imm;10792 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].elem_val_imm;
10686 const array = try sema.resolveInst(inst_data.operand);10793 const array = try sema.resolveInst(inst_data.operand);
10687 const elem_index = try mod.intRef(Type.usize, inst_data.idx);10794 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);10795 return sema.elemVal(block, LazySrcLoc.unneeded, array, elem_index, LazySrcLoc.unneeded, false);
10689}10796}
1069010797
...@@ -10692,7 +10799,8 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10692,7 +10799,8 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
10692 const tracy = trace(@src());10799 const tracy = trace(@src());
10693 defer tracy.end();10800 defer tracy.end();
1069410801
10695 const mod = sema.mod;10802 const pt = sema.pt;
10803 const mod = pt.zcu;
10696 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;10804 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10697 const src = block.nodeOffset(inst_data.src_node);10805 const src = block.nodeOffset(inst_data.src_node);
10698 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;10806 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
...@@ -10703,7 +10811,7 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -10703,7 +10811,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 });10811 const capture_src = block.src(.{ .for_capture_from_input = inst_data.src_node });
10704 const msg = msg: {10812 const msg = msg: {
10705 const msg = try sema.errMsg(capture_src, "pointer capture of non pointer type '{}'", .{10813 const msg = try sema.errMsg(capture_src, "pointer capture of non pointer type '{}'", .{
10706 indexable_ty.fmt(mod),10814 indexable_ty.fmt(pt),
10707 });10815 });
10708 errdefer msg.destroy(sema.gpa);10816 errdefer msg.destroy(sema.gpa);
10709 if (indexable_ty.isIndexable(mod)) {10817 if (indexable_ty.isIndexable(mod)) {
...@@ -10734,12 +10842,13 @@ fn zirArrayInitElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile...@@ -10734,12 +10842,13 @@ fn zirArrayInitElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile
10734 const tracy = trace(@src());10842 const tracy = trace(@src());
10735 defer tracy.end();10843 defer tracy.end();
1073610844
10737 const mod = sema.mod;10845 const pt = sema.pt;
10846 const mod = pt.zcu;
10738 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;10847 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
10739 const src = block.nodeOffset(inst_data.src_node);10848 const src = block.nodeOffset(inst_data.src_node);
10740 const extra = sema.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data;10849 const extra = sema.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data;
10741 const array_ptr = try sema.resolveInst(extra.ptr);10850 const array_ptr = try sema.resolveInst(extra.ptr);
10742 const elem_index = try sema.mod.intRef(Type.usize, extra.index);10851 const elem_index = try pt.intRef(Type.usize, extra.index);
10743 const array_ty = sema.typeOf(array_ptr).childType(mod);10852 const array_ty = sema.typeOf(array_ptr).childType(mod);
10744 switch (array_ty.zigTypeTag(mod)) {10853 switch (array_ty.zigTypeTag(mod)) {
10745 .Array, .Vector => {},10854 .Array, .Vector => {},
...@@ -10892,7 +11001,7 @@ const SwitchProngAnalysis = struct {...@@ -10892,7 +11001,7 @@ const SwitchProngAnalysis = struct {
10892 inline_case_capture,11001 inline_case_capture,
10893 );11002 );
1089411003
10895 if (sema.typeOf(capture_ref).isNoReturn(sema.mod)) {11004 if (sema.typeOf(capture_ref).isNoReturn(sema.pt.zcu)) {
10896 // This prong should be unreachable!11005 // This prong should be unreachable!
10897 return .unreachable_value;11006 return .unreachable_value;
10898 }11007 }
...@@ -10948,7 +11057,7 @@ const SwitchProngAnalysis = struct {...@@ -10948,7 +11057,7 @@ const SwitchProngAnalysis = struct {
10948 inline_case_capture,11057 inline_case_capture,
10949 );11058 );
1095011059
10951 if (sema.typeOf(capture_ref).isNoReturn(sema.mod)) {11060 if (sema.typeOf(capture_ref).isNoReturn(sema.pt.zcu)) {
10952 // No need to analyze any further, the prong is unreachable11061 // No need to analyze any further, the prong is unreachable
10953 return;11062 return;
10954 }11063 }
...@@ -10968,7 +11077,8 @@ const SwitchProngAnalysis = struct {...@@ -10968,7 +11077,8 @@ const SwitchProngAnalysis = struct {
10968 inline_case_capture: Air.Inst.Ref,11077 inline_case_capture: Air.Inst.Ref,
10969 ) CompileError!Air.Inst.Ref {11078 ) CompileError!Air.Inst.Ref {
10970 const sema = spa.sema;11079 const sema = spa.sema;
10971 const mod = sema.mod;11080 const pt = sema.pt;
11081 const mod = pt.zcu;
10972 const operand_ty = sema.typeOf(spa.operand);11082 const operand_ty = sema.typeOf(spa.operand);
10973 if (operand_ty.zigTypeTag(mod) != .Union) {11083 if (operand_ty.zigTypeTag(mod) != .Union) {
10974 const tag_capture_src: LazySrcLoc = .{11084 const tag_capture_src: LazySrcLoc = .{
...@@ -10976,7 +11086,7 @@ const SwitchProngAnalysis = struct {...@@ -10976,7 +11086,7 @@ const SwitchProngAnalysis = struct {
10976 .offset = .{ .switch_tag_capture = capture_src.offset.switch_capture },11086 .offset = .{ .switch_tag_capture = capture_src.offset.switch_capture },
10977 };11087 };
10978 return sema.fail(block, tag_capture_src, "cannot capture tag of non-union type '{}'", .{11088 return sema.fail(block, tag_capture_src, "cannot capture tag of non-union type '{}'", .{
10979 operand_ty.fmt(mod),11089 operand_ty.fmt(pt),
10980 });11090 });
10981 }11091 }
10982 assert(inline_case_capture != .none);11092 assert(inline_case_capture != .none);
...@@ -10993,7 +11103,8 @@ const SwitchProngAnalysis = struct {...@@ -10993,7 +11103,8 @@ const SwitchProngAnalysis = struct {
10993 inline_case_capture: Air.Inst.Ref,11103 inline_case_capture: Air.Inst.Ref,
10994 ) CompileError!Air.Inst.Ref {11104 ) CompileError!Air.Inst.Ref {
10995 const sema = spa.sema;11105 const sema = spa.sema;
10996 const zcu = sema.mod;11106 const pt = sema.pt;
11107 const zcu = pt.zcu;
10997 const ip = &zcu.intern_pool;11108 const ip = &zcu.intern_pool;
1099811109
10999 const zir_datas = sema.code.instructions.items(.data);11110 const zir_datas = sema.code.instructions.items(.data);
...@@ -11010,7 +11121,7 @@ const SwitchProngAnalysis = struct {...@@ -11010,7 +11121,7 @@ const SwitchProngAnalysis = struct {
11010 const union_obj = zcu.typeToUnion(operand_ty).?;11121 const union_obj = zcu.typeToUnion(operand_ty).?;
11011 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);11122 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
11012 if (capture_byref) {11123 if (capture_byref) {
11013 const ptr_field_ty = try zcu.ptrTypeSema(.{11124 const ptr_field_ty = try pt.ptrTypeSema(.{
11014 .child = field_ty.toIntern(),11125 .child = field_ty.toIntern(),
11015 .flags = .{11126 .flags = .{
11016 .is_const = !operand_ptr_ty.ptrIsMutable(zcu),11127 .is_const = !operand_ptr_ty.ptrIsMutable(zcu),
...@@ -11019,7 +11130,7 @@ const SwitchProngAnalysis = struct {...@@ -11019,7 +11130,7 @@ const SwitchProngAnalysis = struct {
11019 },11130 },
11020 });11131 });
11021 if (try sema.resolveDefinedValue(block, operand_src, spa.operand_ptr)) |union_ptr| {11132 if (try sema.resolveDefinedValue(block, operand_src, spa.operand_ptr)) |union_ptr| {
11022 return Air.internedToRef((try union_ptr.ptrField(field_index, zcu)).toIntern());11133 return Air.internedToRef((try union_ptr.ptrField(field_index, pt)).toIntern());
11023 }11134 }
11024 return block.addStructFieldPtr(spa.operand_ptr, field_index, ptr_field_ty);11135 return block.addStructFieldPtr(spa.operand_ptr, field_index, ptr_field_ty);
11025 } else {11136 } else {
...@@ -11078,7 +11189,7 @@ const SwitchProngAnalysis = struct {...@@ -11078,7 +11189,7 @@ const SwitchProngAnalysis = struct {
11078 const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len);11189 const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len);
11079 for (dummy_captures, field_indices) |*dummy, field_idx| {11190 for (dummy_captures, field_indices) |*dummy, field_idx| {
11080 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]);11191 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]);
11081 dummy.* = try zcu.undefRef(field_ty);11192 dummy.* = try pt.undefRef(field_ty);
11082 }11193 }
1108311194
11084 const case_srcs = try sema.arena.alloc(?LazySrcLoc, case_vals.len);11195 const case_srcs = try sema.arena.alloc(?LazySrcLoc, case_vals.len);
...@@ -11113,7 +11224,7 @@ const SwitchProngAnalysis = struct {...@@ -11113,7 +11224,7 @@ const SwitchProngAnalysis = struct {
11113 const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len);11224 const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len);
11114 for (field_indices, dummy_captures) |field_idx, *dummy| {11225 for (field_indices, dummy_captures) |field_idx, *dummy| {
11115 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]);11226 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]);
11116 const field_ptr_ty = try zcu.ptrTypeSema(.{11227 const field_ptr_ty = try pt.ptrTypeSema(.{
11117 .child = field_ty.toIntern(),11228 .child = field_ty.toIntern(),
11118 .flags = .{11229 .flags = .{
11119 .is_const = operand_ptr_info.flags.is_const,11230 .is_const = operand_ptr_info.flags.is_const,
...@@ -11122,7 +11233,7 @@ const SwitchProngAnalysis = struct {...@@ -11122,7 +11233,7 @@ const SwitchProngAnalysis = struct {
11122 .alignment = union_obj.fieldAlign(ip, field_idx),11233 .alignment = union_obj.fieldAlign(ip, field_idx),
11123 },11234 },
11124 });11235 });
11125 dummy.* = try zcu.undefRef(field_ptr_ty);11236 dummy.* = try pt.undefRef(field_ptr_ty);
11126 }11237 }
11127 const case_srcs = try sema.arena.alloc(?LazySrcLoc, case_vals.len);11238 const case_srcs = try sema.arena.alloc(?LazySrcLoc, case_vals.len);
11128 for (case_srcs, 0..) |*case_src, i| {11239 for (case_srcs, 0..) |*case_src, i| {
...@@ -11148,9 +11259,9 @@ const SwitchProngAnalysis = struct {...@@ -11148,9 +11259,9 @@ const SwitchProngAnalysis = struct {
11148 };11259 };
1114911260
11150 if (try sema.resolveDefinedValue(block, operand_src, spa.operand_ptr)) |op_ptr_val| {11261 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);11262 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);11263 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());11264 return Air.internedToRef((try pt.getCoerced(field_ptr_val, capture_ptr_ty)).toIntern());
11154 }11265 }
1115511266
11156 try sema.requireRuntimeBlock(block, operand_src, null);11267 try sema.requireRuntimeBlock(block, operand_src, null);
...@@ -11158,9 +11269,9 @@ const SwitchProngAnalysis = struct {...@@ -11158,9 +11269,9 @@ const SwitchProngAnalysis = struct {
11158 }11269 }
1115911270
11160 if (try sema.resolveDefinedValue(block, operand_src, spa.operand)) |operand_val| {11271 if (try sema.resolveDefinedValue(block, operand_src, spa.operand)) |operand_val| {
11161 if (operand_val.isUndef(zcu)) return zcu.undefRef(capture_ty);11272 if (operand_val.isUndef(zcu)) return pt.undefRef(capture_ty);
11162 const union_val = ip.indexToKey(operand_val.toIntern()).un;11273 const union_val = ip.indexToKey(operand_val.toIntern()).un;
11163 if (Value.fromInterned(union_val.tag).isUndef(zcu)) return zcu.undefRef(capture_ty);11274 if (Value.fromInterned(union_val.tag).isUndef(zcu)) return pt.undefRef(capture_ty);
11164 const uncoerced = Air.internedToRef(union_val.val);11275 const uncoerced = Air.internedToRef(union_val.val);
11165 return sema.coerce(block, capture_ty, uncoerced, operand_src);11276 return sema.coerce(block, capture_ty, uncoerced, operand_src);
11166 }11277 }
...@@ -11304,7 +11415,7 @@ const SwitchProngAnalysis = struct {...@@ -11304,7 +11415,7 @@ const SwitchProngAnalysis = struct {
1130411415
11305 if (case_vals.len == 1) {11416 if (case_vals.len == 1) {
11306 const item_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, case_vals[0], undefined) catch unreachable;11417 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().?);11418 const item_ty = try pt.singleErrorSetType(item_val.getErrorName(zcu).unwrap().?);
11308 return sema.bitCast(block, item_ty, spa.operand, operand_src, null);11419 return sema.bitCast(block, item_ty, spa.operand, operand_src, null);
11309 }11420 }
1131011421
...@@ -11314,7 +11425,7 @@ const SwitchProngAnalysis = struct {...@@ -11314,7 +11425,7 @@ const SwitchProngAnalysis = struct {
11314 const err_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, err, undefined) catch unreachable;11425 const err_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, err, undefined) catch unreachable;
11315 names.putAssumeCapacityNoClobber(err_val.getErrorName(zcu).unwrap().?, {});11426 names.putAssumeCapacityNoClobber(err_val.getErrorName(zcu).unwrap().?, {});
11316 }11427 }
11317 const error_ty = try zcu.errorSetFromUnsortedNames(names.keys());11428 const error_ty = try pt.errorSetFromUnsortedNames(names.keys());
11318 return sema.bitCast(block, error_ty, spa.operand, operand_src, null);11429 return sema.bitCast(block, error_ty, spa.operand, operand_src, null);
11319 },11430 },
11320 else => {11431 else => {
...@@ -11336,7 +11447,8 @@ fn switchCond(...@@ -11336,7 +11447,8 @@ fn switchCond(
11336 src: LazySrcLoc,11447 src: LazySrcLoc,
11337 operand: Air.Inst.Ref,11448 operand: Air.Inst.Ref,
11338) CompileError!Air.Inst.Ref {11449) CompileError!Air.Inst.Ref {
11339 const mod = sema.mod;11450 const pt = sema.pt;
11451 const mod = pt.zcu;
11340 const operand_ty = sema.typeOf(operand);11452 const operand_ty = sema.typeOf(operand);
11341 switch (operand_ty.zigTypeTag(mod)) {11453 switch (operand_ty.zigTypeTag(mod)) {
11342 .Type,11454 .Type,
...@@ -11353,7 +11465,7 @@ fn switchCond(...@@ -11353,7 +11465,7 @@ fn switchCond(
11353 .Enum,11465 .Enum,
11354 => {11466 => {
11355 if (operand_ty.isSlice(mod)) {11467 if (operand_ty.isSlice(mod)) {
11356 return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(mod)});11468 return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(pt)});
11357 }11469 }
11358 if ((try sema.typeHasOnePossibleValue(operand_ty))) |opv| {11470 if ((try sema.typeHasOnePossibleValue(operand_ty))) |opv| {
11359 return Air.internedToRef(opv.toIntern());11471 return Air.internedToRef(opv.toIntern());
...@@ -11362,7 +11474,7 @@ fn switchCond(...@@ -11362,7 +11474,7 @@ fn switchCond(
11362 },11474 },
1136311475
11364 .Union => {11476 .Union => {
11365 try operand_ty.resolveFields(mod);11477 try operand_ty.resolveFields(pt);
11366 const enum_ty = operand_ty.unionTagType(mod) orelse {11478 const enum_ty = operand_ty.unionTagType(mod) orelse {
11367 const msg = msg: {11479 const msg = msg: {
11368 const msg = try sema.errMsg(src, "switch on union with no attached enum", .{});11480 const msg = try sema.errMsg(src, "switch on union with no attached enum", .{});
...@@ -11388,7 +11500,7 @@ fn switchCond(...@@ -11388,7 +11500,7 @@ fn switchCond(
11388 .Vector,11500 .Vector,
11389 .Frame,11501 .Frame,
11390 .AnyFrame,11502 .AnyFrame,
11391 => return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(mod)}),11503 => return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(pt)}),
11392 }11504 }
11393}11505}
1139411506
...@@ -11398,7 +11510,8 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp...@@ -11398,7 +11510,8 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
11398 const tracy = trace(@src());11510 const tracy = trace(@src());
11399 defer tracy.end();11511 defer tracy.end();
1140011512
11401 const mod = sema.mod;11513 const pt = sema.pt;
11514 const mod = pt.zcu;
11402 const gpa = sema.gpa;11515 const gpa = sema.gpa;
11403 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;11516 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
11404 const switch_src = block.nodeOffset(inst_data.src_node);11517 const switch_src = block.nodeOffset(inst_data.src_node);
...@@ -11489,7 +11602,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp...@@ -11489,7 +11602,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
1148911602
11490 if (operand_err_set.zigTypeTag(mod) != .ErrorUnion) {11603 if (operand_err_set.zigTypeTag(mod) != .ErrorUnion) {
11491 return sema.fail(block, switch_src, "expected error union type, found '{}'", .{11604 return sema.fail(block, switch_src, "expected error union type, found '{}'", .{
11492 operand_ty.fmt(mod),11605 operand_ty.fmt(pt),
11493 });11606 });
11494 }11607 }
1149511608
...@@ -11571,7 +11684,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp...@@ -11571,7 +11684,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
11571 if (operand_val.errorUnionIsPayload(mod)) {11684 if (operand_val.errorUnionIsPayload(mod)) {
11572 return sema.resolveBlockBody(block, main_operand_src, &child_block, non_error_case.body, inst, merges);11685 return sema.resolveBlockBody(block, main_operand_src, &child_block, non_error_case.body, inst, merges);
11573 } else {11686 } else {
11574 const err_val = Value.fromInterned(try mod.intern(.{11687 const err_val = Value.fromInterned(try pt.intern(.{
11575 .err = .{11688 .err = .{
11576 .ty = operand_err_set_ty.toIntern(),11689 .ty = operand_err_set_ty.toIntern(),
11577 .name = operand_val.getErrorName(mod).unwrap().?,11690 .name = operand_val.getErrorName(mod).unwrap().?,
...@@ -11708,7 +11821,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -11708,7 +11821,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
11708 const tracy = trace(@src());11821 const tracy = trace(@src());
11709 defer tracy.end();11822 defer tracy.end();
1171011823
11711 const mod = sema.mod;11824 const pt = sema.pt;
11825 const mod = pt.zcu;
11712 const gpa = sema.gpa;11826 const gpa = sema.gpa;
11713 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;11827 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
11714 const src = block.nodeOffset(inst_data.src_node);11828 const src = block.nodeOffset(inst_data.src_node);
...@@ -11783,7 +11897,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -11783,7 +11897,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
11783 // Duplicate checking variables later also used for `inline else`.11897 // Duplicate checking variables later also used for `inline else`.
11784 var seen_enum_fields: []?LazySrcLoc = &.{};11898 var seen_enum_fields: []?LazySrcLoc = &.{};
11785 var seen_errors = SwitchErrorSet.init(gpa);11899 var seen_errors = SwitchErrorSet.init(gpa);
11786 var range_set = RangeSet.init(gpa, mod);11900 var range_set = RangeSet.init(gpa, pt);
11787 var true_count: u8 = 0;11901 var true_count: u8 = 0;
11788 var false_count: u8 = 0;11902 var false_count: u8 = 0;
1178911903
...@@ -11924,7 +12038,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -11924,7 +12038,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
11924 operand_ty.srcLoc(mod),12038 operand_ty.srcLoc(mod),
11925 msg,12039 msg,
11926 "enum '{}' declared here",12040 "enum '{}' declared here",
11927 .{operand_ty.fmt(mod)},12041 .{operand_ty.fmt(pt)},
11928 );12042 );
11929 break :msg msg;12043 break :msg msg;
11930 };12044 };
...@@ -12030,8 +12144,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -12030,8 +12144,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
1203012144
12031 check_range: {12145 check_range: {
12032 if (operand_ty.zigTypeTag(mod) == .Int) {12146 if (operand_ty.zigTypeTag(mod) == .Int) {
12033 const min_int = try operand_ty.minInt(mod, operand_ty);12147 const min_int = try operand_ty.minInt(pt, operand_ty);
12034 const max_int = try operand_ty.maxInt(mod, operand_ty);12148 const max_int = try operand_ty.maxInt(pt, operand_ty);
12035 if (try range_set.spans(min_int.toIntern(), max_int.toIntern())) {12149 if (try range_set.spans(min_int.toIntern(), max_int.toIntern())) {
12036 if (special_prong == .@"else") {12150 if (special_prong == .@"else") {
12037 return sema.fail(12151 return sema.fail(
...@@ -12136,7 +12250,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -12136,7 +12250,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
12136 block,12250 block,
12137 src,12251 src,
12138 "else prong required when switching on type '{}'",12252 "else prong required when switching on type '{}'",
12139 .{operand_ty.fmt(mod)},12253 .{operand_ty.fmt(pt)},
12140 );12254 );
12141 }12255 }
1214212256
...@@ -12212,7 +12326,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -12212,7 +12326,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
12212 .ComptimeFloat,12326 .ComptimeFloat,
12213 .Float,12327 .Float,
12214 => return sema.fail(block, operand_src, "invalid switch operand type '{}'", .{12328 => return sema.fail(block, operand_src, "invalid switch operand type '{}'", .{
12215 operand_ty.fmt(mod),12329 operand_ty.fmt(pt),
12216 }),12330 }),
12217 }12331 }
1221812332
...@@ -12386,7 +12500,8 @@ fn analyzeSwitchRuntimeBlock(...@@ -12386,7 +12500,8 @@ fn analyzeSwitchRuntimeBlock(
12386 cond_dbg_node_index: Zir.Inst.Index,12500 cond_dbg_node_index: Zir.Inst.Index,
12387 allow_err_code_unwrap: bool,12501 allow_err_code_unwrap: bool,
12388) CompileError!Air.Inst.Ref {12502) CompileError!Air.Inst.Ref {
12389 const mod = sema.mod;12503 const pt = sema.pt;
12504 const mod = pt.zcu;
12390 const gpa = sema.gpa;12505 const gpa = sema.gpa;
12391 const ip = &mod.intern_pool;12506 const ip = &mod.intern_pool;
1239212507
...@@ -12496,9 +12611,9 @@ fn analyzeSwitchRuntimeBlock(...@@ -12496,9 +12611,9 @@ fn analyzeSwitchRuntimeBlock(
12496 var item = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item_first_ref, undefined) catch unreachable;12611 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;12612 const item_last = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item_last_ref, undefined) catch unreachable;
1249812613
12499 while (item.compareScalar(.lte, item_last, operand_ty, mod)) : ({12614 while (item.compareScalar(.lte, item_last, operand_ty, pt)) : ({
12500 // Previous validation has resolved any possible lazy values.12615 // 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) {12616 item = sema.intAddScalar(item, try pt.intValue(operand_ty, 1), operand_ty) catch |err| switch (err) {
12502 error.Overflow => unreachable,12617 error.Overflow => unreachable,
12503 else => |e| return e,12618 else => |e| return e,
12504 };12619 };
...@@ -12537,7 +12652,7 @@ fn analyzeSwitchRuntimeBlock(...@@ -12537,7 +12652,7 @@ fn analyzeSwitchRuntimeBlock(
12537 cases_extra.appendAssumeCapacity(@intFromEnum(item_ref));12652 cases_extra.appendAssumeCapacity(@intFromEnum(item_ref));
12538 cases_extra.appendSliceAssumeCapacity(@ptrCast(case_block.instructions.items));12653 cases_extra.appendSliceAssumeCapacity(@ptrCast(case_block.instructions.items));
1253912654
12540 if (item.compareScalar(.eq, item_last, operand_ty, mod)) break;12655 if (item.compareScalar(.eq, item_last, operand_ty, pt)) break;
12541 }12656 }
12542 }12657 }
1254312658
...@@ -12744,14 +12859,14 @@ fn analyzeSwitchRuntimeBlock(...@@ -12744,14 +12859,14 @@ fn analyzeSwitchRuntimeBlock(
12744 .Enum => {12859 .Enum => {
12745 if (operand_ty.isNonexhaustiveEnum(mod) and !union_originally) {12860 if (operand_ty.isNonexhaustiveEnum(mod) and !union_originally) {
12746 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{12861 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{
12747 operand_ty.fmt(mod),12862 operand_ty.fmt(pt),
12748 });12863 });
12749 }12864 }
12750 for (seen_enum_fields, 0..) |f, i| {12865 for (seen_enum_fields, 0..) |f, i| {
12751 if (f != null) continue;12866 if (f != null) continue;
12752 cases_len += 1;12867 cases_len += 1;
1275312868
12754 const item_val = try mod.enumValueFieldIndex(operand_ty, @intCast(i));12869 const item_val = try pt.enumValueFieldIndex(operand_ty, @intCast(i));
12755 const item_ref = Air.internedToRef(item_val.toIntern());12870 const item_ref = Air.internedToRef(item_val.toIntern());
1275612871
12757 case_block.instructions.shrinkRetainingCapacity(0);12872 case_block.instructions.shrinkRetainingCapacity(0);
...@@ -12793,7 +12908,7 @@ fn analyzeSwitchRuntimeBlock(...@@ -12793,7 +12908,7 @@ fn analyzeSwitchRuntimeBlock(
12793 .ErrorSet => {12908 .ErrorSet => {
12794 if (operand_ty.isAnyError(mod)) {12909 if (operand_ty.isAnyError(mod)) {
12795 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{12910 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{
12796 operand_ty.fmt(mod),12911 operand_ty.fmt(pt),
12797 });12912 });
12798 }12913 }
12799 const error_names = operand_ty.errorSetNames(mod);12914 const error_names = operand_ty.errorSetNames(mod);
...@@ -12802,7 +12917,7 @@ fn analyzeSwitchRuntimeBlock(...@@ -12802,7 +12917,7 @@ fn analyzeSwitchRuntimeBlock(
12802 if (seen_errors.contains(error_name)) continue;12917 if (seen_errors.contains(error_name)) continue;
12803 cases_len += 1;12918 cases_len += 1;
1280412919
12805 const item_val = try mod.intern(.{ .err = .{12920 const item_val = try pt.intern(.{ .err = .{
12806 .ty = operand_ty.toIntern(),12921 .ty = operand_ty.toIntern(),
12807 .name = error_name,12922 .name = error_name,
12808 } });12923 } });
...@@ -12930,7 +13045,7 @@ fn analyzeSwitchRuntimeBlock(...@@ -12930,7 +13045,7 @@ fn analyzeSwitchRuntimeBlock(
12930 }13045 }
12931 },13046 },
12932 else => return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{13047 else => return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{
12933 operand_ty.fmt(mod),13048 operand_ty.fmt(pt),
12934 }),13049 }),
12935 };13050 };
1293613051
...@@ -13051,7 +13166,7 @@ fn resolveSwitchComptime(...@@ -13051,7 +13166,7 @@ fn resolveSwitchComptime(
1305113166
13052 const item = case_vals.items[scalar_i];13167 const item = case_vals.items[scalar_i];
13053 const item_val = sema.resolveConstDefinedValue(child_block, LazySrcLoc.unneeded, item, undefined) catch unreachable;13168 const item_val = sema.resolveConstDefinedValue(child_block, LazySrcLoc.unneeded, item, undefined) catch unreachable;
13054 if (operand_val.eql(item_val, operand_ty, sema.mod)) {13169 if (operand_val.eql(item_val, operand_ty, sema.pt.zcu)) {
13055 if (err_set) try sema.maybeErrorUnwrapComptime(child_block, body, cond_operand);13170 if (err_set) try sema.maybeErrorUnwrapComptime(child_block, body, cond_operand);
13056 return spa.resolveProngComptime(13171 return spa.resolveProngComptime(
13057 child_block,13172 child_block,
...@@ -13088,7 +13203,7 @@ fn resolveSwitchComptime(...@@ -13088,7 +13203,7 @@ fn resolveSwitchComptime(
13088 for (items) |item| {13203 for (items) |item| {
13089 // Validation above ensured these will succeed.13204 // Validation above ensured these will succeed.
13090 const item_val = sema.resolveConstDefinedValue(child_block, LazySrcLoc.unneeded, item, undefined) catch unreachable;13205 const item_val = sema.resolveConstDefinedValue(child_block, LazySrcLoc.unneeded, item, undefined) catch unreachable;
13091 if (operand_val.eql(item_val, operand_ty, sema.mod)) {13206 if (operand_val.eql(item_val, operand_ty, sema.pt.zcu)) {
13092 if (err_set) try sema.maybeErrorUnwrapComptime(child_block, body, cond_operand);13207 if (err_set) try sema.maybeErrorUnwrapComptime(child_block, body, cond_operand);
13093 return spa.resolveProngComptime(13208 return spa.resolveProngComptime(
13094 child_block,13209 child_block,
...@@ -13162,7 +13277,7 @@ fn resolveSwitchComptime(...@@ -13162,7 +13277,7 @@ fn resolveSwitchComptime(
13162}13277}
1316313278
13164const RangeSetUnhandledIterator = struct {13279const RangeSetUnhandledIterator = struct {
13165 mod: *Module,13280 pt: Zcu.PerThread,
13166 cur: ?InternPool.Index,13281 cur: ?InternPool.Index,
13167 max: InternPool.Index,13282 max: InternPool.Index,
13168 range_i: usize,13283 range_i: usize,
...@@ -13172,13 +13287,13 @@ const RangeSetUnhandledIterator = struct {...@@ -13172,13 +13287,13 @@ const RangeSetUnhandledIterator = struct {
13172 const preallocated_limbs = math.big.int.calcTwosCompLimbCount(128);13287 const preallocated_limbs = math.big.int.calcTwosCompLimbCount(128);
1317313288
13174 fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator {13289 fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator {
13175 const mod = sema.mod;13290 const pt = sema.pt;
13176 const int_type = mod.intern_pool.indexToKey(ty.toIntern()).int_type;13291 const int_type = pt.zcu.intern_pool.indexToKey(ty.toIntern()).int_type;
13177 const needed_limbs = math.big.int.calcTwosCompLimbCount(int_type.bits);13292 const needed_limbs = math.big.int.calcTwosCompLimbCount(int_type.bits);
13178 return .{13293 return .{
13179 .mod = mod,13294 .pt = pt,
13180 .cur = (try ty.minInt(mod, ty)).toIntern(),13295 .cur = (try ty.minInt(pt, ty)).toIntern(),
13181 .max = (try ty.maxInt(mod, ty)).toIntern(),13296 .max = (try ty.maxInt(pt, ty)).toIntern(),
13182 .range_i = 0,13297 .range_i = 0,
13183 .ranges = range_set.ranges.items,13298 .ranges = range_set.ranges.items,
13184 .limbs = if (needed_limbs > preallocated_limbs)13299 .limbs = if (needed_limbs > preallocated_limbs)
...@@ -13190,13 +13305,13 @@ const RangeSetUnhandledIterator = struct {...@@ -13190,13 +13305,13 @@ const RangeSetUnhandledIterator = struct {
1319013305
13191 fn addOne(it: *const RangeSetUnhandledIterator, val: InternPool.Index) !?InternPool.Index {13306 fn addOne(it: *const RangeSetUnhandledIterator, val: InternPool.Index) !?InternPool.Index {
13192 if (val == it.max) return null;13307 if (val == it.max) return null;
13193 const int = it.mod.intern_pool.indexToKey(val).int;13308 const int = it.pt.zcu.intern_pool.indexToKey(val).int;
1319413309
13195 switch (int.storage) {13310 switch (int.storage) {
13196 inline .u64, .i64 => |val_int| {13311 inline .u64, .i64 => |val_int| {
13197 const next_int = @addWithOverflow(val_int, 1);13312 const next_int = @addWithOverflow(val_int, 1);
13198 if (next_int[1] == 0)13313 if (next_int[1] == 0)
13199 return (try it.mod.intValue(Type.fromInterned(int.ty), next_int[0])).toIntern();13314 return (try it.pt.intValue(Type.fromInterned(int.ty), next_int[0])).toIntern();
13200 },13315 },
13201 .big_int => {},13316 .big_int => {},
13202 .lazy_align, .lazy_size => unreachable,13317 .lazy_align, .lazy_size => unreachable,
...@@ -13212,7 +13327,7 @@ const RangeSetUnhandledIterator = struct {...@@ -13212,7 +13327,7 @@ const RangeSetUnhandledIterator = struct {
13212 );13327 );
1321313328
13214 result_bigint.addScalar(val_bigint, 1);13329 result_bigint.addScalar(val_bigint, 1);
13215 return (try it.mod.intValue_big(Type.fromInterned(int.ty), result_bigint.toConst())).toIntern();13330 return (try it.pt.intValue_big(Type.fromInterned(int.ty), result_bigint.toConst())).toIntern();
13216 }13331 }
1321713332
13218 fn next(it: *RangeSetUnhandledIterator) !?InternPool.Index {13333 fn next(it: *RangeSetUnhandledIterator) !?InternPool.Index {
...@@ -13274,7 +13389,8 @@ fn validateErrSetSwitch(...@@ -13274,7 +13389,8 @@ fn validateErrSetSwitch(
13274 has_else: bool,13389 has_else: bool,
13275) CompileError!?Type {13390) CompileError!?Type {
13276 const gpa = sema.gpa;13391 const gpa = sema.gpa;
13277 const mod = sema.mod;13392 const pt = sema.pt;
13393 const mod = pt.zcu;
13278 const ip = &mod.intern_pool;13394 const ip = &mod.intern_pool;
1327913395
13280 const src_node_offset = inst_data.src_node;13396 const src_node_offset = inst_data.src_node;
...@@ -13426,7 +13542,7 @@ fn validateErrSetSwitch(...@@ -13426,7 +13542,7 @@ fn validateErrSetSwitch(
13426 }13542 }
13427 // No need to keep the hash map metadata correct; here we13543 // No need to keep the hash map metadata correct; here we
13428 // extract the (sorted) keys only.13544 // extract the (sorted) keys only.
13429 return try mod.errorSetFromUnsortedNames(names.keys());13545 return try pt.errorSetFromUnsortedNames(names.keys());
13430 },13546 },
13431 }13547 }
13432 return null;13548 return null;
...@@ -13441,7 +13557,6 @@ fn validateSwitchRange(...@@ -13441,7 +13557,6 @@ fn validateSwitchRange(
13441 operand_ty: Type,13557 operand_ty: Type,
13442 item_src: LazySrcLoc,13558 item_src: LazySrcLoc,
13443) CompileError![2]Air.Inst.Ref {13559) CompileError![2]Air.Inst.Ref {
13444 const mod = sema.mod;
13445 const first_src: LazySrcLoc = .{13560 const first_src: LazySrcLoc = .{
13446 .base_node_inst = item_src.base_node_inst,13561 .base_node_inst = item_src.base_node_inst,
13447 .offset = .{ .switch_case_item_range_first = item_src.offset.switch_case_item },13562 .offset = .{ .switch_case_item_range_first = item_src.offset.switch_case_item },
...@@ -13452,7 +13567,7 @@ fn validateSwitchRange(...@@ -13452,7 +13567,7 @@ fn validateSwitchRange(
13452 };13567 };
13453 const first = try sema.resolveSwitchItemVal(block, first_ref, operand_ty, first_src);13568 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);13569 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)) {13570 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", .{});13571 return sema.fail(block, item_src, "range start value is greater than the end value", .{});
13457 }13572 }
13458 const maybe_prev_src = try range_set.add(first.val, last.val, item_src);13573 const maybe_prev_src = try range_set.add(first.val, last.val, item_src);
...@@ -13483,7 +13598,7 @@ fn validateSwitchItemEnum(...@@ -13483,7 +13598,7 @@ fn validateSwitchItemEnum(
13483 operand_ty: Type,13598 operand_ty: Type,
13484 item_src: LazySrcLoc,13599 item_src: LazySrcLoc,
13485) CompileError!Air.Inst.Ref {13600) CompileError!Air.Inst.Ref {
13486 const ip = &sema.mod.intern_pool;13601 const ip = &sema.pt.zcu.intern_pool;
13487 const item = try sema.resolveSwitchItemVal(block, item_ref, operand_ty, item_src);13602 const item = try sema.resolveSwitchItemVal(block, item_ref, operand_ty, item_src);
13488 const int = ip.indexToKey(item.val).enum_tag.int;13603 const int = ip.indexToKey(item.val).enum_tag.int;
13489 const field_index = ip.loadEnumType(ip.typeOf(item.val)).tagValueIndex(ip, int) orelse {13604 const field_index = ip.loadEnumType(ip.typeOf(item.val)).tagValueIndex(ip, int) orelse {
...@@ -13505,9 +13620,8 @@ fn validateSwitchItemError(...@@ -13505,9 +13620,8 @@ fn validateSwitchItemError(
13505 operand_ty: Type,13620 operand_ty: Type,
13506 item_src: LazySrcLoc,13621 item_src: LazySrcLoc,
13507) CompileError!Air.Inst.Ref {13622) CompileError!Air.Inst.Ref {
13508 const ip = &sema.mod.intern_pool;
13509 const item = try sema.resolveSwitchItemVal(block, item_ref, operand_ty, item_src);13623 const item = try sema.resolveSwitchItemVal(block, item_ref, operand_ty, item_src);
13510 const error_name = ip.indexToKey(item.val).err.name;13624 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|13625 const maybe_prev_src = if (try seen_errors.fetchPut(error_name, item_src)) |prev|
13512 prev.value13626 prev.value
13513 else13627 else
...@@ -13593,7 +13707,7 @@ fn validateSwitchNoRange(...@@ -13593,7 +13707,7 @@ fn validateSwitchNoRange(
13593 const msg = try sema.errMsg(13707 const msg = try sema.errMsg(
13594 operand_src,13708 operand_src,
13595 "ranges not allowed when switching on type '{}'",13709 "ranges not allowed when switching on type '{}'",
13596 .{operand_ty.fmt(sema.mod)},13710 .{operand_ty.fmt(sema.pt)},
13597 );13711 );
13598 errdefer msg.destroy(sema.gpa);13712 errdefer msg.destroy(sema.gpa);
13599 try sema.errNote(13713 try sema.errNote(
...@@ -13615,7 +13729,8 @@ fn maybeErrorUnwrap(...@@ -13615,7 +13729,8 @@ fn maybeErrorUnwrap(
13615 operand_src: LazySrcLoc,13729 operand_src: LazySrcLoc,
13616 allow_err_code_inst: bool,13730 allow_err_code_inst: bool,
13617) !bool {13731) !bool {
13618 const mod = sema.mod;13732 const pt = sema.pt;
13733 const mod = pt.zcu;
13619 if (!mod.backendSupportsFeature(.panic_unwrap_error)) return false;13734 if (!mod.backendSupportsFeature(.panic_unwrap_error)) return false;
1362013735
13621 const tags = sema.code.instructions.items(.tag);13736 const tags = sema.code.instructions.items(.tag);
...@@ -13654,7 +13769,7 @@ fn maybeErrorUnwrap(...@@ -13654,7 +13769,7 @@ fn maybeErrorUnwrap(
13654 return true;13769 return true;
13655 }13770 }
1365613771
13657 const panic_fn = try mod.getBuiltin("panicUnwrapError");13772 const panic_fn = try pt.getBuiltin("panicUnwrapError");
13658 const err_return_trace = try sema.getErrorReturnTrace(block);13773 const err_return_trace = try sema.getErrorReturnTrace(block);
13659 const args: [2]Air.Inst.Ref = .{ err_return_trace, operand };13774 const args: [2]Air.Inst.Ref = .{ err_return_trace, operand };
13660 try sema.callBuiltin(block, operand_src, panic_fn, .auto, &args, .@"safety check");13775 try sema.callBuiltin(block, operand_src, panic_fn, .auto, &args, .@"safety check");
...@@ -13664,7 +13779,7 @@ fn maybeErrorUnwrap(...@@ -13664,7 +13779,7 @@ fn maybeErrorUnwrap(
13664 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;13779 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
13665 const msg_inst = try sema.resolveInst(inst_data.operand);13780 const msg_inst = try sema.resolveInst(inst_data.operand);
1366613781
13667 const panic_fn = try mod.getBuiltin("panic");13782 const panic_fn = try pt.getBuiltin("panic");
13668 const err_return_trace = try sema.getErrorReturnTrace(block);13783 const err_return_trace = try sema.getErrorReturnTrace(block);
13669 const args: [3]Air.Inst.Ref = .{ msg_inst, err_return_trace, .null_value };13784 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");13785 try sema.callBuiltin(block, operand_src, panic_fn, .auto, &args, .@"safety check");
...@@ -13680,7 +13795,8 @@ fn maybeErrorUnwrap(...@@ -13680,7 +13795,8 @@ fn maybeErrorUnwrap(
13680}13795}
1368113796
13682fn maybeErrorUnwrapCondbr(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, cond: Zir.Inst.Ref, cond_src: LazySrcLoc) !void {13797fn maybeErrorUnwrapCondbr(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, cond: Zir.Inst.Ref, cond_src: LazySrcLoc) !void {
13683 const mod = sema.mod;13798 const pt = sema.pt;
13799 const mod = pt.zcu;
13684 const index = cond.toIndex() orelse return;13800 const index = cond.toIndex() orelse return;
13685 if (sema.code.instructions.items(.tag)[@intFromEnum(index)] != .is_non_err) return;13801 if (sema.code.instructions.items(.tag)[@intFromEnum(index)] != .is_non_err) return;
1368613802
...@@ -13713,14 +13829,15 @@ fn maybeErrorUnwrapComptime(sema: *Sema, block: *Block, body: []const Zir.Inst.I...@@ -13713,14 +13829,15 @@ fn maybeErrorUnwrapComptime(sema: *Sema, block: *Block, body: []const Zir.Inst.I
13713 const src = block.nodeOffset(inst_data.src_node);13829 const src = block.nodeOffset(inst_data.src_node);
1371413830
13715 if (try sema.resolveDefinedValue(block, src, operand)) |val| {13831 if (try sema.resolveDefinedValue(block, src, operand)) |val| {
13716 if (val.getErrorName(sema.mod).unwrap()) |name| {13832 if (val.getErrorName(sema.pt.zcu).unwrap()) |name| {
13717 return sema.failWithComptimeErrorRetTrace(block, src, name);13833 return sema.failWithComptimeErrorRetTrace(block, src, name);
13718 }13834 }
13719 }13835 }
13720}13836}
1372113837
13722fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {13838fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13723 const mod = sema.mod;13839 const pt = sema.pt;
13840 const mod = pt.zcu;
13724 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;13841 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;13842 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
13726 const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);13843 const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);
...@@ -13729,7 +13846,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13729,7 +13846,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, .{13846 const field_name = try sema.resolveConstStringIntern(block, name_src, extra.rhs, .{
13730 .needed_comptime_reason = "field name must be comptime-known",13847 .needed_comptime_reason = "field name must be comptime-known",
13731 });13848 });
13732 try ty.resolveFields(mod);13849 try ty.resolveFields(pt);
13733 const ip = &mod.intern_pool;13850 const ip = &mod.intern_pool;
1373413851
13735 const has_field = hf: {13852 const has_field = hf: {
...@@ -13764,14 +13881,15 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13764,14 +13881,15 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13764 else => {},13881 else => {},
13765 }13882 }
13766 return sema.fail(block, ty_src, "type '{}' does not support '@hasField'", .{13883 return sema.fail(block, ty_src, "type '{}' does not support '@hasField'", .{
13767 ty.fmt(mod),13884 ty.fmt(pt),
13768 });13885 });
13769 };13886 };
13770 return if (has_field) .bool_true else .bool_false;13887 return if (has_field) .bool_true else .bool_false;
13771}13888}
1377213889
13773fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {13890fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13774 const mod = sema.mod;13891 const pt = sema.pt;
13892 const mod = pt.zcu;
13775 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;13893 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;13894 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
13777 const src = block.nodeOffset(inst_data.src_node);13895 const src = block.nodeOffset(inst_data.src_node);
...@@ -13804,7 +13922,8 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13804,7 +13922,8 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13804 const tracy = trace(@src());13922 const tracy = trace(@src());
13805 defer tracy.end();13923 defer tracy.end();
1380613924
13807 const zcu = sema.mod;13925 const pt = sema.pt;
13926 const zcu = pt.zcu;
13808 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;13927 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
13809 const operand_src = block.tokenOffset(inst_data.src_tok);13928 const operand_src = block.tokenOffset(inst_data.src_tok);
13810 const operand = inst_data.get(sema.code);13929 const operand = inst_data.get(sema.code);
...@@ -13824,7 +13943,7 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13824,7 +13943,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) });13943 return sema.fail(block, operand_src, "unable to open '{s}': {s}", .{ operand, @errorName(err) });
13825 },13944 },
13826 };13945 };
13827 try zcu.ensureFileAnalyzed(result.file_index);13946 try pt.ensureFileAnalyzed(result.file_index);
13828 const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?;13947 const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?;
13829 return sema.analyzeDeclVal(block, operand_src, file_root_decl_index);13948 return sema.analyzeDeclVal(block, operand_src, file_root_decl_index);
13830}13949}
...@@ -13833,7 +13952,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -13833,7 +13952,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
13833 const tracy = trace(@src());13952 const tracy = trace(@src());
13834 defer tracy.end();13953 defer tracy.end();
1383513954
13836 const mod = sema.mod;13955 const pt = sema.pt;
13837 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;13956 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
13838 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);13957 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
13839 const name = try sema.resolveConstString(block, operand_src, inst_data.operand, .{13958 const name = try sema.resolveConstString(block, operand_src, inst_data.operand, .{
...@@ -13844,7 +13963,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -13844,7 +13963,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", .{});13963 return sema.fail(block, operand_src, "file path name cannot be empty", .{});
13845 }13964 }
1384613965
13847 const val = mod.embedFile(block.getFileScope(mod), name, operand_src) catch |err| switch (err) {13966 const val = pt.embedFile(block.getFileScope(pt.zcu), name, operand_src) catch |err| switch (err) {
13848 error.ImportOutsideModulePath => {13967 error.ImportOutsideModulePath => {
13849 return sema.fail(block, operand_src, "embed of file outside package path: '{s}'", .{name});13968 return sema.fail(block, operand_src, "embed of file outside package path: '{s}'", .{name});
13850 },13969 },
...@@ -13859,7 +13978,8 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -13859,7 +13978,8 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
13859}13978}
1386013979
13861fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {13980fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13862 const mod = sema.mod;13981 const pt = sema.pt;
13982 const mod = pt.zcu;
13863 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;13983 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
13864 const name = try mod.intern_pool.getOrPutString(13984 const name = try mod.intern_pool.getOrPutString(
13865 sema.gpa,13985 sema.gpa,
...@@ -13867,8 +13987,8 @@ fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.R...@@ -13867,8 +13987,8 @@ fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.R
13867 .no_embedded_nulls,13987 .no_embedded_nulls,
13868 );13988 );
13869 _ = try mod.getErrorValue(name);13989 _ = try mod.getErrorValue(name);
13870 const error_set_type = try mod.singleErrorSetType(name);13990 const error_set_type = try pt.singleErrorSetType(name);
13871 return Air.internedToRef((try mod.intern(.{ .err = .{13991 return Air.internedToRef((try pt.intern(.{ .err = .{
13872 .ty = error_set_type.toIntern(),13992 .ty = error_set_type.toIntern(),
13873 .name = name,13993 .name = name,
13874 } })));13994 } })));
...@@ -13883,7 +14003,8 @@ fn zirShl(...@@ -13883,7 +14003,8 @@ fn zirShl(
13883 const tracy = trace(@src());14003 const tracy = trace(@src());
13884 defer tracy.end();14004 defer tracy.end();
1388514005
13886 const mod = sema.mod;14006 const pt = sema.pt;
14007 const mod = pt.zcu;
13887 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;14008 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
13888 const src = block.nodeOffset(inst_data.src_node);14009 const src = block.nodeOffset(inst_data.src_node);
13889 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });14010 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -13906,53 +14027,53 @@ fn zirShl(...@@ -13906,53 +14027,53 @@ fn zirShl(
1390614027
13907 if (maybe_rhs_val) |rhs_val| {14028 if (maybe_rhs_val) |rhs_val| {
13908 if (rhs_val.isUndef(mod)) {14029 if (rhs_val.isUndef(mod)) {
13909 return mod.undefRef(sema.typeOf(lhs));14030 return pt.undefRef(sema.typeOf(lhs));
13910 }14031 }
13911 // If rhs is 0, return lhs without doing any calculations.14032 // If rhs is 0, return lhs without doing any calculations.
13912 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {14033 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
13913 return lhs;14034 return lhs;
13914 }14035 }
13915 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt and air_tag != .shl_sat) {14036 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);14037 const bit_value = try pt.intValue(Type.comptime_int, scalar_ty.intInfo(mod).bits);
13917 if (rhs_ty.zigTypeTag(mod) == .Vector) {14038 if (rhs_ty.zigTypeTag(mod) == .Vector) {
13918 var i: usize = 0;14039 var i: usize = 0;
13919 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {14040 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {
13920 const rhs_elem = try rhs_val.elemValue(mod, i);14041 const rhs_elem = try rhs_val.elemValue(pt, i);
13921 if (rhs_elem.compareHetero(.gte, bit_value, mod)) {14042 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 '{}'", .{14043 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{
13923 rhs_elem.fmtValue(mod, sema),14044 rhs_elem.fmtValue(pt, sema),
13924 i,14045 i,
13925 scalar_ty.fmt(mod),14046 scalar_ty.fmt(pt),
13926 });14047 });
13927 }14048 }
13928 }14049 }
13929 } else if (rhs_val.compareHetero(.gte, bit_value, mod)) {14050 } else if (rhs_val.compareHetero(.gte, bit_value, pt)) {
13930 return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{14051 return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{
13931 rhs_val.fmtValue(mod, sema),14052 rhs_val.fmtValue(pt, sema),
13932 scalar_ty.fmt(mod),14053 scalar_ty.fmt(pt),
13933 });14054 });
13934 }14055 }
13935 }14056 }
13936 if (rhs_ty.zigTypeTag(mod) == .Vector) {14057 if (rhs_ty.zigTypeTag(mod) == .Vector) {
13937 var i: usize = 0;14058 var i: usize = 0;
13938 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {14059 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {
13939 const rhs_elem = try rhs_val.elemValue(mod, i);14060 const rhs_elem = try rhs_val.elemValue(pt, i);
13940 if (rhs_elem.compareHetero(.lt, try mod.intValue(scalar_rhs_ty, 0), mod)) {14061 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}'", .{14062 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
13942 rhs_elem.fmtValue(mod, sema),14063 rhs_elem.fmtValue(pt, sema),
13943 i,14064 i,
13944 });14065 });
13945 }14066 }
13946 }14067 }
13947 } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) {14068 } else if (rhs_val.compareHetero(.lt, try pt.intValue(rhs_ty, 0), pt)) {
13948 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{14069 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{
13949 rhs_val.fmtValue(mod, sema),14070 rhs_val.fmtValue(pt, sema),
13950 });14071 });
13951 }14072 }
13952 }14073 }
1395314074
13954 const runtime_src = if (maybe_lhs_val) |lhs_val| rs: {14075 const runtime_src = if (maybe_lhs_val) |lhs_val| rs: {
13955 if (lhs_val.isUndef(mod)) return mod.undefRef(lhs_ty);14076 if (lhs_val.isUndef(mod)) return pt.undefRef(lhs_ty);
13956 const rhs_val = maybe_rhs_val orelse {14077 const rhs_val = maybe_rhs_val orelse {
13957 if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) {14078 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", .{});14079 return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be comptime-known", .{});
...@@ -13960,17 +14081,17 @@ fn zirShl(...@@ -13960,17 +14081,17 @@ fn zirShl(
13960 break :rs rhs_src;14081 break :rs rhs_src;
13961 };14082 };
13962 const val = if (scalar_ty.zigTypeTag(mod) == .ComptimeInt)14083 const val = if (scalar_ty.zigTypeTag(mod) == .ComptimeInt)
13963 try lhs_val.shl(rhs_val, lhs_ty, sema.arena, mod)14084 try lhs_val.shl(rhs_val, lhs_ty, sema.arena, pt)
13964 else switch (air_tag) {14085 else switch (air_tag) {
13965 .shl_exact => val: {14086 .shl_exact => val: {
13966 const shifted = try lhs_val.shlWithOverflow(rhs_val, lhs_ty, sema.arena, mod);14087 const shifted = try lhs_val.shlWithOverflow(rhs_val, lhs_ty, sema.arena, pt);
13967 if (shifted.overflow_bit.compareAllWithZero(.eq, mod)) {14088 if (shifted.overflow_bit.compareAllWithZero(.eq, pt)) {
13968 break :val shifted.wrapped_result;14089 break :val shifted.wrapped_result;
13969 }14090 }
13970 return sema.fail(block, src, "operation caused overflow", .{});14091 return sema.fail(block, src, "operation caused overflow", .{});
13971 },14092 },
13972 .shl_sat => try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, mod),14093 .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),14094 .shl => try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, pt),
13974 else => unreachable,14095 else => unreachable,
13975 };14096 };
13976 return Air.internedToRef(val.toIntern());14097 return Air.internedToRef(val.toIntern());
...@@ -13981,7 +14102,7 @@ fn zirShl(...@@ -13981,7 +14102,7 @@ fn zirShl(
13981 if (rhs_is_comptime_int or14102 if (rhs_is_comptime_int or
13982 scalar_rhs_ty.intInfo(mod).bits > scalar_ty.intInfo(mod).bits)14103 scalar_rhs_ty.intInfo(mod).bits > scalar_ty.intInfo(mod).bits)
13983 {14104 {
13984 const max_int = Air.internedToRef((try lhs_ty.maxInt(mod, lhs_ty)).toIntern());14105 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 });14106 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);14107 break :rhs try sema.intCast(block, src, lhs_ty, rhs_src, rhs_limited, rhs_src, false);
13987 } else {14108 } else {
...@@ -13993,7 +14114,7 @@ fn zirShl(...@@ -13993,7 +14114,7 @@ fn zirShl(
13993 if (block.wantSafety()) {14114 if (block.wantSafety()) {
13994 const bit_count = scalar_ty.intInfo(mod).bits;14115 const bit_count = scalar_ty.intInfo(mod).bits;
13995 if (!std.math.isPowerOfTwo(bit_count)) {14116 if (!std.math.isPowerOfTwo(bit_count)) {
13996 const bit_count_val = try mod.intValue(scalar_rhs_ty, bit_count);14117 const bit_count_val = try pt.intValue(scalar_rhs_ty, bit_count);
13997 const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: {14118 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());14119 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);14120 const lt = try block.addCmpVector(rhs, bit_count_inst, .lt);
...@@ -14034,7 +14155,7 @@ fn zirShl(...@@ -14034,7 +14155,7 @@ fn zirShl(
14034 })14155 })
14035 else14156 else
14036 ov_bit;14157 ov_bit;
14037 const zero_ov = Air.internedToRef((try mod.intValue(Type.u1, 0)).toIntern());14158 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);14159 const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov);
1403914160
14040 try sema.addSafetyCheck(block, src, no_ov, .shl_overflow);14161 try sema.addSafetyCheck(block, src, no_ov, .shl_overflow);
...@@ -14053,7 +14174,8 @@ fn zirShr(...@@ -14053,7 +14174,8 @@ fn zirShr(
14053 const tracy = trace(@src());14174 const tracy = trace(@src());
14054 defer tracy.end();14175 defer tracy.end();
1405514176
14056 const mod = sema.mod;14177 const pt = sema.pt;
14178 const mod = pt.zcu;
14057 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;14179 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
14058 const src = block.nodeOffset(inst_data.src_node);14180 const src = block.nodeOffset(inst_data.src_node);
14059 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });14181 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -14071,61 +14193,61 @@ fn zirShr(...@@ -14071,61 +14193,61 @@ fn zirShr(
1407114193
14072 const runtime_src = if (maybe_rhs_val) |rhs_val| rs: {14194 const runtime_src = if (maybe_rhs_val) |rhs_val| rs: {
14073 if (rhs_val.isUndef(mod)) {14195 if (rhs_val.isUndef(mod)) {
14074 return mod.undefRef(lhs_ty);14196 return pt.undefRef(lhs_ty);
14075 }14197 }
14076 // If rhs is 0, return lhs without doing any calculations.14198 // If rhs is 0, return lhs without doing any calculations.
14077 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {14199 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
14078 return lhs;14200 return lhs;
14079 }14201 }
14080 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt) {14202 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt) {
14081 const bit_value = try mod.intValue(Type.comptime_int, scalar_ty.intInfo(mod).bits);14203 const bit_value = try pt.intValue(Type.comptime_int, scalar_ty.intInfo(mod).bits);
14082 if (rhs_ty.zigTypeTag(mod) == .Vector) {14204 if (rhs_ty.zigTypeTag(mod) == .Vector) {
14083 var i: usize = 0;14205 var i: usize = 0;
14084 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {14206 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {
14085 const rhs_elem = try rhs_val.elemValue(mod, i);14207 const rhs_elem = try rhs_val.elemValue(pt, i);
14086 if (rhs_elem.compareHetero(.gte, bit_value, mod)) {14208 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 '{}'", .{14209 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{
14088 rhs_elem.fmtValue(mod, sema),14210 rhs_elem.fmtValue(pt, sema),
14089 i,14211 i,
14090 scalar_ty.fmt(mod),14212 scalar_ty.fmt(pt),
14091 });14213 });
14092 }14214 }
14093 }14215 }
14094 } else if (rhs_val.compareHetero(.gte, bit_value, mod)) {14216 } else if (rhs_val.compareHetero(.gte, bit_value, pt)) {
14095 return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{14217 return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{
14096 rhs_val.fmtValue(mod, sema),14218 rhs_val.fmtValue(pt, sema),
14097 scalar_ty.fmt(mod),14219 scalar_ty.fmt(pt),
14098 });14220 });
14099 }14221 }
14100 }14222 }
14101 if (rhs_ty.zigTypeTag(mod) == .Vector) {14223 if (rhs_ty.zigTypeTag(mod) == .Vector) {
14102 var i: usize = 0;14224 var i: usize = 0;
14103 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {14225 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {
14104 const rhs_elem = try rhs_val.elemValue(mod, i);14226 const rhs_elem = try rhs_val.elemValue(pt, i);
14105 if (rhs_elem.compareHetero(.lt, try mod.intValue(rhs_ty.childType(mod), 0), mod)) {14227 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}'", .{14228 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
14107 rhs_elem.fmtValue(mod, sema),14229 rhs_elem.fmtValue(pt, sema),
14108 i,14230 i,
14109 });14231 });
14110 }14232 }
14111 }14233 }
14112 } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) {14234 } else if (rhs_val.compareHetero(.lt, try pt.intValue(rhs_ty, 0), pt)) {
14113 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{14235 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{
14114 rhs_val.fmtValue(mod, sema),14236 rhs_val.fmtValue(pt, sema),
14115 });14237 });
14116 }14238 }
14117 if (maybe_lhs_val) |lhs_val| {14239 if (maybe_lhs_val) |lhs_val| {
14118 if (lhs_val.isUndef(mod)) {14240 if (lhs_val.isUndef(mod)) {
14119 return mod.undefRef(lhs_ty);14241 return pt.undefRef(lhs_ty);
14120 }14242 }
14121 if (air_tag == .shr_exact) {14243 if (air_tag == .shr_exact) {
14122 // Detect if any ones would be shifted out.14244 // Detect if any ones would be shifted out.
14123 const truncated = try lhs_val.intTruncBitsAsValue(lhs_ty, sema.arena, .unsigned, rhs_val, mod);14245 const truncated = try lhs_val.intTruncBitsAsValue(lhs_ty, sema.arena, .unsigned, rhs_val, pt);
14124 if (!(try truncated.compareAllWithZeroSema(.eq, mod))) {14246 if (!(try truncated.compareAllWithZeroSema(.eq, pt))) {
14125 return sema.fail(block, src, "exact shift shifted out 1 bits", .{});14247 return sema.fail(block, src, "exact shift shifted out 1 bits", .{});
14126 }14248 }
14127 }14249 }
14128 const val = try lhs_val.shr(rhs_val, lhs_ty, sema.arena, mod);14250 const val = try lhs_val.shr(rhs_val, lhs_ty, sema.arena, pt);
14129 return Air.internedToRef(val.toIntern());14251 return Air.internedToRef(val.toIntern());
14130 } else {14252 } else {
14131 break :rs lhs_src;14253 break :rs lhs_src;
...@@ -14141,7 +14263,7 @@ fn zirShr(...@@ -14141,7 +14263,7 @@ fn zirShr(
14141 if (block.wantSafety()) {14263 if (block.wantSafety()) {
14142 const bit_count = scalar_ty.intInfo(mod).bits;14264 const bit_count = scalar_ty.intInfo(mod).bits;
14143 if (!std.math.isPowerOfTwo(bit_count)) {14265 if (!std.math.isPowerOfTwo(bit_count)) {
14144 const bit_count_val = try mod.intValue(rhs_ty.scalarType(mod), bit_count);14266 const bit_count_val = try pt.intValue(rhs_ty.scalarType(mod), bit_count);
1414514267
14146 const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: {14268 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());14269 const bit_count_inst = Air.internedToRef((try sema.splat(rhs_ty, bit_count_val)).toIntern());
...@@ -14188,7 +14310,8 @@ fn zirBitwise(...@@ -14188,7 +14310,8 @@ fn zirBitwise(
14188 const tracy = trace(@src());14310 const tracy = trace(@src());
14189 defer tracy.end();14311 defer tracy.end();
1419014312
14191 const mod = sema.mod;14313 const pt = sema.pt;
14314 const mod = pt.zcu;
14192 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;14315 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 });14316 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 });14317 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -14220,9 +14343,9 @@ fn zirBitwise(...@@ -14220,9 +14343,9 @@ fn zirBitwise(
14220 if (try sema.resolveValueIntable(casted_lhs)) |lhs_val| {14343 if (try sema.resolveValueIntable(casted_lhs)) |lhs_val| {
14221 if (try sema.resolveValueIntable(casted_rhs)) |rhs_val| {14344 if (try sema.resolveValueIntable(casted_rhs)) |rhs_val| {
14222 const result_val = switch (air_tag) {14345 const result_val = switch (air_tag) {
14223 .bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena, mod),14346 .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),14347 .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),14348 .xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena, pt),
14226 else => unreachable,14349 else => unreachable,
14227 };14350 };
14228 return Air.internedToRef(result_val.toIntern());14351 return Air.internedToRef(result_val.toIntern());
...@@ -14242,7 +14365,8 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14242,7 +14365,8 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
14242 const tracy = trace(@src());14365 const tracy = trace(@src());
14243 defer tracy.end();14366 defer tracy.end();
1424414367
14245 const mod = sema.mod;14368 const pt = sema.pt;
14369 const mod = pt.zcu;
14246 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;14370 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
14247 const src = block.nodeOffset(inst_data.src_node);14371 const src = block.nodeOffset(inst_data.src_node);
14248 const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });14372 const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
...@@ -14253,26 +14377,26 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14253,26 +14377,26 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1425314377
14254 if (scalar_type.zigTypeTag(mod) != .Int) {14378 if (scalar_type.zigTypeTag(mod) != .Int) {
14255 return sema.fail(block, src, "unable to perform binary not operation on type '{}'", .{14379 return sema.fail(block, src, "unable to perform binary not operation on type '{}'", .{
14256 operand_type.fmt(mod),14380 operand_type.fmt(pt),
14257 });14381 });
14258 }14382 }
1425914383
14260 if (try sema.resolveValue(operand)) |val| {14384 if (try sema.resolveValue(operand)) |val| {
14261 if (val.isUndef(mod)) {14385 if (val.isUndef(mod)) {
14262 return mod.undefRef(operand_type);14386 return pt.undefRef(operand_type);
14263 } else if (operand_type.zigTypeTag(mod) == .Vector) {14387 } else if (operand_type.zigTypeTag(mod) == .Vector) {
14264 const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen(mod));14388 const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen(mod));
14265 const elems = try sema.arena.alloc(InternPool.Index, vec_len);14389 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
14266 for (elems, 0..) |*elem, i| {14390 for (elems, 0..) |*elem, i| {
14267 const elem_val = try val.elemValue(mod, i);14391 const elem_val = try val.elemValue(pt, i);
14268 elem.* = (try elem_val.bitwiseNot(scalar_type, sema.arena, mod)).toIntern();14392 elem.* = (try elem_val.bitwiseNot(scalar_type, sema.arena, pt)).toIntern();
14269 }14393 }
14270 return Air.internedToRef((try mod.intern(.{ .aggregate = .{14394 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
14271 .ty = operand_type.toIntern(),14395 .ty = operand_type.toIntern(),
14272 .storage = .{ .elems = elems },14396 .storage = .{ .elems = elems },
14273 } })));14397 } })));
14274 } else {14398 } else {
14275 const result_val = try val.bitwiseNot(operand_type, sema.arena, mod);14399 const result_val = try val.bitwiseNot(operand_type, sema.arena, pt);
14276 return Air.internedToRef(result_val.toIntern());14400 return Air.internedToRef(result_val.toIntern());
14277 }14401 }
14278 }14402 }
...@@ -14288,7 +14412,8 @@ fn analyzeTupleCat(...@@ -14288,7 +14412,8 @@ fn analyzeTupleCat(
14288 lhs: Air.Inst.Ref,14412 lhs: Air.Inst.Ref,
14289 rhs: Air.Inst.Ref,14413 rhs: Air.Inst.Ref,
14290) CompileError!Air.Inst.Ref {14414) CompileError!Air.Inst.Ref {
14291 const mod = sema.mod;14415 const pt = sema.pt;
14416 const mod = pt.zcu;
14292 const lhs_ty = sema.typeOf(lhs);14417 const lhs_ty = sema.typeOf(lhs);
14293 const rhs_ty = sema.typeOf(rhs);14418 const rhs_ty = sema.typeOf(rhs);
14294 const src = block.nodeOffset(src_node);14419 const src = block.nodeOffset(src_node);
...@@ -14344,14 +14469,14 @@ fn analyzeTupleCat(...@@ -14344,14 +14469,14 @@ fn analyzeTupleCat(
14344 break :rs runtime_src;14469 break :rs runtime_src;
14345 };14470 };
1434614471
14347 const tuple_ty = try mod.intern_pool.getAnonStructType(mod.gpa, .{14472 const tuple_ty = try mod.intern_pool.getAnonStructType(mod.gpa, pt.tid, .{
14348 .types = types,14473 .types = types,
14349 .values = values,14474 .values = values,
14350 .names = &.{},14475 .names = &.{},
14351 });14476 });
1435214477
14353 const runtime_src = opt_runtime_src orelse {14478 const runtime_src = opt_runtime_src orelse {
14354 const tuple_val = try mod.intern(.{ .aggregate = .{14479 const tuple_val = try pt.intern(.{ .aggregate = .{
14355 .ty = tuple_ty,14480 .ty = tuple_ty,
14356 .storage = .{ .elems = values },14481 .storage = .{ .elems = values },
14357 } });14482 } });
...@@ -14386,7 +14511,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14386,7 +14511,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14386 const tracy = trace(@src());14511 const tracy = trace(@src());
14387 defer tracy.end();14512 defer tracy.end();
1438814513
14389 const mod = sema.mod;14514 const pt = sema.pt;
14515 const mod = pt.zcu;
14390 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;14516 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;14517 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
14392 const lhs = try sema.resolveInst(extra.lhs);14518 const lhs = try sema.resolveInst(extra.lhs);
...@@ -14406,11 +14532,11 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14406,11 +14532,11 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1440614532
14407 const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, rhs_ty) orelse lhs_info: {14533 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);14534 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)});14535 return sema.fail(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(pt)});
14410 };14536 };
14411 const rhs_info = try sema.getArrayCatInfo(block, rhs_src, rhs, lhs_ty) orelse {14537 const rhs_info = try sema.getArrayCatInfo(block, rhs_src, rhs, lhs_ty) orelse {
14412 assert(!rhs_is_tuple);14538 assert(!rhs_is_tuple);
14413 return sema.fail(block, rhs_src, "expected indexable; found '{}'", .{rhs_ty.fmt(mod)});14539 return sema.fail(block, rhs_src, "expected indexable; found '{}'", .{rhs_ty.fmt(pt)});
14414 };14540 };
1441514541
14416 const resolved_elem_ty = t: {14542 const resolved_elem_ty = t: {
...@@ -14472,7 +14598,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14472,7 +14598,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14472 ),14598 ),
14473 };14599 };
1447414600
14475 const result_ty = try mod.arrayType(.{14601 const result_ty = try pt.arrayType(.{
14476 .len = result_len,14602 .len = result_len,
14477 .sentinel = if (res_sent_val) |v| v.toIntern() else .none,14603 .sentinel = if (res_sent_val) |v| v.toIntern() else .none,
14478 .child = resolved_elem_ty.toIntern(),14604 .child = resolved_elem_ty.toIntern(),
...@@ -14512,7 +14638,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14512,7 +14638,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14512 while (elem_i < lhs_len) : (elem_i += 1) {14638 while (elem_i < lhs_len) : (elem_i += 1) {
14513 const lhs_elem_i = elem_i;14639 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";14640 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;14641 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());14642 const elem_val_inst = Air.internedToRef(elem_val.toIntern());
14517 const operand_src = block.src(.{ .array_cat_lhs = .{14643 const operand_src = block.src(.{ .array_cat_lhs = .{
14518 .array_cat_offset = inst_data.src_node,14644 .array_cat_offset = inst_data.src_node,
...@@ -14525,7 +14651,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14525,7 +14651,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14525 while (elem_i < result_len) : (elem_i += 1) {14651 while (elem_i < result_len) : (elem_i += 1) {
14526 const rhs_elem_i = elem_i - lhs_len;14652 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";14653 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;14654 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());14655 const elem_val_inst = Air.internedToRef(elem_val.toIntern());
14530 const operand_src = block.src(.{ .array_cat_rhs = .{14656 const operand_src = block.src(.{ .array_cat_rhs = .{
14531 .array_cat_offset = inst_data.src_node,14657 .array_cat_offset = inst_data.src_node,
...@@ -14535,7 +14661,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14535,7 +14661,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);14661 const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined);
14536 element_vals[elem_i] = coerced_elem_val.toIntern();14662 element_vals[elem_i] = coerced_elem_val.toIntern();
14537 }14663 }
14538 return sema.addConstantMaybeRef(try mod.intern(.{ .aggregate = .{14664 return sema.addConstantMaybeRef(try pt.intern(.{ .aggregate = .{
14539 .ty = result_ty.toIntern(),14665 .ty = result_ty.toIntern(),
14540 .storage = .{ .elems = element_vals },14666 .storage = .{ .elems = element_vals },
14541 } }), ptr_addrspace != null);14667 } }), ptr_addrspace != null);
...@@ -14545,19 +14671,19 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14545,19 +14671,19 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14545 try sema.requireRuntimeBlock(block, src, runtime_src);14671 try sema.requireRuntimeBlock(block, src, runtime_src);
1454614672
14547 if (ptr_addrspace) |ptr_as| {14673 if (ptr_addrspace) |ptr_as| {
14548 const alloc_ty = try mod.ptrTypeSema(.{14674 const alloc_ty = try pt.ptrTypeSema(.{
14549 .child = result_ty.toIntern(),14675 .child = result_ty.toIntern(),
14550 .flags = .{ .address_space = ptr_as },14676 .flags = .{ .address_space = ptr_as },
14551 });14677 });
14552 const alloc = try block.addTy(.alloc, alloc_ty);14678 const alloc = try block.addTy(.alloc, alloc_ty);
14553 const elem_ptr_ty = try mod.ptrTypeSema(.{14679 const elem_ptr_ty = try pt.ptrTypeSema(.{
14554 .child = resolved_elem_ty.toIntern(),14680 .child = resolved_elem_ty.toIntern(),
14555 .flags = .{ .address_space = ptr_as },14681 .flags = .{ .address_space = ptr_as },
14556 });14682 });
1455714683
14558 var elem_i: u32 = 0;14684 var elem_i: u32 = 0;
14559 while (elem_i < lhs_len) : (elem_i += 1) {14685 while (elem_i < lhs_len) : (elem_i += 1) {
14560 const elem_index = try mod.intRef(Type.usize, elem_i);14686 const elem_index = try pt.intRef(Type.usize, elem_i);
14561 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);14687 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);
14562 const operand_src = block.src(.{ .array_cat_lhs = .{14688 const operand_src = block.src(.{ .array_cat_lhs = .{
14563 .array_cat_offset = inst_data.src_node,14689 .array_cat_offset = inst_data.src_node,
...@@ -14568,8 +14694,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14568,8 +14694,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14568 }14694 }
14569 while (elem_i < result_len) : (elem_i += 1) {14695 while (elem_i < result_len) : (elem_i += 1) {
14570 const rhs_elem_i = elem_i - lhs_len;14696 const rhs_elem_i = elem_i - lhs_len;
14571 const elem_index = try mod.intRef(Type.usize, elem_i);14697 const elem_index = try pt.intRef(Type.usize, elem_i);
14572 const rhs_index = try mod.intRef(Type.usize, rhs_elem_i);14698 const rhs_index = try pt.intRef(Type.usize, rhs_elem_i);
14573 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);14699 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);
14574 const operand_src = block.src(.{ .array_cat_rhs = .{14700 const operand_src = block.src(.{ .array_cat_rhs = .{
14575 .array_cat_offset = inst_data.src_node,14701 .array_cat_offset = inst_data.src_node,
...@@ -14579,9 +14705,9 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14579,9 +14705,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);14705 try sema.storePtr2(block, src, elem_ptr, src, init, operand_src, .store);
14580 }14706 }
14581 if (res_sent_val) |sent_val| {14707 if (res_sent_val) |sent_val| {
14582 const elem_index = try mod.intRef(Type.usize, result_len);14708 const elem_index = try pt.intRef(Type.usize, result_len);
14583 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);14709 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());14710 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);14711 try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store);
14586 }14712 }
1458714713
...@@ -14592,7 +14718,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14592,7 +14718,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14592 {14718 {
14593 var elem_i: u32 = 0;14719 var elem_i: u32 = 0;
14594 while (elem_i < lhs_len) : (elem_i += 1) {14720 while (elem_i < lhs_len) : (elem_i += 1) {
14595 const index = try mod.intRef(Type.usize, elem_i);14721 const index = try pt.intRef(Type.usize, elem_i);
14596 const operand_src = block.src(.{ .array_cat_lhs = .{14722 const operand_src = block.src(.{ .array_cat_lhs = .{
14597 .array_cat_offset = inst_data.src_node,14723 .array_cat_offset = inst_data.src_node,
14598 .elem_index = elem_i,14724 .elem_index = elem_i,
...@@ -14602,7 +14728,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14602,7 +14728,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14602 }14728 }
14603 while (elem_i < result_len) : (elem_i += 1) {14729 while (elem_i < result_len) : (elem_i += 1) {
14604 const rhs_elem_i = elem_i - lhs_len;14730 const rhs_elem_i = elem_i - lhs_len;
14605 const index = try mod.intRef(Type.usize, rhs_elem_i);14731 const index = try pt.intRef(Type.usize, rhs_elem_i);
14606 const operand_src = block.src(.{ .array_cat_rhs = .{14732 const operand_src = block.src(.{ .array_cat_rhs = .{
14607 .array_cat_offset = inst_data.src_node,14733 .array_cat_offset = inst_data.src_node,
14608 .elem_index = @intCast(rhs_elem_i),14734 .elem_index = @intCast(rhs_elem_i),
...@@ -14616,7 +14742,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14616,7 +14742,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14616}14742}
1461714743
14618fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref, peer_ty: Type) !?Type.ArrayInfo {14744fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref, peer_ty: Type) !?Type.ArrayInfo {
14619 const mod = sema.mod;14745 const pt = sema.pt;
14746 const mod = pt.zcu;
14620 const operand_ty = sema.typeOf(operand);14747 const operand_ty = sema.typeOf(operand);
14621 switch (operand_ty.zigTypeTag(mod)) {14748 switch (operand_ty.zigTypeTag(mod)) {
14622 .Array => return operand_ty.arrayInfo(mod),14749 .Array => return operand_ty.arrayInfo(mod),
...@@ -14633,7 +14760,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins...@@ -14633,7 +14760,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
14633 .none => null,14760 .none => null,
14634 else => Value.fromInterned(ptr_info.sentinel),14761 else => Value.fromInterned(ptr_info.sentinel),
14635 },14762 },
14636 .len = try val.sliceLen(mod),14763 .len = try val.sliceLen(pt),
14637 };14764 };
14638 },14765 },
14639 .One => {14766 .One => {
...@@ -14666,7 +14793,8 @@ fn analyzeTupleMul(...@@ -14666,7 +14793,8 @@ fn analyzeTupleMul(
14666 operand: Air.Inst.Ref,14793 operand: Air.Inst.Ref,
14667 factor: usize,14794 factor: usize,
14668) CompileError!Air.Inst.Ref {14795) CompileError!Air.Inst.Ref {
14669 const mod = sema.mod;14796 const pt = sema.pt;
14797 const mod = pt.zcu;
14670 const operand_ty = sema.typeOf(operand);14798 const operand_ty = sema.typeOf(operand);
14671 const src = block.nodeOffset(src_node);14799 const src = block.nodeOffset(src_node);
14672 const len_src = block.src(.{ .node_offset_bin_rhs = src_node });14800 const len_src = block.src(.{ .node_offset_bin_rhs = src_node });
...@@ -14702,14 +14830,14 @@ fn analyzeTupleMul(...@@ -14702,14 +14830,14 @@ fn analyzeTupleMul(
14702 break :rs runtime_src;14830 break :rs runtime_src;
14703 };14831 };
1470414832
14705 const tuple_ty = try mod.intern_pool.getAnonStructType(mod.gpa, .{14833 const tuple_ty = try mod.intern_pool.getAnonStructType(mod.gpa, pt.tid, .{
14706 .types = types,14834 .types = types,
14707 .values = values,14835 .values = values,
14708 .names = &.{},14836 .names = &.{},
14709 });14837 });
1471014838
14711 const runtime_src = opt_runtime_src orelse {14839 const runtime_src = opt_runtime_src orelse {
14712 const tuple_val = try mod.intern(.{ .aggregate = .{14840 const tuple_val = try pt.intern(.{ .aggregate = .{
14713 .ty = tuple_ty,14841 .ty = tuple_ty,
14714 .storage = .{ .elems = values },14842 .storage = .{ .elems = values },
14715 } });14843 } });
...@@ -14739,7 +14867,8 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14739,7 +14867,8 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14739 const tracy = trace(@src());14867 const tracy = trace(@src());
14740 defer tracy.end();14868 defer tracy.end();
1474114869
14742 const mod = sema.mod;14870 const pt = sema.pt;
14871 const mod = pt.zcu;
14743 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;14872 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;14873 const extra = sema.code.extraData(Zir.Inst.ArrayMul, inst_data.payload_index).data;
14745 const uncoerced_lhs = try sema.resolveInst(extra.lhs);14874 const uncoerced_lhs = try sema.resolveInst(extra.lhs);
...@@ -14762,12 +14891,12 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14762,12 +14891,12 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14762 const lhs_len = uncoerced_lhs_ty.structFieldCount(mod);14891 const lhs_len = uncoerced_lhs_ty.structFieldCount(mod);
14763 const lhs_dest_ty = switch (res_ty.zigTypeTag(mod)) {14892 const lhs_dest_ty = switch (res_ty.zigTypeTag(mod)) {
14764 else => break :no_coerce,14893 else => break :no_coerce,
14765 .Array => try mod.arrayType(.{14894 .Array => try pt.arrayType(.{
14766 .child = res_ty.childType(mod).toIntern(),14895 .child = res_ty.childType(mod).toIntern(),
14767 .len = lhs_len,14896 .len = lhs_len,
14768 .sentinel = if (res_ty.sentinel(mod)) |s| s.toIntern() else .none,14897 .sentinel = if (res_ty.sentinel(mod)) |s| s.toIntern() else .none,
14769 }),14898 }),
14770 .Vector => try mod.vectorType(.{14899 .Vector => try pt.vectorType(.{
14771 .child = res_ty.childType(mod).toIntern(),14900 .child = res_ty.childType(mod).toIntern(),
14772 .len = lhs_len,14901 .len = lhs_len,
14773 }),14902 }),
...@@ -14796,7 +14925,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14796,7 +14925,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 exponentiation14925 // 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 {14926 const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, lhs_ty) orelse {
14798 const msg = msg: {14927 const msg = msg: {
14799 const msg = try sema.errMsg(lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(mod)});14928 const msg = try sema.errMsg(lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(pt)});
14800 errdefer msg.destroy(sema.gpa);14929 errdefer msg.destroy(sema.gpa);
14801 switch (lhs_ty.zigTypeTag(mod)) {14930 switch (lhs_ty.zigTypeTag(mod)) {
14802 .Int, .Float, .ComptimeFloat, .ComptimeInt, .Vector => {14931 .Int, .Float, .ComptimeFloat, .ComptimeInt, .Vector => {
...@@ -14818,7 +14947,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14818,7 +14947,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14818 return sema.fail(block, rhs_src, "operation results in overflow", .{});14947 return sema.fail(block, rhs_src, "operation results in overflow", .{});
14819 const result_len = try sema.usizeCast(block, src, result_len_u64);14948 const result_len = try sema.usizeCast(block, src, result_len_u64);
1482014949
14821 const result_ty = try mod.arrayType(.{14950 const result_ty = try pt.arrayType(.{
14822 .len = result_len,14951 .len = result_len,
14823 .sentinel = if (lhs_info.sentinel) |s| s.toIntern() else .none,14952 .sentinel = if (lhs_info.sentinel) |s| s.toIntern() else .none,
14824 .child = lhs_info.elem_type.toIntern(),14953 .child = lhs_info.elem_type.toIntern(),
...@@ -14839,8 +14968,8 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14839,8 +14968,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, such14968 // Optimization for the common pattern of a single element repeated N times, such
14840 // as zero-filling a byte array.14969 // as zero-filling a byte array.
14841 if (lhs_len == 1 and lhs_info.sentinel == null) {14970 if (lhs_len == 1 and lhs_info.sentinel == null) {
14842 const elem_val = try lhs_sub_val.elemValue(mod, 0);14971 const elem_val = try lhs_sub_val.elemValue(pt, 0);
14843 break :v try mod.intern(.{ .aggregate = .{14972 break :v try pt.intern(.{ .aggregate = .{
14844 .ty = result_ty.toIntern(),14973 .ty = result_ty.toIntern(),
14845 .storage = .{ .repeated_elem = elem_val.toIntern() },14974 .storage = .{ .repeated_elem = elem_val.toIntern() },
14846 } });14975 } });
...@@ -14851,12 +14980,12 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14851,12 +14980,12 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14851 while (elem_i < result_len) {14980 while (elem_i < result_len) {
14852 var lhs_i: usize = 0;14981 var lhs_i: usize = 0;
14853 while (lhs_i < lhs_len) : (lhs_i += 1) {14982 while (lhs_i < lhs_len) : (lhs_i += 1) {
14854 const elem_val = try lhs_sub_val.elemValue(mod, lhs_i);14983 const elem_val = try lhs_sub_val.elemValue(pt, lhs_i);
14855 element_vals[elem_i] = elem_val.toIntern();14984 element_vals[elem_i] = elem_val.toIntern();
14856 elem_i += 1;14985 elem_i += 1;
14857 }14986 }
14858 }14987 }
14859 break :v try mod.intern(.{ .aggregate = .{14988 break :v try pt.intern(.{ .aggregate = .{
14860 .ty = result_ty.toIntern(),14989 .ty = result_ty.toIntern(),
14861 .storage = .{ .elems = element_vals },14990 .storage = .{ .elems = element_vals },
14862 } });14991 } });
...@@ -14870,17 +14999,17 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14870,17 +14999,17 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14870 // to get the same elem values.14999 // to get the same elem values.
14871 const lhs_vals = try sema.arena.alloc(Air.Inst.Ref, lhs_len);15000 const lhs_vals = try sema.arena.alloc(Air.Inst.Ref, lhs_len);
14872 for (lhs_vals, 0..) |*lhs_val, idx| {15001 for (lhs_vals, 0..) |*lhs_val, idx| {
14873 const idx_ref = try mod.intRef(Type.usize, idx);15002 const idx_ref = try pt.intRef(Type.usize, idx);
14874 lhs_val.* = try sema.elemVal(block, lhs_src, lhs, idx_ref, src, false);15003 lhs_val.* = try sema.elemVal(block, lhs_src, lhs, idx_ref, src, false);
14875 }15004 }
1487615005
14877 if (ptr_addrspace) |ptr_as| {15006 if (ptr_addrspace) |ptr_as| {
14878 const alloc_ty = try mod.ptrTypeSema(.{15007 const alloc_ty = try pt.ptrTypeSema(.{
14879 .child = result_ty.toIntern(),15008 .child = result_ty.toIntern(),
14880 .flags = .{ .address_space = ptr_as },15009 .flags = .{ .address_space = ptr_as },
14881 });15010 });
14882 const alloc = try block.addTy(.alloc, alloc_ty);15011 const alloc = try block.addTy(.alloc, alloc_ty);
14883 const elem_ptr_ty = try mod.ptrTypeSema(.{15012 const elem_ptr_ty = try pt.ptrTypeSema(.{
14884 .child = lhs_info.elem_type.toIntern(),15013 .child = lhs_info.elem_type.toIntern(),
14885 .flags = .{ .address_space = ptr_as },15014 .flags = .{ .address_space = ptr_as },
14886 });15015 });
...@@ -14888,14 +15017,14 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14888,14 +15017,14 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14888 var elem_i: usize = 0;15017 var elem_i: usize = 0;
14889 while (elem_i < result_len) {15018 while (elem_i < result_len) {
14890 for (lhs_vals) |lhs_val| {15019 for (lhs_vals) |lhs_val| {
14891 const elem_index = try mod.intRef(Type.usize, elem_i);15020 const elem_index = try pt.intRef(Type.usize, elem_i);
14892 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);15021 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);15022 try sema.storePtr2(block, src, elem_ptr, src, lhs_val, lhs_src, .store);
14894 elem_i += 1;15023 elem_i += 1;
14895 }15024 }
14896 }15025 }
14897 if (lhs_info.sentinel) |sent_val| {15026 if (lhs_info.sentinel) |sent_val| {
14898 const elem_index = try mod.intRef(Type.usize, result_len);15027 const elem_index = try pt.intRef(Type.usize, result_len);
14899 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);15028 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);
14900 const init = Air.internedToRef(sent_val.toIntern());15029 const init = Air.internedToRef(sent_val.toIntern());
14901 try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store);15030 try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store);
...@@ -14912,7 +15041,8 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14912,7 +15041,8 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14912}15041}
1491315042
14914fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15043fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
14915 const mod = sema.mod;15044 const pt = sema.pt;
15045 const mod = pt.zcu;
14916 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;15046 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
14917 const src = block.nodeOffset(inst_data.src_node);15047 const src = block.nodeOffset(inst_data.src_node);
14918 const lhs_src = src;15048 const lhs_src = src;
...@@ -14926,25 +15056,26 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14926,25 +15056,26 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
14926 .Int, .ComptimeInt, .Float, .ComptimeFloat => false,15056 .Int, .ComptimeInt, .Float, .ComptimeFloat => false,
14927 else => true,15057 else => true,
14928 }) {15058 }) {
14929 return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(mod)});15059 return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(pt)});
14930 }15060 }
1493115061
14932 if (rhs_scalar_ty.isAnyFloat()) {15062 if (rhs_scalar_ty.isAnyFloat()) {
14933 // We handle float negation here to ensure negative zero is represented in the bits.15063 // We handle float negation here to ensure negative zero is represented in the bits.
14934 if (try sema.resolveValue(rhs)) |rhs_val| {15064 if (try sema.resolveValue(rhs)) |rhs_val| {
14935 if (rhs_val.isUndef(mod)) return mod.undefRef(rhs_ty);15065 if (rhs_val.isUndef(mod)) return pt.undefRef(rhs_ty);
14936 return Air.internedToRef((try rhs_val.floatNeg(rhs_ty, sema.arena, mod)).toIntern());15066 return Air.internedToRef((try rhs_val.floatNeg(rhs_ty, sema.arena, pt)).toIntern());
14937 }15067 }
14938 try sema.requireRuntimeBlock(block, src, null);15068 try sema.requireRuntimeBlock(block, src, null);
14939 return block.addUnOp(if (block.float_mode == .optimized) .neg_optimized else .neg, rhs);15069 return block.addUnOp(if (block.float_mode == .optimized) .neg_optimized else .neg, rhs);
14940 }15070 }
1494115071
14942 const lhs = Air.internedToRef((try sema.splat(rhs_ty, try mod.intValue(rhs_scalar_ty, 0))).toIntern());15072 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);15073 return sema.analyzeArithmetic(block, .sub, lhs, rhs, src, lhs_src, rhs_src, true);
14944}15074}
1494515075
14946fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15076fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
14947 const mod = sema.mod;15077 const pt = sema.pt;
15078 const mod = pt.zcu;
14948 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;15079 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
14949 const src = block.nodeOffset(inst_data.src_node);15080 const src = block.nodeOffset(inst_data.src_node);
14950 const lhs_src = src;15081 const lhs_src = src;
...@@ -14956,10 +15087,10 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -14956,10 +15087,10 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1495615087
14957 switch (rhs_scalar_ty.zigTypeTag(mod)) {15088 switch (rhs_scalar_ty.zigTypeTag(mod)) {
14958 .Int, .ComptimeInt, .Float, .ComptimeFloat => {},15089 .Int, .ComptimeInt, .Float, .ComptimeFloat => {},
14959 else => return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(mod)}),15090 else => return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(pt)}),
14960 }15091 }
1496115092
14962 const lhs = Air.internedToRef((try sema.splat(rhs_ty, try mod.intValue(rhs_scalar_ty, 0))).toIntern());15093 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);15094 return sema.analyzeArithmetic(block, .subwrap, lhs, rhs, src, lhs_src, rhs_src, true);
14964}15095}
1496515096
...@@ -14985,7 +15116,8 @@ fn zirArithmetic(...@@ -14985,7 +15116,8 @@ fn zirArithmetic(
14985}15116}
1498615117
14987fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15118fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
14988 const mod = sema.mod;15119 const pt = sema.pt;
15120 const mod = pt.zcu;
14989 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;15121 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 });15122 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 });15123 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -15026,13 +15158,13 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15026,13 +15158,13 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15026 // If lhs % rhs is 0, it doesn't matter.15158 // If lhs % rhs is 0, it doesn't matter.
15027 const lhs_val = maybe_lhs_val orelse unreachable;15159 const lhs_val = maybe_lhs_val orelse unreachable;
15028 const rhs_val = maybe_rhs_val orelse unreachable;15160 const rhs_val = maybe_rhs_val orelse unreachable;
15029 const rem = lhs_val.floatRem(rhs_val, resolved_type, sema.arena, mod) catch unreachable;15161 const rem = lhs_val.floatRem(rhs_val, resolved_type, sema.arena, pt) catch unreachable;
15030 if (!rem.compareAllWithZero(.eq, mod)) {15162 if (!rem.compareAllWithZero(.eq, pt)) {
15031 return sema.fail(15163 return sema.fail(
15032 block,15164 block,
15033 src,15165 src,
15034 "ambiguous coercion of division operands '{}' and '{}'; non-zero remainder '{}'",15166 "ambiguous coercion of division operands '{}' and '{}'; non-zero remainder '{}'",
15035 .{ lhs_ty.fmt(mod), rhs_ty.fmt(mod), rem.fmtValue(mod, sema) },15167 .{ lhs_ty.fmt(pt), rhs_ty.fmt(pt), rem.fmtValue(pt, sema) },
15036 );15168 );
15037 }15169 }
15038 }15170 }
...@@ -15068,10 +15200,10 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15068,10 +15200,10 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15068 .Int, .ComptimeInt, .ComptimeFloat => {15200 .Int, .ComptimeInt, .ComptimeFloat => {
15069 if (maybe_lhs_val) |lhs_val| {15201 if (maybe_lhs_val) |lhs_val| {
15070 if (!lhs_val.isUndef(mod)) {15202 if (!lhs_val.isUndef(mod)) {
15071 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {15203 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) {
15072 const scalar_zero = switch (scalar_tag) {15204 const scalar_zero = switch (scalar_tag) {
15073 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),15205 .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0),
15074 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),15206 .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0),
15075 else => unreachable,15207 else => unreachable,
15076 };15208 };
15077 const zero_val = try sema.splat(resolved_type, scalar_zero);15209 const zero_val = try sema.splat(resolved_type, scalar_zero);
...@@ -15083,7 +15215,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15083,7 +15215,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15083 if (rhs_val.isUndef(mod)) {15215 if (rhs_val.isUndef(mod)) {
15084 return sema.failWithUseOfUndef(block, rhs_src);15216 return sema.failWithUseOfUndef(block, rhs_src);
15085 }15217 }
15086 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {15218 if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) {
15087 return sema.failWithDivideByZero(block, rhs_src);15219 return sema.failWithDivideByZero(block, rhs_src);
15088 }15220 }
15089 // TODO: if the RHS is one, return the LHS directly15221 // TODO: if the RHS is one, return the LHS directly
...@@ -15097,25 +15229,25 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15097,25 +15229,25 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15097 if (lhs_val.isUndef(mod)) {15229 if (lhs_val.isUndef(mod)) {
15098 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {15230 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {
15099 if (maybe_rhs_val) |rhs_val| {15231 if (maybe_rhs_val) |rhs_val| {
15100 if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) {15232 if (try sema.compareAll(rhs_val, .neq, try pt.intValue(resolved_type, -1), resolved_type)) {
15101 return mod.undefRef(resolved_type);15233 return pt.undefRef(resolved_type);
15102 }15234 }
15103 }15235 }
15104 return sema.failWithUseOfUndef(block, rhs_src);15236 return sema.failWithUseOfUndef(block, rhs_src);
15105 }15237 }
15106 return mod.undefRef(resolved_type);15238 return pt.undefRef(resolved_type);
15107 }15239 }
1510815240
15109 if (maybe_rhs_val) |rhs_val| {15241 if (maybe_rhs_val) |rhs_val| {
15110 if (is_int) {15242 if (is_int) {
15111 var overflow_idx: ?usize = null;15243 var overflow_idx: ?usize = null;
15112 const res = try lhs_val.intDiv(rhs_val, resolved_type, &overflow_idx, sema.arena, mod);15244 const res = try lhs_val.intDiv(rhs_val, resolved_type, &overflow_idx, sema.arena, pt);
15113 if (overflow_idx) |vec_idx| {15245 if (overflow_idx) |vec_idx| {
15114 return sema.failWithIntegerOverflow(block, src, resolved_type, res, vec_idx);15246 return sema.failWithIntegerOverflow(block, src, resolved_type, res, vec_idx);
15115 }15247 }
15116 return Air.internedToRef(res.toIntern());15248 return Air.internedToRef(res.toIntern());
15117 } else {15249 } else {
15118 return Air.internedToRef((try lhs_val.floatDiv(rhs_val, resolved_type, sema.arena, mod)).toIntern());15250 return Air.internedToRef((try lhs_val.floatDiv(rhs_val, resolved_type, sema.arena, pt)).toIntern());
15119 }15251 }
15120 } else {15252 } else {
15121 break :rs rhs_src;15253 break :rs rhs_src;
...@@ -15138,7 +15270,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15138,7 +15270,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15138 block,15270 block,
15139 src,15271 src,
15140 "division with '{}' and '{}': signed integers must use @divTrunc, @divFloor, or @divExact",15272 "division with '{}' and '{}': signed integers must use @divTrunc, @divFloor, or @divExact",
15141 .{ lhs_ty.fmt(mod), rhs_ty.fmt(mod) },15273 .{ lhs_ty.fmt(pt), rhs_ty.fmt(pt) },
15142 );15274 );
15143 }15275 }
15144 break :blk Air.Inst.Tag.div_trunc;15276 break :blk Air.Inst.Tag.div_trunc;
...@@ -15150,7 +15282,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15150,7 +15282,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15150}15282}
1515115283
15152fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15284fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15153 const mod = sema.mod;15285 const pt = sema.pt;
15286 const mod = pt.zcu;
15154 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;15287 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 });15288 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 });15289 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -15204,10 +15337,10 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15204,10 +15337,10 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15204 if (lhs_val.isUndef(mod)) {15337 if (lhs_val.isUndef(mod)) {
15205 return sema.failWithUseOfUndef(block, rhs_src);15338 return sema.failWithUseOfUndef(block, rhs_src);
15206 } else {15339 } else {
15207 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {15340 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) {
15208 const scalar_zero = switch (scalar_tag) {15341 const scalar_zero = switch (scalar_tag) {
15209 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),15342 .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0),
15210 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),15343 .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0),
15211 else => unreachable,15344 else => unreachable,
15212 };15345 };
15213 const zero_val = try sema.splat(resolved_type, scalar_zero);15346 const zero_val = try sema.splat(resolved_type, scalar_zero);
...@@ -15219,7 +15352,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15219,7 +15352,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15219 if (rhs_val.isUndef(mod)) {15352 if (rhs_val.isUndef(mod)) {
15220 return sema.failWithUseOfUndef(block, rhs_src);15353 return sema.failWithUseOfUndef(block, rhs_src);
15221 }15354 }
15222 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {15355 if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) {
15223 return sema.failWithDivideByZero(block, rhs_src);15356 return sema.failWithDivideByZero(block, rhs_src);
15224 }15357 }
15225 // TODO: if the RHS is one, return the LHS directly15358 // TODO: if the RHS is one, return the LHS directly
...@@ -15227,22 +15360,22 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15227,22 +15360,22 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15227 if (maybe_lhs_val) |lhs_val| {15360 if (maybe_lhs_val) |lhs_val| {
15228 if (maybe_rhs_val) |rhs_val| {15361 if (maybe_rhs_val) |rhs_val| {
15229 if (is_int) {15362 if (is_int) {
15230 const modulus_val = try lhs_val.intMod(rhs_val, resolved_type, sema.arena, mod);15363 const modulus_val = try lhs_val.intMod(rhs_val, resolved_type, sema.arena, pt);
15231 if (!(modulus_val.compareAllWithZero(.eq, mod))) {15364 if (!(modulus_val.compareAllWithZero(.eq, pt))) {
15232 return sema.fail(block, src, "exact division produced remainder", .{});15365 return sema.fail(block, src, "exact division produced remainder", .{});
15233 }15366 }
15234 var overflow_idx: ?usize = null;15367 var overflow_idx: ?usize = null;
15235 const res = try lhs_val.intDiv(rhs_val, resolved_type, &overflow_idx, sema.arena, mod);15368 const res = try lhs_val.intDiv(rhs_val, resolved_type, &overflow_idx, sema.arena, pt);
15236 if (overflow_idx) |vec_idx| {15369 if (overflow_idx) |vec_idx| {
15237 return sema.failWithIntegerOverflow(block, src, resolved_type, res, vec_idx);15370 return sema.failWithIntegerOverflow(block, src, resolved_type, res, vec_idx);
15238 }15371 }
15239 return Air.internedToRef(res.toIntern());15372 return Air.internedToRef(res.toIntern());
15240 } else {15373 } else {
15241 const modulus_val = try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, mod);15374 const modulus_val = try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, pt);
15242 if (!(modulus_val.compareAllWithZero(.eq, mod))) {15375 if (!(modulus_val.compareAllWithZero(.eq, pt))) {
15243 return sema.fail(block, src, "exact division produced remainder", .{});15376 return sema.fail(block, src, "exact division produced remainder", .{});
15244 }15377 }
15245 return Air.internedToRef((try lhs_val.floatDiv(rhs_val, resolved_type, sema.arena, mod)).toIntern());15378 return Air.internedToRef((try lhs_val.floatDiv(rhs_val, resolved_type, sema.arena, pt)).toIntern());
15246 }15379 }
15247 } else break :rs rhs_src;15380 } else break :rs rhs_src;
15248 } else break :rs lhs_src;15381 } else break :rs lhs_src;
...@@ -15286,8 +15419,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15286,8 +15419,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15286 const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs);15419 const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs);
1528715420
15288 const scalar_zero = switch (scalar_tag) {15421 const scalar_zero = switch (scalar_tag) {
15289 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),15422 .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0),
15290 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),15423 .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0),
15291 else => unreachable,15424 else => unreachable,
15292 };15425 };
15293 if (resolved_type.zigTypeTag(mod) == .Vector) {15426 if (resolved_type.zigTypeTag(mod) == .Vector) {
...@@ -15315,7 +15448,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15315,7 +15448,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15315}15448}
1531615449
15317fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15450fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15318 const mod = sema.mod;15451 const pt = sema.pt;
15452 const mod = pt.zcu;
15319 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;15453 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 });15454 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 });15455 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -15371,10 +15505,10 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15371,10 +15505,10 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15371 // If the lhs is undefined, result is undefined.15505 // If the lhs is undefined, result is undefined.
15372 if (maybe_lhs_val) |lhs_val| {15506 if (maybe_lhs_val) |lhs_val| {
15373 if (!lhs_val.isUndef(mod)) {15507 if (!lhs_val.isUndef(mod)) {
15374 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {15508 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) {
15375 const scalar_zero = switch (scalar_tag) {15509 const scalar_zero = switch (scalar_tag) {
15376 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),15510 .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0),
15377 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),15511 .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0),
15378 else => unreachable,15512 else => unreachable,
15379 };15513 };
15380 const zero_val = try sema.splat(resolved_type, scalar_zero);15514 const zero_val = try sema.splat(resolved_type, scalar_zero);
...@@ -15386,7 +15520,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15386,7 +15520,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15386 if (rhs_val.isUndef(mod)) {15520 if (rhs_val.isUndef(mod)) {
15387 return sema.failWithUseOfUndef(block, rhs_src);15521 return sema.failWithUseOfUndef(block, rhs_src);
15388 }15522 }
15389 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {15523 if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) {
15390 return sema.failWithDivideByZero(block, rhs_src);15524 return sema.failWithDivideByZero(block, rhs_src);
15391 }15525 }
15392 // TODO: if the RHS is one, return the LHS directly15526 // TODO: if the RHS is one, return the LHS directly
...@@ -15395,20 +15529,20 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15395,20 +15529,20 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15395 if (lhs_val.isUndef(mod)) {15529 if (lhs_val.isUndef(mod)) {
15396 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {15530 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {
15397 if (maybe_rhs_val) |rhs_val| {15531 if (maybe_rhs_val) |rhs_val| {
15398 if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) {15532 if (try sema.compareAll(rhs_val, .neq, try pt.intValue(resolved_type, -1), resolved_type)) {
15399 return mod.undefRef(resolved_type);15533 return pt.undefRef(resolved_type);
15400 }15534 }
15401 }15535 }
15402 return sema.failWithUseOfUndef(block, rhs_src);15536 return sema.failWithUseOfUndef(block, rhs_src);
15403 }15537 }
15404 return mod.undefRef(resolved_type);15538 return pt.undefRef(resolved_type);
15405 }15539 }
1540615540
15407 if (maybe_rhs_val) |rhs_val| {15541 if (maybe_rhs_val) |rhs_val| {
15408 if (is_int) {15542 if (is_int) {
15409 return Air.internedToRef((try lhs_val.intDivFloor(rhs_val, resolved_type, sema.arena, mod)).toIntern());15543 return Air.internedToRef((try lhs_val.intDivFloor(rhs_val, resolved_type, sema.arena, pt)).toIntern());
15410 } else {15544 } else {
15411 return Air.internedToRef((try lhs_val.floatDivFloor(rhs_val, resolved_type, sema.arena, mod)).toIntern());15545 return Air.internedToRef((try lhs_val.floatDivFloor(rhs_val, resolved_type, sema.arena, pt)).toIntern());
15412 }15546 }
15413 } else break :rs rhs_src;15547 } else break :rs rhs_src;
15414 } else break :rs lhs_src;15548 } else break :rs lhs_src;
...@@ -15425,7 +15559,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15425,7 +15559,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15425}15559}
1542615560
15427fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15561fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15428 const mod = sema.mod;15562 const pt = sema.pt;
15563 const mod = pt.zcu;
15429 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;15564 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 });15565 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 });15566 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -15481,10 +15616,10 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15481,10 +15616,10 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15481 // If the lhs is undefined, result is undefined.15616 // If the lhs is undefined, result is undefined.
15482 if (maybe_lhs_val) |lhs_val| {15617 if (maybe_lhs_val) |lhs_val| {
15483 if (!lhs_val.isUndef(mod)) {15618 if (!lhs_val.isUndef(mod)) {
15484 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {15619 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) {
15485 const scalar_zero = switch (scalar_tag) {15620 const scalar_zero = switch (scalar_tag) {
15486 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),15621 .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0),
15487 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),15622 .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0),
15488 else => unreachable,15623 else => unreachable,
15489 };15624 };
15490 const zero_val = try sema.splat(resolved_type, scalar_zero);15625 const zero_val = try sema.splat(resolved_type, scalar_zero);
...@@ -15496,7 +15631,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15496,7 +15631,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15496 if (rhs_val.isUndef(mod)) {15631 if (rhs_val.isUndef(mod)) {
15497 return sema.failWithUseOfUndef(block, rhs_src);15632 return sema.failWithUseOfUndef(block, rhs_src);
15498 }15633 }
15499 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {15634 if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) {
15500 return sema.failWithDivideByZero(block, rhs_src);15635 return sema.failWithDivideByZero(block, rhs_src);
15501 }15636 }
15502 }15637 }
...@@ -15504,25 +15639,25 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15504,25 +15639,25 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15504 if (lhs_val.isUndef(mod)) {15639 if (lhs_val.isUndef(mod)) {
15505 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {15640 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {
15506 if (maybe_rhs_val) |rhs_val| {15641 if (maybe_rhs_val) |rhs_val| {
15507 if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) {15642 if (try sema.compareAll(rhs_val, .neq, try pt.intValue(resolved_type, -1), resolved_type)) {
15508 return mod.undefRef(resolved_type);15643 return pt.undefRef(resolved_type);
15509 }15644 }
15510 }15645 }
15511 return sema.failWithUseOfUndef(block, rhs_src);15646 return sema.failWithUseOfUndef(block, rhs_src);
15512 }15647 }
15513 return mod.undefRef(resolved_type);15648 return pt.undefRef(resolved_type);
15514 }15649 }
1551515650
15516 if (maybe_rhs_val) |rhs_val| {15651 if (maybe_rhs_val) |rhs_val| {
15517 if (is_int) {15652 if (is_int) {
15518 var overflow_idx: ?usize = null;15653 var overflow_idx: ?usize = null;
15519 const res = try lhs_val.intDiv(rhs_val, resolved_type, &overflow_idx, sema.arena, mod);15654 const res = try lhs_val.intDiv(rhs_val, resolved_type, &overflow_idx, sema.arena, pt);
15520 if (overflow_idx) |vec_idx| {15655 if (overflow_idx) |vec_idx| {
15521 return sema.failWithIntegerOverflow(block, src, resolved_type, res, vec_idx);15656 return sema.failWithIntegerOverflow(block, src, resolved_type, res, vec_idx);
15522 }15657 }
15523 return Air.internedToRef(res.toIntern());15658 return Air.internedToRef(res.toIntern());
15524 } else {15659 } else {
15525 return Air.internedToRef((try lhs_val.floatDivTrunc(rhs_val, resolved_type, sema.arena, mod)).toIntern());15660 return Air.internedToRef((try lhs_val.floatDivTrunc(rhs_val, resolved_type, sema.arena, pt)).toIntern());
15526 }15661 }
15527 } else break :rs rhs_src;15662 } else break :rs rhs_src;
15528 } else break :rs lhs_src;15663 } else break :rs lhs_src;
...@@ -15550,7 +15685,8 @@ fn addDivIntOverflowSafety(...@@ -15550,7 +15685,8 @@ fn addDivIntOverflowSafety(
15550 casted_rhs: Air.Inst.Ref,15685 casted_rhs: Air.Inst.Ref,
15551 is_int: bool,15686 is_int: bool,
15552) CompileError!void {15687) CompileError!void {
15553 const mod = sema.mod;15688 const pt = sema.pt;
15689 const mod = pt.zcu;
15554 if (!is_int) return;15690 if (!is_int) return;
1555515691
15556 // If the LHS is unsigned, it cannot cause overflow.15692 // If the LHS is unsigned, it cannot cause overflow.
...@@ -15561,19 +15697,19 @@ fn addDivIntOverflowSafety(...@@ -15561,19 +15697,19 @@ fn addDivIntOverflowSafety(
15561 return;15697 return;
15562 }15698 }
1556315699
15564 const min_int = try resolved_type.minInt(mod, resolved_type);15700 const min_int = try resolved_type.minInt(pt, resolved_type);
15565 const neg_one_scalar = try mod.intValue(lhs_scalar_ty, -1);15701 const neg_one_scalar = try pt.intValue(lhs_scalar_ty, -1);
15566 const neg_one = try sema.splat(resolved_type, neg_one_scalar);15702 const neg_one = try sema.splat(resolved_type, neg_one_scalar);
1556715703
15568 // If the LHS is comptime-known to be not equal to the min int,15704 // If the LHS is comptime-known to be not equal to the min int,
15569 // no overflow is possible.15705 // no overflow is possible.
15570 if (maybe_lhs_val) |lhs_val| {15706 if (maybe_lhs_val) |lhs_val| {
15571 if (try lhs_val.compareAll(.neq, min_int, resolved_type, mod)) return;15707 if (try lhs_val.compareAll(.neq, min_int, resolved_type, pt)) return;
15572 }15708 }
1557315709
15574 // If the RHS is comptime-known to not be equal to -1, no overflow is possible.15710 // If the RHS is comptime-known to not be equal to -1, no overflow is possible.
15575 if (maybe_rhs_val) |rhs_val| {15711 if (maybe_rhs_val) |rhs_val| {
15576 if (try rhs_val.compareAll(.neq, neg_one, resolved_type, mod)) return;15712 if (try rhs_val.compareAll(.neq, neg_one, resolved_type, pt)) return;
15577 }15713 }
1557815714
15579 var ok: Air.Inst.Ref = .none;15715 var ok: Air.Inst.Ref = .none;
...@@ -15634,11 +15770,12 @@ fn addDivByZeroSafety(...@@ -15634,11 +15770,12 @@ fn addDivByZeroSafety(
15634 // emitted above.15770 // emitted above.
15635 if (maybe_rhs_val != null) return;15771 if (maybe_rhs_val != null) return;
1563615772
15637 const mod = sema.mod;15773 const pt = sema.pt;
15774 const mod = pt.zcu;
15638 const scalar_zero = if (is_int)15775 const scalar_zero = if (is_int)
15639 try mod.intValue(resolved_type.scalarType(mod), 0)15776 try pt.intValue(resolved_type.scalarType(mod), 0)
15640 else15777 else
15641 try mod.floatValue(resolved_type.scalarType(mod), 0.0);15778 try pt.floatValue(resolved_type.scalarType(mod), 0.0);
15642 const ok = if (resolved_type.zigTypeTag(mod) == .Vector) ok: {15779 const ok = if (resolved_type.zigTypeTag(mod) == .Vector) ok: {
15643 const zero_val = try sema.splat(resolved_type, scalar_zero);15780 const zero_val = try sema.splat(resolved_type, scalar_zero);
15644 const zero = Air.internedToRef(zero_val.toIntern());15781 const zero = Air.internedToRef(zero_val.toIntern());
...@@ -15666,7 +15803,8 @@ fn airTag(block: *Block, is_int: bool, normal: Air.Inst.Tag, optimized: Air.Inst...@@ -15666,7 +15803,8 @@ fn airTag(block: *Block, is_int: bool, normal: Air.Inst.Tag, optimized: Air.Inst
15666}15803}
1566715804
15668fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15805fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15669 const mod = sema.mod;15806 const pt = sema.pt;
15807 const mod = pt.zcu;
15670 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;15808 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 });15809 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 });15810 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -15721,16 +15859,16 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -15721,16 +15859,16 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
15721 if (lhs_val.isUndef(mod)) {15859 if (lhs_val.isUndef(mod)) {
15722 return sema.failWithUseOfUndef(block, lhs_src);15860 return sema.failWithUseOfUndef(block, lhs_src);
15723 }15861 }
15724 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {15862 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) {
15725 const scalar_zero = switch (scalar_tag) {15863 const scalar_zero = switch (scalar_tag) {
15726 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),15864 .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0),
15727 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),15865 .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0),
15728 else => unreachable,15866 else => unreachable,
15729 };15867 };
15730 const zero_val = if (is_vector) Value.fromInterned((try mod.intern(.{ .aggregate = .{15868 const zero_val = if (is_vector) Value.fromInterned(try pt.intern(.{ .aggregate = .{
15731 .ty = resolved_type.toIntern(),15869 .ty = resolved_type.toIntern(),
15732 .storage = .{ .repeated_elem = scalar_zero.toIntern() },15870 .storage = .{ .repeated_elem = scalar_zero.toIntern() },
15733 } }))) else scalar_zero;15871 } })) else scalar_zero;
15734 return Air.internedToRef(zero_val.toIntern());15872 return Air.internedToRef(zero_val.toIntern());
15735 }15873 }
15736 } else if (lhs_scalar_ty.isSignedInt(mod)) {15874 } else if (lhs_scalar_ty.isSignedInt(mod)) {
...@@ -15740,18 +15878,18 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -15740,18 +15878,18 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
15740 if (rhs_val.isUndef(mod)) {15878 if (rhs_val.isUndef(mod)) {
15741 return sema.failWithUseOfUndef(block, rhs_src);15879 return sema.failWithUseOfUndef(block, rhs_src);
15742 }15880 }
15743 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {15881 if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) {
15744 return sema.failWithDivideByZero(block, rhs_src);15882 return sema.failWithDivideByZero(block, rhs_src);
15745 }15883 }
15746 if (!(try rhs_val.compareAllWithZeroSema(.gte, mod))) {15884 if (!(try rhs_val.compareAllWithZeroSema(.gte, pt))) {
15747 return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty);15885 return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty);
15748 }15886 }
15749 if (maybe_lhs_val) |lhs_val| {15887 if (maybe_lhs_val) |lhs_val| {
15750 const rem_result = try sema.intRem(resolved_type, lhs_val, rhs_val);15888 const rem_result = try sema.intRem(resolved_type, lhs_val, rhs_val);
15751 // If this answer could possibly be different by doing `intMod`,15889 // If this answer could possibly be different by doing `intMod`,
15752 // we must emit a compile error. Otherwise, it's OK.15890 // we must emit a compile error. Otherwise, it's OK.
15753 if (!(try lhs_val.compareAllWithZeroSema(.gte, mod)) and15891 if (!(try lhs_val.compareAllWithZeroSema(.gte, pt)) and
15754 !(try rem_result.compareAllWithZeroSema(.eq, mod)))15892 !(try rem_result.compareAllWithZeroSema(.eq, pt)))
15755 {15893 {
15756 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);15894 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);
15757 }15895 }
...@@ -15769,17 +15907,17 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -15769,17 +15907,17 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
15769 if (rhs_val.isUndef(mod)) {15907 if (rhs_val.isUndef(mod)) {
15770 return sema.failWithUseOfUndef(block, rhs_src);15908 return sema.failWithUseOfUndef(block, rhs_src);
15771 }15909 }
15772 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {15910 if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) {
15773 return sema.failWithDivideByZero(block, rhs_src);15911 return sema.failWithDivideByZero(block, rhs_src);
15774 }15912 }
15775 if (!(try rhs_val.compareAllWithZeroSema(.gte, mod))) {15913 if (!(try rhs_val.compareAllWithZeroSema(.gte, pt))) {
15776 return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty);15914 return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty);
15777 }15915 }
15778 if (maybe_lhs_val) |lhs_val| {15916 if (maybe_lhs_val) |lhs_val| {
15779 if (lhs_val.isUndef(mod) or !(try lhs_val.compareAllWithZeroSema(.gte, mod))) {15917 if (lhs_val.isUndef(mod) or !(try lhs_val.compareAllWithZeroSema(.gte, pt))) {
15780 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);15918 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);
15781 }15919 }
15782 return Air.internedToRef((try lhs_val.floatRem(rhs_val, resolved_type, sema.arena, mod)).toIntern());15920 return Air.internedToRef((try lhs_val.floatRem(rhs_val, resolved_type, sema.arena, pt)).toIntern());
15783 } else {15921 } else {
15784 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);15922 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);
15785 }15923 }
...@@ -15804,31 +15942,32 @@ fn intRem(...@@ -15804,31 +15942,32 @@ fn intRem(
15804 lhs: Value,15942 lhs: Value,
15805 rhs: Value,15943 rhs: Value,
15806) CompileError!Value {15944) CompileError!Value {
15807 const mod = sema.mod;15945 const pt = sema.pt;
15946 const mod = pt.zcu;
15808 if (ty.zigTypeTag(mod) == .Vector) {15947 if (ty.zigTypeTag(mod) == .Vector) {
15809 const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod));15948 const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod));
15810 const scalar_ty = ty.scalarType(mod);15949 const scalar_ty = ty.scalarType(mod);
15811 for (result_data, 0..) |*scalar, i| {15950 for (result_data, 0..) |*scalar, i| {
15812 const lhs_elem = try lhs.elemValue(mod, i);15951 const lhs_elem = try lhs.elemValue(pt, i);
15813 const rhs_elem = try rhs.elemValue(mod, i);15952 const rhs_elem = try rhs.elemValue(pt, i);
15814 scalar.* = (try sema.intRemScalar(lhs_elem, rhs_elem, scalar_ty)).toIntern();15953 scalar.* = (try sema.intRemScalar(lhs_elem, rhs_elem, scalar_ty)).toIntern();
15815 }15954 }
15816 return Value.fromInterned((try mod.intern(.{ .aggregate = .{15955 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
15817 .ty = ty.toIntern(),15956 .ty = ty.toIntern(),
15818 .storage = .{ .elems = result_data },15957 .storage = .{ .elems = result_data },
15819 } })));15958 } }));
15820 }15959 }
15821 return sema.intRemScalar(lhs, rhs, ty);15960 return sema.intRemScalar(lhs, rhs, ty);
15822}15961}
1582315962
15824fn intRemScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) CompileError!Value {15963fn intRemScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) CompileError!Value {
15825 const mod = sema.mod;15964 const pt = sema.pt;
15826 // TODO is this a performance issue? maybe we should try the operation without15965 // TODO is this a performance issue? maybe we should try the operation without
15827 // resorting to BigInt first.15966 // resorting to BigInt first.
15828 var lhs_space: Value.BigIntSpace = undefined;15967 var lhs_space: Value.BigIntSpace = undefined;
15829 var rhs_space: Value.BigIntSpace = undefined;15968 var rhs_space: Value.BigIntSpace = undefined;
15830 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema);15969 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, pt, .sema);
15831 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema);15970 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, pt, .sema);
15832 const limbs_q = try sema.arena.alloc(15971 const limbs_q = try sema.arena.alloc(
15833 math.big.Limb,15972 math.big.Limb,
15834 lhs_bigint.limbs.len,15973 lhs_bigint.limbs.len,
...@@ -15846,11 +15985,12 @@ fn intRemScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) CompileErr...@@ -15846,11 +15985,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 };15985 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 };15986 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);15987 result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);
15849 return mod.intValue_big(scalar_ty, result_r.toConst());15988 return pt.intValue_big(scalar_ty, result_r.toConst());
15850}15989}
1585115990
15852fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15991fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15853 const mod = sema.mod;15992 const pt = sema.pt;
15993 const mod = pt.zcu;
15854 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;15994 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 });15995 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 });15996 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -15904,11 +16044,11 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15904,11 +16044,11 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15904 if (rhs_val.isUndef(mod)) {16044 if (rhs_val.isUndef(mod)) {
15905 return sema.failWithUseOfUndef(block, rhs_src);16045 return sema.failWithUseOfUndef(block, rhs_src);
15906 }16046 }
15907 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {16047 if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) {
15908 return sema.failWithDivideByZero(block, rhs_src);16048 return sema.failWithDivideByZero(block, rhs_src);
15909 }16049 }
15910 if (maybe_lhs_val) |lhs_val| {16050 if (maybe_lhs_val) |lhs_val| {
15911 return Air.internedToRef((try lhs_val.intMod(rhs_val, resolved_type, sema.arena, mod)).toIntern());16051 return Air.internedToRef((try lhs_val.intMod(rhs_val, resolved_type, sema.arena, pt)).toIntern());
15912 }16052 }
15913 break :rs lhs_src;16053 break :rs lhs_src;
15914 } else {16054 } else {
...@@ -15920,16 +16060,16 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15920,16 +16060,16 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15920 if (rhs_val.isUndef(mod)) {16060 if (rhs_val.isUndef(mod)) {
15921 return sema.failWithUseOfUndef(block, rhs_src);16061 return sema.failWithUseOfUndef(block, rhs_src);
15922 }16062 }
15923 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {16063 if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) {
15924 return sema.failWithDivideByZero(block, rhs_src);16064 return sema.failWithDivideByZero(block, rhs_src);
15925 }16065 }
15926 }16066 }
15927 if (maybe_lhs_val) |lhs_val| {16067 if (maybe_lhs_val) |lhs_val| {
15928 if (lhs_val.isUndef(mod)) {16068 if (lhs_val.isUndef(mod)) {
15929 return mod.undefRef(resolved_type);16069 return pt.undefRef(resolved_type);
15930 }16070 }
15931 if (maybe_rhs_val) |rhs_val| {16071 if (maybe_rhs_val) |rhs_val| {
15932 return Air.internedToRef((try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, mod)).toIntern());16072 return Air.internedToRef((try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, pt)).toIntern());
15933 } else break :rs rhs_src;16073 } else break :rs rhs_src;
15934 } else break :rs lhs_src;16074 } else break :rs lhs_src;
15935 };16075 };
...@@ -15945,7 +16085,8 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15945,7 +16085,8 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15945}16085}
1594616086
15947fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {16087fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15948 const mod = sema.mod;16088 const pt = sema.pt;
16089 const mod = pt.zcu;
15949 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;16090 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 });16091 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 });16092 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
...@@ -15999,7 +16140,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15999,7 +16140,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15999 if (rhs_val.isUndef(mod)) {16140 if (rhs_val.isUndef(mod)) {
16000 return sema.failWithUseOfUndef(block, rhs_src);16141 return sema.failWithUseOfUndef(block, rhs_src);
16001 }16142 }
16002 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {16143 if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) {
16003 return sema.failWithDivideByZero(block, rhs_src);16144 return sema.failWithDivideByZero(block, rhs_src);
16004 }16145 }
16005 if (maybe_lhs_val) |lhs_val| {16146 if (maybe_lhs_val) |lhs_val| {
...@@ -16015,16 +16156,16 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -16015,16 +16156,16 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
16015 if (rhs_val.isUndef(mod)) {16156 if (rhs_val.isUndef(mod)) {
16016 return sema.failWithUseOfUndef(block, rhs_src);16157 return sema.failWithUseOfUndef(block, rhs_src);
16017 }16158 }
16018 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {16159 if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) {
16019 return sema.failWithDivideByZero(block, rhs_src);16160 return sema.failWithDivideByZero(block, rhs_src);
16020 }16161 }
16021 }16162 }
16022 if (maybe_lhs_val) |lhs_val| {16163 if (maybe_lhs_val) |lhs_val| {
16023 if (lhs_val.isUndef(mod)) {16164 if (lhs_val.isUndef(mod)) {
16024 return mod.undefRef(resolved_type);16165 return pt.undefRef(resolved_type);
16025 }16166 }
16026 if (maybe_rhs_val) |rhs_val| {16167 if (maybe_rhs_val) |rhs_val| {
16027 return Air.internedToRef((try lhs_val.floatRem(rhs_val, resolved_type, sema.arena, mod)).toIntern());16168 return Air.internedToRef((try lhs_val.floatRem(rhs_val, resolved_type, sema.arena, pt)).toIntern());
16028 } else break :rs rhs_src;16169 } else break :rs rhs_src;
16029 } else break :rs lhs_src;16170 } else break :rs lhs_src;
16030 };16171 };
...@@ -16059,7 +16200,8 @@ fn zirOverflowArithmetic(...@@ -16059,7 +16200,8 @@ fn zirOverflowArithmetic(
1605916200
16060 const lhs_ty = sema.typeOf(uncasted_lhs);16201 const lhs_ty = sema.typeOf(uncasted_lhs);
16061 const rhs_ty = sema.typeOf(uncasted_rhs);16202 const rhs_ty = sema.typeOf(uncasted_rhs);
16062 const mod = sema.mod;16203 const pt = sema.pt;
16204 const mod = pt.zcu;
16063 const ip = &mod.intern_pool;16205 const ip = &mod.intern_pool;
1606416206
16065 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);16207 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
...@@ -16081,7 +16223,7 @@ fn zirOverflowArithmetic(...@@ -16081,7 +16223,7 @@ fn zirOverflowArithmetic(
16081 const rhs = try sema.coerce(block, rhs_dest_ty, uncasted_rhs, rhs_src);16223 const rhs = try sema.coerce(block, rhs_dest_ty, uncasted_rhs, rhs_src);
1608216224
16083 if (dest_ty.scalarType(mod).zigTypeTag(mod) != .Int) {16225 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)});16226 return sema.fail(block, src, "expected vector of integers or integer tag type, found '{}'", .{dest_ty.fmt(pt)});
16085 }16227 }
1608616228
16087 const maybe_lhs_val = try sema.resolveValue(lhs);16229 const maybe_lhs_val = try sema.resolveValue(lhs);
...@@ -16095,19 +16237,19 @@ fn zirOverflowArithmetic(...@@ -16095,19 +16237,19 @@ fn zirOverflowArithmetic(
16095 wrapped: Value = Value.@"unreachable",16237 wrapped: Value = Value.@"unreachable",
16096 overflow_bit: Value,16238 overflow_bit: Value,
16097 } = result: {16239 } = result: {
16098 const zero_bit = try mod.intValue(Type.u1, 0);16240 const zero_bit = try pt.intValue(Type.u1, 0);
16099 switch (zir_tag) {16241 switch (zir_tag) {
16100 .add_with_overflow => {16242 .add_with_overflow => {
16101 // If either of the arguments is zero, `false` is returned and the other is stored16243 // If either of the arguments is zero, `false` is returned and the other is stored
16102 // to the result, even if it is undefined..16244 // to the result, even if it is undefined..
16103 // Otherwise, if either of the argument is undefined, undefined is returned.16245 // Otherwise, if either of the argument is undefined, undefined is returned.
16104 if (maybe_lhs_val) |lhs_val| {16246 if (maybe_lhs_val) |lhs_val| {
16105 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, mod))) {16247 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 };16248 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };
16107 }16249 }
16108 }16250 }
16109 if (maybe_rhs_val) |rhs_val| {16251 if (maybe_rhs_val) |rhs_val| {
16110 if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroSema(.eq, mod))) {16252 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 };16253 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
16112 }16254 }
16113 }16255 }
...@@ -16128,7 +16270,7 @@ fn zirOverflowArithmetic(...@@ -16128,7 +16270,7 @@ fn zirOverflowArithmetic(
16128 if (maybe_rhs_val) |rhs_val| {16270 if (maybe_rhs_val) |rhs_val| {
16129 if (rhs_val.isUndef(mod)) {16271 if (rhs_val.isUndef(mod)) {
16130 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };16272 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
16131 } else if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {16273 } else if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
16132 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };16274 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
16133 } else if (maybe_lhs_val) |lhs_val| {16275 } else if (maybe_lhs_val) |lhs_val| {
16134 if (lhs_val.isUndef(mod)) {16276 if (lhs_val.isUndef(mod)) {
...@@ -16144,10 +16286,10 @@ fn zirOverflowArithmetic(...@@ -16144,10 +16286,10 @@ fn zirOverflowArithmetic(
16144 // If either of the arguments is zero, the result is zero and no overflow occured.16286 // 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.16287 // 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.16288 // Otherwise, if either of the arguments is undefined, both results are undefined.
16147 const scalar_one = try mod.intValue(dest_ty.scalarType(mod), 1);16289 const scalar_one = try pt.intValue(dest_ty.scalarType(mod), 1);
16148 if (maybe_lhs_val) |lhs_val| {16290 if (maybe_lhs_val) |lhs_val| {
16149 if (!lhs_val.isUndef(mod)) {16291 if (!lhs_val.isUndef(mod)) {
16150 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {16292 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) {
16151 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };16293 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)) {16294 } 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 };16295 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };
...@@ -16157,7 +16299,7 @@ fn zirOverflowArithmetic(...@@ -16157,7 +16299,7 @@ fn zirOverflowArithmetic(
1615716299
16158 if (maybe_rhs_val) |rhs_val| {16300 if (maybe_rhs_val) |rhs_val| {
16159 if (!rhs_val.isUndef(mod)) {16301 if (!rhs_val.isUndef(mod)) {
16160 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {16302 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
16161 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };16303 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)) {16304 } 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 };16305 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
...@@ -16171,7 +16313,7 @@ fn zirOverflowArithmetic(...@@ -16171,7 +16313,7 @@ fn zirOverflowArithmetic(
16171 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };16313 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
16172 }16314 }
1617316315
16174 const result = try lhs_val.intMulWithOverflow(rhs_val, dest_ty, sema.arena, mod);16316 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 };16317 break :result .{ .overflow_bit = result.overflow_bit, .wrapped = result.wrapped_result };
16176 }16318 }
16177 }16319 }
...@@ -16181,12 +16323,12 @@ fn zirOverflowArithmetic(...@@ -16181,12 +16323,12 @@ fn zirOverflowArithmetic(
16181 // If rhs is zero, the result is lhs (even if undefined) and no overflow occurred.16323 // 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.16324 // Oterhwise if either of the arguments is undefined, both results are undefined.
16183 if (maybe_lhs_val) |lhs_val| {16325 if (maybe_lhs_val) |lhs_val| {
16184 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, mod))) {16326 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 };16327 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
16186 }16328 }
16187 }16329 }
16188 if (maybe_rhs_val) |rhs_val| {16330 if (maybe_rhs_val) |rhs_val| {
16189 if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroSema(.eq, mod))) {16331 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 };16332 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
16191 }16333 }
16192 }16334 }
...@@ -16196,7 +16338,7 @@ fn zirOverflowArithmetic(...@@ -16196,7 +16338,7 @@ fn zirOverflowArithmetic(
16196 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };16338 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
16197 }16339 }
1619816340
16199 const result = try lhs_val.shlWithOverflow(rhs_val, dest_ty, sema.arena, mod);16341 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 };16342 break :result .{ .overflow_bit = result.overflow_bit, .wrapped = result.wrapped_result };
16201 }16343 }
16202 }16344 }
...@@ -16235,7 +16377,7 @@ fn zirOverflowArithmetic(...@@ -16235,7 +16377,7 @@ fn zirOverflowArithmetic(
16235 }16377 }
1623616378
16237 if (result.inst == .none) {16379 if (result.inst == .none) {
16238 return Air.internedToRef((try mod.intern(.{ .aggregate = .{16380 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
16239 .ty = tuple_ty.toIntern(),16381 .ty = tuple_ty.toIntern(),
16240 .storage = .{ .elems = &.{16382 .storage = .{ .elems = &.{
16241 result.wrapped.toIntern(),16383 result.wrapped.toIntern(),
...@@ -16251,9 +16393,10 @@ fn zirOverflowArithmetic(...@@ -16251,9 +16393,10 @@ fn zirOverflowArithmetic(
16251}16393}
1625216394
16253fn splat(sema: *Sema, ty: Type, val: Value) !Value {16395fn splat(sema: *Sema, ty: Type, val: Value) !Value {
16254 const mod = sema.mod;16396 const pt = sema.pt;
16397 const mod = pt.zcu;
16255 if (ty.zigTypeTag(mod) != .Vector) return val;16398 if (ty.zigTypeTag(mod) != .Vector) return val;
16256 const repeated = try mod.intern(.{ .aggregate = .{16399 const repeated = try pt.intern(.{ .aggregate = .{
16257 .ty = ty.toIntern(),16400 .ty = ty.toIntern(),
16258 .storage = .{ .repeated_elem = val.toIntern() },16401 .storage = .{ .repeated_elem = val.toIntern() },
16259 } });16402 } });
...@@ -16261,16 +16404,17 @@ fn splat(sema: *Sema, ty: Type, val: Value) !Value {...@@ -16261,16 +16404,17 @@ fn splat(sema: *Sema, ty: Type, val: Value) !Value {
16261}16404}
1626216405
16263fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type {16406fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type {
16264 const mod = sema.mod;16407 const pt = sema.pt;
16408 const mod = pt.zcu;
16265 const ip = &mod.intern_pool;16409 const ip = &mod.intern_pool;
16266 const ov_ty = if (ty.zigTypeTag(mod) == .Vector) try mod.vectorType(.{16410 const ov_ty = if (ty.zigTypeTag(mod) == .Vector) try pt.vectorType(.{
16267 .len = ty.vectorLen(mod),16411 .len = ty.vectorLen(mod),
16268 .child = .u1_type,16412 .child = .u1_type,
16269 }) else Type.u1;16413 }) else Type.u1;
1627016414
16271 const types = [2]InternPool.Index{ ty.toIntern(), ov_ty.toIntern() };16415 const types = [2]InternPool.Index{ ty.toIntern(), ov_ty.toIntern() };
16272 const values = [2]InternPool.Index{ .none, .none };16416 const values = [2]InternPool.Index{ .none, .none };
16273 const tuple_ty = try ip.getAnonStructType(mod.gpa, .{16417 const tuple_ty = try ip.getAnonStructType(mod.gpa, pt.tid, .{
16274 .types = &types,16418 .types = &types,
16275 .values = &values,16419 .values = &values,
16276 .names = &.{},16420 .names = &.{},
...@@ -16290,7 +16434,8 @@ fn analyzeArithmetic(...@@ -16290,7 +16434,8 @@ fn analyzeArithmetic(
16290 rhs_src: LazySrcLoc,16434 rhs_src: LazySrcLoc,
16291 want_safety: bool,16435 want_safety: bool,
16292) CompileError!Air.Inst.Ref {16436) CompileError!Air.Inst.Ref {
16293 const mod = sema.mod;16437 const pt = sema.pt;
16438 const mod = pt.zcu;
16294 const lhs_ty = sema.typeOf(lhs);16439 const lhs_ty = sema.typeOf(lhs);
16295 const rhs_ty = sema.typeOf(rhs);16440 const rhs_ty = sema.typeOf(rhs);
16296 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);16441 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
...@@ -16337,7 +16482,7 @@ fn analyzeArithmetic(...@@ -16337,7 +16482,7 @@ fn analyzeArithmetic(
16337 // overflow (max_int), causing illegal behavior.16482 // overflow (max_int), causing illegal behavior.
16338 // For floats: either operand being undef makes the result undef.16483 // For floats: either operand being undef makes the result undef.
16339 if (maybe_lhs_val) |lhs_val| {16484 if (maybe_lhs_val) |lhs_val| {
16340 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, mod))) {16485 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) {
16341 return casted_rhs;16486 return casted_rhs;
16342 }16487 }
16343 }16488 }
...@@ -16346,10 +16491,10 @@ fn analyzeArithmetic(...@@ -16346,10 +16491,10 @@ fn analyzeArithmetic(
16346 if (is_int) {16491 if (is_int) {
16347 return sema.failWithUseOfUndef(block, rhs_src);16492 return sema.failWithUseOfUndef(block, rhs_src);
16348 } else {16493 } else {
16349 return mod.undefRef(resolved_type);16494 return pt.undefRef(resolved_type);
16350 }16495 }
16351 }16496 }
16352 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {16497 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
16353 return casted_lhs;16498 return casted_lhs;
16354 }16499 }
16355 }16500 }
...@@ -16359,7 +16504,7 @@ fn analyzeArithmetic(...@@ -16359,7 +16504,7 @@ fn analyzeArithmetic(
16359 if (is_int) {16504 if (is_int) {
16360 return sema.failWithUseOfUndef(block, lhs_src);16505 return sema.failWithUseOfUndef(block, lhs_src);
16361 } else {16506 } else {
16362 return mod.undefRef(resolved_type);16507 return pt.undefRef(resolved_type);
16363 }16508 }
16364 }16509 }
16365 if (maybe_rhs_val) |rhs_val| {16510 if (maybe_rhs_val) |rhs_val| {
...@@ -16371,7 +16516,7 @@ fn analyzeArithmetic(...@@ -16371,7 +16516,7 @@ fn analyzeArithmetic(
16371 }16516 }
16372 return Air.internedToRef(sum.toIntern());16517 return Air.internedToRef(sum.toIntern());
16373 } else {16518 } else {
16374 return Air.internedToRef((try Value.floatAdd(lhs_val, rhs_val, resolved_type, sema.arena, mod)).toIntern());16519 return Air.internedToRef((try Value.floatAdd(lhs_val, rhs_val, resolved_type, sema.arena, pt)).toIntern());
16375 }16520 }
16376 } else break :rs .{ rhs_src, air_tag, .add_safe };16521 } else break :rs .{ rhs_src, air_tag, .add_safe };
16377 } else break :rs .{ lhs_src, air_tag, .add_safe };16522 } else break :rs .{ lhs_src, air_tag, .add_safe };
...@@ -16381,15 +16526,15 @@ fn analyzeArithmetic(...@@ -16381,15 +16526,15 @@ fn analyzeArithmetic(
16381 // If either of the operands are zero, the other operand is returned.16526 // If either of the operands are zero, the other operand is returned.
16382 // If either of the operands are undefined, the result is undefined.16527 // If either of the operands are undefined, the result is undefined.
16383 if (maybe_lhs_val) |lhs_val| {16528 if (maybe_lhs_val) |lhs_val| {
16384 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, mod))) {16529 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) {
16385 return casted_rhs;16530 return casted_rhs;
16386 }16531 }
16387 }16532 }
16388 if (maybe_rhs_val) |rhs_val| {16533 if (maybe_rhs_val) |rhs_val| {
16389 if (rhs_val.isUndef(mod)) {16534 if (rhs_val.isUndef(mod)) {
16390 return mod.undefRef(resolved_type);16535 return pt.undefRef(resolved_type);
16391 }16536 }
16392 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {16537 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
16393 return casted_lhs;16538 return casted_lhs;
16394 }16539 }
16395 if (maybe_lhs_val) |lhs_val| {16540 if (maybe_lhs_val) |lhs_val| {
...@@ -16402,26 +16547,26 @@ fn analyzeArithmetic(...@@ -16402,26 +16547,26 @@ fn analyzeArithmetic(
16402 // If either of the operands are zero, then the other operand is returned.16547 // 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.16548 // If either of the operands are undefined, the result is undefined.
16404 if (maybe_lhs_val) |lhs_val| {16549 if (maybe_lhs_val) |lhs_val| {
16405 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, mod))) {16550 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) {
16406 return casted_rhs;16551 return casted_rhs;
16407 }16552 }
16408 }16553 }
16409 if (maybe_rhs_val) |rhs_val| {16554 if (maybe_rhs_val) |rhs_val| {
16410 if (rhs_val.isUndef(mod)) {16555 if (rhs_val.isUndef(mod)) {
16411 return mod.undefRef(resolved_type);16556 return pt.undefRef(resolved_type);
16412 }16557 }
16413 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {16558 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
16414 return casted_lhs;16559 return casted_lhs;
16415 }16560 }
16416 if (maybe_lhs_val) |lhs_val| {16561 if (maybe_lhs_val) |lhs_val| {
16417 if (lhs_val.isUndef(mod)) {16562 if (lhs_val.isUndef(mod)) {
16418 return mod.undefRef(resolved_type);16563 return pt.undefRef(resolved_type);
16419 }16564 }
1642016565
16421 const val = if (scalar_tag == .ComptimeInt)16566 const val = if (scalar_tag == .ComptimeInt)
16422 try sema.intAdd(lhs_val, rhs_val, resolved_type, undefined)16567 try sema.intAdd(lhs_val, rhs_val, resolved_type, undefined)
16423 else16568 else
16424 try lhs_val.intAddSat(rhs_val, resolved_type, sema.arena, mod);16569 try lhs_val.intAddSat(rhs_val, resolved_type, sema.arena, pt);
1642516570
16426 return Air.internedToRef(val.toIntern());16571 return Air.internedToRef(val.toIntern());
16427 } else break :rs .{16572 } else break :rs .{
...@@ -16448,10 +16593,10 @@ fn analyzeArithmetic(...@@ -16448,10 +16593,10 @@ fn analyzeArithmetic(
16448 if (is_int) {16593 if (is_int) {
16449 return sema.failWithUseOfUndef(block, rhs_src);16594 return sema.failWithUseOfUndef(block, rhs_src);
16450 } else {16595 } else {
16451 return mod.undefRef(resolved_type);16596 return pt.undefRef(resolved_type);
16452 }16597 }
16453 }16598 }
16454 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {16599 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
16455 return casted_lhs;16600 return casted_lhs;
16456 }16601 }
16457 }16602 }
...@@ -16461,7 +16606,7 @@ fn analyzeArithmetic(...@@ -16461,7 +16606,7 @@ fn analyzeArithmetic(
16461 if (is_int) {16606 if (is_int) {
16462 return sema.failWithUseOfUndef(block, lhs_src);16607 return sema.failWithUseOfUndef(block, lhs_src);
16463 } else {16608 } else {
16464 return mod.undefRef(resolved_type);16609 return pt.undefRef(resolved_type);
16465 }16610 }
16466 }16611 }
16467 if (maybe_rhs_val) |rhs_val| {16612 if (maybe_rhs_val) |rhs_val| {
...@@ -16473,7 +16618,7 @@ fn analyzeArithmetic(...@@ -16473,7 +16618,7 @@ fn analyzeArithmetic(
16473 }16618 }
16474 return Air.internedToRef(diff.toIntern());16619 return Air.internedToRef(diff.toIntern());
16475 } else {16620 } else {
16476 return Air.internedToRef((try Value.floatSub(lhs_val, rhs_val, resolved_type, sema.arena, mod)).toIntern());16621 return Air.internedToRef((try Value.floatSub(lhs_val, rhs_val, resolved_type, sema.arena, pt)).toIntern());
16477 }16622 }
16478 } else break :rs .{ rhs_src, air_tag, .sub_safe };16623 } else break :rs .{ rhs_src, air_tag, .sub_safe };
16479 } else break :rs .{ lhs_src, air_tag, .sub_safe };16624 } else break :rs .{ lhs_src, air_tag, .sub_safe };
...@@ -16484,15 +16629,15 @@ fn analyzeArithmetic(...@@ -16484,15 +16629,15 @@ fn analyzeArithmetic(
16484 // If either of the operands are undefined, the result is undefined.16629 // If either of the operands are undefined, the result is undefined.
16485 if (maybe_rhs_val) |rhs_val| {16630 if (maybe_rhs_val) |rhs_val| {
16486 if (rhs_val.isUndef(mod)) {16631 if (rhs_val.isUndef(mod)) {
16487 return mod.undefRef(resolved_type);16632 return pt.undefRef(resolved_type);
16488 }16633 }
16489 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {16634 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
16490 return casted_lhs;16635 return casted_lhs;
16491 }16636 }
16492 }16637 }
16493 if (maybe_lhs_val) |lhs_val| {16638 if (maybe_lhs_val) |lhs_val| {
16494 if (lhs_val.isUndef(mod)) {16639 if (lhs_val.isUndef(mod)) {
16495 return mod.undefRef(resolved_type);16640 return pt.undefRef(resolved_type);
16496 }16641 }
16497 if (maybe_rhs_val) |rhs_val| {16642 if (maybe_rhs_val) |rhs_val| {
16498 return Air.internedToRef((try sema.numberSubWrapScalar(lhs_val, rhs_val, resolved_type)).toIntern());16643 return Air.internedToRef((try sema.numberSubWrapScalar(lhs_val, rhs_val, resolved_type)).toIntern());
...@@ -16505,21 +16650,21 @@ fn analyzeArithmetic(...@@ -16505,21 +16650,21 @@ fn analyzeArithmetic(
16505 // If either of the operands are undefined, the result is undefined.16650 // If either of the operands are undefined, the result is undefined.
16506 if (maybe_rhs_val) |rhs_val| {16651 if (maybe_rhs_val) |rhs_val| {
16507 if (rhs_val.isUndef(mod)) {16652 if (rhs_val.isUndef(mod)) {
16508 return mod.undefRef(resolved_type);16653 return pt.undefRef(resolved_type);
16509 }16654 }
16510 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {16655 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
16511 return casted_lhs;16656 return casted_lhs;
16512 }16657 }
16513 }16658 }
16514 if (maybe_lhs_val) |lhs_val| {16659 if (maybe_lhs_val) |lhs_val| {
16515 if (lhs_val.isUndef(mod)) {16660 if (lhs_val.isUndef(mod)) {
16516 return mod.undefRef(resolved_type);16661 return pt.undefRef(resolved_type);
16517 }16662 }
16518 if (maybe_rhs_val) |rhs_val| {16663 if (maybe_rhs_val) |rhs_val| {
16519 const val = if (scalar_tag == .ComptimeInt)16664 const val = if (scalar_tag == .ComptimeInt)
16520 try sema.intSub(lhs_val, rhs_val, resolved_type, undefined)16665 try sema.intSub(lhs_val, rhs_val, resolved_type, undefined)
16521 else16666 else
16522 try lhs_val.intSubSat(rhs_val, resolved_type, sema.arena, mod);16667 try lhs_val.intSubSat(rhs_val, resolved_type, sema.arena, pt);
1652316668
16524 return Air.internedToRef(val.toIntern());16669 return Air.internedToRef(val.toIntern());
16525 } else break :rs .{ rhs_src, .sub_sat, .sub_sat };16670 } else break :rs .{ rhs_src, .sub_sat, .sub_sat };
...@@ -16540,13 +16685,13 @@ fn analyzeArithmetic(...@@ -16540,13 +16685,13 @@ fn analyzeArithmetic(
16540 // the result is nan.16685 // the result is nan.
16541 // If either of the operands are nan, the result is nan.16686 // If either of the operands are nan, the result is nan.
16542 const scalar_zero = switch (scalar_tag) {16687 const scalar_zero = switch (scalar_tag) {
16543 .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 0.0),16688 .ComptimeFloat, .Float => try pt.floatValue(scalar_type, 0.0),
16544 .ComptimeInt, .Int => try mod.intValue(scalar_type, 0),16689 .ComptimeInt, .Int => try pt.intValue(scalar_type, 0),
16545 else => unreachable,16690 else => unreachable,
16546 };16691 };
16547 const scalar_one = switch (scalar_tag) {16692 const scalar_one = switch (scalar_tag) {
16548 .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 1.0),16693 .ComptimeFloat, .Float => try pt.floatValue(scalar_type, 1.0),
16549 .ComptimeInt, .Int => try mod.intValue(scalar_type, 1),16694 .ComptimeInt, .Int => try pt.intValue(scalar_type, 1),
16550 else => unreachable,16695 else => unreachable,
16551 };16696 };
16552 if (maybe_lhs_val) |lhs_val| {16697 if (maybe_lhs_val) |lhs_val| {
...@@ -16554,13 +16699,13 @@ fn analyzeArithmetic(...@@ -16554,13 +16699,13 @@ fn analyzeArithmetic(
16554 if (lhs_val.isNan(mod)) {16699 if (lhs_val.isNan(mod)) {
16555 return Air.internedToRef(lhs_val.toIntern());16700 return Air.internedToRef(lhs_val.toIntern());
16556 }16701 }
16557 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) lz: {16702 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) lz: {
16558 if (maybe_rhs_val) |rhs_val| {16703 if (maybe_rhs_val) |rhs_val| {
16559 if (rhs_val.isNan(mod)) {16704 if (rhs_val.isNan(mod)) {
16560 return Air.internedToRef(rhs_val.toIntern());16705 return Air.internedToRef(rhs_val.toIntern());
16561 }16706 }
16562 if (rhs_val.isInf(mod)) {16707 if (rhs_val.isInf(mod)) {
16563 return Air.internedToRef((try mod.floatValue(resolved_type, std.math.nan(f128))).toIntern());16708 return Air.internedToRef((try pt.floatValue(resolved_type, std.math.nan(f128))).toIntern());
16564 }16709 }
16565 } else if (resolved_type.isAnyFloat()) {16710 } else if (resolved_type.isAnyFloat()) {
16566 break :lz;16711 break :lz;
...@@ -16579,16 +16724,16 @@ fn analyzeArithmetic(...@@ -16579,16 +16724,16 @@ fn analyzeArithmetic(
16579 if (is_int) {16724 if (is_int) {
16580 return sema.failWithUseOfUndef(block, rhs_src);16725 return sema.failWithUseOfUndef(block, rhs_src);
16581 } else {16726 } else {
16582 return mod.undefRef(resolved_type);16727 return pt.undefRef(resolved_type);
16583 }16728 }
16584 }16729 }
16585 if (rhs_val.isNan(mod)) {16730 if (rhs_val.isNan(mod)) {
16586 return Air.internedToRef(rhs_val.toIntern());16731 return Air.internedToRef(rhs_val.toIntern());
16587 }16732 }
16588 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) rz: {16733 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) rz: {
16589 if (maybe_lhs_val) |lhs_val| {16734 if (maybe_lhs_val) |lhs_val| {
16590 if (lhs_val.isInf(mod)) {16735 if (lhs_val.isInf(mod)) {
16591 return Air.internedToRef((try mod.floatValue(resolved_type, std.math.nan(f128))).toIntern());16736 return Air.internedToRef((try pt.floatValue(resolved_type, std.math.nan(f128))).toIntern());
16592 }16737 }
16593 } else if (resolved_type.isAnyFloat()) {16738 } else if (resolved_type.isAnyFloat()) {
16594 break :rz;16739 break :rz;
...@@ -16604,18 +16749,18 @@ fn analyzeArithmetic(...@@ -16604,18 +16749,18 @@ fn analyzeArithmetic(
16604 if (is_int) {16749 if (is_int) {
16605 return sema.failWithUseOfUndef(block, lhs_src);16750 return sema.failWithUseOfUndef(block, lhs_src);
16606 } else {16751 } else {
16607 return mod.undefRef(resolved_type);16752 return pt.undefRef(resolved_type);
16608 }16753 }
16609 }16754 }
16610 if (is_int) {16755 if (is_int) {
16611 var overflow_idx: ?usize = null;16756 var overflow_idx: ?usize = null;
16612 const product = try lhs_val.intMul(rhs_val, resolved_type, &overflow_idx, sema.arena, mod);16757 const product = try lhs_val.intMul(rhs_val, resolved_type, &overflow_idx, sema.arena, pt);
16613 if (overflow_idx) |vec_idx| {16758 if (overflow_idx) |vec_idx| {
16614 return sema.failWithIntegerOverflow(block, src, resolved_type, product, vec_idx);16759 return sema.failWithIntegerOverflow(block, src, resolved_type, product, vec_idx);
16615 }16760 }
16616 return Air.internedToRef(product.toIntern());16761 return Air.internedToRef(product.toIntern());
16617 } else {16762 } else {
16618 return Air.internedToRef((try lhs_val.floatMul(rhs_val, resolved_type, sema.arena, mod)).toIntern());16763 return Air.internedToRef((try lhs_val.floatMul(rhs_val, resolved_type, sema.arena, pt)).toIntern());
16619 }16764 }
16620 } else break :rs .{ lhs_src, air_tag, .mul_safe };16765 } else break :rs .{ lhs_src, air_tag, .mul_safe };
16621 } else break :rs .{ rhs_src, air_tag, .mul_safe };16766 } else break :rs .{ rhs_src, air_tag, .mul_safe };
...@@ -16626,18 +16771,18 @@ fn analyzeArithmetic(...@@ -16626,18 +16771,18 @@ fn analyzeArithmetic(
16626 // If either of the operands are one, result is the other operand.16771 // If either of the operands are one, result is the other operand.
16627 // If either of the operands are undefined, result is undefined.16772 // If either of the operands are undefined, result is undefined.
16628 const scalar_zero = switch (scalar_tag) {16773 const scalar_zero = switch (scalar_tag) {
16629 .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 0.0),16774 .ComptimeFloat, .Float => try pt.floatValue(scalar_type, 0.0),
16630 .ComptimeInt, .Int => try mod.intValue(scalar_type, 0),16775 .ComptimeInt, .Int => try pt.intValue(scalar_type, 0),
16631 else => unreachable,16776 else => unreachable,
16632 };16777 };
16633 const scalar_one = switch (scalar_tag) {16778 const scalar_one = switch (scalar_tag) {
16634 .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 1.0),16779 .ComptimeFloat, .Float => try pt.floatValue(scalar_type, 1.0),
16635 .ComptimeInt, .Int => try mod.intValue(scalar_type, 1),16780 .ComptimeInt, .Int => try pt.intValue(scalar_type, 1),
16636 else => unreachable,16781 else => unreachable,
16637 };16782 };
16638 if (maybe_lhs_val) |lhs_val| {16783 if (maybe_lhs_val) |lhs_val| {
16639 if (!lhs_val.isUndef(mod)) {16784 if (!lhs_val.isUndef(mod)) {
16640 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {16785 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) {
16641 const zero_val = try sema.splat(resolved_type, scalar_zero);16786 const zero_val = try sema.splat(resolved_type, scalar_zero);
16642 return Air.internedToRef(zero_val.toIntern());16787 return Air.internedToRef(zero_val.toIntern());
16643 }16788 }
...@@ -16648,9 +16793,9 @@ fn analyzeArithmetic(...@@ -16648,9 +16793,9 @@ fn analyzeArithmetic(
16648 }16793 }
16649 if (maybe_rhs_val) |rhs_val| {16794 if (maybe_rhs_val) |rhs_val| {
16650 if (rhs_val.isUndef(mod)) {16795 if (rhs_val.isUndef(mod)) {
16651 return mod.undefRef(resolved_type);16796 return pt.undefRef(resolved_type);
16652 }16797 }
16653 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {16798 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
16654 const zero_val = try sema.splat(resolved_type, scalar_zero);16799 const zero_val = try sema.splat(resolved_type, scalar_zero);
16655 return Air.internedToRef(zero_val.toIntern());16800 return Air.internedToRef(zero_val.toIntern());
16656 }16801 }
...@@ -16659,9 +16804,9 @@ fn analyzeArithmetic(...@@ -16659,9 +16804,9 @@ fn analyzeArithmetic(
16659 }16804 }
16660 if (maybe_lhs_val) |lhs_val| {16805 if (maybe_lhs_val) |lhs_val| {
16661 if (lhs_val.isUndef(mod)) {16806 if (lhs_val.isUndef(mod)) {
16662 return mod.undefRef(resolved_type);16807 return pt.undefRef(resolved_type);
16663 }16808 }
16664 return Air.internedToRef((try lhs_val.numberMulWrap(rhs_val, resolved_type, sema.arena, mod)).toIntern());16809 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 };16810 } else break :rs .{ lhs_src, .mul_wrap, .mul_wrap };
16666 } else break :rs .{ rhs_src, .mul_wrap, .mul_wrap };16811 } else break :rs .{ rhs_src, .mul_wrap, .mul_wrap };
16667 },16812 },
...@@ -16671,18 +16816,18 @@ fn analyzeArithmetic(...@@ -16671,18 +16816,18 @@ fn analyzeArithmetic(
16671 // If either of the operands are one, result is the other operand.16816 // If either of the operands are one, result is the other operand.
16672 // If either of the operands are undefined, result is undefined.16817 // If either of the operands are undefined, result is undefined.
16673 const scalar_zero = switch (scalar_tag) {16818 const scalar_zero = switch (scalar_tag) {
16674 .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 0.0),16819 .ComptimeFloat, .Float => try pt.floatValue(scalar_type, 0.0),
16675 .ComptimeInt, .Int => try mod.intValue(scalar_type, 0),16820 .ComptimeInt, .Int => try pt.intValue(scalar_type, 0),
16676 else => unreachable,16821 else => unreachable,
16677 };16822 };
16678 const scalar_one = switch (scalar_tag) {16823 const scalar_one = switch (scalar_tag) {
16679 .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 1.0),16824 .ComptimeFloat, .Float => try pt.floatValue(scalar_type, 1.0),
16680 .ComptimeInt, .Int => try mod.intValue(scalar_type, 1),16825 .ComptimeInt, .Int => try pt.intValue(scalar_type, 1),
16681 else => unreachable,16826 else => unreachable,
16682 };16827 };
16683 if (maybe_lhs_val) |lhs_val| {16828 if (maybe_lhs_val) |lhs_val| {
16684 if (!lhs_val.isUndef(mod)) {16829 if (!lhs_val.isUndef(mod)) {
16685 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {16830 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) {
16686 const zero_val = try sema.splat(resolved_type, scalar_zero);16831 const zero_val = try sema.splat(resolved_type, scalar_zero);
16687 return Air.internedToRef(zero_val.toIntern());16832 return Air.internedToRef(zero_val.toIntern());
16688 }16833 }
...@@ -16693,9 +16838,9 @@ fn analyzeArithmetic(...@@ -16693,9 +16838,9 @@ fn analyzeArithmetic(
16693 }16838 }
16694 if (maybe_rhs_val) |rhs_val| {16839 if (maybe_rhs_val) |rhs_val| {
16695 if (rhs_val.isUndef(mod)) {16840 if (rhs_val.isUndef(mod)) {
16696 return mod.undefRef(resolved_type);16841 return pt.undefRef(resolved_type);
16697 }16842 }
16698 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {16843 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
16699 const zero_val = try sema.splat(resolved_type, scalar_zero);16844 const zero_val = try sema.splat(resolved_type, scalar_zero);
16700 return Air.internedToRef(zero_val.toIntern());16845 return Air.internedToRef(zero_val.toIntern());
16701 }16846 }
...@@ -16704,13 +16849,13 @@ fn analyzeArithmetic(...@@ -16704,13 +16849,13 @@ fn analyzeArithmetic(
16704 }16849 }
16705 if (maybe_lhs_val) |lhs_val| {16850 if (maybe_lhs_val) |lhs_val| {
16706 if (lhs_val.isUndef(mod)) {16851 if (lhs_val.isUndef(mod)) {
16707 return mod.undefRef(resolved_type);16852 return pt.undefRef(resolved_type);
16708 }16853 }
1670916854
16710 const val = if (scalar_tag == .ComptimeInt)16855 const val = if (scalar_tag == .ComptimeInt)
16711 try lhs_val.intMul(rhs_val, resolved_type, undefined, sema.arena, mod)16856 try lhs_val.intMul(rhs_val, resolved_type, undefined, sema.arena, pt)
16712 else16857 else
16713 try lhs_val.intMulSat(rhs_val, resolved_type, sema.arena, mod);16858 try lhs_val.intMulSat(rhs_val, resolved_type, sema.arena, pt);
1671416859
16715 return Air.internedToRef(val.toIntern());16860 return Air.internedToRef(val.toIntern());
16716 } else break :rs .{ lhs_src, .mul_sat, .mul_sat };16861 } else break :rs .{ lhs_src, .mul_sat, .mul_sat };
...@@ -16758,7 +16903,7 @@ fn analyzeArithmetic(...@@ -16758,7 +16903,7 @@ fn analyzeArithmetic(
16758 })16903 })
16759 else16904 else
16760 ov_bit;16905 ov_bit;
16761 const zero_ov = Air.internedToRef((try mod.intValue(Type.u1, 0)).toIntern());16906 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);16907 const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov);
1676316908
16764 try sema.addSafetyCheck(block, src, no_ov, .integer_overflow);16909 try sema.addSafetyCheck(block, src, no_ov, .integer_overflow);
...@@ -16782,7 +16927,8 @@ fn analyzePtrArithmetic(...@@ -16782,7 +16927,8 @@ fn analyzePtrArithmetic(
16782 // TODO if the operand is comptime-known to be negative, or is a negative int,16927 // TODO if the operand is comptime-known to be negative, or is a negative int,
16783 // coerce to isize instead of usize.16928 // coerce to isize instead of usize.
16784 const offset = try sema.coerce(block, Type.usize, uncasted_offset, offset_src);16929 const offset = try sema.coerce(block, Type.usize, uncasted_offset, offset_src);
16785 const mod = sema.mod;16930 const pt = sema.pt;
16931 const mod = pt.zcu;
16786 const opt_ptr_val = try sema.resolveValue(ptr);16932 const opt_ptr_val = try sema.resolveValue(ptr);
16787 const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset);16933 const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset);
16788 const ptr_ty = sema.typeOf(ptr);16934 const ptr_ty = sema.typeOf(ptr);
...@@ -16800,7 +16946,7 @@ fn analyzePtrArithmetic(...@@ -16800,7 +16946,7 @@ fn analyzePtrArithmetic(
16800 // it being a multiple of the type size.16946 // it being a multiple of the type size.
16801 const elem_size = try sema.typeAbiSize(Type.fromInterned(ptr_info.child));16947 const elem_size = try sema.typeAbiSize(Type.fromInterned(ptr_info.child));
16802 const addend = if (opt_off_val) |off_val| a: {16948 const addend = if (opt_off_val) |off_val| a: {
16803 const off_int = try sema.usizeCast(block, offset_src, try off_val.toUnsignedIntSema(mod));16949 const off_int = try sema.usizeCast(block, offset_src, try off_val.toUnsignedIntSema(pt));
16804 break :a elem_size * off_int;16950 break :a elem_size * off_int;
16805 } else elem_size;16951 } else elem_size;
1680616952
...@@ -16813,7 +16959,7 @@ fn analyzePtrArithmetic(...@@ -16813,7 +16959,7 @@ fn analyzePtrArithmetic(
16813 ));16959 ));
16814 assert(new_align != .none);16960 assert(new_align != .none);
1681516961
16816 break :t try mod.ptrTypeSema(.{16962 break :t try pt.ptrTypeSema(.{
16817 .child = ptr_info.child,16963 .child = ptr_info.child,
16818 .sentinel = ptr_info.sentinel,16964 .sentinel = ptr_info.sentinel,
16819 .flags = .{16965 .flags = .{
...@@ -16830,16 +16976,16 @@ fn analyzePtrArithmetic(...@@ -16830,16 +16976,16 @@ fn analyzePtrArithmetic(
16830 const runtime_src = rs: {16976 const runtime_src = rs: {
16831 if (opt_ptr_val) |ptr_val| {16977 if (opt_ptr_val) |ptr_val| {
16832 if (opt_off_val) |offset_val| {16978 if (opt_off_val) |offset_val| {
16833 if (ptr_val.isUndef(mod)) return mod.undefRef(new_ptr_ty);16979 if (ptr_val.isUndef(mod)) return pt.undefRef(new_ptr_ty);
1683416980
16835 const offset_int = try sema.usizeCast(block, offset_src, try offset_val.toUnsignedIntSema(mod));16981 const offset_int = try sema.usizeCast(block, offset_src, try offset_val.toUnsignedIntSema(pt));
16836 if (offset_int == 0) return ptr;16982 if (offset_int == 0) return ptr;
16837 if (air_tag == .ptr_sub) {16983 if (air_tag == .ptr_sub) {
16838 const elem_size = try sema.typeAbiSize(Type.fromInterned(ptr_info.child));16984 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);16985 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());16986 return Air.internedToRef(new_ptr_val.toIntern());
16841 } else {16987 } else {
16842 const new_ptr_val = try mod.getCoerced(try ptr_val.ptrElem(offset_int, mod), new_ptr_ty);16988 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());16989 return Air.internedToRef(new_ptr_val.toIntern());
16844 }16990 }
16845 } else break :rs offset_src;16991 } else break :rs offset_src;
...@@ -16879,6 +17025,8 @@ fn zirAsm(...@@ -16879,6 +17025,8 @@ fn zirAsm(
16879 const tracy = trace(@src());17025 const tracy = trace(@src());
16880 defer tracy.end();17026 defer tracy.end();
1688117027
17028 const pt = sema.pt;
17029 const mod = pt.zcu;
16882 const extra = sema.code.extraData(Zir.Inst.Asm, extended.operand);17030 const extra = sema.code.extraData(Zir.Inst.Asm, extended.operand);
16883 const src = block.nodeOffset(extra.data.src_node);17031 const src = block.nodeOffset(extra.data.src_node);
16884 const ret_ty_src = block.src(.{ .node_offset_asm_ret_ty = extra.data.src_node });17032 const ret_ty_src = block.src(.{ .node_offset_asm_ret_ty = extra.data.src_node });
...@@ -16910,7 +17058,7 @@ fn zirAsm(...@@ -16910,7 +17058,7 @@ fn zirAsm(
16910 if (is_volatile) {17058 if (is_volatile) {
16911 return sema.fail(block, src, "volatile keyword is redundant on module-level assembly", .{});17059 return sema.fail(block, src, "volatile keyword is redundant on module-level assembly", .{});
16912 }17060 }
16913 try sema.mod.addGlobalAssembly(sema.owner_decl_index, asm_source);17061 try mod.addGlobalAssembly(sema.owner_decl_index, asm_source);
16914 return .void_value;17062 return .void_value;
16915 }17063 }
1691617064
...@@ -16959,7 +17107,6 @@ fn zirAsm(...@@ -16959,7 +17107,6 @@ fn zirAsm(
1695917107
16960 const args = try sema.arena.alloc(Air.Inst.Ref, inputs_len);17108 const args = try sema.arena.alloc(Air.Inst.Ref, inputs_len);
16961 const inputs = try sema.arena.alloc(ConstraintName, inputs_len);17109 const inputs = try sema.arena.alloc(ConstraintName, inputs_len);
16962 const mod = sema.mod;
1696317110
16964 for (args, 0..) |*arg, arg_i| {17111 for (args, 0..) |*arg, arg_i| {
16965 const input = sema.code.extraData(Zir.Inst.Asm.Input, extra_i);17112 const input = sema.code.extraData(Zir.Inst.Asm.Input, extra_i);
...@@ -17049,7 +17196,8 @@ fn zirCmpEq(...@@ -17049,7 +17196,8 @@ fn zirCmpEq(
17049 const tracy = trace(@src());17196 const tracy = trace(@src());
17050 defer tracy.end();17197 defer tracy.end();
1705117198
17052 const mod = sema.mod;17199 const pt = sema.pt;
17200 const mod = pt.zcu;
17053 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;17201 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;17202 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
17055 const src: LazySrcLoc = block.nodeOffset(inst_data.src_node);17203 const src: LazySrcLoc = block.nodeOffset(inst_data.src_node);
...@@ -17077,7 +17225,7 @@ fn zirCmpEq(...@@ -17077,7 +17225,7 @@ fn zirCmpEq(
1707717225
17078 if (lhs_ty_tag == .Null or rhs_ty_tag == .Null) {17226 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;17227 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)});17228 return sema.fail(block, src, "comparison of '{}' with null", .{non_null_type.fmt(pt)});
17081 }17229 }
1708217230
17083 if (lhs_ty_tag == .Union and (rhs_ty_tag == .EnumLiteral or rhs_ty_tag == .Enum)) {17231 if (lhs_ty_tag == .Union and (rhs_ty_tag == .EnumLiteral or rhs_ty_tag == .Enum)) {
...@@ -17092,7 +17240,7 @@ fn zirCmpEq(...@@ -17092,7 +17240,7 @@ fn zirCmpEq(
17092 if (try sema.resolveValue(lhs)) |lval| {17240 if (try sema.resolveValue(lhs)) |lval| {
17093 if (try sema.resolveValue(rhs)) |rval| {17241 if (try sema.resolveValue(rhs)) |rval| {
17094 if (lval.isUndef(mod) or rval.isUndef(mod)) {17242 if (lval.isUndef(mod) or rval.isUndef(mod)) {
17095 return mod.undefRef(Type.bool);17243 return pt.undefRef(Type.bool);
17096 }17244 }
17097 const lkey = mod.intern_pool.indexToKey(lval.toIntern());17245 const lkey = mod.intern_pool.indexToKey(lval.toIntern());
17098 const rkey = mod.intern_pool.indexToKey(rval.toIntern());17246 const rkey = mod.intern_pool.indexToKey(rval.toIntern());
...@@ -17128,14 +17276,15 @@ fn analyzeCmpUnionTag(...@@ -17128,14 +17276,15 @@ fn analyzeCmpUnionTag(
17128 tag_src: LazySrcLoc,17276 tag_src: LazySrcLoc,
17129 op: std.math.CompareOperator,17277 op: std.math.CompareOperator,
17130) CompileError!Air.Inst.Ref {17278) CompileError!Air.Inst.Ref {
17131 const mod = sema.mod;17279 const pt = sema.pt;
17280 const mod = pt.zcu;
17132 const union_ty = sema.typeOf(un);17281 const union_ty = sema.typeOf(un);
17133 try union_ty.resolveFields(mod);17282 try union_ty.resolveFields(pt);
17134 const union_tag_ty = union_ty.unionTagType(mod) orelse {17283 const union_tag_ty = union_ty.unionTagType(mod) orelse {
17135 const msg = msg: {17284 const msg = msg: {
17136 const msg = try sema.errMsg(un_src, "comparison of union and enum literal is only valid for tagged union types", .{});17285 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);17286 errdefer msg.destroy(sema.gpa);
17138 try sema.errNote(union_ty.srcLoc(mod), msg, "union '{}' is not a tagged union", .{union_ty.fmt(mod)});17287 try sema.errNote(union_ty.srcLoc(mod), msg, "union '{}' is not a tagged union", .{union_ty.fmt(pt)});
17139 break :msg msg;17288 break :msg msg;
17140 };17289 };
17141 return sema.failWithOwnedErrorMsg(block, msg);17290 return sema.failWithOwnedErrorMsg(block, msg);
...@@ -17146,7 +17295,7 @@ fn analyzeCmpUnionTag(...@@ -17146,7 +17295,7 @@ fn analyzeCmpUnionTag(
17146 const coerced_union = try sema.coerce(block, union_tag_ty, un, un_src);17295 const coerced_union = try sema.coerce(block, union_tag_ty, un, un_src);
1714717296
17148 if (try sema.resolveValue(coerced_tag)) |enum_val| {17297 if (try sema.resolveValue(coerced_tag)) |enum_val| {
17149 if (enum_val.isUndef(mod)) return mod.undefRef(Type.bool);17298 if (enum_val.isUndef(mod)) return pt.undefRef(Type.bool);
17150 const field_ty = union_ty.unionFieldType(enum_val, mod).?;17299 const field_ty = union_ty.unionFieldType(enum_val, mod).?;
17151 if (field_ty.zigTypeTag(mod) == .NoReturn) {17300 if (field_ty.zigTypeTag(mod) == .NoReturn) {
17152 return .bool_false;17301 return .bool_false;
...@@ -17187,7 +17336,8 @@ fn analyzeCmp(...@@ -17187,7 +17336,8 @@ fn analyzeCmp(
17187 rhs_src: LazySrcLoc,17336 rhs_src: LazySrcLoc,
17188 is_equality_cmp: bool,17337 is_equality_cmp: bool,
17189) CompileError!Air.Inst.Ref {17338) CompileError!Air.Inst.Ref {
17190 const mod = sema.mod;17339 const pt = sema.pt;
17340 const mod = pt.zcu;
17191 const lhs_ty = sema.typeOf(lhs);17341 const lhs_ty = sema.typeOf(lhs);
17192 const rhs_ty = sema.typeOf(rhs);17342 const rhs_ty = sema.typeOf(rhs);
17193 if (lhs_ty.zigTypeTag(mod) != .Optional and rhs_ty.zigTypeTag(mod) != .Optional) {17343 if (lhs_ty.zigTypeTag(mod) != .Optional and rhs_ty.zigTypeTag(mod) != .Optional) {
...@@ -17215,7 +17365,7 @@ fn analyzeCmp(...@@ -17215,7 +17365,7 @@ fn analyzeCmp(
17215 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } });17365 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } });
17216 if (!resolved_type.isSelfComparable(mod, is_equality_cmp)) {17366 if (!resolved_type.isSelfComparable(mod, is_equality_cmp)) {
17217 return sema.fail(block, src, "operator {s} not allowed for type '{}'", .{17367 return sema.fail(block, src, "operator {s} not allowed for type '{}'", .{
17218 compareOperatorName(op), resolved_type.fmt(mod),17368 compareOperatorName(op), resolved_type.fmt(pt),
17219 });17369 });
17220 }17370 }
17221 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);17371 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
...@@ -17244,13 +17394,14 @@ fn cmpSelf(...@@ -17244,13 +17394,14 @@ fn cmpSelf(
17244 lhs_src: LazySrcLoc,17394 lhs_src: LazySrcLoc,
17245 rhs_src: LazySrcLoc,17395 rhs_src: LazySrcLoc,
17246) CompileError!Air.Inst.Ref {17396) CompileError!Air.Inst.Ref {
17247 const mod = sema.mod;17397 const pt = sema.pt;
17398 const mod = pt.zcu;
17248 const resolved_type = sema.typeOf(casted_lhs);17399 const resolved_type = sema.typeOf(casted_lhs);
17249 const runtime_src: LazySrcLoc = src: {17400 const runtime_src: LazySrcLoc = src: {
17250 if (try sema.resolveValue(casted_lhs)) |lhs_val| {17401 if (try sema.resolveValue(casted_lhs)) |lhs_val| {
17251 if (lhs_val.isUndef(mod)) return mod.undefRef(Type.bool);17402 if (lhs_val.isUndef(mod)) return pt.undefRef(Type.bool);
17252 if (try sema.resolveValue(casted_rhs)) |rhs_val| {17403 if (try sema.resolveValue(casted_rhs)) |rhs_val| {
17253 if (rhs_val.isUndef(mod)) return mod.undefRef(Type.bool);17404 if (rhs_val.isUndef(mod)) return pt.undefRef(Type.bool);
1725417405
17255 if (resolved_type.zigTypeTag(mod) == .Vector) {17406 if (resolved_type.zigTypeTag(mod) == .Vector) {
17256 const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_type);17407 const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_type);
...@@ -17273,7 +17424,7 @@ fn cmpSelf(...@@ -17273,7 +17424,7 @@ fn cmpSelf(
17273 // bool eq/neq more efficiently.17424 // bool eq/neq more efficiently.
17274 if (resolved_type.zigTypeTag(mod) == .Bool) {17425 if (resolved_type.zigTypeTag(mod) == .Bool) {
17275 if (try sema.resolveValue(casted_rhs)) |rhs_val| {17426 if (try sema.resolveValue(casted_rhs)) |rhs_val| {
17276 if (rhs_val.isUndef(mod)) return mod.undefRef(Type.bool);17427 if (rhs_val.isUndef(mod)) return pt.undefRef(Type.bool);
17277 return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(), lhs_src);17428 return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(), lhs_src);
17278 }17429 }
17279 }17430 }
...@@ -17310,24 +17461,24 @@ fn runtimeBoolCmp(...@@ -17310,24 +17461,24 @@ fn runtimeBoolCmp(
17310}17461}
1731117462
17312fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {17463fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
17313 const mod = sema.mod;17464 const pt = sema.pt;
17314 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;17465 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
17315 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);17466 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
17316 const ty = try sema.resolveType(block, operand_src, inst_data.operand);17467 const ty = try sema.resolveType(block, operand_src, inst_data.operand);
17317 switch (ty.zigTypeTag(mod)) {17468 switch (ty.zigTypeTag(pt.zcu)) {
17318 .Fn,17469 .Fn,
17319 .NoReturn,17470 .NoReturn,
17320 .Undefined,17471 .Undefined,
17321 .Null,17472 .Null,
17322 .Opaque,17473 .Opaque,
17323 => return sema.fail(block, operand_src, "no size available for type '{}'", .{ty.fmt(mod)}),17474 => return sema.fail(block, operand_src, "no size available for type '{}'", .{ty.fmt(pt)}),
1732417475
17325 .Type,17476 .Type,
17326 .EnumLiteral,17477 .EnumLiteral,
17327 .ComptimeFloat,17478 .ComptimeFloat,
17328 .ComptimeInt,17479 .ComptimeInt,
17329 .Void,17480 .Void,
17330 => return mod.intRef(Type.comptime_int, 0),17481 => return pt.intRef(Type.comptime_int, 0),
1733117482
17332 .Bool,17483 .Bool,
17333 .Int,17484 .Int,
...@@ -17345,12 +17496,13 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -17345,12 +17496,13 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
17345 .AnyFrame,17496 .AnyFrame,
17346 => {},17497 => {},
17347 }17498 }
17348 const val = try ty.lazyAbiSize(mod);17499 const val = try ty.lazyAbiSize(pt);
17349 return Air.internedToRef(val.toIntern());17500 return Air.internedToRef(val.toIntern());
17350}17501}
1735117502
17352fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {17503fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
17353 const mod = sema.mod;17504 const pt = sema.pt;
17505 const mod = pt.zcu;
17354 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;17506 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
17355 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);17507 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
17356 const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);17508 const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);
...@@ -17360,14 +17512,14 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -17360,14 +17512,14 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
17360 .Undefined,17512 .Undefined,
17361 .Null,17513 .Null,
17362 .Opaque,17514 .Opaque,
17363 => return sema.fail(block, operand_src, "no size available for type '{}'", .{operand_ty.fmt(mod)}),17515 => return sema.fail(block, operand_src, "no size available for type '{}'", .{operand_ty.fmt(pt)}),
1736417516
17365 .Type,17517 .Type,
17366 .EnumLiteral,17518 .EnumLiteral,
17367 .ComptimeFloat,17519 .ComptimeFloat,
17368 .ComptimeInt,17520 .ComptimeInt,
17369 .Void,17521 .Void,
17370 => return mod.intRef(Type.comptime_int, 0),17522 => return pt.intRef(Type.comptime_int, 0),
1737117523
17372 .Bool,17524 .Bool,
17373 .Int,17525 .Int,
...@@ -17385,8 +17537,8 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -17385,8 +17537,8 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
17385 .AnyFrame,17537 .AnyFrame,
17386 => {},17538 => {},
17387 }17539 }
17388 const bit_size = try operand_ty.bitSizeAdvanced(mod, .sema);17540 const bit_size = try operand_ty.bitSizeAdvanced(pt, .sema);
17389 return mod.intRef(Type.comptime_int, bit_size);17541 return pt.intRef(Type.comptime_int, bit_size);
17390}17542}
1739117543
17392fn zirThis(17544fn zirThis(
...@@ -17394,14 +17546,16 @@ fn zirThis(...@@ -17394,14 +17546,16 @@ fn zirThis(
17394 block: *Block,17546 block: *Block,
17395 extended: Zir.Inst.Extended.InstData,17547 extended: Zir.Inst.Extended.InstData,
17396) CompileError!Air.Inst.Ref {17548) CompileError!Air.Inst.Ref {
17397 const mod = sema.mod;17549 const pt = sema.pt;
17550 const mod = pt.zcu;
17398 const this_decl_index = mod.namespacePtr(block.namespace).decl_index;17551 const this_decl_index = mod.namespacePtr(block.namespace).decl_index;
17399 const src = block.nodeOffset(@bitCast(extended.operand));17552 const src = block.nodeOffset(@bitCast(extended.operand));
17400 return sema.analyzeDeclVal(block, src, this_decl_index);17553 return sema.analyzeDeclVal(block, src, this_decl_index);
17401}17554}
1740217555
17403fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {17556fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
17404 const mod = sema.mod;17557 const pt = sema.pt;
17558 const mod = pt.zcu;
17405 const ip = &mod.intern_pool;17559 const ip = &mod.intern_pool;
17406 const captures = mod.namespacePtr(block.namespace).getType(mod).getCaptures(mod);17560 const captures = mod.namespacePtr(block.namespace).getType(mod).getCaptures(mod);
1740717561
...@@ -17489,7 +17643,7 @@ fn zirRetAddr(...@@ -17489,7 +17643,7 @@ fn zirRetAddr(
17489 _ = extended;17643 _ = extended;
17490 if (block.is_comptime) {17644 if (block.is_comptime) {
17491 // TODO: we could give a meaningful lazy value here. #1493817645 // TODO: we could give a meaningful lazy value here. #14938
17492 return sema.mod.intRef(Type.usize, 0);17646 return sema.pt.intRef(Type.usize, 0);
17493 } else {17647 } else {
17494 return block.addNoOp(.ret_addr);17648 return block.addNoOp(.ret_addr);
17495 }17649 }
...@@ -17514,7 +17668,8 @@ fn zirBuiltinSrc(...@@ -17514,7 +17668,8 @@ fn zirBuiltinSrc(
17514 const tracy = trace(@src());17668 const tracy = trace(@src());
17515 defer tracy.end();17669 defer tracy.end();
1751617670
17517 const mod = sema.mod;17671 const pt = sema.pt;
17672 const mod = pt.zcu;
17518 const extra = sema.code.extraData(Zir.Inst.Src, extended.operand).data;17673 const extra = sema.code.extraData(Zir.Inst.Src, extended.operand).data;
17519 const fn_owner_decl = mod.funcOwnerDeclPtr(sema.func_index);17674 const fn_owner_decl = mod.funcOwnerDeclPtr(sema.func_index);
17520 const ip = &mod.intern_pool;17675 const ip = &mod.intern_pool;
...@@ -17522,43 +17677,43 @@ fn zirBuiltinSrc(...@@ -17522,43 +17677,43 @@ fn zirBuiltinSrc(
1752217677
17523 const func_name_val = v: {17678 const func_name_val = v: {
17524 const func_name_len = fn_owner_decl.name.length(ip);17679 const func_name_len = fn_owner_decl.name.length(ip);
17525 const array_ty = try ip.get(gpa, .{ .array_type = .{17680 const array_ty = try pt.intern(.{ .array_type = .{
17526 .len = func_name_len,17681 .len = func_name_len,
17527 .sentinel = .zero_u8,17682 .sentinel = .zero_u8,
17528 .child = .u8_type,17683 .child = .u8_type,
17529 } });17684 } });
17530 break :v try ip.get(gpa, .{ .slice = .{17685 break :v try pt.intern(.{ .slice = .{
17531 .ty = .slice_const_u8_sentinel_0_type,17686 .ty = .slice_const_u8_sentinel_0_type,
17532 .ptr = try ip.get(gpa, .{ .ptr = .{17687 .ptr = try pt.intern(.{ .ptr = .{
17533 .ty = .manyptr_const_u8_sentinel_0_type,17688 .ty = .manyptr_const_u8_sentinel_0_type,
17534 .base_addr = .{ .anon_decl = .{17689 .base_addr = .{ .anon_decl = .{
17535 .orig_ty = .slice_const_u8_sentinel_0_type,17690 .orig_ty = .slice_const_u8_sentinel_0_type,
17536 .val = try ip.get(gpa, .{ .aggregate = .{17691 .val = try pt.intern(.{ .aggregate = .{
17537 .ty = array_ty,17692 .ty = array_ty,
17538 .storage = .{ .bytes = fn_owner_decl.name.toString() },17693 .storage = .{ .bytes = fn_owner_decl.name.toString() },
17539 } }),17694 } }),
17540 } },17695 } },
17541 .byte_offset = 0,17696 .byte_offset = 0,
17542 } }),17697 } }),
17543 .len = (try mod.intValue(Type.usize, func_name_len)).toIntern(),17698 .len = (try pt.intValue(Type.usize, func_name_len)).toIntern(),
17544 } });17699 } });
17545 };17700 };
1754617701
17547 const file_name_val = v: {17702 const file_name_val = v: {
17548 // The compiler must not call realpath anywhere.17703 // The compiler must not call realpath anywhere.
17549 const file_name = try fn_owner_decl.getFileScope(mod).fullPath(sema.arena);17704 const file_name = try fn_owner_decl.getFileScope(mod).fullPath(sema.arena);
17550 const array_ty = try ip.get(gpa, .{ .array_type = .{17705 const array_ty = try pt.intern(.{ .array_type = .{
17551 .len = file_name.len,17706 .len = file_name.len,
17552 .sentinel = .zero_u8,17707 .sentinel = .zero_u8,
17553 .child = .u8_type,17708 .child = .u8_type,
17554 } });17709 } });
17555 break :v try ip.get(gpa, .{ .slice = .{17710 break :v try pt.intern(.{ .slice = .{
17556 .ty = .slice_const_u8_sentinel_0_type,17711 .ty = .slice_const_u8_sentinel_0_type,
17557 .ptr = try ip.get(gpa, .{ .ptr = .{17712 .ptr = try pt.intern(.{ .ptr = .{
17558 .ty = .manyptr_const_u8_sentinel_0_type,17713 .ty = .manyptr_const_u8_sentinel_0_type,
17559 .base_addr = .{ .anon_decl = .{17714 .base_addr = .{ .anon_decl = .{
17560 .orig_ty = .slice_const_u8_sentinel_0_type,17715 .orig_ty = .slice_const_u8_sentinel_0_type,
17561 .val = try ip.get(gpa, .{ .aggregate = .{17716 .val = try pt.intern(.{ .aggregate = .{
17562 .ty = array_ty,17717 .ty = array_ty,
17563 .storage = .{17718 .storage = .{
17564 .bytes = try ip.getOrPutString(gpa, file_name, .maybe_embedded_nulls),17719 .bytes = try ip.getOrPutString(gpa, file_name, .maybe_embedded_nulls),
...@@ -17567,35 +17722,36 @@ fn zirBuiltinSrc(...@@ -17567,35 +17722,36 @@ fn zirBuiltinSrc(
17567 } },17722 } },
17568 .byte_offset = 0,17723 .byte_offset = 0,
17569 } }),17724 } }),
17570 .len = (try mod.intValue(Type.usize, file_name.len)).toIntern(),17725 .len = (try pt.intValue(Type.usize, file_name.len)).toIntern(),
17571 } });17726 } });
17572 };17727 };
1757317728
17574 const src_loc_ty = try mod.getBuiltinType("SourceLocation");17729 const src_loc_ty = try pt.getBuiltinType("SourceLocation");
17575 const fields = .{17730 const fields = .{
17576 // file: [:0]const u8,17731 // file: [:0]const u8,
17577 file_name_val,17732 file_name_val,
17578 // fn_name: [:0]const u8,17733 // fn_name: [:0]const u8,
17579 func_name_val,17734 func_name_val,
17580 // line: u32,17735 // line: u32,
17581 (try mod.intValue(Type.u32, extra.line + 1)).toIntern(),17736 (try pt.intValue(Type.u32, extra.line + 1)).toIntern(),
17582 // column: u32,17737 // column: u32,
17583 (try mod.intValue(Type.u32, extra.column + 1)).toIntern(),17738 (try pt.intValue(Type.u32, extra.column + 1)).toIntern(),
17584 };17739 };
17585 return Air.internedToRef((try mod.intern(.{ .aggregate = .{17740 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
17586 .ty = src_loc_ty.toIntern(),17741 .ty = src_loc_ty.toIntern(),
17587 .storage = .{ .elems = &fields },17742 .storage = .{ .elems = &fields },
17588 } })));17743 } })));
17589}17744}
1759017745
17591fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {17746fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
17592 const mod = sema.mod;17747 const pt = sema.pt;
17748 const mod = pt.zcu;
17593 const gpa = sema.gpa;17749 const gpa = sema.gpa;
17594 const ip = &mod.intern_pool;17750 const ip = &mod.intern_pool;
17595 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;17751 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
17596 const src = block.nodeOffset(inst_data.src_node);17752 const src = block.nodeOffset(inst_data.src_node);
17597 const ty = try sema.resolveType(block, src, inst_data.operand);17753 const ty = try sema.resolveType(block, src, inst_data.operand);
17598 const type_info_ty = try mod.getBuiltinType("Type");17754 const type_info_ty = try pt.getBuiltinType("Type");
17599 const type_info_tag_ty = type_info_ty.unionTagType(mod).?;17755 const type_info_tag_ty = type_info_ty.unionTagType(mod).?;
1760017756
17601 if (ty.typeDeclInst(mod)) |type_decl_inst| {17757 if (ty.typeDeclInst(mod)) |type_decl_inst| {
...@@ -17612,9 +17768,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17612,9 +17768,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17612 .Undefined,17768 .Undefined,
17613 .Null,17769 .Null,
17614 .EnumLiteral,17770 .EnumLiteral,
17615 => |type_info_tag| return Air.internedToRef((try mod.intern(.{ .un = .{17771 => |type_info_tag| return Air.internedToRef((try pt.intern(.{ .un = .{
17616 .ty = type_info_ty.toIntern(),17772 .ty = type_info_ty.toIntern(),
17617 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(type_info_tag))).toIntern(),17773 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(type_info_tag))).toIntern(),
17618 .val = .void_value,17774 .val = .void_value,
17619 } }))),17775 } }))),
17620 .Fn => {17776 .Fn => {
...@@ -17643,8 +17799,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17643,8 +17799,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17643 for (param_vals, 0..) |*param_val, i| {17799 for (param_vals, 0..) |*param_val, i| {
17644 const param_ty = func_ty_info.param_types.get(ip)[i];17800 const param_ty = func_ty_info.param_types.get(ip)[i];
17645 const is_generic = param_ty == .generic_poison_type;17801 const is_generic = param_ty == .generic_poison_type;
17646 const param_ty_val = try ip.get(gpa, .{ .opt = .{17802 const param_ty_val = try pt.intern(.{ .opt = .{
17647 .ty = try ip.get(gpa, .{ .opt_type = .type_type }),17803 .ty = try pt.intern(.{ .opt_type = .type_type }),
17648 .val = if (is_generic) .none else param_ty,17804 .val = if (is_generic) .none else param_ty,
17649 } });17805 } });
1765017806
...@@ -17661,22 +17817,22 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17661,22 +17817,22 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17661 // type: ?type,17817 // type: ?type,
17662 param_ty_val,17818 param_ty_val,
17663 };17819 };
17664 param_val.* = try mod.intern(.{ .aggregate = .{17820 param_val.* = try pt.intern(.{ .aggregate = .{
17665 .ty = param_info_ty.toIntern(),17821 .ty = param_info_ty.toIntern(),
17666 .storage = .{ .elems = &param_fields },17822 .storage = .{ .elems = &param_fields },
17667 } });17823 } });
17668 }17824 }
1766917825
17670 const args_val = v: {17826 const args_val = v: {
17671 const new_decl_ty = try mod.arrayType(.{17827 const new_decl_ty = try pt.arrayType(.{
17672 .len = param_vals.len,17828 .len = param_vals.len,
17673 .child = param_info_ty.toIntern(),17829 .child = param_info_ty.toIntern(),
17674 });17830 });
17675 const new_decl_val = try mod.intern(.{ .aggregate = .{17831 const new_decl_val = try pt.intern(.{ .aggregate = .{
17676 .ty = new_decl_ty.toIntern(),17832 .ty = new_decl_ty.toIntern(),
17677 .storage = .{ .elems = param_vals },17833 .storage = .{ .elems = param_vals },
17678 } });17834 } });
17679 const slice_ty = (try mod.ptrTypeSema(.{17835 const slice_ty = (try pt.ptrTypeSema(.{
17680 .child = param_info_ty.toIntern(),17836 .child = param_info_ty.toIntern(),
17681 .flags = .{17837 .flags = .{
17682 .size = .Slice,17838 .size = .Slice,
...@@ -17684,9 +17840,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17684,9 +17840,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17684 },17840 },
17685 })).toIntern();17841 })).toIntern();
17686 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();17842 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();
17687 break :v try mod.intern(.{ .slice = .{17843 break :v try pt.intern(.{ .slice = .{
17688 .ty = slice_ty,17844 .ty = slice_ty,
17689 .ptr = try mod.intern(.{ .ptr = .{17845 .ptr = try pt.intern(.{ .ptr = .{
17690 .ty = manyptr_ty,17846 .ty = manyptr_ty,
17691 .base_addr = .{ .anon_decl = .{17847 .base_addr = .{ .anon_decl = .{
17692 .orig_ty = manyptr_ty,17848 .orig_ty = manyptr_ty,
...@@ -17694,23 +17850,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17694,23 +17850,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17694 } },17850 } },
17695 .byte_offset = 0,17851 .byte_offset = 0,
17696 } }),17852 } }),
17697 .len = (try mod.intValue(Type.usize, param_vals.len)).toIntern(),17853 .len = (try pt.intValue(Type.usize, param_vals.len)).toIntern(),
17698 } });17854 } });
17699 };17855 };
1770017856
17701 const ret_ty_opt = try mod.intern(.{ .opt = .{17857 const ret_ty_opt = try pt.intern(.{ .opt = .{
17702 .ty = try ip.get(gpa, .{ .opt_type = .type_type }),17858 .ty = try pt.intern(.{ .opt_type = .type_type }),
17703 .val = if (func_ty_info.return_type == .generic_poison_type)17859 .val = if (func_ty_info.return_type == .generic_poison_type)
17704 .none17860 .none
17705 else17861 else
17706 func_ty_info.return_type,17862 func_ty_info.return_type,
17707 } });17863 } });
1770817864
17709 const callconv_ty = try mod.getBuiltinType("CallingConvention");17865 const callconv_ty = try pt.getBuiltinType("CallingConvention");
1771017866
17711 const field_values = .{17867 const field_values = .{
17712 // calling_convention: CallingConvention,17868 // calling_convention: CallingConvention,
17713 (try mod.enumValueFieldIndex(callconv_ty, @intFromEnum(func_ty_info.cc))).toIntern(),17869 (try pt.enumValueFieldIndex(callconv_ty, @intFromEnum(func_ty_info.cc))).toIntern(),
17714 // is_generic: bool,17870 // is_generic: bool,
17715 Value.makeBool(func_ty_info.is_generic).toIntern(),17871 Value.makeBool(func_ty_info.is_generic).toIntern(),
17716 // is_var_args: bool,17872 // is_var_args: bool,
...@@ -17720,10 +17876,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17720,10 +17876,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17720 // args: []const Fn.Param,17876 // args: []const Fn.Param,
17721 args_val,17877 args_val,
17722 };17878 };
17723 return Air.internedToRef((try mod.intern(.{ .un = .{17879 return Air.internedToRef((try pt.intern(.{ .un = .{
17724 .ty = type_info_ty.toIntern(),17880 .ty = type_info_ty.toIntern(),
17725 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Fn))).toIntern(),17881 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Fn))).toIntern(),
17726 .val = try mod.intern(.{ .aggregate = .{17882 .val = try pt.intern(.{ .aggregate = .{
17727 .ty = fn_info_ty.toIntern(),17883 .ty = fn_info_ty.toIntern(),
17728 .storage = .{ .elems = &field_values },17884 .storage = .{ .elems = &field_values },
17729 } }),17885 } }),
...@@ -17740,18 +17896,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17740,18 +17896,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17740 const int_info_decl = mod.declPtr(int_info_decl_index);17896 const int_info_decl = mod.declPtr(int_info_decl_index);
17741 const int_info_ty = int_info_decl.val.toType();17897 const int_info_ty = int_info_decl.val.toType();
1774217898
17743 const signedness_ty = try mod.getBuiltinType("Signedness");17899 const signedness_ty = try pt.getBuiltinType("Signedness");
17744 const info = ty.intInfo(mod);17900 const info = ty.intInfo(mod);
17745 const field_values = .{17901 const field_values = .{
17746 // signedness: Signedness,17902 // signedness: Signedness,
17747 (try mod.enumValueFieldIndex(signedness_ty, @intFromEnum(info.signedness))).toIntern(),17903 (try pt.enumValueFieldIndex(signedness_ty, @intFromEnum(info.signedness))).toIntern(),
17748 // bits: u16,17904 // bits: u16,
17749 (try mod.intValue(Type.u16, info.bits)).toIntern(),17905 (try pt.intValue(Type.u16, info.bits)).toIntern(),
17750 };17906 };
17751 return Air.internedToRef((try mod.intern(.{ .un = .{17907 return Air.internedToRef((try pt.intern(.{ .un = .{
17752 .ty = type_info_ty.toIntern(),17908 .ty = type_info_ty.toIntern(),
17753 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Int))).toIntern(),17909 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Int))).toIntern(),
17754 .val = try mod.intern(.{ .aggregate = .{17910 .val = try pt.intern(.{ .aggregate = .{
17755 .ty = int_info_ty.toIntern(),17911 .ty = int_info_ty.toIntern(),
17756 .storage = .{ .elems = &field_values },17912 .storage = .{ .elems = &field_values },
17757 } }),17913 } }),
...@@ -17770,12 +17926,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17770,12 +17926,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1777017926
17771 const field_vals = .{17927 const field_vals = .{
17772 // bits: u16,17928 // bits: u16,
17773 (try mod.intValue(Type.u16, ty.bitSize(mod))).toIntern(),17929 (try pt.intValue(Type.u16, ty.bitSize(pt))).toIntern(),
17774 };17930 };
17775 return Air.internedToRef((try mod.intern(.{ .un = .{17931 return Air.internedToRef((try pt.intern(.{ .un = .{
17776 .ty = type_info_ty.toIntern(),17932 .ty = type_info_ty.toIntern(),
17777 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Float))).toIntern(),17933 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Float))).toIntern(),
17778 .val = try mod.intern(.{ .aggregate = .{17934 .val = try pt.intern(.{ .aggregate = .{
17779 .ty = float_info_ty.toIntern(),17935 .ty = float_info_ty.toIntern(),
17780 .storage = .{ .elems = &field_vals },17936 .storage = .{ .elems = &field_vals },
17781 } }),17937 } }),
...@@ -17784,16 +17940,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17784,16 +17940,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17784 .Pointer => {17940 .Pointer => {
17785 const info = ty.ptrInfo(mod);17941 const info = ty.ptrInfo(mod);
17786 const alignment = if (info.flags.alignment.toByteUnits()) |alignment|17942 const alignment = if (info.flags.alignment.toByteUnits()) |alignment|
17787 try mod.intValue(Type.comptime_int, alignment)17943 try pt.intValue(Type.comptime_int, alignment)
17788 else17944 else
17789 try Type.fromInterned(info.child).lazyAbiAlignment(mod);17945 try Type.fromInterned(info.child).lazyAbiAlignment(pt);
1779017946
17791 const addrspace_ty = try mod.getBuiltinType("AddressSpace");17947 const addrspace_ty = try pt.getBuiltinType("AddressSpace");
17792 const pointer_ty = t: {17948 const pointer_ty = t: {
17793 const decl_index = (try sema.namespaceLookup(17949 const decl_index = (try sema.namespaceLookup(
17794 block,17950 block,
17795 src,17951 src,
17796 (try mod.getBuiltinType("Type")).getNamespaceIndex(mod),17952 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
17797 try ip.getOrPutString(gpa, "Pointer", .no_embedded_nulls),17953 try ip.getOrPutString(gpa, "Pointer", .no_embedded_nulls),
17798 )).?;17954 )).?;
17799 try sema.ensureDeclAnalyzed(decl_index);17955 try sema.ensureDeclAnalyzed(decl_index);
...@@ -17814,7 +17970,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17814,7 +17970,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1781417970
17815 const field_values = .{17971 const field_values = .{
17816 // size: Size,17972 // size: Size,
17817 (try mod.enumValueFieldIndex(ptr_size_ty, @intFromEnum(info.flags.size))).toIntern(),17973 (try pt.enumValueFieldIndex(ptr_size_ty, @intFromEnum(info.flags.size))).toIntern(),
17818 // is_const: bool,17974 // is_const: bool,
17819 Value.makeBool(info.flags.is_const).toIntern(),17975 Value.makeBool(info.flags.is_const).toIntern(),
17820 // is_volatile: bool,17976 // is_volatile: bool,
...@@ -17822,7 +17978,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17822,7 +17978,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17822 // alignment: comptime_int,17978 // alignment: comptime_int,
17823 alignment.toIntern(),17979 alignment.toIntern(),
17824 // address_space: AddressSpace17980 // address_space: AddressSpace
17825 (try mod.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.flags.address_space))).toIntern(),17981 (try pt.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.flags.address_space))).toIntern(),
17826 // child: type,17982 // child: type,
17827 info.child,17983 info.child,
17828 // is_allowzero: bool,17984 // is_allowzero: bool,
...@@ -17833,10 +17989,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17833,10 +17989,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17833 else => Value.fromInterned(info.sentinel),17989 else => Value.fromInterned(info.sentinel),
17834 })).toIntern(),17990 })).toIntern(),
17835 };17991 };
17836 return Air.internedToRef((try mod.intern(.{ .un = .{17992 return Air.internedToRef((try pt.intern(.{ .un = .{
17837 .ty = type_info_ty.toIntern(),17993 .ty = type_info_ty.toIntern(),
17838 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Pointer))).toIntern(),17994 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Pointer))).toIntern(),
17839 .val = try mod.intern(.{ .aggregate = .{17995 .val = try pt.intern(.{ .aggregate = .{
17840 .ty = pointer_ty.toIntern(),17996 .ty = pointer_ty.toIntern(),
17841 .storage = .{ .elems = &field_values },17997 .storage = .{ .elems = &field_values },
17842 } }),17998 } }),
...@@ -17858,16 +18014,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17858,16 +18014,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17858 const info = ty.arrayInfo(mod);18014 const info = ty.arrayInfo(mod);
17859 const field_values = .{18015 const field_values = .{
17860 // len: comptime_int,18016 // len: comptime_int,
17861 (try mod.intValue(Type.comptime_int, info.len)).toIntern(),18017 (try pt.intValue(Type.comptime_int, info.len)).toIntern(),
17862 // child: type,18018 // child: type,
17863 info.elem_type.toIntern(),18019 info.elem_type.toIntern(),
17864 // sentinel: ?*const anyopaque,18020 // sentinel: ?*const anyopaque,
17865 (try sema.optRefValue(info.sentinel)).toIntern(),18021 (try sema.optRefValue(info.sentinel)).toIntern(),
17866 };18022 };
17867 return Air.internedToRef((try mod.intern(.{ .un = .{18023 return Air.internedToRef((try pt.intern(.{ .un = .{
17868 .ty = type_info_ty.toIntern(),18024 .ty = type_info_ty.toIntern(),
17869 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Array))).toIntern(),18025 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Array))).toIntern(),
17870 .val = try mod.intern(.{ .aggregate = .{18026 .val = try pt.intern(.{ .aggregate = .{
17871 .ty = array_field_ty.toIntern(),18027 .ty = array_field_ty.toIntern(),
17872 .storage = .{ .elems = &field_values },18028 .storage = .{ .elems = &field_values },
17873 } }),18029 } }),
...@@ -17889,14 +18045,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17889,14 +18045,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17889 const info = ty.arrayInfo(mod);18045 const info = ty.arrayInfo(mod);
17890 const field_values = .{18046 const field_values = .{
17891 // len: comptime_int,18047 // len: comptime_int,
17892 (try mod.intValue(Type.comptime_int, info.len)).toIntern(),18048 (try pt.intValue(Type.comptime_int, info.len)).toIntern(),
17893 // child: type,18049 // child: type,
17894 info.elem_type.toIntern(),18050 info.elem_type.toIntern(),
17895 };18051 };
17896 return Air.internedToRef((try mod.intern(.{ .un = .{18052 return Air.internedToRef((try pt.intern(.{ .un = .{
17897 .ty = type_info_ty.toIntern(),18053 .ty = type_info_ty.toIntern(),
17898 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Vector))).toIntern(),18054 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Vector))).toIntern(),
17899 .val = try mod.intern(.{ .aggregate = .{18055 .val = try pt.intern(.{ .aggregate = .{
17900 .ty = vector_field_ty.toIntern(),18056 .ty = vector_field_ty.toIntern(),
17901 .storage = .{ .elems = &field_values },18057 .storage = .{ .elems = &field_values },
17902 } }),18058 } }),
...@@ -17919,10 +18075,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17919,10 +18075,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17919 // child: type,18075 // child: type,
17920 ty.optionalChild(mod).toIntern(),18076 ty.optionalChild(mod).toIntern(),
17921 };18077 };
17922 return Air.internedToRef((try mod.intern(.{ .un = .{18078 return Air.internedToRef((try pt.intern(.{ .un = .{
17923 .ty = type_info_ty.toIntern(),18079 .ty = type_info_ty.toIntern(),
17924 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Optional))).toIntern(),18080 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Optional))).toIntern(),
17925 .val = try mod.intern(.{ .aggregate = .{18081 .val = try pt.intern(.{ .aggregate = .{
17926 .ty = optional_field_ty.toIntern(),18082 .ty = optional_field_ty.toIntern(),
17927 .storage = .{ .elems = &field_values },18083 .storage = .{ .elems = &field_values },
17928 } }),18084 } }),
...@@ -17954,18 +18110,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17954,18 +18110,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17954 const error_name = names.get(ip)[error_index];18110 const error_name = names.get(ip)[error_index];
17955 const error_name_len = error_name.length(ip);18111 const error_name_len = error_name.length(ip);
17956 const error_name_val = v: {18112 const error_name_val = v: {
17957 const new_decl_ty = try mod.arrayType(.{18113 const new_decl_ty = try pt.arrayType(.{
17958 .len = error_name_len,18114 .len = error_name_len,
17959 .sentinel = .zero_u8,18115 .sentinel = .zero_u8,
17960 .child = .u8_type,18116 .child = .u8_type,
17961 });18117 });
17962 const new_decl_val = try mod.intern(.{ .aggregate = .{18118 const new_decl_val = try pt.intern(.{ .aggregate = .{
17963 .ty = new_decl_ty.toIntern(),18119 .ty = new_decl_ty.toIntern(),
17964 .storage = .{ .bytes = error_name.toString() },18120 .storage = .{ .bytes = error_name.toString() },
17965 } });18121 } });
17966 break :v try mod.intern(.{ .slice = .{18122 break :v try pt.intern(.{ .slice = .{
17967 .ty = .slice_const_u8_sentinel_0_type,18123 .ty = .slice_const_u8_sentinel_0_type,
17968 .ptr = try mod.intern(.{ .ptr = .{18124 .ptr = try pt.intern(.{ .ptr = .{
17969 .ty = .manyptr_const_u8_sentinel_0_type,18125 .ty = .manyptr_const_u8_sentinel_0_type,
17970 .base_addr = .{ .anon_decl = .{18126 .base_addr = .{ .anon_decl = .{
17971 .val = new_decl_val,18127 .val = new_decl_val,
...@@ -17973,7 +18129,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17973,7 +18129,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17973 } },18129 } },
17974 .byte_offset = 0,18130 .byte_offset = 0,
17975 } }),18131 } }),
17976 .len = (try mod.intValue(Type.usize, error_name_len)).toIntern(),18132 .len = (try pt.intValue(Type.usize, error_name_len)).toIntern(),
17977 } });18133 } });
17978 };18134 };
1797918135
...@@ -17981,7 +18137,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17981,7 +18137,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17981 // name: [:0]const u8,18137 // name: [:0]const u8,
17982 error_name_val,18138 error_name_val,
17983 };18139 };
17984 field_val.* = try mod.intern(.{ .aggregate = .{18140 field_val.* = try pt.intern(.{ .aggregate = .{
17985 .ty = error_field_ty.toIntern(),18141 .ty = error_field_ty.toIntern(),
17986 .storage = .{ .elems = &error_field_fields },18142 .storage = .{ .elems = &error_field_fields },
17987 } });18143 } });
...@@ -17992,27 +18148,27 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17992,27 +18148,27 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17992 };18148 };
1799318149
17994 // Build our ?[]const Error value18150 // Build our ?[]const Error value
17995 const slice_errors_ty = try mod.ptrTypeSema(.{18151 const slice_errors_ty = try pt.ptrTypeSema(.{
17996 .child = error_field_ty.toIntern(),18152 .child = error_field_ty.toIntern(),
17997 .flags = .{18153 .flags = .{
17998 .size = .Slice,18154 .size = .Slice,
17999 .is_const = true,18155 .is_const = true,
18000 },18156 },
18001 });18157 });
18002 const opt_slice_errors_ty = try mod.optionalType(slice_errors_ty.toIntern());18158 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: {18159 const errors_payload_val: InternPool.Index = if (error_field_vals) |vals| v: {
18004 const array_errors_ty = try mod.arrayType(.{18160 const array_errors_ty = try pt.arrayType(.{
18005 .len = vals.len,18161 .len = vals.len,
18006 .child = error_field_ty.toIntern(),18162 .child = error_field_ty.toIntern(),
18007 });18163 });
18008 const new_decl_val = try mod.intern(.{ .aggregate = .{18164 const new_decl_val = try pt.intern(.{ .aggregate = .{
18009 .ty = array_errors_ty.toIntern(),18165 .ty = array_errors_ty.toIntern(),
18010 .storage = .{ .elems = vals },18166 .storage = .{ .elems = vals },
18011 } });18167 } });
18012 const manyptr_errors_ty = slice_errors_ty.slicePtrFieldType(mod).toIntern();18168 const manyptr_errors_ty = slice_errors_ty.slicePtrFieldType(mod).toIntern();
18013 break :v try mod.intern(.{ .slice = .{18169 break :v try pt.intern(.{ .slice = .{
18014 .ty = slice_errors_ty.toIntern(),18170 .ty = slice_errors_ty.toIntern(),
18015 .ptr = try mod.intern(.{ .ptr = .{18171 .ptr = try pt.intern(.{ .ptr = .{
18016 .ty = manyptr_errors_ty,18172 .ty = manyptr_errors_ty,
18017 .base_addr = .{ .anon_decl = .{18173 .base_addr = .{ .anon_decl = .{
18018 .orig_ty = manyptr_errors_ty,18174 .orig_ty = manyptr_errors_ty,
...@@ -18020,18 +18176,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18020,18 +18176,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18020 } },18176 } },
18021 .byte_offset = 0,18177 .byte_offset = 0,
18022 } }),18178 } }),
18023 .len = (try mod.intValue(Type.usize, vals.len)).toIntern(),18179 .len = (try pt.intValue(Type.usize, vals.len)).toIntern(),
18024 } });18180 } });
18025 } else .none;18181 } else .none;
18026 const errors_val = try mod.intern(.{ .opt = .{18182 const errors_val = try pt.intern(.{ .opt = .{
18027 .ty = opt_slice_errors_ty.toIntern(),18183 .ty = opt_slice_errors_ty.toIntern(),
18028 .val = errors_payload_val,18184 .val = errors_payload_val,
18029 } });18185 } });
1803018186
18031 // Construct Type{ .ErrorSet = errors_val }18187 // Construct Type{ .ErrorSet = errors_val }
18032 return Air.internedToRef((try mod.intern(.{ .un = .{18188 return Air.internedToRef((try pt.intern(.{ .un = .{
18033 .ty = type_info_ty.toIntern(),18189 .ty = type_info_ty.toIntern(),
18034 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.ErrorSet))).toIntern(),18190 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.ErrorSet))).toIntern(),
18035 .val = errors_val,18191 .val = errors_val,
18036 } })));18192 } })));
18037 },18193 },
...@@ -18054,10 +18210,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18054,10 +18210,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18054 // payload: type,18210 // payload: type,
18055 ty.errorUnionPayload(mod).toIntern(),18211 ty.errorUnionPayload(mod).toIntern(),
18056 };18212 };
18057 return Air.internedToRef((try mod.intern(.{ .un = .{18213 return Air.internedToRef((try pt.intern(.{ .un = .{
18058 .ty = type_info_ty.toIntern(),18214 .ty = type_info_ty.toIntern(),
18059 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.ErrorUnion))).toIntern(),18215 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.ErrorUnion))).toIntern(),
18060 .val = try mod.intern(.{ .aggregate = .{18216 .val = try pt.intern(.{ .aggregate = .{
18061 .ty = error_union_field_ty.toIntern(),18217 .ty = error_union_field_ty.toIntern(),
18062 .storage = .{ .elems = &field_values },18218 .storage = .{ .elems = &field_values },
18063 } }),18219 } }),
...@@ -18082,30 +18238,31 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18082,30 +18238,31 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18082 for (enum_field_vals, 0..) |*field_val, tag_index| {18238 for (enum_field_vals, 0..) |*field_val, tag_index| {
18083 const enum_type = ip.loadEnumType(ty.toIntern());18239 const enum_type = ip.loadEnumType(ty.toIntern());
18084 const value_val = if (enum_type.values.len > 0)18240 const value_val = if (enum_type.values.len > 0)
18085 try mod.intern_pool.getCoercedInts(18241 try ip.getCoercedInts(
18086 mod.gpa,18242 mod.gpa,
18087 mod.intern_pool.indexToKey(enum_type.values.get(ip)[tag_index]).int,18243 pt.tid,
18244 ip.indexToKey(enum_type.values.get(ip)[tag_index]).int,
18088 .comptime_int_type,18245 .comptime_int_type,
18089 )18246 )
18090 else18247 else
18091 (try mod.intValue(Type.comptime_int, tag_index)).toIntern();18248 (try pt.intValue(Type.comptime_int, tag_index)).toIntern();
1809218249
18093 // TODO: write something like getCoercedInts to avoid needing to dupe18250 // TODO: write something like getCoercedInts to avoid needing to dupe
18094 const name_val = v: {18251 const name_val = v: {
18095 const tag_name = enum_type.names.get(ip)[tag_index];18252 const tag_name = enum_type.names.get(ip)[tag_index];
18096 const tag_name_len = tag_name.length(ip);18253 const tag_name_len = tag_name.length(ip);
18097 const new_decl_ty = try mod.arrayType(.{18254 const new_decl_ty = try pt.arrayType(.{
18098 .len = tag_name_len,18255 .len = tag_name_len,
18099 .sentinel = .zero_u8,18256 .sentinel = .zero_u8,
18100 .child = .u8_type,18257 .child = .u8_type,
18101 });18258 });
18102 const new_decl_val = try mod.intern(.{ .aggregate = .{18259 const new_decl_val = try pt.intern(.{ .aggregate = .{
18103 .ty = new_decl_ty.toIntern(),18260 .ty = new_decl_ty.toIntern(),
18104 .storage = .{ .bytes = tag_name.toString() },18261 .storage = .{ .bytes = tag_name.toString() },
18105 } });18262 } });
18106 break :v try mod.intern(.{ .slice = .{18263 break :v try pt.intern(.{ .slice = .{
18107 .ty = .slice_const_u8_sentinel_0_type,18264 .ty = .slice_const_u8_sentinel_0_type,
18108 .ptr = try mod.intern(.{ .ptr = .{18265 .ptr = try pt.intern(.{ .ptr = .{
18109 .ty = .manyptr_const_u8_sentinel_0_type,18266 .ty = .manyptr_const_u8_sentinel_0_type,
18110 .base_addr = .{ .anon_decl = .{18267 .base_addr = .{ .anon_decl = .{
18111 .val = new_decl_val,18268 .val = new_decl_val,
...@@ -18113,7 +18270,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18113,7 +18270,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18113 } },18270 } },
18114 .byte_offset = 0,18271 .byte_offset = 0,
18115 } }),18272 } }),
18116 .len = (try mod.intValue(Type.usize, tag_name_len)).toIntern(),18273 .len = (try pt.intValue(Type.usize, tag_name_len)).toIntern(),
18117 } });18274 } });
18118 };18275 };
1811918276
...@@ -18123,22 +18280,22 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18123,22 +18280,22 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18123 // value: comptime_int,18280 // value: comptime_int,
18124 value_val,18281 value_val,
18125 };18282 };
18126 field_val.* = try mod.intern(.{ .aggregate = .{18283 field_val.* = try pt.intern(.{ .aggregate = .{
18127 .ty = enum_field_ty.toIntern(),18284 .ty = enum_field_ty.toIntern(),
18128 .storage = .{ .elems = &enum_field_fields },18285 .storage = .{ .elems = &enum_field_fields },
18129 } });18286 } });
18130 }18287 }
1813118288
18132 const fields_val = v: {18289 const fields_val = v: {
18133 const fields_array_ty = try mod.arrayType(.{18290 const fields_array_ty = try pt.arrayType(.{
18134 .len = enum_field_vals.len,18291 .len = enum_field_vals.len,
18135 .child = enum_field_ty.toIntern(),18292 .child = enum_field_ty.toIntern(),
18136 });18293 });
18137 const new_decl_val = try mod.intern(.{ .aggregate = .{18294 const new_decl_val = try pt.intern(.{ .aggregate = .{
18138 .ty = fields_array_ty.toIntern(),18295 .ty = fields_array_ty.toIntern(),
18139 .storage = .{ .elems = enum_field_vals },18296 .storage = .{ .elems = enum_field_vals },
18140 } });18297 } });
18141 const slice_ty = (try mod.ptrTypeSema(.{18298 const slice_ty = (try pt.ptrTypeSema(.{
18142 .child = enum_field_ty.toIntern(),18299 .child = enum_field_ty.toIntern(),
18143 .flags = .{18300 .flags = .{
18144 .size = .Slice,18301 .size = .Slice,
...@@ -18146,9 +18303,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18146,9 +18303,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18146 },18303 },
18147 })).toIntern();18304 })).toIntern();
18148 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();18305 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();
18149 break :v try mod.intern(.{ .slice = .{18306 break :v try pt.intern(.{ .slice = .{
18150 .ty = slice_ty,18307 .ty = slice_ty,
18151 .ptr = try mod.intern(.{ .ptr = .{18308 .ptr = try pt.intern(.{ .ptr = .{
18152 .ty = manyptr_ty,18309 .ty = manyptr_ty,
18153 .base_addr = .{ .anon_decl = .{18310 .base_addr = .{ .anon_decl = .{
18154 .val = new_decl_val,18311 .val = new_decl_val,
...@@ -18156,7 +18313,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18156,7 +18313,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18156 } },18313 } },
18157 .byte_offset = 0,18314 .byte_offset = 0,
18158 } }),18315 } }),
18159 .len = (try mod.intValue(Type.usize, enum_field_vals.len)).toIntern(),18316 .len = (try pt.intValue(Type.usize, enum_field_vals.len)).toIntern(),
18160 } });18317 } });
18161 };18318 };
1816218319
...@@ -18184,10 +18341,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18184,10 +18341,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18184 // is_exhaustive: bool,18341 // is_exhaustive: bool,
18185 is_exhaustive.toIntern(),18342 is_exhaustive.toIntern(),
18186 };18343 };
18187 return Air.internedToRef((try mod.intern(.{ .un = .{18344 return Air.internedToRef((try pt.intern(.{ .un = .{
18188 .ty = type_info_ty.toIntern(),18345 .ty = type_info_ty.toIntern(),
18189 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Enum))).toIntern(),18346 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Enum))).toIntern(),
18190 .val = try mod.intern(.{ .aggregate = .{18347 .val = try pt.intern(.{ .aggregate = .{
18191 .ty = type_enum_ty.toIntern(),18348 .ty = type_enum_ty.toIntern(),
18192 .storage = .{ .elems = &field_values },18349 .storage = .{ .elems = &field_values },
18193 } }),18350 } }),
...@@ -18218,7 +18375,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18218,7 +18375,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18218 break :t union_field_ty_decl.val.toType();18375 break :t union_field_ty_decl.val.toType();
18219 };18376 };
1822018377
18221 try ty.resolveLayout(mod); // Getting alignment requires type layout18378 try ty.resolveLayout(pt); // Getting alignment requires type layout
18222 const union_obj = mod.typeToUnion(ty).?;18379 const union_obj = mod.typeToUnion(ty).?;
18223 const tag_type = union_obj.loadTagType(ip);18380 const tag_type = union_obj.loadTagType(ip);
18224 const layout = union_obj.getLayout(ip);18381 const layout = union_obj.getLayout(ip);
...@@ -18230,18 +18387,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18230,18 +18387,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18230 const name_val = v: {18387 const name_val = v: {
18231 const field_name = tag_type.names.get(ip)[field_index];18388 const field_name = tag_type.names.get(ip)[field_index];
18232 const field_name_len = field_name.length(ip);18389 const field_name_len = field_name.length(ip);
18233 const new_decl_ty = try mod.arrayType(.{18390 const new_decl_ty = try pt.arrayType(.{
18234 .len = field_name_len,18391 .len = field_name_len,
18235 .sentinel = .zero_u8,18392 .sentinel = .zero_u8,
18236 .child = .u8_type,18393 .child = .u8_type,
18237 });18394 });
18238 const new_decl_val = try mod.intern(.{ .aggregate = .{18395 const new_decl_val = try pt.intern(.{ .aggregate = .{
18239 .ty = new_decl_ty.toIntern(),18396 .ty = new_decl_ty.toIntern(),
18240 .storage = .{ .bytes = field_name.toString() },18397 .storage = .{ .bytes = field_name.toString() },
18241 } });18398 } });
18242 break :v try mod.intern(.{ .slice = .{18399 break :v try pt.intern(.{ .slice = .{
18243 .ty = .slice_const_u8_sentinel_0_type,18400 .ty = .slice_const_u8_sentinel_0_type,
18244 .ptr = try mod.intern(.{ .ptr = .{18401 .ptr = try pt.intern(.{ .ptr = .{
18245 .ty = .manyptr_const_u8_sentinel_0_type,18402 .ty = .manyptr_const_u8_sentinel_0_type,
18246 .base_addr = .{ .anon_decl = .{18403 .base_addr = .{ .anon_decl = .{
18247 .val = new_decl_val,18404 .val = new_decl_val,
...@@ -18249,12 +18406,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18249,12 +18406,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18249 } },18406 } },
18250 .byte_offset = 0,18407 .byte_offset = 0,
18251 } }),18408 } }),
18252 .len = (try mod.intValue(Type.usize, field_name_len)).toIntern(),18409 .len = (try pt.intValue(Type.usize, field_name_len)).toIntern(),
18253 } });18410 } });
18254 };18411 };
1825518412
18256 const alignment = switch (layout) {18413 const alignment = switch (layout) {
18257 .auto, .@"extern" => try mod.unionFieldNormalAlignmentAdvanced(union_obj, @intCast(field_index), .sema),18414 .auto, .@"extern" => try pt.unionFieldNormalAlignmentAdvanced(union_obj, @intCast(field_index), .sema),
18258 .@"packed" => .none,18415 .@"packed" => .none,
18259 };18416 };
1826018417
...@@ -18265,24 +18422,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18265,24 +18422,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18265 // type: type,18422 // type: type,
18266 field_ty,18423 field_ty,
18267 // alignment: comptime_int,18424 // alignment: comptime_int,
18268 (try mod.intValue(Type.comptime_int, alignment.toByteUnits() orelse 0)).toIntern(),18425 (try pt.intValue(Type.comptime_int, alignment.toByteUnits() orelse 0)).toIntern(),
18269 };18426 };
18270 field_val.* = try mod.intern(.{ .aggregate = .{18427 field_val.* = try pt.intern(.{ .aggregate = .{
18271 .ty = union_field_ty.toIntern(),18428 .ty = union_field_ty.toIntern(),
18272 .storage = .{ .elems = &union_field_fields },18429 .storage = .{ .elems = &union_field_fields },
18273 } });18430 } });
18274 }18431 }
1827518432
18276 const fields_val = v: {18433 const fields_val = v: {
18277 const array_fields_ty = try mod.arrayType(.{18434 const array_fields_ty = try pt.arrayType(.{
18278 .len = union_field_vals.len,18435 .len = union_field_vals.len,
18279 .child = union_field_ty.toIntern(),18436 .child = union_field_ty.toIntern(),
18280 });18437 });
18281 const new_decl_val = try mod.intern(.{ .aggregate = .{18438 const new_decl_val = try pt.intern(.{ .aggregate = .{
18282 .ty = array_fields_ty.toIntern(),18439 .ty = array_fields_ty.toIntern(),
18283 .storage = .{ .elems = union_field_vals },18440 .storage = .{ .elems = union_field_vals },
18284 } });18441 } });
18285 const slice_ty = (try mod.ptrTypeSema(.{18442 const slice_ty = (try pt.ptrTypeSema(.{
18286 .child = union_field_ty.toIntern(),18443 .child = union_field_ty.toIntern(),
18287 .flags = .{18444 .flags = .{
18288 .size = .Slice,18445 .size = .Slice,
...@@ -18290,9 +18447,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18290,9 +18447,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18290 },18447 },
18291 })).toIntern();18448 })).toIntern();
18292 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();18449 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();
18293 break :v try mod.intern(.{ .slice = .{18450 break :v try pt.intern(.{ .slice = .{
18294 .ty = slice_ty,18451 .ty = slice_ty,
18295 .ptr = try mod.intern(.{ .ptr = .{18452 .ptr = try pt.intern(.{ .ptr = .{
18296 .ty = manyptr_ty,18453 .ty = manyptr_ty,
18297 .base_addr = .{ .anon_decl = .{18454 .base_addr = .{ .anon_decl = .{
18298 .orig_ty = manyptr_ty,18455 .orig_ty = manyptr_ty,
...@@ -18300,14 +18457,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18300,14 +18457,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18300 } },18457 } },
18301 .byte_offset = 0,18458 .byte_offset = 0,
18302 } }),18459 } }),
18303 .len = (try mod.intValue(Type.usize, union_field_vals.len)).toIntern(),18460 .len = (try pt.intValue(Type.usize, union_field_vals.len)).toIntern(),
18304 } });18461 } });
18305 };18462 };
1830618463
18307 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));18464 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));
1830818465
18309 const enum_tag_ty_val = try mod.intern(.{ .opt = .{18466 const enum_tag_ty_val = try pt.intern(.{ .opt = .{
18310 .ty = (try mod.optionalType(.type_type)).toIntern(),18467 .ty = (try pt.optionalType(.type_type)).toIntern(),
18311 .val = if (ty.unionTagType(mod)) |tag_ty| tag_ty.toIntern() else .none,18468 .val = if (ty.unionTagType(mod)) |tag_ty| tag_ty.toIntern() else .none,
18312 } });18469 } });
1831318470
...@@ -18315,7 +18472,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18315,7 +18472,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18315 const decl_index = (try sema.namespaceLookup(18472 const decl_index = (try sema.namespaceLookup(
18316 block,18473 block,
18317 src,18474 src,
18318 (try mod.getBuiltinType("Type")).getNamespaceIndex(mod),18475 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
18319 try ip.getOrPutString(gpa, "ContainerLayout", .no_embedded_nulls),18476 try ip.getOrPutString(gpa, "ContainerLayout", .no_embedded_nulls),
18320 )).?;18477 )).?;
18321 try sema.ensureDeclAnalyzed(decl_index);18478 try sema.ensureDeclAnalyzed(decl_index);
...@@ -18325,7 +18482,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18325,7 +18482,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1832518482
18326 const field_values = .{18483 const field_values = .{
18327 // layout: ContainerLayout,18484 // layout: ContainerLayout,
18328 (try mod.enumValueFieldIndex(container_layout_ty, @intFromEnum(layout))).toIntern(),18485 (try pt.enumValueFieldIndex(container_layout_ty, @intFromEnum(layout))).toIntern(),
1832918486
18330 // tag_type: ?type,18487 // tag_type: ?type,
18331 enum_tag_ty_val,18488 enum_tag_ty_val,
...@@ -18334,10 +18491,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18334,10 +18491,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18334 // decls: []const Declaration,18491 // decls: []const Declaration,
18335 decls_val,18492 decls_val,
18336 };18493 };
18337 return Air.internedToRef((try mod.intern(.{ .un = .{18494 return Air.internedToRef((try pt.intern(.{ .un = .{
18338 .ty = type_info_ty.toIntern(),18495 .ty = type_info_ty.toIntern(),
18339 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Union))).toIntern(),18496 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Union))).toIntern(),
18340 .val = try mod.intern(.{ .aggregate = .{18497 .val = try pt.intern(.{ .aggregate = .{
18341 .ty = type_union_ty.toIntern(),18498 .ty = type_union_ty.toIntern(),
18342 .storage = .{ .elems = &field_values },18499 .storage = .{ .elems = &field_values },
18343 } }),18500 } }),
...@@ -18368,7 +18525,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18368,7 +18525,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18368 break :t struct_field_ty_decl.val.toType();18525 break :t struct_field_ty_decl.val.toType();
18369 };18526 };
1837018527
18371 try ty.resolveLayout(mod); // Getting alignment requires type layout18528 try ty.resolveLayout(pt); // Getting alignment requires type layout
1837218529
18373 var struct_field_vals: []InternPool.Index = &.{};18530 var struct_field_vals: []InternPool.Index = &.{};
18374 defer gpa.free(struct_field_vals);18531 defer gpa.free(struct_field_vals);
...@@ -18385,18 +18542,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18385,18 +18542,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18385 else18542 else
18386 try ip.getOrPutStringFmt(gpa, "{d}", .{field_index}, .no_embedded_nulls);18543 try ip.getOrPutStringFmt(gpa, "{d}", .{field_index}, .no_embedded_nulls);
18387 const field_name_len = field_name.length(ip);18544 const field_name_len = field_name.length(ip);
18388 const new_decl_ty = try mod.arrayType(.{18545 const new_decl_ty = try pt.arrayType(.{
18389 .len = field_name_len,18546 .len = field_name_len,
18390 .sentinel = .zero_u8,18547 .sentinel = .zero_u8,
18391 .child = .u8_type,18548 .child = .u8_type,
18392 });18549 });
18393 const new_decl_val = try mod.intern(.{ .aggregate = .{18550 const new_decl_val = try pt.intern(.{ .aggregate = .{
18394 .ty = new_decl_ty.toIntern(),18551 .ty = new_decl_ty.toIntern(),
18395 .storage = .{ .bytes = field_name.toString() },18552 .storage = .{ .bytes = field_name.toString() },
18396 } });18553 } });
18397 break :v try mod.intern(.{ .slice = .{18554 break :v try pt.intern(.{ .slice = .{
18398 .ty = .slice_const_u8_sentinel_0_type,18555 .ty = .slice_const_u8_sentinel_0_type,
18399 .ptr = try mod.intern(.{ .ptr = .{18556 .ptr = try pt.intern(.{ .ptr = .{
18400 .ty = .manyptr_const_u8_sentinel_0_type,18557 .ty = .manyptr_const_u8_sentinel_0_type,
18401 .base_addr = .{ .anon_decl = .{18558 .base_addr = .{ .anon_decl = .{
18402 .val = new_decl_val,18559 .val = new_decl_val,
...@@ -18404,11 +18561,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18404,11 +18561,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18404 } },18561 } },
18405 .byte_offset = 0,18562 .byte_offset = 0,
18406 } }),18563 } }),
18407 .len = (try mod.intValue(Type.usize, field_name_len)).toIntern(),18564 .len = (try pt.intValue(Type.usize, field_name_len)).toIntern(),
18408 } });18565 } });
18409 };18566 };
1841018567
18411 try Type.fromInterned(field_ty).resolveLayout(mod);18568 try Type.fromInterned(field_ty).resolveLayout(pt);
1841218569
18413 const is_comptime = field_val != .none;18570 const is_comptime = field_val != .none;
18414 const opt_default_val = if (is_comptime) Value.fromInterned(field_val) else null;18571 const opt_default_val = if (is_comptime) Value.fromInterned(field_val) else null;
...@@ -18423,9 +18580,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18423,9 +18580,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18423 // is_comptime: bool,18580 // is_comptime: bool,
18424 Value.makeBool(is_comptime).toIntern(),18581 Value.makeBool(is_comptime).toIntern(),
18425 // alignment: comptime_int,18582 // alignment: comptime_int,
18426 (try mod.intValue(Type.comptime_int, Type.fromInterned(field_ty).abiAlignment(mod).toByteUnits() orelse 0)).toIntern(),18583 (try pt.intValue(Type.comptime_int, Type.fromInterned(field_ty).abiAlignment(pt).toByteUnits() orelse 0)).toIntern(),
18427 };18584 };
18428 struct_field_val.* = try mod.intern(.{ .aggregate = .{18585 struct_field_val.* = try pt.intern(.{ .aggregate = .{
18429 .ty = struct_field_ty.toIntern(),18586 .ty = struct_field_ty.toIntern(),
18430 .storage = .{ .elems = &struct_field_fields },18587 .storage = .{ .elems = &struct_field_fields },
18431 } });18588 } });
...@@ -18437,7 +18594,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18437,7 +18594,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18437 };18594 };
18438 struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len);18595 struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len);
1843918596
18440 try ty.resolveStructFieldInits(mod);18597 try ty.resolveStructFieldInits(pt);
1844118598
18442 for (struct_field_vals, 0..) |*field_val, field_index| {18599 for (struct_field_vals, 0..) |*field_val, field_index| {
18443 const field_name = if (struct_type.fieldName(ip, field_index).unwrap()) |field_name|18600 const field_name = if (struct_type.fieldName(ip, field_index).unwrap()) |field_name|
...@@ -18449,18 +18606,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18449,18 +18606,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18449 const field_init = struct_type.fieldInit(ip, field_index);18606 const field_init = struct_type.fieldInit(ip, field_index);
18450 const field_is_comptime = struct_type.fieldIsComptime(ip, field_index);18607 const field_is_comptime = struct_type.fieldIsComptime(ip, field_index);
18451 const name_val = v: {18608 const name_val = v: {
18452 const new_decl_ty = try mod.arrayType(.{18609 const new_decl_ty = try pt.arrayType(.{
18453 .len = field_name_len,18610 .len = field_name_len,
18454 .sentinel = .zero_u8,18611 .sentinel = .zero_u8,
18455 .child = .u8_type,18612 .child = .u8_type,
18456 });18613 });
18457 const new_decl_val = try mod.intern(.{ .aggregate = .{18614 const new_decl_val = try pt.intern(.{ .aggregate = .{
18458 .ty = new_decl_ty.toIntern(),18615 .ty = new_decl_ty.toIntern(),
18459 .storage = .{ .bytes = field_name.toString() },18616 .storage = .{ .bytes = field_name.toString() },
18460 } });18617 } });
18461 break :v try mod.intern(.{ .slice = .{18618 break :v try pt.intern(.{ .slice = .{
18462 .ty = .slice_const_u8_sentinel_0_type,18619 .ty = .slice_const_u8_sentinel_0_type,
18463 .ptr = try mod.intern(.{ .ptr = .{18620 .ptr = try pt.intern(.{ .ptr = .{
18464 .ty = .manyptr_const_u8_sentinel_0_type,18621 .ty = .manyptr_const_u8_sentinel_0_type,
18465 .base_addr = .{ .anon_decl = .{18622 .base_addr = .{ .anon_decl = .{
18466 .val = new_decl_val,18623 .val = new_decl_val,
...@@ -18468,7 +18625,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18468,7 +18625,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18468 } },18625 } },
18469 .byte_offset = 0,18626 .byte_offset = 0,
18470 } }),18627 } }),
18471 .len = (try mod.intValue(Type.usize, field_name_len)).toIntern(),18628 .len = (try pt.intValue(Type.usize, field_name_len)).toIntern(),
18472 } });18629 } });
18473 };18630 };
1847418631
...@@ -18476,7 +18633,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18476,7 +18633,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18476 const default_val_ptr = try sema.optRefValue(opt_default_val);18633 const default_val_ptr = try sema.optRefValue(opt_default_val);
18477 const alignment = switch (struct_type.layout) {18634 const alignment = switch (struct_type.layout) {
18478 .@"packed" => .none,18635 .@"packed" => .none,
18479 else => try mod.structFieldAlignmentAdvanced(18636 else => try pt.structFieldAlignmentAdvanced(
18480 struct_type.fieldAlign(ip, field_index),18637 struct_type.fieldAlign(ip, field_index),
18481 field_ty,18638 field_ty,
18482 struct_type.layout,18639 struct_type.layout,
...@@ -18494,9 +18651,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18494,9 +18651,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18494 // is_comptime: bool,18651 // is_comptime: bool,
18495 Value.makeBool(field_is_comptime).toIntern(),18652 Value.makeBool(field_is_comptime).toIntern(),
18496 // alignment: comptime_int,18653 // alignment: comptime_int,
18497 (try mod.intValue(Type.comptime_int, alignment.toByteUnits() orelse 0)).toIntern(),18654 (try pt.intValue(Type.comptime_int, alignment.toByteUnits() orelse 0)).toIntern(),
18498 };18655 };
18499 field_val.* = try mod.intern(.{ .aggregate = .{18656 field_val.* = try pt.intern(.{ .aggregate = .{
18500 .ty = struct_field_ty.toIntern(),18657 .ty = struct_field_ty.toIntern(),
18501 .storage = .{ .elems = &struct_field_fields },18658 .storage = .{ .elems = &struct_field_fields },
18502 } });18659 } });
...@@ -18504,15 +18661,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18504,15 +18661,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18504 }18661 }
1850518662
18506 const fields_val = v: {18663 const fields_val = v: {
18507 const array_fields_ty = try mod.arrayType(.{18664 const array_fields_ty = try pt.arrayType(.{
18508 .len = struct_field_vals.len,18665 .len = struct_field_vals.len,
18509 .child = struct_field_ty.toIntern(),18666 .child = struct_field_ty.toIntern(),
18510 });18667 });
18511 const new_decl_val = try mod.intern(.{ .aggregate = .{18668 const new_decl_val = try pt.intern(.{ .aggregate = .{
18512 .ty = array_fields_ty.toIntern(),18669 .ty = array_fields_ty.toIntern(),
18513 .storage = .{ .elems = struct_field_vals },18670 .storage = .{ .elems = struct_field_vals },
18514 } });18671 } });
18515 const slice_ty = (try mod.ptrTypeSema(.{18672 const slice_ty = (try pt.ptrTypeSema(.{
18516 .child = struct_field_ty.toIntern(),18673 .child = struct_field_ty.toIntern(),
18517 .flags = .{18674 .flags = .{
18518 .size = .Slice,18675 .size = .Slice,
...@@ -18520,9 +18677,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18520,9 +18677,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18520 },18677 },
18521 })).toIntern();18678 })).toIntern();
18522 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();18679 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();
18523 break :v try mod.intern(.{ .slice = .{18680 break :v try pt.intern(.{ .slice = .{
18524 .ty = slice_ty,18681 .ty = slice_ty,
18525 .ptr = try mod.intern(.{ .ptr = .{18682 .ptr = try pt.intern(.{ .ptr = .{
18526 .ty = manyptr_ty,18683 .ty = manyptr_ty,
18527 .base_addr = .{ .anon_decl = .{18684 .base_addr = .{ .anon_decl = .{
18528 .orig_ty = manyptr_ty,18685 .orig_ty = manyptr_ty,
...@@ -18530,14 +18687,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18530,14 +18687,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18530 } },18687 } },
18531 .byte_offset = 0,18688 .byte_offset = 0,
18532 } }),18689 } }),
18533 .len = (try mod.intValue(Type.usize, struct_field_vals.len)).toIntern(),18690 .len = (try pt.intValue(Type.usize, struct_field_vals.len)).toIntern(),
18534 } });18691 } });
18535 };18692 };
1853618693
18537 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));18694 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));
1853818695
18539 const backing_integer_val = try mod.intern(.{ .opt = .{18696 const backing_integer_val = try pt.intern(.{ .opt = .{
18540 .ty = (try mod.optionalType(.type_type)).toIntern(),18697 .ty = (try pt.optionalType(.type_type)).toIntern(),
18541 .val = if (mod.typeToPackedStruct(ty)) |packed_struct| val: {18698 .val = if (mod.typeToPackedStruct(ty)) |packed_struct| val: {
18542 assert(Type.fromInterned(packed_struct.backingIntType(ip).*).isInt(mod));18699 assert(Type.fromInterned(packed_struct.backingIntType(ip).*).isInt(mod));
18543 break :val packed_struct.backingIntType(ip).*;18700 break :val packed_struct.backingIntType(ip).*;
...@@ -18548,7 +18705,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18548,7 +18705,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18548 const decl_index = (try sema.namespaceLookup(18705 const decl_index = (try sema.namespaceLookup(
18549 block,18706 block,
18550 src,18707 src,
18551 (try mod.getBuiltinType("Type")).getNamespaceIndex(mod),18708 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
18552 try ip.getOrPutString(gpa, "ContainerLayout", .no_embedded_nulls),18709 try ip.getOrPutString(gpa, "ContainerLayout", .no_embedded_nulls),
18553 )).?;18710 )).?;
18554 try sema.ensureDeclAnalyzed(decl_index);18711 try sema.ensureDeclAnalyzed(decl_index);
...@@ -18560,7 +18717,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18560,7 +18717,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1856018717
18561 const field_values = [_]InternPool.Index{18718 const field_values = [_]InternPool.Index{
18562 // layout: ContainerLayout,18719 // layout: ContainerLayout,
18563 (try mod.enumValueFieldIndex(container_layout_ty, @intFromEnum(layout))).toIntern(),18720 (try pt.enumValueFieldIndex(container_layout_ty, @intFromEnum(layout))).toIntern(),
18564 // backing_integer: ?type,18721 // backing_integer: ?type,
18565 backing_integer_val,18722 backing_integer_val,
18566 // fields: []const StructField,18723 // fields: []const StructField,
...@@ -18570,10 +18727,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18570,10 +18727,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18570 // is_tuple: bool,18727 // is_tuple: bool,
18571 Value.makeBool(ty.isTuple(mod)).toIntern(),18728 Value.makeBool(ty.isTuple(mod)).toIntern(),
18572 };18729 };
18573 return Air.internedToRef((try mod.intern(.{ .un = .{18730 return Air.internedToRef((try pt.intern(.{ .un = .{
18574 .ty = type_info_ty.toIntern(),18731 .ty = type_info_ty.toIntern(),
18575 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Struct))).toIntern(),18732 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Struct))).toIntern(),
18576 .val = try mod.intern(.{ .aggregate = .{18733 .val = try pt.intern(.{ .aggregate = .{
18577 .ty = type_struct_ty.toIntern(),18734 .ty = type_struct_ty.toIntern(),
18578 .storage = .{ .elems = &field_values },18735 .storage = .{ .elems = &field_values },
18579 } }),18736 } }),
...@@ -18592,17 +18749,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18592,17 +18749,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18592 break :t type_opaque_ty_decl.val.toType();18749 break :t type_opaque_ty_decl.val.toType();
18593 };18750 };
1859418751
18595 try ty.resolveFields(mod);18752 try ty.resolveFields(pt);
18596 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));18753 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));
1859718754
18598 const field_values = .{18755 const field_values = .{
18599 // decls: []const Declaration,18756 // decls: []const Declaration,
18600 decls_val,18757 decls_val,
18601 };18758 };
18602 return Air.internedToRef((try mod.intern(.{ .un = .{18759 return Air.internedToRef((try pt.intern(.{ .un = .{
18603 .ty = type_info_ty.toIntern(),18760 .ty = type_info_ty.toIntern(),
18604 .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Opaque))).toIntern(),18761 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Opaque))).toIntern(),
18605 .val = try mod.intern(.{ .aggregate = .{18762 .val = try pt.intern(.{ .aggregate = .{
18606 .ty = type_opaque_ty.toIntern(),18763 .ty = type_opaque_ty.toIntern(),
18607 .storage = .{ .elems = &field_values },18764 .storage = .{ .elems = &field_values },
18608 } }),18765 } }),
...@@ -18620,7 +18777,8 @@ fn typeInfoDecls(...@@ -18620,7 +18777,8 @@ fn typeInfoDecls(
18620 type_info_ty: Type,18777 type_info_ty: Type,
18621 opt_namespace: InternPool.OptionalNamespaceIndex,18778 opt_namespace: InternPool.OptionalNamespaceIndex,
18622) CompileError!InternPool.Index {18779) CompileError!InternPool.Index {
18623 const mod = sema.mod;18780 const pt = sema.pt;
18781 const mod = pt.zcu;
18624 const gpa = sema.gpa;18782 const gpa = sema.gpa;
1862518783
18626 const declaration_ty = t: {18784 const declaration_ty = t: {
...@@ -18643,15 +18801,15 @@ fn typeInfoDecls(...@@ -18643,15 +18801,15 @@ fn typeInfoDecls(
1864318801
18644 try sema.typeInfoNamespaceDecls(block, opt_namespace, declaration_ty, &decl_vals, &seen_namespaces);18802 try sema.typeInfoNamespaceDecls(block, opt_namespace, declaration_ty, &decl_vals, &seen_namespaces);
1864518803
18646 const array_decl_ty = try mod.arrayType(.{18804 const array_decl_ty = try pt.arrayType(.{
18647 .len = decl_vals.items.len,18805 .len = decl_vals.items.len,
18648 .child = declaration_ty.toIntern(),18806 .child = declaration_ty.toIntern(),
18649 });18807 });
18650 const new_decl_val = try mod.intern(.{ .aggregate = .{18808 const new_decl_val = try pt.intern(.{ .aggregate = .{
18651 .ty = array_decl_ty.toIntern(),18809 .ty = array_decl_ty.toIntern(),
18652 .storage = .{ .elems = decl_vals.items },18810 .storage = .{ .elems = decl_vals.items },
18653 } });18811 } });
18654 const slice_ty = (try mod.ptrTypeSema(.{18812 const slice_ty = (try pt.ptrTypeSema(.{
18655 .child = declaration_ty.toIntern(),18813 .child = declaration_ty.toIntern(),
18656 .flags = .{18814 .flags = .{
18657 .size = .Slice,18815 .size = .Slice,
...@@ -18659,9 +18817,9 @@ fn typeInfoDecls(...@@ -18659,9 +18817,9 @@ fn typeInfoDecls(
18659 },18817 },
18660 })).toIntern();18818 })).toIntern();
18661 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();18819 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();
18662 return try mod.intern(.{ .slice = .{18820 return try pt.intern(.{ .slice = .{
18663 .ty = slice_ty,18821 .ty = slice_ty,
18664 .ptr = try mod.intern(.{ .ptr = .{18822 .ptr = try pt.intern(.{ .ptr = .{
18665 .ty = manyptr_ty,18823 .ty = manyptr_ty,
18666 .base_addr = .{ .anon_decl = .{18824 .base_addr = .{ .anon_decl = .{
18667 .orig_ty = manyptr_ty,18825 .orig_ty = manyptr_ty,
...@@ -18669,7 +18827,7 @@ fn typeInfoDecls(...@@ -18669,7 +18827,7 @@ fn typeInfoDecls(
18669 } },18827 } },
18670 .byte_offset = 0,18828 .byte_offset = 0,
18671 } }),18829 } }),
18672 .len = (try mod.intValue(Type.usize, decl_vals.items.len)).toIntern(),18830 .len = (try pt.intValue(Type.usize, decl_vals.items.len)).toIntern(),
18673 } });18831 } });
18674}18832}
1867518833
...@@ -18681,7 +18839,8 @@ fn typeInfoNamespaceDecls(...@@ -18681,7 +18839,8 @@ fn typeInfoNamespaceDecls(
18681 decl_vals: *std.ArrayList(InternPool.Index),18839 decl_vals: *std.ArrayList(InternPool.Index),
18682 seen_namespaces: *std.AutoHashMap(*Namespace, void),18840 seen_namespaces: *std.AutoHashMap(*Namespace, void),
18683) !void {18841) !void {
18684 const mod = sema.mod;18842 const pt = sema.pt;
18843 const mod = pt.zcu;
18685 const ip = &mod.intern_pool;18844 const ip = &mod.intern_pool;
1868618845
18687 const namespace_index = opt_namespace_index.unwrap() orelse return;18846 const namespace_index = opt_namespace_index.unwrap() orelse return;
...@@ -18703,18 +18862,18 @@ fn typeInfoNamespaceDecls(...@@ -18703,18 +18862,18 @@ fn typeInfoNamespaceDecls(
18703 if (decl.kind != .named) continue;18862 if (decl.kind != .named) continue;
18704 const name_val = v: {18863 const name_val = v: {
18705 const decl_name_len = decl.name.length(ip);18864 const decl_name_len = decl.name.length(ip);
18706 const new_decl_ty = try mod.arrayType(.{18865 const new_decl_ty = try pt.arrayType(.{
18707 .len = decl_name_len,18866 .len = decl_name_len,
18708 .sentinel = .zero_u8,18867 .sentinel = .zero_u8,
18709 .child = .u8_type,18868 .child = .u8_type,
18710 });18869 });
18711 const new_decl_val = try mod.intern(.{ .aggregate = .{18870 const new_decl_val = try pt.intern(.{ .aggregate = .{
18712 .ty = new_decl_ty.toIntern(),18871 .ty = new_decl_ty.toIntern(),
18713 .storage = .{ .bytes = decl.name.toString() },18872 .storage = .{ .bytes = decl.name.toString() },
18714 } });18873 } });
18715 break :v try mod.intern(.{ .slice = .{18874 break :v try pt.intern(.{ .slice = .{
18716 .ty = .slice_const_u8_sentinel_0_type,18875 .ty = .slice_const_u8_sentinel_0_type,
18717 .ptr = try mod.intern(.{ .ptr = .{18876 .ptr = try pt.intern(.{ .ptr = .{
18718 .ty = .manyptr_const_u8_sentinel_0_type,18877 .ty = .manyptr_const_u8_sentinel_0_type,
18719 .base_addr = .{ .anon_decl = .{18878 .base_addr = .{ .anon_decl = .{
18720 .orig_ty = .slice_const_u8_sentinel_0_type,18879 .orig_ty = .slice_const_u8_sentinel_0_type,
...@@ -18722,7 +18881,7 @@ fn typeInfoNamespaceDecls(...@@ -18722,7 +18881,7 @@ fn typeInfoNamespaceDecls(
18722 } },18881 } },
18723 .byte_offset = 0,18882 .byte_offset = 0,
18724 } }),18883 } }),
18725 .len = (try mod.intValue(Type.usize, decl_name_len)).toIntern(),18884 .len = (try pt.intValue(Type.usize, decl_name_len)).toIntern(),
18726 } });18885 } });
18727 };18886 };
1872818887
...@@ -18730,7 +18889,7 @@ fn typeInfoNamespaceDecls(...@@ -18730,7 +18889,7 @@ fn typeInfoNamespaceDecls(
18730 //name: [:0]const u8,18889 //name: [:0]const u8,
18731 name_val,18890 name_val,
18732 };18891 };
18733 try decl_vals.append(try mod.intern(.{ .aggregate = .{18892 try decl_vals.append(try pt.intern(.{ .aggregate = .{
18734 .ty = declaration_ty.toIntern(),18893 .ty = declaration_ty.toIntern(),
18735 .storage = .{ .elems = &fields },18894 .storage = .{ .elems = &fields },
18736 } }));18895 } }));
...@@ -18782,11 +18941,12 @@ fn zirTypeofLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -18782,11 +18941,12 @@ fn zirTypeofLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
18782}18941}
1878318942
18784fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) CompileError!Type {18943fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) CompileError!Type {
18785 const mod = sema.mod;18944 const pt = sema.pt;
18945 const mod = pt.zcu;
18786 switch (operand.zigTypeTag(mod)) {18946 switch (operand.zigTypeTag(mod)) {
18787 .ComptimeInt => return Type.comptime_int,18947 .ComptimeInt => return Type.comptime_int,
18788 .Int => {18948 .Int => {
18789 const bits = operand.bitSize(mod);18949 const bits = operand.bitSize(pt);
18790 const count = if (bits == 0)18950 const count = if (bits == 0)
18791 018951 0
18792 else blk: {18952 else blk: {
...@@ -18797,12 +18957,12 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi...@@ -18797,12 +18957,12 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi
18797 }18957 }
18798 break :blk count;18958 break :blk count;
18799 };18959 };
18800 return mod.intType(.unsigned, count);18960 return pt.intType(.unsigned, count);
18801 },18961 },
18802 .Vector => {18962 .Vector => {
18803 const elem_ty = operand.elemType2(mod);18963 const elem_ty = operand.elemType2(mod);
18804 const log2_elem_ty = try sema.log2IntType(block, elem_ty, src);18964 const log2_elem_ty = try sema.log2IntType(block, elem_ty, src);
18805 return mod.vectorType(.{18965 return pt.vectorType(.{
18806 .len = operand.vectorLen(mod),18966 .len = operand.vectorLen(mod),
18807 .child = log2_elem_ty.toIntern(),18967 .child = log2_elem_ty.toIntern(),
18808 });18968 });
...@@ -18813,7 +18973,7 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi...@@ -18813,7 +18973,7 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi
18813 block,18973 block,
18814 src,18974 src,
18815 "bit shifting operation expected integer type, found '{}'",18975 "bit shifting operation expected integer type, found '{}'",
18816 .{operand.fmt(mod)},18976 .{operand.fmt(pt)},
18817 );18977 );
18818}18978}
1881918979
...@@ -18865,7 +19025,8 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -18865,7 +19025,8 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
18865 const tracy = trace(@src());19025 const tracy = trace(@src());
18866 defer tracy.end();19026 defer tracy.end();
1886719027
18868 const mod = sema.mod;19028 const pt = sema.pt;
19029 const mod = pt.zcu;
18869 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;19030 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
18870 const src = block.nodeOffset(inst_data.src_node);19031 const src = block.nodeOffset(inst_data.src_node);
18871 const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });19032 const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
...@@ -18874,7 +19035,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -18874,7 +19035,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);19035 const operand = try sema.coerce(block, Type.bool, uncasted_operand, operand_src);
18875 if (try sema.resolveValue(operand)) |val| {19036 if (try sema.resolveValue(operand)) |val| {
18876 return if (val.isUndef(mod))19037 return if (val.isUndef(mod))
18877 mod.undefRef(Type.bool)19038 pt.undefRef(Type.bool)
18878 else if (val.toBool()) .bool_false else .bool_true;19039 else if (val.toBool()) .bool_false else .bool_true;
18879 }19040 }
18880 try sema.requireRuntimeBlock(block, src, null);19041 try sema.requireRuntimeBlock(block, src, null);
...@@ -18890,7 +19051,8 @@ fn zirBoolBr(...@@ -18890,7 +19051,8 @@ fn zirBoolBr(
18890 const tracy = trace(@src());19051 const tracy = trace(@src());
18891 defer tracy.end();19052 defer tracy.end();
1889219053
18893 const mod = sema.mod;19054 const pt = sema.pt;
19055 const mod = pt.zcu;
18894 const gpa = sema.gpa;19056 const gpa = sema.gpa;
1889519057
18896 const datas = sema.code.instructions.items(.data);19058 const datas = sema.code.instructions.items(.data);
...@@ -19006,7 +19168,8 @@ fn finishCondBr(...@@ -19006,7 +19168,8 @@ fn finishCondBr(
19006}19168}
1900719169
19008fn checkNullableType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {19170fn checkNullableType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
19009 const mod = sema.mod;19171 const pt = sema.pt;
19172 const mod = pt.zcu;
19010 switch (ty.zigTypeTag(mod)) {19173 switch (ty.zigTypeTag(mod)) {
19011 .Optional, .Null, .Undefined => return,19174 .Optional, .Null, .Undefined => return,
19012 .Pointer => if (ty.isPtrLikeOptional(mod)) return,19175 .Pointer => if (ty.isPtrLikeOptional(mod)) return,
...@@ -19038,7 +19201,8 @@ fn zirIsNonNullPtr(...@@ -19038,7 +19201,8 @@ fn zirIsNonNullPtr(
19038 const tracy = trace(@src());19201 const tracy = trace(@src());
19039 defer tracy.end();19202 defer tracy.end();
1904019203
19041 const mod = sema.mod;19204 const pt = sema.pt;
19205 const mod = pt.zcu;
19042 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;19206 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
19043 const src = block.nodeOffset(inst_data.src_node);19207 const src = block.nodeOffset(inst_data.src_node);
19044 const ptr = try sema.resolveInst(inst_data.operand);19208 const ptr = try sema.resolveInst(inst_data.operand);
...@@ -19051,11 +19215,12 @@ fn zirIsNonNullPtr(...@@ -19051,11 +19215,12 @@ fn zirIsNonNullPtr(
19051}19215}
1905219216
19053fn checkErrorType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {19217fn checkErrorType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
19054 const mod = sema.mod;19218 const pt = sema.pt;
19219 const mod = pt.zcu;
19055 switch (ty.zigTypeTag(mod)) {19220 switch (ty.zigTypeTag(mod)) {
19056 .ErrorSet, .ErrorUnion, .Undefined => return,19221 .ErrorSet, .ErrorUnion, .Undefined => return,
19057 else => return sema.fail(block, src, "expected error union type, found '{}'", .{19222 else => return sema.fail(block, src, "expected error union type, found '{}'", .{
19058 ty.fmt(mod),19223 ty.fmt(pt),
19059 }),19224 }),
19060 }19225 }
19061}19226}
...@@ -19075,7 +19240,8 @@ fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -19075,7 +19240,8 @@ fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
19075 const tracy = trace(@src());19240 const tracy = trace(@src());
19076 defer tracy.end();19241 defer tracy.end();
1907719242
19078 const mod = sema.mod;19243 const pt = sema.pt;
19244 const mod = pt.zcu;
19079 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;19245 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
19080 const src = block.nodeOffset(inst_data.src_node);19246 const src = block.nodeOffset(inst_data.src_node);
19081 const ptr = try sema.resolveInst(inst_data.operand);19247 const ptr = try sema.resolveInst(inst_data.operand);
...@@ -19102,7 +19268,8 @@ fn zirCondbr(...@@ -19102,7 +19268,8 @@ fn zirCondbr(
19102 const tracy = trace(@src());19268 const tracy = trace(@src());
19103 defer tracy.end();19269 defer tracy.end();
1910419270
19105 const mod = sema.mod;19271 const pt = sema.pt;
19272 const mod = pt.zcu;
19106 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;19273 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 });19274 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);19275 const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);
...@@ -19177,10 +19344,11 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -19177,10 +19344,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);19344 const body = sema.code.bodySlice(extra.end, extra.data.body_len);
19178 const err_union = try sema.resolveInst(extra.data.operand);19345 const err_union = try sema.resolveInst(extra.data.operand);
19179 const err_union_ty = sema.typeOf(err_union);19346 const err_union_ty = sema.typeOf(err_union);
19180 const mod = sema.mod;19347 const pt = sema.pt;
19348 const mod = pt.zcu;
19181 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) {19349 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) {
19182 return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{19350 return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{
19183 err_union_ty.fmt(mod),19351 err_union_ty.fmt(pt),
19184 });19352 });
19185 }19353 }
19186 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union);19354 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union);
...@@ -19225,10 +19393,11 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -19225,10 +19393,11 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
19225 const operand = try sema.resolveInst(extra.data.operand);19393 const operand = try sema.resolveInst(extra.data.operand);
19226 const err_union = try sema.analyzeLoad(parent_block, src, operand, operand_src);19394 const err_union = try sema.analyzeLoad(parent_block, src, operand, operand_src);
19227 const err_union_ty = sema.typeOf(err_union);19395 const err_union_ty = sema.typeOf(err_union);
19228 const mod = sema.mod;19396 const pt = sema.pt;
19397 const mod = pt.zcu;
19229 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) {19398 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) {
19230 return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{19399 return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{
19231 err_union_ty.fmt(mod),19400 err_union_ty.fmt(pt),
19232 });19401 });
19233 }19402 }
19234 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union);19403 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union);
...@@ -19251,7 +19420,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -19251,7 +19420,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
1925119420
19252 const operand_ty = sema.typeOf(operand);19421 const operand_ty = sema.typeOf(operand);
19253 const ptr_info = operand_ty.ptrInfo(mod);19422 const ptr_info = operand_ty.ptrInfo(mod);
19254 const res_ty = try mod.ptrTypeSema(.{19423 const res_ty = try pt.ptrTypeSema(.{
19255 .child = err_union_ty.errorUnionPayload(mod).toIntern(),19424 .child = err_union_ty.errorUnionPayload(mod).toIntern(),
19256 .flags = .{19425 .flags = .{
19257 .is_const = ptr_info.flags.is_const,19426 .is_const = ptr_info.flags.is_const,
...@@ -19366,7 +19535,8 @@ fn zirRetErrValue(...@@ -19366,7 +19535,8 @@ fn zirRetErrValue(
19366 block: *Block,19535 block: *Block,
19367 inst: Zir.Inst.Index,19536 inst: Zir.Inst.Index,
19368) CompileError!void {19537) CompileError!void {
19369 const mod = sema.mod;19538 const pt = sema.pt;
19539 const mod = pt.zcu;
19370 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;19540 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
19371 const src = block.tokenOffset(inst_data.src_tok);19541 const src = block.tokenOffset(inst_data.src_tok);
19372 const err_name = try mod.intern_pool.getOrPutString(19542 const err_name = try mod.intern_pool.getOrPutString(
...@@ -19376,8 +19546,8 @@ fn zirRetErrValue(...@@ -19376,8 +19546,8 @@ fn zirRetErrValue(
19376 );19546 );
19377 _ = try mod.getErrorValue(err_name);19547 _ = try mod.getErrorValue(err_name);
19378 // Return the error code from the function.19548 // Return the error code from the function.
19379 const error_set_type = try mod.singleErrorSetType(err_name);19549 const error_set_type = try pt.singleErrorSetType(err_name);
19380 const result_inst = Air.internedToRef((try mod.intern(.{ .err = .{19550 const result_inst = Air.internedToRef((try pt.intern(.{ .err = .{
19381 .ty = error_set_type.toIntern(),19551 .ty = error_set_type.toIntern(),
19382 .name = err_name,19552 .name = err_name,
19383 } })));19553 } })));
...@@ -19392,7 +19562,8 @@ fn zirRetImplicit(...@@ -19392,7 +19562,8 @@ fn zirRetImplicit(
19392 const tracy = trace(@src());19562 const tracy = trace(@src());
19393 defer tracy.end();19563 defer tracy.end();
1939419564
19395 const mod = sema.mod;19565 const pt = sema.pt;
19566 const mod = pt.zcu;
19396 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok;19567 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok;
19397 const r_brace_src = block.tokenOffset(inst_data.src_tok);19568 const r_brace_src = block.tokenOffset(inst_data.src_tok);
19398 if (block.inlining == null and sema.func_is_naked) {19569 if (block.inlining == null and sema.func_is_naked) {
...@@ -19412,7 +19583,7 @@ fn zirRetImplicit(...@@ -19412,7 +19583,7 @@ fn zirRetImplicit(
19412 if (base_tag == .NoReturn) {19583 if (base_tag == .NoReturn) {
19413 const msg = msg: {19584 const msg = msg: {
19414 const msg = try sema.errMsg(ret_ty_src, "function declared '{}' implicitly returns", .{19585 const msg = try sema.errMsg(ret_ty_src, "function declared '{}' implicitly returns", .{
19415 sema.fn_ret_ty.fmt(mod),19586 sema.fn_ret_ty.fmt(pt),
19416 });19587 });
19417 errdefer msg.destroy(sema.gpa);19588 errdefer msg.destroy(sema.gpa);
19418 try sema.errNote(r_brace_src, msg, "control flow reaches end of body here", .{});19589 try sema.errNote(r_brace_src, msg, "control flow reaches end of body here", .{});
...@@ -19422,7 +19593,7 @@ fn zirRetImplicit(...@@ -19422,7 +19593,7 @@ fn zirRetImplicit(
19422 } else if (base_tag != .Void) {19593 } else if (base_tag != .Void) {
19423 const msg = msg: {19594 const msg = msg: {
19424 const msg = try sema.errMsg(ret_ty_src, "function with non-void return type '{}' implicitly returns", .{19595 const msg = try sema.errMsg(ret_ty_src, "function with non-void return type '{}' implicitly returns", .{
19425 sema.fn_ret_ty.fmt(mod),19596 sema.fn_ret_ty.fmt(pt),
19426 });19597 });
19427 errdefer msg.destroy(sema.gpa);19598 errdefer msg.destroy(sema.gpa);
19428 try sema.errNote(r_brace_src, msg, "control flow reaches end of body here", .{});19599 try sema.errNote(r_brace_src, msg, "control flow reaches end of body here", .{});
...@@ -19474,7 +19645,7 @@ fn retWithErrTracing(...@@ -19474,7 +19645,7 @@ fn retWithErrTracing(
19474 ret_tag: Air.Inst.Tag,19645 ret_tag: Air.Inst.Tag,
19475 operand: Air.Inst.Ref,19646 operand: Air.Inst.Ref,
19476) CompileError!void {19647) CompileError!void {
19477 const mod = sema.mod;19648 const pt = sema.pt;
19478 const need_check = switch (is_non_err) {19649 const need_check = switch (is_non_err) {
19479 .bool_true => {19650 .bool_true => {
19480 _ = try block.addUnOp(ret_tag, operand);19651 _ = try block.addUnOp(ret_tag, operand);
...@@ -19484,11 +19655,11 @@ fn retWithErrTracing(...@@ -19484,11 +19655,11 @@ fn retWithErrTracing(
19484 else => true,19655 else => true,
19485 };19656 };
19486 const gpa = sema.gpa;19657 const gpa = sema.gpa;
19487 const stack_trace_ty = try mod.getBuiltinType("StackTrace");19658 const stack_trace_ty = try pt.getBuiltinType("StackTrace");
19488 try stack_trace_ty.resolveFields(mod);19659 try stack_trace_ty.resolveFields(pt);
19489 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);19660 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);19661 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
19491 const return_err_fn = try mod.getBuiltin("returnError");19662 const return_err_fn = try pt.getBuiltin("returnError");
19492 const args: [1]Air.Inst.Ref = .{err_return_trace};19663 const args: [1]Air.Inst.Ref = .{err_return_trace};
1949319664
19494 if (!need_check) {19665 if (!need_check) {
...@@ -19524,12 +19695,14 @@ fn retWithErrTracing(...@@ -19524,12 +19695,14 @@ fn retWithErrTracing(
19524}19695}
1952519696
19526fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool {19697fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool {
19527 const mod = sema.mod;19698 const pt = sema.pt;
19699 const mod = pt.zcu;
19528 return fn_ret_ty.isError(mod) and mod.comp.config.any_error_tracing;19700 return fn_ret_ty.isError(mod) and mod.comp.config.any_error_tracing;
19529}19701}
1953019702
19531fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {19703fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
19532 const mod = sema.mod;19704 const pt = sema.pt;
19705 const mod = pt.zcu;
19533 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].save_err_ret_index;19706 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].save_err_ret_index;
1953419707
19535 if (!block.ownerModule().error_tracing) return;19708 if (!block.ownerModule().error_tracing) return;
...@@ -19559,7 +19732,8 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_...@@ -19559,7 +19732,8 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_
19559 const tracy = trace(@src());19732 const tracy = trace(@src());
19560 defer tracy.end();19733 defer tracy.end();
1956119734
19562 const mod = sema.mod;19735 const pt = sema.pt;
19736 const mod = pt.zcu;
1956319737
19564 const saved_index = if (target_block.toIndexAllowNone()) |zir_block| b: {19738 const saved_index = if (target_block.toIndexAllowNone()) |zir_block| b: {
19565 var block = start_block;19739 var block = start_block;
...@@ -19597,7 +19771,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_...@@ -19597,7 +19771,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_
19597 if (is_non_error) return;19771 if (is_non_error) return;
1959819772
19599 const saved_index_val = try sema.resolveDefinedValue(start_block, src, saved_index);19773 const saved_index_val = try sema.resolveDefinedValue(start_block, src, saved_index);
19600 const saved_index_int = saved_index_val.?.toUnsignedInt(mod);19774 const saved_index_int = saved_index_val.?.toUnsignedInt(pt);
19601 assert(saved_index_int <= sema.comptime_err_ret_trace.items.len);19775 assert(saved_index_int <= sema.comptime_err_ret_trace.items.len);
19602 sema.comptime_err_ret_trace.items.len = @intCast(saved_index_int);19776 sema.comptime_err_ret_trace.items.len = @intCast(saved_index_int);
19603 return;19777 return;
...@@ -19612,7 +19786,8 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_...@@ -19612,7 +19786,8 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_
19612}19786}
1961319787
19614fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {19788fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {
19615 const mod = sema.mod;19789 const pt = sema.pt;
19790 const mod = pt.zcu;
19616 const ip = &mod.intern_pool;19791 const ip = &mod.intern_pool;
19617 assert(sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion);19792 assert(sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion);
19618 const err_set_ty = sema.fn_ret_ty.errorUnionSet(mod).toIntern();19793 const err_set_ty = sema.fn_ret_ty.errorUnionSet(mod).toIntern();
...@@ -19632,7 +19807,8 @@ fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {...@@ -19632,7 +19807,8 @@ fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {
1963219807
19633fn addToInferredErrorSetPtr(sema: *Sema, ies: *InferredErrorSet, op_ty: Type) !void {19808fn addToInferredErrorSetPtr(sema: *Sema, ies: *InferredErrorSet, op_ty: Type) !void {
19634 const arena = sema.arena;19809 const arena = sema.arena;
19635 const mod = sema.mod;19810 const pt = sema.pt;
19811 const mod = pt.zcu;
19636 const ip = &mod.intern_pool;19812 const ip = &mod.intern_pool;
19637 switch (op_ty.zigTypeTag(mod)) {19813 switch (op_ty.zigTypeTag(mod)) {
19638 .ErrorSet => try ies.addErrorSet(op_ty, ip, arena),19814 .ErrorSet => try ies.addErrorSet(op_ty, ip, arena),
...@@ -19651,7 +19827,8 @@ fn analyzeRet(...@@ -19651,7 +19827,8 @@ fn analyzeRet(
19651 // Special case for returning an error to an inferred error set; we need to19827 // 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, so19828 // add the error tag to the inferred error set of the in-scope function, so
19653 // that the coercion below works correctly.19829 // that the coercion below works correctly.
19654 const mod = sema.mod;19830 const pt = sema.pt;
19831 const mod = pt.zcu;
19655 if (sema.fn_ret_ty_ies != null and sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion) {19832 if (sema.fn_ret_ty_ies != null and sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion) {
19656 try sema.addToInferredErrorSet(uncasted_operand);19833 try sema.addToInferredErrorSet(uncasted_operand);
19657 }19834 }
...@@ -19691,7 +19868,7 @@ fn analyzeRet(...@@ -19691,7 +19868,7 @@ fn analyzeRet(
19691 return sema.failWithOwnedErrorMsg(block, msg);19868 return sema.failWithOwnedErrorMsg(block, msg);
19692 }19869 }
1969319870
19694 try sema.fn_ret_ty.resolveLayout(mod);19871 try sema.fn_ret_ty.resolveLayout(pt);
1969519872
19696 try sema.validateRuntimeValue(block, operand_src, operand);19873 try sema.validateRuntimeValue(block, operand_src, operand);
1969719874
...@@ -19718,7 +19895,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19718,7 +19895,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19718 const tracy = trace(@src());19895 const tracy = trace(@src());
19719 defer tracy.end();19896 defer tracy.end();
1972019897
19721 const mod = sema.mod;19898 const pt = sema.pt;
19899 const mod = pt.zcu;
19722 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].ptr_type;19900 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);19901 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 });19902 const elem_ty_src = block.src(.{ .node_offset_ptr_elem = extra.data.src_node });
...@@ -19773,7 +19951,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19773,7 +19951,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19773 },19951 },
19774 else => {},19952 else => {},
19775 }19953 }
19776 const align_bytes = (try val.getUnsignedIntAdvanced(mod, .sema)).?;19954 const align_bytes = (try val.getUnsignedIntAdvanced(pt, .sema)).?;
19777 break :blk try sema.validateAlignAllowZero(block, align_src, align_bytes);19955 break :blk try sema.validateAlignAllowZero(block, align_src, align_bytes);
19778 } else .none;19956 } else .none;
1977919957
...@@ -19804,13 +19982,13 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19804,13 +19982,13 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19804 if (host_size != 0) {19982 if (host_size != 0) {
19805 if (bit_offset >= host_size * 8) {19983 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", .{19984 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,19985 elem_ty.fmt(pt), bit_offset, bit_offset - host_size * 8, host_size,
19808 });19986 });
19809 }19987 }
19810 const elem_bit_size = try elem_ty.bitSizeAdvanced(mod, .sema);19988 const elem_bit_size = try elem_ty.bitSizeAdvanced(pt, .sema);
19811 if (elem_bit_size > host_size * 8 - bit_offset) {19989 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", .{19990 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,19991 elem_ty.fmt(pt), bit_offset, elem_bit_size - (host_size * 8 - bit_offset), host_size,
19814 });19992 });
19815 }19993 }
19816 }19994 }
...@@ -19824,7 +20002,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19824,7 +20002,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19824 } else if (inst_data.size == .C) {20002 } else if (inst_data.size == .C) {
19825 if (!try sema.validateExternType(elem_ty, .other)) {20003 if (!try sema.validateExternType(elem_ty, .other)) {
19826 const msg = msg: {20004 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)});20005 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);20006 errdefer msg.destroy(sema.gpa);
1982920007
19830 try sema.explainWhyTypeIsNotExtern(msg, elem_ty_src, elem_ty, .other);20008 try sema.explainWhyTypeIsNotExtern(msg, elem_ty_src, elem_ty, .other);
...@@ -19841,14 +20019,14 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19841,14 +20019,14 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1984120019
19842 if (host_size != 0 and !try sema.validatePackedType(elem_ty)) {20020 if (host_size != 0 and !try sema.validatePackedType(elem_ty)) {
19843 return sema.failWithOwnedErrorMsg(block, msg: {20021 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)});20022 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);20023 errdefer msg.destroy(sema.gpa);
19846 try sema.explainWhyTypeIsNotPacked(msg, elem_ty_src, elem_ty);20024 try sema.explainWhyTypeIsNotPacked(msg, elem_ty_src, elem_ty);
19847 break :msg msg;20025 break :msg msg;
19848 });20026 });
19849 }20027 }
1985020028
19851 const ty = try mod.ptrTypeSema(.{20029 const ty = try pt.ptrTypeSema(.{
19852 .child = elem_ty.toIntern(),20030 .child = elem_ty.toIntern(),
19853 .sentinel = sentinel,20031 .sentinel = sentinel,
19854 .flags = .{20032 .flags = .{
...@@ -19875,7 +20053,8 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -19875,7 +20053,8 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
19875 const src = block.nodeOffset(inst_data.src_node);20053 const src = block.nodeOffset(inst_data.src_node);
19876 const ty_src = block.src(.{ .node_offset_init_ty = inst_data.src_node });20054 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);20055 const obj_ty = try sema.resolveType(block, ty_src, inst_data.operand);
19878 const mod = sema.mod;20056 const pt = sema.pt;
20057 const mod = pt.zcu;
1987920058
19880 switch (obj_ty.zigTypeTag(mod)) {20059 switch (obj_ty.zigTypeTag(mod)) {
19881 .Struct => return sema.structInitEmpty(block, obj_ty, src, src),20060 .Struct => return sema.structInitEmpty(block, obj_ty, src, src),
...@@ -19890,7 +20069,8 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is...@@ -19890,7 +20069,8 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is
19890 const tracy = trace(@src());20069 const tracy = trace(@src());
19891 defer tracy.end();20070 defer tracy.end();
1989220071
19893 const mod = sema.mod;20072 const pt = sema.pt;
20073 const mod = pt.zcu;
19894 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;20074 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
19895 const src = block.nodeOffset(inst_data.src_node);20075 const src = block.nodeOffset(inst_data.src_node);
19896 const ty_operand = sema.resolveType(block, src, inst_data.operand) catch |err| switch (err) {20076 const ty_operand = sema.resolveType(block, src, inst_data.operand) catch |err| switch (err) {
...@@ -19905,7 +20085,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is...@@ -19905,7 +20085,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is
19905 break :ty ptr_ty.childType(mod);20085 break :ty ptr_ty.childType(mod);
19906 }20086 }
19907 // To make `&.{}` a `[:s]T`, the init should be a `[0:s]T`.20087 // To make `&.{}` a `[:s]T`, the init should be a `[0:s]T`.
19908 break :ty try mod.arrayType(.{20088 break :ty try pt.arrayType(.{
19909 .len = 0,20089 .len = 0,
19910 .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,20090 .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,
19911 .child = ptr_ty.childType(mod).toIntern(),20091 .child = ptr_ty.childType(mod).toIntern(),
...@@ -19936,10 +20116,11 @@ fn structInitEmpty(...@@ -19936,10 +20116,11 @@ fn structInitEmpty(
19936 dest_src: LazySrcLoc,20116 dest_src: LazySrcLoc,
19937 init_src: LazySrcLoc,20117 init_src: LazySrcLoc,
19938) CompileError!Air.Inst.Ref {20118) CompileError!Air.Inst.Ref {
19939 const mod = sema.mod;20119 const pt = sema.pt;
20120 const mod = pt.zcu;
19940 const gpa = sema.gpa;20121 const gpa = sema.gpa;
19941 // This logic must be synchronized with that in `zirStructInit`.20122 // This logic must be synchronized with that in `zirStructInit`.
19942 try struct_ty.resolveFields(mod);20123 try struct_ty.resolveFields(pt);
1994320124
19944 // The init values to use for the struct instance.20125 // The init values to use for the struct instance.
19945 const field_inits = try gpa.alloc(Air.Inst.Ref, struct_ty.structFieldCount(mod));20126 const field_inits = try gpa.alloc(Air.Inst.Ref, struct_ty.structFieldCount(mod));
...@@ -19950,7 +20131,8 @@ fn structInitEmpty(...@@ -19950,7 +20131,8 @@ fn structInitEmpty(
19950}20131}
1995120132
19952fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) CompileError!Air.Inst.Ref {20133fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) CompileError!Air.Inst.Ref {
19953 const mod = sema.mod;20134 const pt = sema.pt;
20135 const mod = pt.zcu;
19954 const arr_len = obj_ty.arrayLen(mod);20136 const arr_len = obj_ty.arrayLen(mod);
19955 if (arr_len != 0) {20137 if (arr_len != 0) {
19956 if (obj_ty.zigTypeTag(mod) == .Array) {20138 if (obj_ty.zigTypeTag(mod) == .Array) {
...@@ -19959,21 +20141,22 @@ fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) Com...@@ -19959,21 +20141,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});20141 return sema.fail(block, src, "expected {d} vector elements; found 0", .{arr_len});
19960 }20142 }
19961 }20143 }
19962 return Air.internedToRef((try mod.intern(.{ .aggregate = .{20144 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
19963 .ty = obj_ty.toIntern(),20145 .ty = obj_ty.toIntern(),
19964 .storage = .{ .elems = &.{} },20146 .storage = .{ .elems = &.{} },
19965 } })));20147 } })));
19966}20148}
1996720149
19968fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {20150fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
20151 const pt = sema.pt;
19969 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;20152 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
19970 const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);20153 const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);
19971 const field_src = block.builtinCallArgSrc(inst_data.src_node, 1);20154 const field_src = block.builtinCallArgSrc(inst_data.src_node, 1);
19972 const init_src = block.builtinCallArgSrc(inst_data.src_node, 2);20155 const init_src = block.builtinCallArgSrc(inst_data.src_node, 2);
19973 const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data;20156 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);20157 const union_ty = try sema.resolveType(block, ty_src, extra.union_type);
19975 if (union_ty.zigTypeTag(sema.mod) != .Union) {20158 if (union_ty.zigTypeTag(pt.zcu) != .Union) {
19976 return sema.fail(block, ty_src, "expected union type, found '{}'", .{union_ty.fmt(sema.mod)});20159 return sema.fail(block, ty_src, "expected union type, found '{}'", .{union_ty.fmt(pt)});
19977 }20160 }
19978 const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, .{20161 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",20162 .needed_comptime_reason = "name of field being initialized must be comptime-known",
...@@ -19992,7 +20175,8 @@ fn unionInit(...@@ -19992,7 +20175,8 @@ fn unionInit(
19992 field_name: InternPool.NullTerminatedString,20175 field_name: InternPool.NullTerminatedString,
19993 field_src: LazySrcLoc,20176 field_src: LazySrcLoc,
19994) CompileError!Air.Inst.Ref {20177) CompileError!Air.Inst.Ref {
19995 const mod = sema.mod;20178 const pt = sema.pt;
20179 const mod = pt.zcu;
19996 const ip = &mod.intern_pool;20180 const ip = &mod.intern_pool;
19997 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_src);20181 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]);20182 const field_ty = Type.fromInterned(mod.typeToUnion(union_ty).?.field_types.get(ip)[field_index]);
...@@ -20000,8 +20184,8 @@ fn unionInit(...@@ -20000,8 +20184,8 @@ fn unionInit(
2000020184
20001 if (try sema.resolveValue(init)) |init_val| {20185 if (try sema.resolveValue(init)) |init_val| {
20002 const tag_ty = union_ty.unionTagTypeHypothetical(mod);20186 const tag_ty = union_ty.unionTagTypeHypothetical(mod);
20003 const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index);20187 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);
20004 return Air.internedToRef((try mod.intern(.{ .un = .{20188 return Air.internedToRef((try pt.intern(.{ .un = .{
20005 .ty = union_ty.toIntern(),20189 .ty = union_ty.toIntern(),
20006 .tag = tag_val.toIntern(),20190 .tag = tag_val.toIntern(),
20007 .val = init_val.toIntern(),20191 .val = init_val.toIntern(),
...@@ -20025,7 +20209,8 @@ fn zirStructInit(...@@ -20025,7 +20209,8 @@ fn zirStructInit(
20025 const extra = sema.code.extraData(Zir.Inst.StructInit, inst_data.payload_index);20209 const extra = sema.code.extraData(Zir.Inst.StructInit, inst_data.payload_index);
20026 const src = block.nodeOffset(inst_data.src_node);20210 const src = block.nodeOffset(inst_data.src_node);
2002720211
20028 const mod = sema.mod;20212 const pt = sema.pt;
20213 const mod = pt.zcu;
20029 const ip = &mod.intern_pool;20214 const ip = &mod.intern_pool;
20030 const first_item = sema.code.extraData(Zir.Inst.StructInit.Item, extra.end).data;20215 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;20216 const first_field_type_data = zir_datas[@intFromEnum(first_item.field_type)].pl_node;
...@@ -20038,7 +20223,7 @@ fn zirStructInit(...@@ -20038,7 +20223,7 @@ fn zirStructInit(
20038 else => |e| return e,20223 else => |e| return e,
20039 };20224 };
20040 const resolved_ty = result_ty.optEuBaseType(mod);20225 const resolved_ty = result_ty.optEuBaseType(mod);
20041 try resolved_ty.resolveLayout(mod);20226 try resolved_ty.resolveLayout(pt);
2004220227
20043 if (resolved_ty.zigTypeTag(mod) == .Struct) {20228 if (resolved_ty.zigTypeTag(mod) == .Struct) {
20044 // This logic must be synchronized with that in `zirStructInitEmpty`.20229 // This logic must be synchronized with that in `zirStructInitEmpty`.
...@@ -20079,8 +20264,8 @@ fn zirStructInit(...@@ -20079,8 +20264,8 @@ fn zirStructInit(
20079 const field_ty = resolved_ty.structFieldType(field_index, mod);20264 const field_ty = resolved_ty.structFieldType(field_index, mod);
20080 field_inits[field_index] = try sema.coerce(block, field_ty, uncoerced_init, field_src);20265 field_inits[field_index] = try sema.coerce(block, field_ty, uncoerced_init, field_src);
20081 if (!is_packed) {20266 if (!is_packed) {
20082 try resolved_ty.resolveStructFieldInits(mod);20267 try resolved_ty.resolveStructFieldInits(pt);
20083 if (try resolved_ty.structFieldValueComptime(mod, field_index)) |default_value| {20268 if (try resolved_ty.structFieldValueComptime(pt, field_index)) |default_value| {
20084 const init_val = (try sema.resolveValue(field_inits[field_index])) orelse {20269 const init_val = (try sema.resolveValue(field_inits[field_index])) orelse {
20085 return sema.failWithNeededComptime(block, field_src, .{20270 return sema.failWithNeededComptime(block, field_src, .{
20086 .needed_comptime_reason = "value stored in comptime field must be comptime-known",20271 .needed_comptime_reason = "value stored in comptime field must be comptime-known",
...@@ -20112,7 +20297,7 @@ fn zirStructInit(...@@ -20112,7 +20297,7 @@ fn zirStructInit(
20112 );20297 );
20113 const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src);20298 const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src);
20114 const tag_ty = resolved_ty.unionTagTypeHypothetical(mod);20299 const tag_ty = resolved_ty.unionTagTypeHypothetical(mod);
20115 const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index);20300 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]);20301 const field_ty = Type.fromInterned(mod.typeToUnion(resolved_ty).?.field_types.get(ip)[field_index]);
2011720302
20118 if (field_ty.zigTypeTag(mod) == .NoReturn) {20303 if (field_ty.zigTypeTag(mod) == .NoReturn) {
...@@ -20132,11 +20317,11 @@ fn zirStructInit(...@@ -20132,11 +20317,11 @@ fn zirStructInit(
20132 const init_inst = try sema.coerce(block, field_ty, uncoerced_init_inst, field_src);20317 const init_inst = try sema.coerce(block, field_ty, uncoerced_init_inst, field_src);
2013320318
20134 if (try sema.resolveValue(init_inst)) |val| {20319 if (try sema.resolveValue(init_inst)) |val| {
20135 const struct_val = Value.fromInterned((try mod.intern(.{ .un = .{20320 const struct_val = Value.fromInterned(try pt.intern(.{ .un = .{
20136 .ty = resolved_ty.toIntern(),20321 .ty = resolved_ty.toIntern(),
20137 .tag = tag_val.toIntern(),20322 .tag = tag_val.toIntern(),
20138 .val = val.toIntern(),20323 .val = val.toIntern(),
20139 } })));20324 } }));
20140 const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val.toIntern()), src);20325 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)).?;20326 const final_val = (try sema.resolveValue(final_val_inst)).?;
20142 return sema.addConstantMaybeRef(final_val.toIntern(), is_ref);20327 return sema.addConstantMaybeRef(final_val.toIntern(), is_ref);
...@@ -20152,7 +20337,7 @@ fn zirStructInit(...@@ -20152,7 +20337,7 @@ fn zirStructInit(
2015220337
20153 if (is_ref) {20338 if (is_ref) {
20154 const target = mod.getTarget();20339 const target = mod.getTarget();
20155 const alloc_ty = try mod.ptrTypeSema(.{20340 const alloc_ty = try pt.ptrTypeSema(.{
20156 .child = result_ty.toIntern(),20341 .child = result_ty.toIntern(),
20157 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20342 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20158 });20343 });
...@@ -20182,7 +20367,8 @@ fn finishStructInit(...@@ -20182,7 +20367,8 @@ fn finishStructInit(
20182 result_ty: Type,20367 result_ty: Type,
20183 is_ref: bool,20368 is_ref: bool,
20184) CompileError!Air.Inst.Ref {20369) CompileError!Air.Inst.Ref {
20185 const mod = sema.mod;20370 const pt = sema.pt;
20371 const mod = pt.zcu;
20186 const ip = &mod.intern_pool;20372 const ip = &mod.intern_pool;
2018720373
20188 var root_msg: ?*Module.ErrorMsg = null;20374 var root_msg: ?*Module.ErrorMsg = null;
...@@ -20242,7 +20428,7 @@ fn finishStructInit(...@@ -20242,7 +20428,7 @@ fn finishStructInit(
20242 continue;20428 continue;
20243 }20429 }
2024420430
20245 try struct_ty.resolveStructFieldInits(mod);20431 try struct_ty.resolveStructFieldInits(pt);
2024620432
20247 const field_init = struct_type.fieldInit(ip, i);20433 const field_init = struct_type.fieldInit(ip, i);
20248 if (field_init == .none) {20434 if (field_init == .none) {
...@@ -20289,7 +20475,7 @@ fn finishStructInit(...@@ -20289,7 +20475,7 @@ fn finishStructInit(
20289 for (elems, field_inits) |*elem, field_init| {20475 for (elems, field_inits) |*elem, field_init| {
20290 elem.* = (sema.resolveValue(field_init) catch unreachable).?.toIntern();20476 elem.* = (sema.resolveValue(field_init) catch unreachable).?.toIntern();
20291 }20477 }
20292 const struct_val = try mod.intern(.{ .aggregate = .{20478 const struct_val = try pt.intern(.{ .aggregate = .{
20293 .ty = struct_ty.toIntern(),20479 .ty = struct_ty.toIntern(),
20294 .storage = .{ .elems = elems },20480 .storage = .{ .elems = elems },
20295 } });20481 } });
...@@ -20312,9 +20498,9 @@ fn finishStructInit(...@@ -20312,9 +20498,9 @@ fn finishStructInit(
20312 }20498 }
2031320499
20314 if (is_ref) {20500 if (is_ref) {
20315 try struct_ty.resolveLayout(mod);20501 try struct_ty.resolveLayout(pt);
20316 const target = sema.mod.getTarget();20502 const target = mod.getTarget();
20317 const alloc_ty = try mod.ptrTypeSema(.{20503 const alloc_ty = try pt.ptrTypeSema(.{
20318 .child = result_ty.toIntern(),20504 .child = result_ty.toIntern(),
20319 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20505 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20320 });20506 });
...@@ -20334,7 +20520,7 @@ fn finishStructInit(...@@ -20334,7 +20520,7 @@ fn finishStructInit(
20334 .init_node_offset = init_src.offset.node_offset.x,20520 .init_node_offset = init_src.offset.node_offset.x,
20335 .elem_index = @intCast(runtime_index),20521 .elem_index = @intCast(runtime_index),
20336 } }));20522 } }));
20337 try struct_ty.resolveStructFieldInits(mod);20523 try struct_ty.resolveStructFieldInits(pt);
20338 const struct_val = try block.addAggregateInit(struct_ty, field_inits);20524 const struct_val = try block.addAggregateInit(struct_ty, field_inits);
20339 return sema.coerce(block, result_ty, struct_val, init_src);20525 return sema.coerce(block, result_ty, struct_val, init_src);
20340}20526}
...@@ -20364,7 +20550,8 @@ fn structInitAnon(...@@ -20364,7 +20550,8 @@ fn structInitAnon(
20364 extra_end: usize,20550 extra_end: usize,
20365 is_ref: bool,20551 is_ref: bool,
20366) CompileError!Air.Inst.Ref {20552) CompileError!Air.Inst.Ref {
20367 const mod = sema.mod;20553 const pt = sema.pt;
20554 const mod = pt.zcu;
20368 const gpa = sema.gpa;20555 const gpa = sema.gpa;
20369 const ip = &mod.intern_pool;20556 const ip = &mod.intern_pool;
20370 const zir_datas = sema.code.instructions.items(.data);20557 const zir_datas = sema.code.instructions.items(.data);
...@@ -20422,14 +20609,14 @@ fn structInitAnon(...@@ -20422,14 +20609,14 @@ fn structInitAnon(
20422 break :rs runtime_index;20609 break :rs runtime_index;
20423 };20610 };
2042420611
20425 const tuple_ty = try ip.getAnonStructType(gpa, .{20612 const tuple_ty = try ip.getAnonStructType(gpa, pt.tid, .{
20426 .names = names,20613 .names = names,
20427 .types = types,20614 .types = types,
20428 .values = values,20615 .values = values,
20429 });20616 });
2043020617
20431 const runtime_index = opt_runtime_index orelse {20618 const runtime_index = opt_runtime_index orelse {
20432 const tuple_val = try mod.intern(.{ .aggregate = .{20619 const tuple_val = try pt.intern(.{ .aggregate = .{
20433 .ty = tuple_ty,20620 .ty = tuple_ty,
20434 .storage = .{ .elems = values },20621 .storage = .{ .elems = values },
20435 } });20622 } });
...@@ -20443,7 +20630,7 @@ fn structInitAnon(...@@ -20443,7 +20630,7 @@ fn structInitAnon(
2044320630
20444 if (is_ref) {20631 if (is_ref) {
20445 const target = mod.getTarget();20632 const target = mod.getTarget();
20446 const alloc_ty = try mod.ptrTypeSema(.{20633 const alloc_ty = try pt.ptrTypeSema(.{
20447 .child = tuple_ty,20634 .child = tuple_ty,
20448 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20635 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20449 });20636 });
...@@ -20457,7 +20644,7 @@ fn structInitAnon(...@@ -20457,7 +20644,7 @@ fn structInitAnon(
20457 };20644 };
20458 extra_index = item.end;20645 extra_index = item.end;
2045920646
20460 const field_ptr_ty = try mod.ptrTypeSema(.{20647 const field_ptr_ty = try pt.ptrTypeSema(.{
20461 .child = field_ty,20648 .child = field_ty,
20462 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20649 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20463 });20650 });
...@@ -20491,7 +20678,8 @@ fn zirArrayInit(...@@ -20491,7 +20678,8 @@ fn zirArrayInit(
20491 inst: Zir.Inst.Index,20678 inst: Zir.Inst.Index,
20492 is_ref: bool,20679 is_ref: bool,
20493) CompileError!Air.Inst.Ref {20680) CompileError!Air.Inst.Ref {
20494 const mod = sema.mod;20681 const pt = sema.pt;
20682 const mod = pt.zcu;
20495 const gpa = sema.gpa;20683 const gpa = sema.gpa;
20496 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;20684 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
20497 const src = block.nodeOffset(inst_data.src_node);20685 const src = block.nodeOffset(inst_data.src_node);
...@@ -20550,8 +20738,8 @@ fn zirArrayInit(...@@ -20550,8 +20738,8 @@ fn zirArrayInit(
20550 dest.* = try sema.coerce(block, elem_ty, resolved_arg, elem_src);20738 dest.* = try sema.coerce(block, elem_ty, resolved_arg, elem_src);
20551 if (is_tuple) {20739 if (is_tuple) {
20552 if (array_ty.structFieldIsComptime(i, mod))20740 if (array_ty.structFieldIsComptime(i, mod))
20553 try array_ty.resolveStructFieldInits(mod);20741 try array_ty.resolveStructFieldInits(pt);
20554 if (try array_ty.structFieldValueComptime(mod, i)) |field_val| {20742 if (try array_ty.structFieldValueComptime(pt, i)) |field_val| {
20555 const init_val = try sema.resolveValue(dest.*) orelse {20743 const init_val = try sema.resolveValue(dest.*) orelse {
20556 return sema.failWithNeededComptime(block, elem_src, .{20744 return sema.failWithNeededComptime(block, elem_src, .{
20557 .needed_comptime_reason = "value stored in comptime field must be comptime-known",20745 .needed_comptime_reason = "value stored in comptime field must be comptime-known",
...@@ -20581,7 +20769,7 @@ fn zirArrayInit(...@@ -20581,7 +20769,7 @@ fn zirArrayInit(
20581 // We checked that all args are comptime above.20769 // We checked that all args are comptime above.
20582 val.* = (sema.resolveValue(arg) catch unreachable).?.toIntern();20770 val.* = (sema.resolveValue(arg) catch unreachable).?.toIntern();
20583 }20771 }
20584 const arr_val = try mod.intern(.{ .aggregate = .{20772 const arr_val = try pt.intern(.{ .aggregate = .{
20585 .ty = array_ty.toIntern(),20773 .ty = array_ty.toIntern(),
20586 .storage = .{ .elems = elem_vals },20774 .storage = .{ .elems = elem_vals },
20587 } });20775 } });
...@@ -20597,7 +20785,7 @@ fn zirArrayInit(...@@ -20597,7 +20785,7 @@ fn zirArrayInit(
2059720785
20598 if (is_ref) {20786 if (is_ref) {
20599 const target = mod.getTarget();20787 const target = mod.getTarget();
20600 const alloc_ty = try mod.ptrTypeSema(.{20788 const alloc_ty = try pt.ptrTypeSema(.{
20601 .child = result_ty.toIntern(),20789 .child = result_ty.toIntern(),
20602 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20790 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20603 });20791 });
...@@ -20606,27 +20794,27 @@ fn zirArrayInit(...@@ -20606,27 +20794,27 @@ fn zirArrayInit(
2060620794
20607 if (is_tuple) {20795 if (is_tuple) {
20608 for (resolved_args, 0..) |arg, i| {20796 for (resolved_args, 0..) |arg, i| {
20609 const elem_ptr_ty = try mod.ptrTypeSema(.{20797 const elem_ptr_ty = try pt.ptrTypeSema(.{
20610 .child = array_ty.structFieldType(i, mod).toIntern(),20798 .child = array_ty.structFieldType(i, mod).toIntern(),
20611 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20799 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20612 });20800 });
20613 const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern());20801 const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern());
2061420802
20615 const index = try mod.intRef(Type.usize, i);20803 const index = try pt.intRef(Type.usize, i);
20616 const elem_ptr = try block.addPtrElemPtrTypeRef(base_ptr, index, elem_ptr_ty_ref);20804 const elem_ptr = try block.addPtrElemPtrTypeRef(base_ptr, index, elem_ptr_ty_ref);
20617 _ = try block.addBinOp(.store, elem_ptr, arg);20805 _ = try block.addBinOp(.store, elem_ptr, arg);
20618 }20806 }
20619 return sema.makePtrConst(block, alloc);20807 return sema.makePtrConst(block, alloc);
20620 }20808 }
2062120809
20622 const elem_ptr_ty = try mod.ptrTypeSema(.{20810 const elem_ptr_ty = try pt.ptrTypeSema(.{
20623 .child = array_ty.elemType2(mod).toIntern(),20811 .child = array_ty.elemType2(mod).toIntern(),
20624 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20812 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20625 });20813 });
20626 const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern());20814 const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern());
2062720815
20628 for (resolved_args, 0..) |arg, i| {20816 for (resolved_args, 0..) |arg, i| {
20629 const index = try mod.intRef(Type.usize, i);20817 const index = try pt.intRef(Type.usize, i);
20630 const elem_ptr = try block.addPtrElemPtrTypeRef(base_ptr, index, elem_ptr_ty_ref);20818 const elem_ptr = try block.addPtrElemPtrTypeRef(base_ptr, index, elem_ptr_ty_ref);
20631 _ = try block.addBinOp(.store, elem_ptr, arg);20819 _ = try block.addBinOp(.store, elem_ptr, arg);
20632 }20820 }
...@@ -20656,7 +20844,8 @@ fn arrayInitAnon(...@@ -20656,7 +20844,8 @@ fn arrayInitAnon(
20656 operands: []const Zir.Inst.Ref,20844 operands: []const Zir.Inst.Ref,
20657 is_ref: bool,20845 is_ref: bool,
20658) CompileError!Air.Inst.Ref {20846) CompileError!Air.Inst.Ref {
20659 const mod = sema.mod;20847 const pt = sema.pt;
20848 const mod = pt.zcu;
20660 const gpa = sema.gpa;20849 const gpa = sema.gpa;
20661 const ip = &mod.intern_pool;20850 const ip = &mod.intern_pool;
2066220851
...@@ -20689,14 +20878,14 @@ fn arrayInitAnon(...@@ -20689,14 +20878,14 @@ fn arrayInitAnon(
20689 break :rs runtime_src;20878 break :rs runtime_src;
20690 };20879 };
2069120880
20692 const tuple_ty = try ip.getAnonStructType(gpa, .{20881 const tuple_ty = try ip.getAnonStructType(gpa, pt.tid, .{
20693 .types = types,20882 .types = types,
20694 .values = values,20883 .values = values,
20695 .names = &.{},20884 .names = &.{},
20696 });20885 });
2069720886
20698 const runtime_src = opt_runtime_src orelse {20887 const runtime_src = opt_runtime_src orelse {
20699 const tuple_val = try mod.intern(.{ .aggregate = .{20888 const tuple_val = try pt.intern(.{ .aggregate = .{
20700 .ty = tuple_ty,20889 .ty = tuple_ty,
20701 .storage = .{ .elems = values },20890 .storage = .{ .elems = values },
20702 } });20891 } });
...@@ -20706,15 +20895,15 @@ fn arrayInitAnon(...@@ -20706,15 +20895,15 @@ fn arrayInitAnon(
20706 try sema.requireRuntimeBlock(block, src, runtime_src);20895 try sema.requireRuntimeBlock(block, src, runtime_src);
2070720896
20708 if (is_ref) {20897 if (is_ref) {
20709 const target = sema.mod.getTarget();20898 const target = sema.pt.zcu.getTarget();
20710 const alloc_ty = try mod.ptrTypeSema(.{20899 const alloc_ty = try pt.ptrTypeSema(.{
20711 .child = tuple_ty,20900 .child = tuple_ty,
20712 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20901 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20713 });20902 });
20714 const alloc = try block.addTy(.alloc, alloc_ty);20903 const alloc = try block.addTy(.alloc, alloc_ty);
20715 for (operands, 0..) |operand, i_usize| {20904 for (operands, 0..) |operand, i_usize| {
20716 const i: u32 = @intCast(i_usize);20905 const i: u32 = @intCast(i_usize);
20717 const field_ptr_ty = try mod.ptrTypeSema(.{20906 const field_ptr_ty = try pt.ptrTypeSema(.{
20718 .child = types[i],20907 .child = types[i],
20719 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20908 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20720 });20909 });
...@@ -20752,7 +20941,8 @@ fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -20752,7 +20941,8 @@ fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
20752}20941}
2075320942
20754fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {20943fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
20755 const mod = sema.mod;20944 const pt = sema.pt;
20945 const mod = pt.zcu;
20756 const ip = &mod.intern_pool;20946 const ip = &mod.intern_pool;
20757 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;20947 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;20948 const extra = sema.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data;
...@@ -20780,11 +20970,12 @@ fn fieldType(...@@ -20780,11 +20970,12 @@ fn fieldType(
20780 field_src: LazySrcLoc,20970 field_src: LazySrcLoc,
20781 ty_src: LazySrcLoc,20971 ty_src: LazySrcLoc,
20782) CompileError!Air.Inst.Ref {20972) CompileError!Air.Inst.Ref {
20783 const mod = sema.mod;20973 const pt = sema.pt;
20974 const mod = pt.zcu;
20784 const ip = &mod.intern_pool;20975 const ip = &mod.intern_pool;
20785 var cur_ty = aggregate_ty;20976 var cur_ty = aggregate_ty;
20786 while (true) {20977 while (true) {
20787 try cur_ty.resolveFields(mod);20978 try cur_ty.resolveFields(pt);
20788 switch (cur_ty.zigTypeTag(mod)) {20979 switch (cur_ty.zigTypeTag(mod)) {
20789 .Struct => switch (ip.indexToKey(cur_ty.toIntern())) {20980 .Struct => switch (ip.indexToKey(cur_ty.toIntern())) {
20790 .anon_struct_type => |anon_struct| {20981 .anon_struct_type => |anon_struct| {
...@@ -20823,7 +21014,7 @@ fn fieldType(...@@ -20823,7 +21014,7 @@ fn fieldType(
20823 else => {},21014 else => {},
20824 }21015 }
20825 return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{21016 return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{
20826 cur_ty.fmt(sema.mod),21017 cur_ty.fmt(pt),
20827 });21018 });
20828 }21019 }
20829}21020}
...@@ -20833,12 +21024,13 @@ fn zirErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {...@@ -20833,12 +21024,13 @@ fn zirErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
20833}21024}
2083421025
20835fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {21026fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
20836 const mod = sema.mod;21027 const pt = sema.pt;
21028 const mod = pt.zcu;
20837 const ip = &mod.intern_pool;21029 const ip = &mod.intern_pool;
20838 const stack_trace_ty = try mod.getBuiltinType("StackTrace");21030 const stack_trace_ty = try pt.getBuiltinType("StackTrace");
20839 try stack_trace_ty.resolveFields(mod);21031 try stack_trace_ty.resolveFields(pt);
20840 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);21032 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());21033 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
2084221034
20843 if (sema.owner_func_index != .none and21035 if (sema.owner_func_index != .none and
20844 ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn and21036 ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn and
...@@ -20846,7 +21038,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {...@@ -20846,7 +21038,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
20846 {21038 {
20847 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);21039 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);
20848 }21040 }
20849 return Air.internedToRef((try mod.intern(.{ .opt = .{21041 return Air.internedToRef((try pt.intern(.{ .opt = .{
20850 .ty = opt_ptr_stack_trace_ty.toIntern(),21042 .ty = opt_ptr_stack_trace_ty.toIntern(),
20851 .val = .none,21043 .val = .none,
20852 } })));21044 } })));
...@@ -20862,19 +21054,20 @@ fn zirFrame(...@@ -20862,19 +21054,20 @@ fn zirFrame(
20862}21054}
2086321055
20864fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {21056fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
20865 const mod = sema.mod;21057 const pt = sema.pt;
20866 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;21058 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
20867 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);21059 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
20868 const ty = try sema.resolveType(block, operand_src, inst_data.operand);21060 const ty = try sema.resolveType(block, operand_src, inst_data.operand);
20869 if (ty.isNoReturn(mod)) {21061 if (ty.isNoReturn(pt.zcu)) {
20870 return sema.fail(block, operand_src, "no align available for type '{}'", .{ty.fmt(sema.mod)});21062 return sema.fail(block, operand_src, "no align available for type '{}'", .{ty.fmt(pt)});
20871 }21063 }
20872 const val = try ty.lazyAbiAlignment(mod);21064 const val = try ty.lazyAbiAlignment(pt);
20873 return Air.internedToRef(val.toIntern());21065 return Air.internedToRef(val.toIntern());
20874}21066}
2087521067
20876fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {21068fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
20877 const mod = sema.mod;21069 const pt = sema.pt;
21070 const mod = pt.zcu;
20878 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;21071 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
20879 const src = block.nodeOffset(inst_data.src_node);21072 const src = block.nodeOffset(inst_data.src_node);
20880 const operand = try sema.resolveInst(inst_data.operand);21073 const operand = try sema.resolveInst(inst_data.operand);
...@@ -20886,25 +21079,25 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -20886,25 +21079,25 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
20886 }21079 }
20887 if (try sema.resolveValue(operand)) |val| {21080 if (try sema.resolveValue(operand)) |val| {
20888 if (!is_vector) {21081 if (!is_vector) {
20889 if (val.isUndef(mod)) return mod.undefRef(Type.u1);21082 if (val.isUndef(mod)) return pt.undefRef(Type.u1);
20890 if (val.toBool()) return Air.internedToRef((try mod.intValue(Type.u1, 1)).toIntern());21083 if (val.toBool()) return Air.internedToRef((try pt.intValue(Type.u1, 1)).toIntern());
20891 return Air.internedToRef((try mod.intValue(Type.u1, 0)).toIntern());21084 return Air.internedToRef((try pt.intValue(Type.u1, 0)).toIntern());
20892 }21085 }
20893 const len = operand_ty.vectorLen(mod);21086 const len = operand_ty.vectorLen(mod);
20894 const dest_ty = try mod.vectorType(.{ .child = .u1_type, .len = len });21087 const dest_ty = try pt.vectorType(.{ .child = .u1_type, .len = len });
20895 if (val.isUndef(mod)) return mod.undefRef(dest_ty);21088 if (val.isUndef(mod)) return pt.undefRef(dest_ty);
20896 const new_elems = try sema.arena.alloc(InternPool.Index, len);21089 const new_elems = try sema.arena.alloc(InternPool.Index, len);
20897 for (new_elems, 0..) |*new_elem, i| {21090 for (new_elems, 0..) |*new_elem, i| {
20898 const old_elem = try val.elemValue(mod, i);21091 const old_elem = try val.elemValue(pt, i);
20899 const new_val = if (old_elem.isUndef(mod))21092 const new_val = if (old_elem.isUndef(mod))
20900 try mod.undefValue(Type.u1)21093 try pt.undefValue(Type.u1)
20901 else if (old_elem.toBool())21094 else if (old_elem.toBool())
20902 try mod.intValue(Type.u1, 1)21095 try pt.intValue(Type.u1, 1)
20903 else21096 else
20904 try mod.intValue(Type.u1, 0);21097 try pt.intValue(Type.u1, 0);
20905 new_elem.* = new_val.toIntern();21098 new_elem.* = new_val.toIntern();
20906 }21099 }
20907 return Air.internedToRef(try mod.intern(.{ .aggregate = .{21100 return Air.internedToRef(try pt.intern(.{ .aggregate = .{
20908 .ty = dest_ty.toIntern(),21101 .ty = dest_ty.toIntern(),
20909 .storage = .{ .elems = new_elems },21102 .storage = .{ .elems = new_elems },
20910 } }));21103 } }));
...@@ -20913,10 +21106,10 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -20913,10 +21106,10 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
20913 return block.addUnOp(.int_from_bool, operand);21106 return block.addUnOp(.int_from_bool, operand);
20914 }21107 }
20915 const len = operand_ty.vectorLen(mod);21108 const len = operand_ty.vectorLen(mod);
20916 const dest_ty = try mod.vectorType(.{ .child = .u1_type, .len = len });21109 const dest_ty = try pt.vectorType(.{ .child = .u1_type, .len = len });
20917 const new_elems = try sema.arena.alloc(Air.Inst.Ref, len);21110 const new_elems = try sema.arena.alloc(Air.Inst.Ref, len);
20918 for (new_elems, 0..) |*new_elem, i| {21111 for (new_elems, 0..) |*new_elem, i| {
20919 const idx_ref = try mod.intRef(Type.usize, i);21112 const idx_ref = try pt.intRef(Type.usize, i);
20920 const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref);21113 const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref);
20921 new_elem.* = try block.addUnOp(.int_from_bool, old_elem);21114 new_elem.* = try block.addUnOp(.int_from_bool, old_elem);
20922 }21115 }
...@@ -20930,7 +21123,7 @@ fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -20930,7 +21123,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);21123 const operand = try sema.coerce(block, Type.anyerror, uncoerced_operand, operand_src);
2093121124
20932 if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {21125 if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {
20933 const err_name = sema.mod.intern_pool.indexToKey(val.toIntern()).err.name;21126 const err_name = sema.pt.zcu.intern_pool.indexToKey(val.toIntern()).err.name;
20934 return sema.addNullTerminatedStrLit(err_name);21127 return sema.addNullTerminatedStrLit(err_name);
20935 }21128 }
2093621129
...@@ -20944,7 +21137,8 @@ fn zirAbs(...@@ -20944,7 +21137,8 @@ fn zirAbs(
20944 block: *Block,21137 block: *Block,
20945 inst: Zir.Inst.Index,21138 inst: Zir.Inst.Index,
20946) CompileError!Air.Inst.Ref {21139) CompileError!Air.Inst.Ref {
20947 const mod = sema.mod;21140 const pt = sema.pt;
21141 const mod = pt.zcu;
20948 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;21142 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
20949 const operand = try sema.resolveInst(inst_data.operand);21143 const operand = try sema.resolveInst(inst_data.operand);
20950 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);21144 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
...@@ -20953,12 +21147,12 @@ fn zirAbs(...@@ -20953,12 +21147,12 @@ fn zirAbs(
2095321147
20954 const result_ty = switch (scalar_ty.zigTypeTag(mod)) {21148 const result_ty = switch (scalar_ty.zigTypeTag(mod)) {
20955 .ComptimeFloat, .Float, .ComptimeInt => operand_ty,21149 .ComptimeFloat, .Float, .ComptimeInt => operand_ty,
20956 .Int => if (scalar_ty.isSignedInt(mod)) try operand_ty.toUnsigned(mod) else return operand,21150 .Int => if (scalar_ty.isSignedInt(mod)) try operand_ty.toUnsigned(pt) else return operand,
20957 else => return sema.fail(21151 else => return sema.fail(
20958 block,21152 block,
20959 operand_src,21153 operand_src,
20960 "expected integer, float, or vector of either integers or floats, found '{}'",21154 "expected integer, float, or vector of either integers or floats, found '{}'",
20961 .{operand_ty.fmt(mod)},21155 .{operand_ty.fmt(pt)},
20962 ),21156 ),
20963 };21157 };
2096421158
...@@ -20972,30 +21166,31 @@ fn maybeConstantUnaryMath(...@@ -20972,30 +21166,31 @@ fn maybeConstantUnaryMath(
20972 sema: *Sema,21166 sema: *Sema,
20973 operand: Air.Inst.Ref,21167 operand: Air.Inst.Ref,
20974 result_ty: Type,21168 result_ty: Type,
20975 comptime eval: fn (Value, Type, Allocator, *Module) Allocator.Error!Value,21169 comptime eval: fn (Value, Type, Allocator, Zcu.PerThread) Allocator.Error!Value,
20976) CompileError!?Air.Inst.Ref {21170) CompileError!?Air.Inst.Ref {
20977 const mod = sema.mod;21171 const pt = sema.pt;
21172 const mod = pt.zcu;
20978 switch (result_ty.zigTypeTag(mod)) {21173 switch (result_ty.zigTypeTag(mod)) {
20979 .Vector => if (try sema.resolveValue(operand)) |val| {21174 .Vector => if (try sema.resolveValue(operand)) |val| {
20980 const scalar_ty = result_ty.scalarType(mod);21175 const scalar_ty = result_ty.scalarType(mod);
20981 const vec_len = result_ty.vectorLen(mod);21176 const vec_len = result_ty.vectorLen(mod);
20982 if (val.isUndef(mod))21177 if (val.isUndef(mod))
20983 return try mod.undefRef(result_ty);21178 return try pt.undefRef(result_ty);
2098421179
20985 const elems = try sema.arena.alloc(InternPool.Index, vec_len);21180 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
20986 for (elems, 0..) |*elem, i| {21181 for (elems, 0..) |*elem, i| {
20987 const elem_val = try val.elemValue(sema.mod, i);21182 const elem_val = try val.elemValue(pt, i);
20988 elem.* = (try eval(elem_val, scalar_ty, sema.arena, sema.mod)).toIntern();21183 elem.* = (try eval(elem_val, scalar_ty, sema.arena, pt)).toIntern();
20989 }21184 }
20990 return Air.internedToRef((try mod.intern(.{ .aggregate = .{21185 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
20991 .ty = result_ty.toIntern(),21186 .ty = result_ty.toIntern(),
20992 .storage = .{ .elems = elems },21187 .storage = .{ .elems = elems },
20993 } })));21188 } })));
20994 },21189 },
20995 else => if (try sema.resolveValue(operand)) |operand_val| {21190 else => if (try sema.resolveValue(operand)) |operand_val| {
20996 if (operand_val.isUndef(mod))21191 if (operand_val.isUndef(mod))
20997 return try mod.undefRef(result_ty);21192 return try pt.undefRef(result_ty);
20998 const result_val = try eval(operand_val, result_ty, sema.arena, sema.mod);21193 const result_val = try eval(operand_val, result_ty, sema.arena, pt);
20999 return Air.internedToRef(result_val.toIntern());21194 return Air.internedToRef(result_val.toIntern());
21000 },21195 },
21001 }21196 }
...@@ -21007,12 +21202,13 @@ fn zirUnaryMath(...@@ -21007,12 +21202,13 @@ fn zirUnaryMath(
21007 block: *Block,21202 block: *Block,
21008 inst: Zir.Inst.Index,21203 inst: Zir.Inst.Index,
21009 air_tag: Air.Inst.Tag,21204 air_tag: Air.Inst.Tag,
21010 comptime eval: fn (Value, Type, Allocator, *Module) Allocator.Error!Value,21205 comptime eval: fn (Value, Type, Allocator, Zcu.PerThread) Allocator.Error!Value,
21011) CompileError!Air.Inst.Ref {21206) CompileError!Air.Inst.Ref {
21012 const tracy = trace(@src());21207 const tracy = trace(@src());
21013 defer tracy.end();21208 defer tracy.end();
2101421209
21015 const mod = sema.mod;21210 const pt = sema.pt;
21211 const mod = pt.zcu;
21016 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;21212 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
21017 const operand = try sema.resolveInst(inst_data.operand);21213 const operand = try sema.resolveInst(inst_data.operand);
21018 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);21214 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
...@@ -21025,7 +21221,7 @@ fn zirUnaryMath(...@@ -21025,7 +21221,7 @@ fn zirUnaryMath(
21025 block,21221 block,
21026 operand_src,21222 operand_src,
21027 "expected vector of floats or float type, found '{}'",21223 "expected vector of floats or float type, found '{}'",
21028 .{operand_ty.fmt(sema.mod)},21224 .{operand_ty.fmt(pt)},
21029 ),21225 ),
21030 }21226 }
2103121227
...@@ -21041,10 +21237,11 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -21041,10 +21237,11 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
21041 const src = block.nodeOffset(inst_data.src_node);21237 const src = block.nodeOffset(inst_data.src_node);
21042 const operand = try sema.resolveInst(inst_data.operand);21238 const operand = try sema.resolveInst(inst_data.operand);
21043 const operand_ty = sema.typeOf(operand);21239 const operand_ty = sema.typeOf(operand);
21044 const mod = sema.mod;21240 const pt = sema.pt;
21241 const mod = pt.zcu;
21045 const ip = &mod.intern_pool;21242 const ip = &mod.intern_pool;
2104621243
21047 try operand_ty.resolveLayout(mod);21244 try operand_ty.resolveLayout(pt);
21048 const enum_ty = switch (operand_ty.zigTypeTag(mod)) {21245 const enum_ty = switch (operand_ty.zigTypeTag(mod)) {
21049 .EnumLiteral => {21246 .EnumLiteral => {
21050 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, operand, undefined);21247 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, operand, undefined);
...@@ -21053,9 +21250,9 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -21053,9 +21250,9 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
21053 },21250 },
21054 .Enum => operand_ty,21251 .Enum => operand_ty,
21055 .Union => operand_ty.unionTagType(mod) orelse21252 .Union => operand_ty.unionTagType(mod) orelse
21056 return sema.fail(block, src, "union '{}' is untagged", .{operand_ty.fmt(sema.mod)}),21253 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 '{}'", .{21254 else => return sema.fail(block, operand_src, "expected enum or union; found '{}'", .{
21058 operand_ty.fmt(mod),21255 operand_ty.fmt(pt),
21059 }),21256 }),
21060 };21257 };
21061 if (enum_ty.enumFieldCount(mod) == 0) {21258 if (enum_ty.enumFieldCount(mod) == 0) {
...@@ -21063,7 +21260,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -21063,7 +21260,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
21063 // it prevents a crash.21260 // it prevents a crash.
21064 // https://github.com/ziglang/zig/issues/1590921261 // https://github.com/ziglang/zig/issues/15909
21065 return sema.fail(block, operand_src, "cannot get @tagName of empty enum '{}'", .{21262 return sema.fail(block, operand_src, "cannot get @tagName of empty enum '{}'", .{
21066 enum_ty.fmt(mod),21263 enum_ty.fmt(pt),
21067 });21264 });
21068 }21265 }
21069 const enum_decl_index = enum_ty.getOwnerDecl(mod);21266 const enum_decl_index = enum_ty.getOwnerDecl(mod);
...@@ -21072,7 +21269,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -21072,7 +21269,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
21072 const field_index = enum_ty.enumTagFieldIndex(val, mod) orelse {21269 const field_index = enum_ty.enumTagFieldIndex(val, mod) orelse {
21073 const msg = msg: {21270 const msg = msg: {
21074 const msg = try sema.errMsg(src, "no field with value '{}' in enum '{}'", .{21271 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),21272 val.fmtValue(pt, sema), mod.declPtr(enum_decl_index).name.fmt(ip),
21076 });21273 });
21077 errdefer msg.destroy(sema.gpa);21274 errdefer msg.destroy(sema.gpa);
21078 try sema.errNote(enum_ty.srcLoc(mod), msg, "declared here", .{});21275 try sema.errNote(enum_ty.srcLoc(mod), msg, "declared here", .{});
...@@ -21085,7 +21282,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -21085,7 +21282,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
21085 return sema.addNullTerminatedStrLit(field_name);21282 return sema.addNullTerminatedStrLit(field_name);
21086 }21283 }
21087 try sema.requireRuntimeBlock(block, src, operand_src);21284 try sema.requireRuntimeBlock(block, src, operand_src);
21088 if (block.wantSafety() and sema.mod.backendSupportsFeature(.is_named_enum_value)) {21285 if (block.wantSafety() and mod.backendSupportsFeature(.is_named_enum_value)) {
21089 const ok = try block.addUnOp(.is_named_enum_value, casted_operand);21286 const ok = try block.addUnOp(.is_named_enum_value, casted_operand);
21090 try sema.addSafetyCheck(block, src, ok, .invalid_enum_value);21287 try sema.addSafetyCheck(block, src, ok, .invalid_enum_value);
21091 }21288 }
...@@ -21101,7 +21298,8 @@ fn zirReify(...@@ -21101,7 +21298,8 @@ fn zirReify(
21101 extended: Zir.Inst.Extended.InstData,21298 extended: Zir.Inst.Extended.InstData,
21102 inst: Zir.Inst.Index,21299 inst: Zir.Inst.Index,
21103) CompileError!Air.Inst.Ref {21300) CompileError!Air.Inst.Ref {
21104 const mod = sema.mod;21301 const pt = sema.pt;
21302 const mod = pt.zcu;
21105 const gpa = sema.gpa;21303 const gpa = sema.gpa;
21106 const ip = &mod.intern_pool;21304 const ip = &mod.intern_pool;
21107 const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small);21305 const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small);
...@@ -21120,7 +21318,7 @@ fn zirReify(...@@ -21120,7 +21318,7 @@ fn zirReify(
21120 },21318 },
21121 },21319 },
21122 };21320 };
21123 const type_info_ty = try mod.getBuiltinType("Type");21321 const type_info_ty = try pt.getBuiltinType("Type");
21124 const uncasted_operand = try sema.resolveInst(extra.operand);21322 const uncasted_operand = try sema.resolveInst(extra.operand);
21125 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);21323 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, .{21324 const val = try sema.resolveConstDefinedValue(block, operand_src, type_info, .{
...@@ -21145,36 +21343,36 @@ fn zirReify(...@@ -21145,36 +21343,36 @@ fn zirReify(
21145 .Int => {21343 .Int => {
21146 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21344 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
21147 const signedness_val = try Value.fromInterned(union_val.val).fieldValue(21345 const signedness_val = try Value.fromInterned(union_val.val).fieldValue(
21148 mod,21346 pt,
21149 struct_type.nameIndex(ip, try ip.getOrPutString(gpa, "signedness", .no_embedded_nulls)).?,21347 struct_type.nameIndex(ip, try ip.getOrPutString(gpa, "signedness", .no_embedded_nulls)).?,
21150 );21348 );
21151 const bits_val = try Value.fromInterned(union_val.val).fieldValue(21349 const bits_val = try Value.fromInterned(union_val.val).fieldValue(
21152 mod,21350 pt,
21153 struct_type.nameIndex(ip, try ip.getOrPutString(gpa, "bits", .no_embedded_nulls)).?,21351 struct_type.nameIndex(ip, try ip.getOrPutString(gpa, "bits", .no_embedded_nulls)).?,
21154 );21352 );
2115521353
21156 const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);21354 const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);
21157 const bits: u16 = @intCast(try bits_val.toUnsignedIntSema(mod));21355 const bits: u16 = @intCast(try bits_val.toUnsignedIntSema(pt));
21158 const ty = try mod.intType(signedness, bits);21356 const ty = try pt.intType(signedness, bits);
21159 return Air.internedToRef(ty.toIntern());21357 return Air.internedToRef(ty.toIntern());
21160 },21358 },
21161 .Vector => {21359 .Vector => {
21162 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21360 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(21361 const len_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21164 ip,21362 ip,
21165 try ip.getOrPutString(gpa, "len", .no_embedded_nulls),21363 try ip.getOrPutString(gpa, "len", .no_embedded_nulls),
21166 ).?);21364 ).?);
21167 const child_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21365 const child_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21168 ip,21366 ip,
21169 try ip.getOrPutString(gpa, "child", .no_embedded_nulls),21367 try ip.getOrPutString(gpa, "child", .no_embedded_nulls),
21170 ).?);21368 ).?);
2117121369
21172 const len: u32 = @intCast(try len_val.toUnsignedIntSema(mod));21370 const len: u32 = @intCast(try len_val.toUnsignedIntSema(pt));
21173 const child_ty = child_val.toType();21371 const child_ty = child_val.toType();
2117421372
21175 try sema.checkVectorElemType(block, src, child_ty);21373 try sema.checkVectorElemType(block, src, child_ty);
2117621374
21177 const ty = try mod.vectorType(.{21375 const ty = try pt.vectorType(.{
21178 .len = len,21376 .len = len,
21179 .child = child_ty.toIntern(),21377 .child = child_ty.toIntern(),
21180 });21378 });
...@@ -21182,12 +21380,12 @@ fn zirReify(...@@ -21182,12 +21380,12 @@ fn zirReify(
21182 },21380 },
21183 .Float => {21381 .Float => {
21184 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21382 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(21383 const bits_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21186 ip,21384 ip,
21187 try ip.getOrPutString(gpa, "bits", .no_embedded_nulls),21385 try ip.getOrPutString(gpa, "bits", .no_embedded_nulls),
21188 ).?);21386 ).?);
2118921387
21190 const bits: u16 = @intCast(try bits_val.toUnsignedIntSema(mod));21388 const bits: u16 = @intCast(try bits_val.toUnsignedIntSema(pt));
21191 const ty = switch (bits) {21389 const ty = switch (bits) {
21192 16 => Type.f16,21390 16 => Type.f16,
21193 32 => Type.f32,21391 32 => Type.f32,
...@@ -21200,35 +21398,35 @@ fn zirReify(...@@ -21200,35 +21398,35 @@ fn zirReify(
21200 },21398 },
21201 .Pointer => {21399 .Pointer => {
21202 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21400 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(21401 const size_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21204 ip,21402 ip,
21205 try ip.getOrPutString(gpa, "size", .no_embedded_nulls),21403 try ip.getOrPutString(gpa, "size", .no_embedded_nulls),
21206 ).?);21404 ).?);
21207 const is_const_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21405 const is_const_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21208 ip,21406 ip,
21209 try ip.getOrPutString(gpa, "is_const", .no_embedded_nulls),21407 try ip.getOrPutString(gpa, "is_const", .no_embedded_nulls),
21210 ).?);21408 ).?);
21211 const is_volatile_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21409 const is_volatile_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21212 ip,21410 ip,
21213 try ip.getOrPutString(gpa, "is_volatile", .no_embedded_nulls),21411 try ip.getOrPutString(gpa, "is_volatile", .no_embedded_nulls),
21214 ).?);21412 ).?);
21215 const alignment_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21413 const alignment_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21216 ip,21414 ip,
21217 try ip.getOrPutString(gpa, "alignment", .no_embedded_nulls),21415 try ip.getOrPutString(gpa, "alignment", .no_embedded_nulls),
21218 ).?);21416 ).?);
21219 const address_space_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21417 const address_space_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21220 ip,21418 ip,
21221 try ip.getOrPutString(gpa, "address_space", .no_embedded_nulls),21419 try ip.getOrPutString(gpa, "address_space", .no_embedded_nulls),
21222 ).?);21420 ).?);
21223 const child_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21421 const child_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21224 ip,21422 ip,
21225 try ip.getOrPutString(gpa, "child", .no_embedded_nulls),21423 try ip.getOrPutString(gpa, "child", .no_embedded_nulls),
21226 ).?);21424 ).?);
21227 const is_allowzero_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21425 const is_allowzero_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21228 ip,21426 ip,
21229 try ip.getOrPutString(gpa, "is_allowzero", .no_embedded_nulls),21427 try ip.getOrPutString(gpa, "is_allowzero", .no_embedded_nulls),
21230 ).?);21428 ).?);
21231 const sentinel_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21429 const sentinel_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21232 ip,21430 ip,
21233 try ip.getOrPutString(gpa, "sentinel", .no_embedded_nulls),21431 try ip.getOrPutString(gpa, "sentinel", .no_embedded_nulls),
21234 ).?);21432 ).?);
...@@ -21237,7 +21435,7 @@ fn zirReify(...@@ -21237,7 +21435,7 @@ fn zirReify(
21237 return sema.fail(block, src, "alignment must fit in 'u32'", .{});21435 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
21238 }21436 }
2123921437
21240 const alignment_val_int = (try alignment_val.getUnsignedIntAdvanced(mod, .sema)).?;21438 const alignment_val_int = (try alignment_val.getUnsignedIntAdvanced(pt, .sema)).?;
21241 if (alignment_val_int > 0 and !math.isPowerOfTwo(alignment_val_int)) {21439 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});21440 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{alignment_val_int});
21243 }21441 }
...@@ -21245,7 +21443,7 @@ fn zirReify(...@@ -21245,7 +21443,7 @@ fn zirReify(
2124521443
21246 const elem_ty = child_val.toType();21444 const elem_ty = child_val.toType();
21247 if (abi_align != .none) {21445 if (abi_align != .none) {
21248 try elem_ty.resolveLayout(mod);21446 try elem_ty.resolveLayout(pt);
21249 }21447 }
2125021448
21251 const ptr_size = mod.toEnum(std.builtin.Type.Pointer.Size, size_val);21449 const ptr_size = mod.toEnum(std.builtin.Type.Pointer.Size, size_val);
...@@ -21256,7 +21454,7 @@ fn zirReify(...@@ -21256,7 +21454,7 @@ fn zirReify(
21256 return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{});21454 return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{});
21257 }21455 }
21258 const sentinel_ptr_val = sentinel_val.optionalValue(mod).?;21456 const sentinel_ptr_val = sentinel_val.optionalValue(mod).?;
21259 const ptr_ty = try mod.singleMutPtrType(elem_ty);21457 const ptr_ty = try pt.singleMutPtrType(elem_ty);
21260 const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;21458 const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;
21261 break :s sent_val.toIntern();21459 break :s sent_val.toIntern();
21262 }21460 }
...@@ -21274,7 +21472,7 @@ fn zirReify(...@@ -21274,7 +21472,7 @@ fn zirReify(
21274 } else if (ptr_size == .C) {21472 } else if (ptr_size == .C) {
21275 if (!try sema.validateExternType(elem_ty, .other)) {21473 if (!try sema.validateExternType(elem_ty, .other)) {
21276 const msg = msg: {21474 const msg = msg: {
21277 const msg = try sema.errMsg(src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(mod)});21475 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);21476 errdefer msg.destroy(gpa);
2127921477
21280 try sema.explainWhyTypeIsNotExtern(msg, src, elem_ty, .other);21478 try sema.explainWhyTypeIsNotExtern(msg, src, elem_ty, .other);
...@@ -21289,7 +21487,7 @@ fn zirReify(...@@ -21289,7 +21487,7 @@ fn zirReify(
21289 }21487 }
21290 }21488 }
2129121489
21292 const ty = try mod.ptrTypeSema(.{21490 const ty = try pt.ptrTypeSema(.{
21293 .child = elem_ty.toIntern(),21491 .child = elem_ty.toIntern(),
21294 .sentinel = actual_sentinel,21492 .sentinel = actual_sentinel,
21295 .flags = .{21493 .flags = .{
...@@ -21305,27 +21503,27 @@ fn zirReify(...@@ -21305,27 +21503,27 @@ fn zirReify(
21305 },21503 },
21306 .Array => {21504 .Array => {
21307 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21505 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(21506 const len_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21309 ip,21507 ip,
21310 try ip.getOrPutString(gpa, "len", .no_embedded_nulls),21508 try ip.getOrPutString(gpa, "len", .no_embedded_nulls),
21311 ).?);21509 ).?);
21312 const child_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21510 const child_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21313 ip,21511 ip,
21314 try ip.getOrPutString(gpa, "child", .no_embedded_nulls),21512 try ip.getOrPutString(gpa, "child", .no_embedded_nulls),
21315 ).?);21513 ).?);
21316 const sentinel_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21514 const sentinel_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21317 ip,21515 ip,
21318 try ip.getOrPutString(gpa, "sentinel", .no_embedded_nulls),21516 try ip.getOrPutString(gpa, "sentinel", .no_embedded_nulls),
21319 ).?);21517 ).?);
2132021518
21321 const len = try len_val.toUnsignedIntSema(mod);21519 const len = try len_val.toUnsignedIntSema(pt);
21322 const child_ty = child_val.toType();21520 const child_ty = child_val.toType();
21323 const sentinel = if (sentinel_val.optionalValue(mod)) |p| blk: {21521 const sentinel = if (sentinel_val.optionalValue(mod)) |p| blk: {
21324 const ptr_ty = try mod.singleMutPtrType(child_ty);21522 const ptr_ty = try pt.singleMutPtrType(child_ty);
21325 break :blk (try sema.pointerDeref(block, src, p, ptr_ty)).?;21523 break :blk (try sema.pointerDeref(block, src, p, ptr_ty)).?;
21326 } else null;21524 } else null;
2132721525
21328 const ty = try mod.arrayType(.{21526 const ty = try pt.arrayType(.{
21329 .len = len,21527 .len = len,
21330 .sentinel = if (sentinel) |s| s.toIntern() else .none,21528 .sentinel = if (sentinel) |s| s.toIntern() else .none,
21331 .child = child_ty.toIntern(),21529 .child = child_ty.toIntern(),
...@@ -21334,23 +21532,23 @@ fn zirReify(...@@ -21334,23 +21532,23 @@ fn zirReify(
21334 },21532 },
21335 .Optional => {21533 .Optional => {
21336 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21534 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(21535 const child_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21338 ip,21536 ip,
21339 try ip.getOrPutString(gpa, "child", .no_embedded_nulls),21537 try ip.getOrPutString(gpa, "child", .no_embedded_nulls),
21340 ).?);21538 ).?);
2134121539
21342 const child_ty = child_val.toType();21540 const child_ty = child_val.toType();
2134321541
21344 const ty = try mod.optionalType(child_ty.toIntern());21542 const ty = try pt.optionalType(child_ty.toIntern());
21345 return Air.internedToRef(ty.toIntern());21543 return Air.internedToRef(ty.toIntern());
21346 },21544 },
21347 .ErrorUnion => {21545 .ErrorUnion => {
21348 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21546 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(21547 const error_set_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21350 ip,21548 ip,
21351 try ip.getOrPutString(gpa, "error_set", .no_embedded_nulls),21549 try ip.getOrPutString(gpa, "error_set", .no_embedded_nulls),
21352 ).?);21550 ).?);
21353 const payload_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21551 const payload_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21354 ip,21552 ip,
21355 try ip.getOrPutString(gpa, "payload", .no_embedded_nulls),21553 try ip.getOrPutString(gpa, "payload", .no_embedded_nulls),
21356 ).?);21554 ).?);
...@@ -21362,7 +21560,7 @@ fn zirReify(...@@ -21362,7 +21560,7 @@ fn zirReify(
21362 return sema.fail(block, src, "Type.ErrorUnion.error_set must be an error set type", .{});21560 return sema.fail(block, src, "Type.ErrorUnion.error_set must be an error set type", .{});
21363 }21561 }
2136421562
21365 const ty = try mod.errorUnionType(error_set_ty, payload_ty);21563 const ty = try pt.errorUnionType(error_set_ty, payload_ty);
21366 return Air.internedToRef(ty.toIntern());21564 return Air.internedToRef(ty.toIntern());
21367 },21565 },
21368 .ErrorSet => {21566 .ErrorSet => {
...@@ -21377,9 +21575,9 @@ fn zirReify(...@@ -21377,9 +21575,9 @@ fn zirReify(
21377 var names: InferredErrorSet.NameMap = .{};21575 var names: InferredErrorSet.NameMap = .{};
21378 try names.ensureUnusedCapacity(sema.arena, len);21576 try names.ensureUnusedCapacity(sema.arena, len);
21379 for (0..len) |i| {21577 for (0..len) |i| {
21380 const elem_val = try names_val.elemValue(mod, i);21578 const elem_val = try names_val.elemValue(pt, i);
21381 const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern()));21579 const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern()));
21382 const name_val = try elem_val.fieldValue(mod, elem_struct_type.nameIndex(21580 const name_val = try elem_val.fieldValue(pt, elem_struct_type.nameIndex(
21383 ip,21581 ip,
21384 try ip.getOrPutString(gpa, "name", .no_embedded_nulls),21582 try ip.getOrPutString(gpa, "name", .no_embedded_nulls),
21385 ).?);21583 ).?);
...@@ -21396,28 +21594,28 @@ fn zirReify(...@@ -21396,28 +21594,28 @@ fn zirReify(
21396 }21594 }
21397 }21595 }
2139821596
21399 const ty = try mod.errorSetFromUnsortedNames(names.keys());21597 const ty = try pt.errorSetFromUnsortedNames(names.keys());
21400 return Air.internedToRef(ty.toIntern());21598 return Air.internedToRef(ty.toIntern());
21401 },21599 },
21402 .Struct => {21600 .Struct => {
21403 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21601 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(21602 const layout_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21405 ip,21603 ip,
21406 try ip.getOrPutString(gpa, "layout", .no_embedded_nulls),21604 try ip.getOrPutString(gpa, "layout", .no_embedded_nulls),
21407 ).?);21605 ).?);
21408 const backing_integer_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21606 const backing_integer_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21409 ip,21607 ip,
21410 try ip.getOrPutString(gpa, "backing_integer", .no_embedded_nulls),21608 try ip.getOrPutString(gpa, "backing_integer", .no_embedded_nulls),
21411 ).?);21609 ).?);
21412 const fields_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21610 const fields_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21413 ip,21611 ip,
21414 try ip.getOrPutString(gpa, "fields", .no_embedded_nulls),21612 try ip.getOrPutString(gpa, "fields", .no_embedded_nulls),
21415 ).?);21613 ).?);
21416 const decls_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21614 const decls_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21417 ip,21615 ip,
21418 try ip.getOrPutString(gpa, "decls", .no_embedded_nulls),21616 try ip.getOrPutString(gpa, "decls", .no_embedded_nulls),
21419 ).?);21617 ).?);
21420 const is_tuple_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21618 const is_tuple_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21421 ip,21619 ip,
21422 try ip.getOrPutString(gpa, "is_tuple", .no_embedded_nulls),21620 try ip.getOrPutString(gpa, "is_tuple", .no_embedded_nulls),
21423 ).?);21621 ).?);
...@@ -21425,7 +21623,7 @@ fn zirReify(...@@ -21425,7 +21623,7 @@ fn zirReify(
21425 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);21623 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
2142621624
21427 // Decls21625 // Decls
21428 if (try decls_val.sliceLen(mod) > 0) {21626 if (try decls_val.sliceLen(pt) > 0) {
21429 return sema.fail(block, src, "reified structs must have no decls", .{});21627 return sema.fail(block, src, "reified structs must have no decls", .{});
21430 }21628 }
2143121629
...@@ -21441,24 +21639,24 @@ fn zirReify(...@@ -21441,24 +21639,24 @@ fn zirReify(
21441 },21639 },
21442 .Enum => {21640 .Enum => {
21443 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21641 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(21642 const tag_type_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21445 ip,21643 ip,
21446 try ip.getOrPutString(gpa, "tag_type", .no_embedded_nulls),21644 try ip.getOrPutString(gpa, "tag_type", .no_embedded_nulls),
21447 ).?);21645 ).?);
21448 const fields_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21646 const fields_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21449 ip,21647 ip,
21450 try ip.getOrPutString(gpa, "fields", .no_embedded_nulls),21648 try ip.getOrPutString(gpa, "fields", .no_embedded_nulls),
21451 ).?);21649 ).?);
21452 const decls_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21650 const decls_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21453 ip,21651 ip,
21454 try ip.getOrPutString(gpa, "decls", .no_embedded_nulls),21652 try ip.getOrPutString(gpa, "decls", .no_embedded_nulls),
21455 ).?);21653 ).?);
21456 const is_exhaustive_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21654 const is_exhaustive_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21457 ip,21655 ip,
21458 try ip.getOrPutString(gpa, "is_exhaustive", .no_embedded_nulls),21656 try ip.getOrPutString(gpa, "is_exhaustive", .no_embedded_nulls),
21459 ).?);21657 ).?);
2146021658
21461 if (try decls_val.sliceLen(mod) > 0) {21659 if (try decls_val.sliceLen(pt) > 0) {
21462 return sema.fail(block, src, "reified enums must have no decls", .{});21660 return sema.fail(block, src, "reified enums must have no decls", .{});
21463 }21661 }
2146421662
...@@ -21470,17 +21668,17 @@ fn zirReify(...@@ -21470,17 +21668,17 @@ fn zirReify(
21470 },21668 },
21471 .Opaque => {21669 .Opaque => {
21472 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21670 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(21671 const decls_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21474 ip,21672 ip,
21475 try ip.getOrPutString(gpa, "decls", .no_embedded_nulls),21673 try ip.getOrPutString(gpa, "decls", .no_embedded_nulls),
21476 ).?);21674 ).?);
2147721675
21478 // Decls21676 // Decls
21479 if (try decls_val.sliceLen(mod) > 0) {21677 if (try decls_val.sliceLen(pt) > 0) {
21480 return sema.fail(block, src, "reified opaque must have no decls", .{});21678 return sema.fail(block, src, "reified opaque must have no decls", .{});
21481 }21679 }
2148221680
21483 const wip_ty = switch (try ip.getOpaqueType(gpa, .{21681 const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, .{
21484 .has_namespace = false,21682 .has_namespace = false,
21485 .key = .{ .reified = .{21683 .key = .{ .reified = .{
21486 .zir_index = try block.trackZir(inst),21684 .zir_index = try block.trackZir(inst),
...@@ -21501,30 +21699,30 @@ fn zirReify(...@@ -21501,30 +21699,30 @@ fn zirReify(
21501 mod.declPtr(new_decl_index).owns_tv = true;21699 mod.declPtr(new_decl_index).owns_tv = true;
21502 errdefer mod.abortAnonDecl(new_decl_index);21700 errdefer mod.abortAnonDecl(new_decl_index);
2150321701
21504 try mod.finalizeAnonDecl(new_decl_index);21702 try pt.finalizeAnonDecl(new_decl_index);
2150521703
21506 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));21704 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));
21507 },21705 },
21508 .Union => {21706 .Union => {
21509 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21707 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(21708 const layout_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21511 ip,21709 ip,
21512 try ip.getOrPutString(gpa, "layout", .no_embedded_nulls),21710 try ip.getOrPutString(gpa, "layout", .no_embedded_nulls),
21513 ).?);21711 ).?);
21514 const tag_type_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21712 const tag_type_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21515 ip,21713 ip,
21516 try ip.getOrPutString(gpa, "tag_type", .no_embedded_nulls),21714 try ip.getOrPutString(gpa, "tag_type", .no_embedded_nulls),
21517 ).?);21715 ).?);
21518 const fields_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21716 const fields_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21519 ip,21717 ip,
21520 try ip.getOrPutString(gpa, "fields", .no_embedded_nulls),21718 try ip.getOrPutString(gpa, "fields", .no_embedded_nulls),
21521 ).?);21719 ).?);
21522 const decls_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21720 const decls_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21523 ip,21721 ip,
21524 try ip.getOrPutString(gpa, "decls", .no_embedded_nulls),21722 try ip.getOrPutString(gpa, "decls", .no_embedded_nulls),
21525 ).?);21723 ).?);
2152621724
21527 if (try decls_val.sliceLen(mod) > 0) {21725 if (try decls_val.sliceLen(pt) > 0) {
21528 return sema.fail(block, src, "reified unions must have no decls", .{});21726 return sema.fail(block, src, "reified unions must have no decls", .{});
21529 }21727 }
21530 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);21728 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
...@@ -21537,23 +21735,23 @@ fn zirReify(...@@ -21537,23 +21735,23 @@ fn zirReify(
21537 },21735 },
21538 .Fn => {21736 .Fn => {
21539 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21737 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(21738 const calling_convention_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21541 ip,21739 ip,
21542 try ip.getOrPutString(gpa, "calling_convention", .no_embedded_nulls),21740 try ip.getOrPutString(gpa, "calling_convention", .no_embedded_nulls),
21543 ).?);21741 ).?);
21544 const is_generic_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21742 const is_generic_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21545 ip,21743 ip,
21546 try ip.getOrPutString(gpa, "is_generic", .no_embedded_nulls),21744 try ip.getOrPutString(gpa, "is_generic", .no_embedded_nulls),
21547 ).?);21745 ).?);
21548 const is_var_args_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21746 const is_var_args_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21549 ip,21747 ip,
21550 try ip.getOrPutString(gpa, "is_var_args", .no_embedded_nulls),21748 try ip.getOrPutString(gpa, "is_var_args", .no_embedded_nulls),
21551 ).?);21749 ).?);
21552 const return_type_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21750 const return_type_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21553 ip,21751 ip,
21554 try ip.getOrPutString(gpa, "return_type", .no_embedded_nulls),21752 try ip.getOrPutString(gpa, "return_type", .no_embedded_nulls),
21555 ).?);21753 ).?);
21556 const params_slice_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(21754 const params_slice_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21557 ip,21755 ip,
21558 try ip.getOrPutString(gpa, "params", .no_embedded_nulls),21756 try ip.getOrPutString(gpa, "params", .no_embedded_nulls),
21559 ).?);21757 ).?);
...@@ -21581,17 +21779,17 @@ fn zirReify(...@@ -21581,17 +21779,17 @@ fn zirReify(
2158121779
21582 var noalias_bits: u32 = 0;21780 var noalias_bits: u32 = 0;
21583 for (param_types, 0..) |*param_type, i| {21781 for (param_types, 0..) |*param_type, i| {
21584 const elem_val = try params_val.elemValue(mod, i);21782 const elem_val = try params_val.elemValue(pt, i);
21585 const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern()));21783 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(21784 const param_is_generic_val = try elem_val.fieldValue(pt, elem_struct_type.nameIndex(
21587 ip,21785 ip,
21588 try ip.getOrPutString(gpa, "is_generic", .no_embedded_nulls),21786 try ip.getOrPutString(gpa, "is_generic", .no_embedded_nulls),
21589 ).?);21787 ).?);
21590 const param_is_noalias_val = try elem_val.fieldValue(mod, elem_struct_type.nameIndex(21788 const param_is_noalias_val = try elem_val.fieldValue(pt, elem_struct_type.nameIndex(
21591 ip,21789 ip,
21592 try ip.getOrPutString(gpa, "is_noalias", .no_embedded_nulls),21790 try ip.getOrPutString(gpa, "is_noalias", .no_embedded_nulls),
21593 ).?);21791 ).?);
21594 const opt_param_type_val = try elem_val.fieldValue(mod, elem_struct_type.nameIndex(21792 const opt_param_type_val = try elem_val.fieldValue(pt, elem_struct_type.nameIndex(
21595 ip,21793 ip,
21596 try ip.getOrPutString(gpa, "type", .no_embedded_nulls),21794 try ip.getOrPutString(gpa, "type", .no_embedded_nulls),
21597 ).?);21795 ).?);
...@@ -21613,7 +21811,7 @@ fn zirReify(...@@ -21613,7 +21811,7 @@ fn zirReify(
21613 }21811 }
21614 }21812 }
2161521813
21616 const ty = try mod.funcType(.{21814 const ty = try pt.funcType(.{
21617 .param_types = param_types,21815 .param_types = param_types,
21618 .noalias_bits = noalias_bits,21816 .noalias_bits = noalias_bits,
21619 .return_type = return_type.toIntern(),21817 .return_type = return_type.toIntern(),
...@@ -21636,7 +21834,8 @@ fn reifyEnum(...@@ -21636,7 +21834,8 @@ fn reifyEnum(
21636 fields_val: Value,21834 fields_val: Value,
21637 name_strategy: Zir.Inst.NameStrategy,21835 name_strategy: Zir.Inst.NameStrategy,
21638) CompileError!Air.Inst.Ref {21836) CompileError!Air.Inst.Ref {
21639 const mod = sema.mod;21837 const pt = sema.pt;
21838 const mod = pt.zcu;
21640 const gpa = sema.gpa;21839 const gpa = sema.gpa;
21641 const ip = &mod.intern_pool;21840 const ip = &mod.intern_pool;
2164221841
...@@ -21656,10 +21855,10 @@ fn reifyEnum(...@@ -21656,10 +21855,10 @@ fn reifyEnum(
21656 std.hash.autoHash(&hasher, fields_len);21855 std.hash.autoHash(&hasher, fields_len);
2165721856
21658 for (0..fields_len) |field_idx| {21857 for (0..fields_len) |field_idx| {
21659 const field_info = try fields_val.elemValue(mod, field_idx);21858 const field_info = try fields_val.elemValue(pt, field_idx);
2166021859
21661 const field_name_val = try field_info.fieldValue(mod, 0);21860 const field_name_val = try field_info.fieldValue(pt, 0);
21662 const field_value_val = try sema.resolveLazyValue(try field_info.fieldValue(mod, 1));21861 const field_value_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 1));
2166321862
21664 const field_name = try sema.sliceToIpString(block, src, field_name_val, .{21863 const field_name = try sema.sliceToIpString(block, src, field_name_val, .{
21665 .needed_comptime_reason = "enum field name must be comptime-known",21864 .needed_comptime_reason = "enum field name must be comptime-known",
...@@ -21671,7 +21870,7 @@ fn reifyEnum(...@@ -21671,7 +21870,7 @@ fn reifyEnum(
21671 });21870 });
21672 }21871 }
2167321872
21674 const wip_ty = switch (try ip.getEnumType(gpa, .{21873 const wip_ty = switch (try ip.getEnumType(gpa, pt.tid, .{
21675 .has_namespace = false,21874 .has_namespace = false,
21676 .has_values = true,21875 .has_values = true,
21677 .tag_mode = if (is_exhaustive) .explicit else .nonexhaustive,21876 .tag_mode = if (is_exhaustive) .explicit else .nonexhaustive,
...@@ -21704,10 +21903,10 @@ fn reifyEnum(...@@ -21704,10 +21903,10 @@ fn reifyEnum(
21704 wip_ty.setTagTy(ip, tag_ty.toIntern());21903 wip_ty.setTagTy(ip, tag_ty.toIntern());
2170521904
21706 for (0..fields_len) |field_idx| {21905 for (0..fields_len) |field_idx| {
21707 const field_info = try fields_val.elemValue(mod, field_idx);21906 const field_info = try fields_val.elemValue(pt, field_idx);
2170821907
21709 const field_name_val = try field_info.fieldValue(mod, 0);21908 const field_name_val = try field_info.fieldValue(pt, 0);
21710 const field_value_val = try sema.resolveLazyValue(try field_info.fieldValue(mod, 1));21909 const field_value_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 1));
2171121910
21712 // Don't pass a reason; first loop acts as an assertion that this is valid.21911 // 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);21912 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);
...@@ -21716,12 +21915,12 @@ fn reifyEnum(...@@ -21716,12 +21915,12 @@ fn reifyEnum(
21716 // TODO: better source location21915 // TODO: better source location
21717 return sema.fail(block, src, "field '{}' with enumeration value '{}' is too large for backing int type '{}'", .{21916 return sema.fail(block, src, "field '{}' with enumeration value '{}' is too large for backing int type '{}'", .{
21718 field_name.fmt(ip),21917 field_name.fmt(ip),
21719 field_value_val.fmtValue(mod, sema),21918 field_value_val.fmtValue(pt, sema),
21720 tag_ty.fmt(mod),21919 tag_ty.fmt(pt),
21721 });21920 });
21722 }21921 }
2172321922
21724 const coerced_field_val = try mod.getCoerced(field_value_val, tag_ty);21923 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| {21924 if (wip_ty.nextField(ip, field_name, coerced_field_val.toIntern())) |conflict| {
21726 return sema.failWithOwnedErrorMsg(block, switch (conflict.kind) {21925 return sema.failWithOwnedErrorMsg(block, switch (conflict.kind) {
21727 .name => msg: {21926 .name => msg: {
...@@ -21732,7 +21931,7 @@ fn reifyEnum(...@@ -21732,7 +21931,7 @@ fn reifyEnum(
21732 break :msg msg;21931 break :msg msg;
21733 },21932 },
21734 .value => msg: {21933 .value => msg: {
21735 const msg = try sema.errMsg(src, "enum tag value {} already taken", .{field_value_val.fmtValue(mod, sema)});21934 const msg = try sema.errMsg(src, "enum tag value {} already taken", .{field_value_val.fmtValue(pt, sema)});
21736 errdefer msg.destroy(gpa);21935 errdefer msg.destroy(gpa);
21737 _ = conflict.prev_field_idx; // TODO: this note is incorrect21936 _ = conflict.prev_field_idx; // TODO: this note is incorrect
21738 try sema.errNote(src, msg, "other enum tag value here", .{});21937 try sema.errNote(src, msg, "other enum tag value here", .{});
...@@ -21742,11 +21941,11 @@ fn reifyEnum(...@@ -21742,11 +21941,11 @@ fn reifyEnum(
21742 }21941 }
21743 }21942 }
2174421943
21745 if (!is_exhaustive and fields_len > 1 and std.math.log2_int(u64, fields_len) == tag_ty.bitSize(mod)) {21944 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", .{});21945 return sema.fail(block, src, "non-exhaustive enum specified every value", .{});
21747 }21946 }
2174821947
21749 try mod.finalizeAnonDecl(new_decl_index);21948 try pt.finalizeAnonDecl(new_decl_index);
21750 return Air.internedToRef(wip_ty.index);21949 return Air.internedToRef(wip_ty.index);
21751}21950}
2175221951
...@@ -21760,7 +21959,8 @@ fn reifyUnion(...@@ -21760,7 +21959,8 @@ fn reifyUnion(
21760 fields_val: Value,21959 fields_val: Value,
21761 name_strategy: Zir.Inst.NameStrategy,21960 name_strategy: Zir.Inst.NameStrategy,
21762) CompileError!Air.Inst.Ref {21961) CompileError!Air.Inst.Ref {
21763 const mod = sema.mod;21962 const pt = sema.pt;
21963 const mod = pt.zcu;
21764 const gpa = sema.gpa;21964 const gpa = sema.gpa;
21765 const ip = &mod.intern_pool;21965 const ip = &mod.intern_pool;
2176621966
...@@ -21782,11 +21982,11 @@ fn reifyUnion(...@@ -21782,11 +21982,11 @@ fn reifyUnion(
21782 var any_aligns = false;21982 var any_aligns = false;
2178321983
21784 for (0..fields_len) |field_idx| {21984 for (0..fields_len) |field_idx| {
21785 const field_info = try fields_val.elemValue(mod, field_idx);21985 const field_info = try fields_val.elemValue(pt, field_idx);
2178621986
21787 const field_name_val = try field_info.fieldValue(mod, 0);21987 const field_name_val = try field_info.fieldValue(pt, 0);
21788 const field_type_val = try field_info.fieldValue(mod, 1);21988 const field_type_val = try field_info.fieldValue(pt, 1);
21789 const field_align_val = try sema.resolveLazyValue(try field_info.fieldValue(mod, 2));21989 const field_align_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 2));
2179021990
21791 const field_name = try sema.sliceToIpString(block, src, field_name_val, .{21991 const field_name = try sema.sliceToIpString(block, src, field_name_val, .{
21792 .needed_comptime_reason = "union field name must be comptime-known",21992 .needed_comptime_reason = "union field name must be comptime-known",
...@@ -21798,12 +21998,12 @@ fn reifyUnion(...@@ -21798,12 +21998,12 @@ fn reifyUnion(
21798 field_align_val.toIntern(),21998 field_align_val.toIntern(),
21799 });21999 });
2180022000
21801 if (field_align_val.toUnsignedInt(mod) != 0) {22001 if (field_align_val.toUnsignedInt(pt) != 0) {
21802 any_aligns = true;22002 any_aligns = true;
21803 }22003 }
21804 }22004 }
2180522005
21806 const wip_ty = switch (try ip.getUnionType(gpa, .{22006 const wip_ty = switch (try ip.getUnionType(gpa, pt.tid, .{
21807 .flags = .{22007 .flags = .{
21808 .layout = layout,22008 .layout = layout,
21809 .status = .none,22009 .status = .none,
...@@ -21861,10 +22061,10 @@ fn reifyUnion(...@@ -21861,10 +22061,10 @@ fn reifyUnion(
21861 var seen_tags = try std.DynamicBitSetUnmanaged.initEmpty(sema.arena, tag_ty_fields_len);22061 var seen_tags = try std.DynamicBitSetUnmanaged.initEmpty(sema.arena, tag_ty_fields_len);
2186222062
21863 for (field_types, 0..) |*field_ty, field_idx| {22063 for (field_types, 0..) |*field_ty, field_idx| {
21864 const field_info = try fields_val.elemValue(mod, field_idx);22064 const field_info = try fields_val.elemValue(pt, field_idx);
2186522065
21866 const field_name_val = try field_info.fieldValue(mod, 0);22066 const field_name_val = try field_info.fieldValue(pt, 0);
21867 const field_type_val = try field_info.fieldValue(mod, 1);22067 const field_type_val = try field_info.fieldValue(pt, 1);
2186822068
21869 // Don't pass a reason; first loop acts as an assertion that this is valid.22069 // 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);22070 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);
...@@ -21872,7 +22072,7 @@ fn reifyUnion(...@@ -21872,7 +22072,7 @@ fn reifyUnion(
21872 const enum_index = enum_tag_ty.enumFieldIndex(field_name, mod) orelse {22072 const enum_index = enum_tag_ty.enumFieldIndex(field_name, mod) orelse {
21873 // TODO: better source location22073 // TODO: better source location
21874 return sema.fail(block, src, "no field named '{}' in enum '{}'", .{22074 return sema.fail(block, src, "no field named '{}' in enum '{}'", .{
21875 field_name.fmt(ip), enum_tag_ty.fmt(mod),22075 field_name.fmt(ip), enum_tag_ty.fmt(pt),
21876 });22076 });
21877 };22077 };
21878 if (seen_tags.isSet(enum_index)) {22078 if (seen_tags.isSet(enum_index)) {
...@@ -21883,7 +22083,7 @@ fn reifyUnion(...@@ -21883,7 +22083,7 @@ fn reifyUnion(
2188322083
21884 field_ty.* = field_type_val.toIntern();22084 field_ty.* = field_type_val.toIntern();
21885 if (any_aligns) {22085 if (any_aligns) {
21886 const byte_align = try (try field_info.fieldValue(mod, 2)).toUnsignedIntSema(mod);22086 const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt);
21887 if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) {22087 if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) {
21888 // TODO: better source location22088 // TODO: better source location
21889 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align});22089 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align});
...@@ -21913,10 +22113,10 @@ fn reifyUnion(...@@ -21913,10 +22113,10 @@ fn reifyUnion(
21913 try field_names.ensureTotalCapacity(sema.arena, fields_len);22113 try field_names.ensureTotalCapacity(sema.arena, fields_len);
2191422114
21915 for (field_types, 0..) |*field_ty, field_idx| {22115 for (field_types, 0..) |*field_ty, field_idx| {
21916 const field_info = try fields_val.elemValue(mod, field_idx);22116 const field_info = try fields_val.elemValue(pt, field_idx);
2191722117
21918 const field_name_val = try field_info.fieldValue(mod, 0);22118 const field_name_val = try field_info.fieldValue(pt, 0);
21919 const field_type_val = try field_info.fieldValue(mod, 1);22119 const field_type_val = try field_info.fieldValue(pt, 1);
2192022120
21921 // Don't pass a reason; first loop acts as an assertion that this is valid.22121 // 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);22122 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);
...@@ -21928,7 +22128,7 @@ fn reifyUnion(...@@ -21928,7 +22128,7 @@ fn reifyUnion(
2192822128
21929 field_ty.* = field_type_val.toIntern();22129 field_ty.* = field_type_val.toIntern();
21930 if (any_aligns) {22130 if (any_aligns) {
21931 const byte_align = try (try field_info.fieldValue(mod, 2)).toUnsignedIntSema(mod);22131 const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt);
21932 if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) {22132 if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) {
21933 // TODO: better source location22133 // TODO: better source location
21934 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align});22134 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align});
...@@ -21955,7 +22155,7 @@ fn reifyUnion(...@@ -21955,7 +22155,7 @@ fn reifyUnion(
21955 }22155 }
21956 if (layout == .@"extern" and !try sema.validateExternType(field_ty, .union_field)) {22156 if (layout == .@"extern" and !try sema.validateExternType(field_ty, .union_field)) {
21957 return sema.failWithOwnedErrorMsg(block, msg: {22157 return sema.failWithOwnedErrorMsg(block, msg: {
21958 const msg = try sema.errMsg(src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)});22158 const msg = try sema.errMsg(src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
21959 errdefer msg.destroy(gpa);22159 errdefer msg.destroy(gpa);
2196022160
21961 try sema.explainWhyTypeIsNotExtern(msg, src, field_ty, .union_field);22161 try sema.explainWhyTypeIsNotExtern(msg, src, field_ty, .union_field);
...@@ -21965,7 +22165,7 @@ fn reifyUnion(...@@ -21965,7 +22165,7 @@ fn reifyUnion(
21965 });22165 });
21966 } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) {22166 } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) {
21967 return sema.failWithOwnedErrorMsg(block, msg: {22167 return sema.failWithOwnedErrorMsg(block, msg: {
21968 const msg = try sema.errMsg(src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)});22168 const msg = try sema.errMsg(src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
21969 errdefer msg.destroy(gpa);22169 errdefer msg.destroy(gpa);
2197022170
21971 try sema.explainWhyTypeIsNotPacked(msg, src, field_ty);22171 try sema.explainWhyTypeIsNotPacked(msg, src, field_ty);
...@@ -21984,7 +22184,7 @@ fn reifyUnion(...@@ -21984,7 +22184,7 @@ fn reifyUnion(
21984 loaded_union.tagTypePtr(ip).* = enum_tag_ty;22184 loaded_union.tagTypePtr(ip).* = enum_tag_ty;
21985 loaded_union.flagsPtr(ip).status = .have_field_types;22185 loaded_union.flagsPtr(ip).status = .have_field_types;
2198622186
21987 try mod.finalizeAnonDecl(new_decl_index);22187 try pt.finalizeAnonDecl(new_decl_index);
21988 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });22188 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
21989 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));22189 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));
21990 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));22190 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));
...@@ -22001,7 +22201,8 @@ fn reifyStruct(...@@ -22001,7 +22201,8 @@ fn reifyStruct(
22001 name_strategy: Zir.Inst.NameStrategy,22201 name_strategy: Zir.Inst.NameStrategy,
22002 is_tuple: bool,22202 is_tuple: bool,
22003) CompileError!Air.Inst.Ref {22203) CompileError!Air.Inst.Ref {
22004 const mod = sema.mod;22204 const pt = sema.pt;
22205 const mod = pt.zcu;
22005 const gpa = sema.gpa;22206 const gpa = sema.gpa;
22006 const ip = &mod.intern_pool;22207 const ip = &mod.intern_pool;
2200722208
...@@ -22026,20 +22227,20 @@ fn reifyStruct(...@@ -22026,20 +22227,20 @@ fn reifyStruct(
22026 var any_aligned_fields = false;22227 var any_aligned_fields = false;
2202722228
22028 for (0..fields_len) |field_idx| {22229 for (0..fields_len) |field_idx| {
22029 const field_info = try fields_val.elemValue(mod, field_idx);22230 const field_info = try fields_val.elemValue(pt, field_idx);
2203022231
22031 const field_name_val = try field_info.fieldValue(mod, 0);22232 const field_name_val = try field_info.fieldValue(pt, 0);
22032 const field_type_val = try field_info.fieldValue(mod, 1);22233 const field_type_val = try field_info.fieldValue(pt, 1);
22033 const field_default_value_val = try field_info.fieldValue(mod, 2);22234 const field_default_value_val = try field_info.fieldValue(pt, 2);
22034 const field_is_comptime_val = try field_info.fieldValue(mod, 3);22235 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));22236 const field_alignment_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 4));
2203622237
22037 const field_name = try sema.sliceToIpString(block, src, field_name_val, .{22238 const field_name = try sema.sliceToIpString(block, src, field_name_val, .{
22038 .needed_comptime_reason = "struct field name must be comptime-known",22239 .needed_comptime_reason = "struct field name must be comptime-known",
22039 });22240 });
22040 const field_is_comptime = field_is_comptime_val.toBool();22241 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: {22242 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());22243 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.22244 // 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(22245 const val = try sema.pointerDeref(block, src, ptr_val, ptr_ty) orelse return sema.failWithNeededComptime(
22045 block,22246 block,
...@@ -22060,14 +22261,14 @@ fn reifyStruct(...@@ -22060,14 +22261,14 @@ fn reifyStruct(
2206022261
22061 if (field_is_comptime) any_comptime_fields = true;22262 if (field_is_comptime) any_comptime_fields = true;
22062 if (field_default_value != .none) any_default_inits = true;22263 if (field_default_value != .none) any_default_inits = true;
22063 switch (try field_alignment_val.orderAgainstZeroAdvanced(mod, .sema)) {22264 switch (try field_alignment_val.orderAgainstZeroAdvanced(pt, .sema)) {
22064 .eq => {},22265 .eq => {},
22065 .gt => any_aligned_fields = true,22266 .gt => any_aligned_fields = true,
22066 .lt => unreachable,22267 .lt => unreachable,
22067 }22268 }
22068 }22269 }
2206922270
22070 const wip_ty = switch (try ip.getStructType(gpa, .{22271 const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{
22071 .layout = layout,22272 .layout = layout,
22072 .fields_len = fields_len,22273 .fields_len = fields_len,
22073 .known_non_opv = false,22274 .known_non_opv = false,
...@@ -22107,13 +22308,13 @@ fn reifyStruct(...@@ -22107,13 +22308,13 @@ fn reifyStruct(
22107 const struct_type = ip.loadStructType(wip_ty.index);22308 const struct_type = ip.loadStructType(wip_ty.index);
2210822309
22109 for (0..fields_len) |field_idx| {22310 for (0..fields_len) |field_idx| {
22110 const field_info = try fields_val.elemValue(mod, field_idx);22311 const field_info = try fields_val.elemValue(pt, field_idx);
2211122312
22112 const field_name_val = try field_info.fieldValue(mod, 0);22313 const field_name_val = try field_info.fieldValue(pt, 0);
22113 const field_type_val = try field_info.fieldValue(mod, 1);22314 const field_type_val = try field_info.fieldValue(pt, 1);
22114 const field_default_value_val = try field_info.fieldValue(mod, 2);22315 const field_default_value_val = try field_info.fieldValue(pt, 2);
22115 const field_is_comptime_val = try field_info.fieldValue(mod, 3);22316 const field_is_comptime_val = try field_info.fieldValue(pt, 3);
22116 const field_alignment_val = try field_info.fieldValue(mod, 4);22317 const field_alignment_val = try field_info.fieldValue(pt, 4);
2211722318
22118 const field_ty = field_type_val.toType();22319 const field_ty = field_type_val.toType();
22119 // Don't pass a reason; first loop acts as an assertion that this is valid.22320 // Don't pass a reason; first loop acts as an assertion that this is valid.
...@@ -22143,7 +22344,7 @@ fn reifyStruct(...@@ -22143,7 +22344,7 @@ fn reifyStruct(
22143 return sema.fail(block, src, "alignment must fit in 'u32'", .{});22344 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
22144 }22345 }
2214522346
22146 const byte_align = try field_alignment_val.toUnsignedIntSema(mod);22347 const byte_align = try field_alignment_val.toUnsignedIntSema(pt);
22147 if (byte_align == 0) {22348 if (byte_align == 0) {
22148 if (layout != .@"packed") {22349 if (layout != .@"packed") {
22149 struct_type.field_aligns.get(ip)[field_idx] = .none;22350 struct_type.field_aligns.get(ip)[field_idx] = .none;
...@@ -22168,7 +22369,7 @@ fn reifyStruct(...@@ -22168,7 +22369,7 @@ fn reifyStruct(
22168 const field_default: InternPool.Index = d: {22369 const field_default: InternPool.Index = d: {
22169 if (!any_default_inits) break :d .none;22370 if (!any_default_inits) break :d .none;
22170 const ptr_val = field_default_value_val.optionalValue(mod) orelse break :d .none;22371 const ptr_val = field_default_value_val.optionalValue(mod) orelse break :d .none;
22171 const ptr_ty = try mod.singleConstPtrType(field_ty);22372 const ptr_ty = try pt.singleConstPtrType(field_ty);
22172 // Asserted comptime-dereferencable above.22373 // Asserted comptime-dereferencable above.
22173 const val = (try sema.pointerDeref(block, src, ptr_val, ptr_ty)).?;22374 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.22375 // We already resolved this for deduplication, so we may as well do it now.
...@@ -22204,7 +22405,7 @@ fn reifyStruct(...@@ -22204,7 +22405,7 @@ fn reifyStruct(
22204 }22405 }
22205 if (layout == .@"extern" and !try sema.validateExternType(field_ty, .struct_field)) {22406 if (layout == .@"extern" and !try sema.validateExternType(field_ty, .struct_field)) {
22206 return sema.failWithOwnedErrorMsg(block, msg: {22407 return sema.failWithOwnedErrorMsg(block, msg: {
22207 const msg = try sema.errMsg(src, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});22408 const msg = try sema.errMsg(src, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
22208 errdefer msg.destroy(gpa);22409 errdefer msg.destroy(gpa);
2220922410
22210 try sema.explainWhyTypeIsNotExtern(msg, src, field_ty, .struct_field);22411 try sema.explainWhyTypeIsNotExtern(msg, src, field_ty, .struct_field);
...@@ -22214,7 +22415,7 @@ fn reifyStruct(...@@ -22214,7 +22415,7 @@ fn reifyStruct(
22214 });22415 });
22215 } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) {22416 } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) {
22216 return sema.failWithOwnedErrorMsg(block, msg: {22417 return sema.failWithOwnedErrorMsg(block, msg: {
22217 const msg = try sema.errMsg(src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});22418 const msg = try sema.errMsg(src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
22218 errdefer msg.destroy(gpa);22419 errdefer msg.destroy(gpa);
2221922420
22220 try sema.explainWhyTypeIsNotPacked(msg, src, field_ty);22421 try sema.explainWhyTypeIsNotPacked(msg, src, field_ty);
...@@ -22229,7 +22430,7 @@ fn reifyStruct(...@@ -22229,7 +22430,7 @@ fn reifyStruct(
22229 var fields_bit_sum: u64 = 0;22430 var fields_bit_sum: u64 = 0;
22230 for (0..struct_type.field_types.len) |field_idx| {22431 for (0..struct_type.field_types.len) |field_idx| {
22231 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_idx]);22432 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_idx]);
22232 field_ty.resolveLayout(mod) catch |err| switch (err) {22433 field_ty.resolveLayout(pt) catch |err| switch (err) {
22233 error.AnalysisFail => {22434 error.AnalysisFail => {
22234 const msg = sema.err orelse return err;22435 const msg = sema.err orelse return err;
22235 try sema.errNote(src, msg, "while checking a field of this struct", .{});22436 try sema.errNote(src, msg, "while checking a field of this struct", .{});
...@@ -22237,7 +22438,7 @@ fn reifyStruct(...@@ -22237,7 +22438,7 @@ fn reifyStruct(
22237 },22438 },
22238 else => return err,22439 else => return err,
22239 };22440 };
22240 fields_bit_sum += field_ty.bitSize(mod);22441 fields_bit_sum += field_ty.bitSize(pt);
22241 }22442 }
2224222443
22243 if (opt_backing_int_val.optionalValue(mod)) |backing_int_val| {22444 if (opt_backing_int_val.optionalValue(mod)) |backing_int_val| {
...@@ -22245,20 +22446,21 @@ fn reifyStruct(...@@ -22245,20 +22446,21 @@ fn reifyStruct(
22245 try sema.checkBackingIntType(block, src, backing_int_ty, fields_bit_sum);22446 try sema.checkBackingIntType(block, src, backing_int_ty, fields_bit_sum);
22246 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();22447 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();
22247 } else {22448 } else {
22248 const backing_int_ty = try mod.intType(.unsigned, @intCast(fields_bit_sum));22449 const backing_int_ty = try pt.intType(.unsigned, @intCast(fields_bit_sum));
22249 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();22450 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();
22250 }22451 }
22251 }22452 }
2225222453
22253 try mod.finalizeAnonDecl(new_decl_index);22454 try pt.finalizeAnonDecl(new_decl_index);
22254 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });22455 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
22255 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));22456 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));
22256 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));22457 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));
22257}22458}
2225822459
22259fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {22460fn 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");22461 const pt = sema.pt;
22261 const va_list_ptr = try sema.mod.singleMutPtrType(va_list_ty);22462 const va_list_ty = try pt.getBuiltinType("VaList");
22463 const va_list_ptr = try pt.singleMutPtrType(va_list_ty);
2226222464
22263 const inst = try sema.resolveInst(zir_ref);22465 const inst = try sema.resolveInst(zir_ref);
22264 return sema.coerce(block, va_list_ptr, inst, src);22466 return sema.coerce(block, va_list_ptr, inst, src);
...@@ -22275,7 +22477,7 @@ fn zirCVaArg(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -22275,7 +22477,7 @@ fn zirCVaArg(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
2227522477
22276 if (!try sema.validateExternType(arg_ty, .param_ty)) {22478 if (!try sema.validateExternType(arg_ty, .param_ty)) {
22277 const msg = msg: {22479 const msg = msg: {
22278 const msg = try sema.errMsg(ty_src, "cannot get '{}' from variadic argument", .{arg_ty.fmt(sema.mod)});22480 const msg = try sema.errMsg(ty_src, "cannot get '{}' from variadic argument", .{arg_ty.fmt(sema.pt)});
22279 errdefer msg.destroy(sema.gpa);22481 errdefer msg.destroy(sema.gpa);
2228022482
22281 try sema.explainWhyTypeIsNotExtern(msg, ty_src, arg_ty, .param_ty);22483 try sema.explainWhyTypeIsNotExtern(msg, ty_src, arg_ty, .param_ty);
...@@ -22296,7 +22498,7 @@ fn zirCVaCopy(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)...@@ -22296,7 +22498,7 @@ fn zirCVaCopy(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)
22296 const va_list_src = block.builtinCallArgSrc(extra.node, 0);22498 const va_list_src = block.builtinCallArgSrc(extra.node, 0);
2229722499
22298 const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.operand);22500 const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.operand);
22299 const va_list_ty = try sema.mod.getBuiltinType("VaList");22501 const va_list_ty = try sema.pt.getBuiltinType("VaList");
2230022502
22301 try sema.requireRuntimeBlock(block, src, null);22503 try sema.requireRuntimeBlock(block, src, null);
22302 return block.addTyOp(.c_va_copy, va_list_ty, va_list_ref);22504 return block.addTyOp(.c_va_copy, va_list_ty, va_list_ref);
...@@ -22316,7 +22518,7 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -22316,7 +22518,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 {22518fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
22317 const src = block.nodeOffset(@bitCast(extended.operand));22519 const src = block.nodeOffset(@bitCast(extended.operand));
2231822520
22319 const va_list_ty = try sema.mod.getBuiltinType("VaList");22521 const va_list_ty = try sema.pt.getBuiltinType("VaList");
22320 try sema.requireRuntimeBlock(block, src, null);22522 try sema.requireRuntimeBlock(block, src, null);
22321 return block.addInst(.{22523 return block.addInst(.{
22322 .tag = .c_va_start,22524 .tag = .c_va_start,
...@@ -22325,14 +22527,15 @@ fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)...@@ -22325,14 +22527,15 @@ fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)
22325}22527}
2232622528
22327fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {22529fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
22328 const mod = sema.mod;22530 const pt = sema.pt;
22531 const mod = pt.zcu;
22329 const ip = &mod.intern_pool;22532 const ip = &mod.intern_pool;
2233022533
22331 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;22534 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
22332 const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);22535 const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);
22333 const ty = try sema.resolveType(block, ty_src, inst_data.operand);22536 const ty = try sema.resolveType(block, ty_src, inst_data.operand);
2233422537
22335 const type_name = try ip.getOrPutStringFmt(sema.gpa, "{}", .{ty.fmt(mod)}, .no_embedded_nulls);22538 const type_name = try ip.getOrPutStringFmt(sema.gpa, "{}", .{ty.fmt(pt)}, .no_embedded_nulls);
22336 return sema.addNullTerminatedStrLit(type_name);22539 return sema.addNullTerminatedStrLit(type_name);
22337}22540}
2233822541
...@@ -22349,7 +22552,8 @@ fn zirFrameSize(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -22349,7 +22552,8 @@ fn zirFrameSize(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
22349}22552}
2235022553
22351fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {22554fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
22352 const mod = sema.mod;22555 const pt = sema.pt;
22556 const mod = pt.zcu;
22353 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;22557 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
22354 const src = block.nodeOffset(inst_data.src_node);22558 const src = block.nodeOffset(inst_data.src_node);
22355 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;22559 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
...@@ -22380,23 +22584,23 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -22380,23 +22584,23 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
22380 if (dest_scalar_ty.intInfo(mod).bits == 0) {22584 if (dest_scalar_ty.intInfo(mod).bits == 0) {
22381 if (!is_vector) {22585 if (!is_vector) {
22382 if (block.wantSafety()) {22586 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()));22587 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);22588 try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds);
22385 }22589 }
22386 return Air.internedToRef((try mod.intValue(dest_ty, 0)).toIntern());22590 return Air.internedToRef((try pt.intValue(dest_ty, 0)).toIntern());
22387 }22591 }
22388 if (block.wantSafety()) {22592 if (block.wantSafety()) {
22389 const len = dest_ty.vectorLen(mod);22593 const len = dest_ty.vectorLen(mod);
22390 for (0..len) |i| {22594 for (0..len) |i| {
22391 const idx_ref = try mod.intRef(Type.usize, i);22595 const idx_ref = try pt.intRef(Type.usize, i);
22392 const elem_ref = try block.addBinOp(.array_elem_val, operand, idx_ref);22596 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()));22597 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);22598 try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds);
22395 }22599 }
22396 }22600 }
22397 return Air.internedToRef(try mod.intern(.{ .aggregate = .{22601 return Air.internedToRef(try pt.intern(.{ .aggregate = .{
22398 .ty = dest_ty.toIntern(),22602 .ty = dest_ty.toIntern(),
22399 .storage = .{ .repeated_elem = (try mod.intValue(dest_scalar_ty, 0)).toIntern() },22603 .storage = .{ .repeated_elem = (try pt.intValue(dest_scalar_ty, 0)).toIntern() },
22400 } }));22604 } }));
22401 }22605 }
22402 if (!is_vector) {22606 if (!is_vector) {
...@@ -22404,8 +22608,8 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -22404,8 +22608,8 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
22404 if (block.wantSafety()) {22608 if (block.wantSafety()) {
22405 const back = try block.addTyOp(.float_from_int, operand_ty, result);22609 const back = try block.addTyOp(.float_from_int, operand_ty, result);
22406 const diff = try block.addBinOp(.sub, operand, back);22610 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()));22611 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()));22612 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);22613 const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg);
22410 try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds);22614 try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds);
22411 }22615 }
...@@ -22414,14 +22618,14 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -22414,14 +22618,14 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
22414 const len = dest_ty.vectorLen(mod);22618 const len = dest_ty.vectorLen(mod);
22415 const new_elems = try sema.arena.alloc(Air.Inst.Ref, len);22619 const new_elems = try sema.arena.alloc(Air.Inst.Ref, len);
22416 for (new_elems, 0..) |*new_elem, i| {22620 for (new_elems, 0..) |*new_elem, i| {
22417 const idx_ref = try mod.intRef(Type.usize, i);22621 const idx_ref = try pt.intRef(Type.usize, i);
22418 const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref);22622 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);22623 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()) {22624 if (block.wantSafety()) {
22421 const back = try block.addTyOp(.float_from_int, operand_scalar_ty, result);22625 const back = try block.addTyOp(.float_from_int, operand_scalar_ty, result);
22422 const diff = try block.addBinOp(.sub, old_elem, back);22626 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()));22627 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()));22628 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);22629 const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg);
22426 try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds);22630 try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds);
22427 }22631 }
...@@ -22431,7 +22635,8 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -22431,7 +22635,8 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
22431}22635}
2243222636
22433fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {22637fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
22434 const mod = sema.mod;22638 const pt = sema.pt;
22639 const mod = pt.zcu;
22435 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;22640 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
22436 const src = block.nodeOffset(inst_data.src_node);22641 const src = block.nodeOffset(inst_data.src_node);
22437 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;22642 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
...@@ -22450,7 +22655,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -22450,7 +22655,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
22450 _ = try sema.checkIntType(block, operand_src, operand_scalar_ty);22655 _ = try sema.checkIntType(block, operand_src, operand_scalar_ty);
2245122656
22452 if (try sema.resolveValue(operand)) |operand_val| {22657 if (try sema.resolveValue(operand)) |operand_val| {
22453 const result_val = try operand_val.floatFromIntAdvanced(sema.arena, operand_ty, dest_ty, mod, .sema);22658 const result_val = try operand_val.floatFromIntAdvanced(sema.arena, operand_ty, dest_ty, pt, .sema);
22454 return Air.internedToRef(result_val.toIntern());22659 return Air.internedToRef(result_val.toIntern());
22455 } else if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeFloat) {22660 } else if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeFloat) {
22456 return sema.failWithNeededComptime(block, operand_src, .{22661 return sema.failWithNeededComptime(block, operand_src, .{
...@@ -22465,7 +22670,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -22465,7 +22670,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
22465 const len = operand_ty.vectorLen(mod);22670 const len = operand_ty.vectorLen(mod);
22466 const new_elems = try sema.arena.alloc(Air.Inst.Ref, len);22671 const new_elems = try sema.arena.alloc(Air.Inst.Ref, len);
22467 for (new_elems, 0..) |*new_elem, i| {22672 for (new_elems, 0..) |*new_elem, i| {
22468 const idx_ref = try mod.intRef(Type.usize, i);22673 const idx_ref = try pt.intRef(Type.usize, i);
22469 const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref);22674 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);22675 new_elem.* = try block.addTyOp(.float_from_int, dest_scalar_ty, old_elem);
22471 }22676 }
...@@ -22473,7 +22678,8 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -22473,7 +22678,8 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
22473}22678}
2247422679
22475fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {22680fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
22476 const mod = sema.mod;22681 const pt = sema.pt;
22682 const mod = pt.zcu;
22477 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;22683 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
22478 const src = block.nodeOffset(inst_data.src_node);22684 const src = block.nodeOffset(inst_data.src_node);
2247922685
...@@ -22489,7 +22695,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -22489,7 +22695,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
22489 const is_vector = dest_ty.zigTypeTag(mod) == .Vector;22695 const is_vector = dest_ty.zigTypeTag(mod) == .Vector;
22490 const operand_ty = if (is_vector) operand_ty: {22696 const operand_ty = if (is_vector) operand_ty: {
22491 const len = dest_ty.vectorLen(mod);22697 const len = dest_ty.vectorLen(mod);
22492 break :operand_ty try mod.vectorType(.{ .child = .usize_type, .len = len });22698 break :operand_ty try pt.vectorType(.{ .child = .usize_type, .len = len });
22493 } else Type.usize;22699 } else Type.usize;
2249422700
22495 const operand_coerced = try sema.coerce(block, operand_ty, operand_res, operand_src);22701 const operand_coerced = try sema.coerce(block, operand_ty, operand_res, operand_src);
...@@ -22498,11 +22704,11 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -22498,11 +22704,11 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
22498 try sema.checkPtrType(block, src, ptr_ty, true);22704 try sema.checkPtrType(block, src, ptr_ty, true);
2249922705
22500 const elem_ty = ptr_ty.elemType2(mod);22706 const elem_ty = ptr_ty.elemType2(mod);
22501 const ptr_align = try ptr_ty.ptrAlignmentAdvanced(mod, .sema);22707 const ptr_align = try ptr_ty.ptrAlignmentAdvanced(pt, .sema);
2250222708
22503 if (ptr_ty.isSlice(mod)) {22709 if (ptr_ty.isSlice(mod)) {
22504 const msg = msg: {22710 const msg = msg: {
22505 const msg = try sema.errMsg(src, "integer cannot be converted to slice type '{}'", .{ptr_ty.fmt(sema.mod)});22711 const msg = try sema.errMsg(src, "integer cannot be converted to slice type '{}'", .{ptr_ty.fmt(pt)});
22506 errdefer msg.destroy(sema.gpa);22712 errdefer msg.destroy(sema.gpa);
22507 try sema.errNote(src, msg, "slice length cannot be inferred from address", .{});22713 try sema.errNote(src, msg, "slice length cannot be inferred from address", .{});
22508 break :msg msg;22714 break :msg msg;
...@@ -22518,18 +22724,18 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -22518,18 +22724,18 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
22518 const len = dest_ty.vectorLen(mod);22724 const len = dest_ty.vectorLen(mod);
22519 const new_elems = try sema.arena.alloc(InternPool.Index, len);22725 const new_elems = try sema.arena.alloc(InternPool.Index, len);
22520 for (new_elems, 0..) |*new_elem, i| {22726 for (new_elems, 0..) |*new_elem, i| {
22521 const elem = try val.elemValue(mod, i);22727 const elem = try val.elemValue(pt, i);
22522 const ptr_val = try sema.ptrFromIntVal(block, operand_src, elem, ptr_ty, ptr_align);22728 const ptr_val = try sema.ptrFromIntVal(block, operand_src, elem, ptr_ty, ptr_align);
22523 new_elem.* = ptr_val.toIntern();22729 new_elem.* = ptr_val.toIntern();
22524 }22730 }
22525 return Air.internedToRef(try mod.intern(.{ .aggregate = .{22731 return Air.internedToRef(try pt.intern(.{ .aggregate = .{
22526 .ty = dest_ty.toIntern(),22732 .ty = dest_ty.toIntern(),
22527 .storage = .{ .elems = new_elems },22733 .storage = .{ .elems = new_elems },
22528 } }));22734 } }));
22529 }22735 }
22530 if (try sema.typeRequiresComptime(ptr_ty)) {22736 if (try sema.typeRequiresComptime(ptr_ty)) {
22531 return sema.failWithOwnedErrorMsg(block, msg: {22737 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)});22738 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);22739 errdefer msg.destroy(sema.gpa);
2253422740
22535 try sema.explainWhyTypeIsComptime(msg, src, ptr_ty);22741 try sema.explainWhyTypeIsComptime(msg, src, ptr_ty);
...@@ -22545,7 +22751,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -22545,7 +22751,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
22545 }22751 }
22546 if (ptr_align.compare(.gt, .@"1")) {22752 if (ptr_align.compare(.gt, .@"1")) {
22547 const align_bytes_minus_1 = ptr_align.toByteUnits().? - 1;22753 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());22754 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);22755 const remainder = try block.addBinOp(.bit_and, operand_coerced, align_minus_1);
22550 const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize);22756 const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize);
22551 try sema.addSafetyCheck(block, src, is_aligned, .incorrect_alignment);22757 try sema.addSafetyCheck(block, src, is_aligned, .incorrect_alignment);
...@@ -22557,7 +22763,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -22557,7 +22763,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
22557 const len = dest_ty.vectorLen(mod);22763 const len = dest_ty.vectorLen(mod);
22558 if (block.wantSafety() and (try sema.typeHasRuntimeBits(elem_ty) or elem_ty.zigTypeTag(mod) == .Fn)) {22764 if (block.wantSafety() and (try sema.typeHasRuntimeBits(elem_ty) or elem_ty.zigTypeTag(mod) == .Fn)) {
22559 for (0..len) |i| {22765 for (0..len) |i| {
22560 const idx_ref = try mod.intRef(Type.usize, i);22766 const idx_ref = try pt.intRef(Type.usize, i);
22561 const elem_coerced = try block.addBinOp(.array_elem_val, operand_coerced, idx_ref);22767 const elem_coerced = try block.addBinOp(.array_elem_val, operand_coerced, idx_ref);
22562 if (!ptr_ty.isAllowzeroPtr(mod)) {22768 if (!ptr_ty.isAllowzeroPtr(mod)) {
22563 const is_non_zero = try block.addBinOp(.cmp_neq, elem_coerced, .zero_usize);22769 const is_non_zero = try block.addBinOp(.cmp_neq, elem_coerced, .zero_usize);
...@@ -22565,7 +22771,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -22565,7 +22771,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
22565 }22771 }
22566 if (ptr_align.compare(.gt, .@"1")) {22772 if (ptr_align.compare(.gt, .@"1")) {
22567 const align_bytes_minus_1 = ptr_align.toByteUnits().? - 1;22773 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());22774 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);22775 const remainder = try block.addBinOp(.bit_and, elem_coerced, align_minus_1);
22570 const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize);22776 const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize);
22571 try sema.addSafetyCheck(block, src, is_aligned, .incorrect_alignment);22777 try sema.addSafetyCheck(block, src, is_aligned, .incorrect_alignment);
...@@ -22575,7 +22781,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -22575,7 +22781,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2257522781
22576 const new_elems = try sema.arena.alloc(Air.Inst.Ref, len);22782 const new_elems = try sema.arena.alloc(Air.Inst.Ref, len);
22577 for (new_elems, 0..) |*new_elem, i| {22783 for (new_elems, 0..) |*new_elem, i| {
22578 const idx_ref = try mod.intRef(Type.usize, i);22784 const idx_ref = try pt.intRef(Type.usize, i);
22579 const old_elem = try block.addBinOp(.array_elem_val, operand_coerced, idx_ref);22785 const old_elem = try block.addBinOp(.array_elem_val, operand_coerced, idx_ref);
22580 new_elem.* = try block.addBitCast(ptr_ty, old_elem);22786 new_elem.* = try block.addBitCast(ptr_ty, old_elem);
22581 }22787 }
...@@ -22590,31 +22796,33 @@ fn ptrFromIntVal(...@@ -22590,31 +22796,33 @@ fn ptrFromIntVal(
22590 ptr_ty: Type,22796 ptr_ty: Type,
22591 ptr_align: Alignment,22797 ptr_align: Alignment,
22592) !Value {22798) !Value {
22593 const zcu = sema.mod;22799 const pt = sema.pt;
22800 const zcu = pt.zcu;
22594 if (operand_val.isUndef(zcu)) {22801 if (operand_val.isUndef(zcu)) {
22595 if (ptr_ty.isAllowzeroPtr(zcu) and ptr_align == .@"1") {22802 if (ptr_ty.isAllowzeroPtr(zcu) and ptr_align == .@"1") {
22596 return zcu.undefValue(ptr_ty);22803 return pt.undefValue(ptr_ty);
22597 }22804 }
22598 return sema.failWithUseOfUndef(block, operand_src);22805 return sema.failWithUseOfUndef(block, operand_src);
22599 }22806 }
22600 const addr = try operand_val.toUnsignedIntSema(zcu);22807 const addr = try operand_val.toUnsignedIntSema(pt);
22601 if (!ptr_ty.isAllowzeroPtr(zcu) and addr == 0)22808 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)});22809 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))22810 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)});22811 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{ptr_ty.fmt(pt)});
2260522812
22606 return switch (ptr_ty.zigTypeTag(zcu)) {22813 return switch (ptr_ty.zigTypeTag(zcu)) {
22607 .Optional => Value.fromInterned((try zcu.intern(.{ .opt = .{22814 .Optional => Value.fromInterned(try pt.intern(.{ .opt = .{
22608 .ty = ptr_ty.toIntern(),22815 .ty = ptr_ty.toIntern(),
22609 .val = if (addr == 0) .none else (try zcu.ptrIntValue(ptr_ty.childType(zcu), addr)).toIntern(),22816 .val = if (addr == 0) .none else (try pt.ptrIntValue(ptr_ty.childType(zcu), addr)).toIntern(),
22610 } }))),22817 } })),
22611 .Pointer => try zcu.ptrIntValue(ptr_ty, addr),22818 .Pointer => try pt.ptrIntValue(ptr_ty, addr),
22612 else => unreachable,22819 else => unreachable,
22613 };22820 };
22614}22821}
2261522822
22616fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {22823fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
22617 const mod = sema.mod;22824 const pt = sema.pt;
22825 const mod = pt.zcu;
22618 const ip = &mod.intern_pool;22826 const ip = &mod.intern_pool;
22619 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;22827 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
22620 const src = block.nodeOffset(extra.node);22828 const src = block.nodeOffset(extra.node);
...@@ -22642,8 +22850,8 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData...@@ -22642,8 +22850,8 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
22642 errdefer msg.destroy(sema.gpa);22850 errdefer msg.destroy(sema.gpa);
22643 const dest_ty = base_dest_ty.errorUnionPayload(mod);22851 const dest_ty = base_dest_ty.errorUnionPayload(mod);
22644 const operand_ty = base_operand_ty.errorUnionPayload(mod);22852 const operand_ty = base_operand_ty.errorUnionPayload(mod);
22645 try sema.errNote(src, msg, "destination payload is '{}'", .{dest_ty.fmt(mod)});22853 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)});22854 try sema.errNote(src, msg, "operand payload is '{}'", .{operand_ty.fmt(pt)});
22647 try addDeclaredHereNote(sema, msg, dest_ty);22855 try addDeclaredHereNote(sema, msg, dest_ty);
22648 try addDeclaredHereNote(sema, msg, operand_ty);22856 try addDeclaredHereNote(sema, msg, operand_ty);
22649 break :msg msg;22857 break :msg msg;
...@@ -22684,7 +22892,7 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData...@@ -22684,7 +22892,7 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
22684 };22892 };
22685 if (disjoint and dest_tag != .ErrorUnion) {22893 if (disjoint and dest_tag != .ErrorUnion) {
22686 return sema.fail(block, src, "error sets '{}' and '{}' have no common errors", .{22894 return sema.fail(block, src, "error sets '{}' and '{}' have no common errors", .{
22687 operand_ty.fmt(sema.mod), dest_ty.fmt(sema.mod),22895 operand_ty.fmt(pt), dest_ty.fmt(pt),
22688 });22896 });
22689 }22897 }
2269022898
...@@ -22700,24 +22908,24 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData...@@ -22700,24 +22908,24 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
22700 }22908 }
22701 if (!Type.errorSetHasFieldIp(ip, dest_ty.toIntern(), error_name)) {22909 if (!Type.errorSetHasFieldIp(ip, dest_ty.toIntern(), error_name)) {
22702 return sema.fail(block, src, "'error.{}' not a member of error set '{}'", .{22910 return sema.fail(block, src, "'error.{}' not a member of error set '{}'", .{
22703 error_name.fmt(ip), dest_ty.fmt(sema.mod),22911 error_name.fmt(ip), dest_ty.fmt(pt),
22704 });22912 });
22705 }22913 }
22706 }22914 }
2270722915
22708 return Air.internedToRef((try mod.getCoerced(val, base_dest_ty)).toIntern());22916 return Air.internedToRef((try pt.getCoerced(val, base_dest_ty)).toIntern());
22709 }22917 }
2271022918
22711 try sema.requireRuntimeBlock(block, src, operand_src);22919 try sema.requireRuntimeBlock(block, src, operand_src);
22712 const err_int_ty = try mod.errorIntType();22920 const err_int_ty = try pt.errorIntType();
22713 if (block.wantSafety() and !dest_ty.isAnyError(mod) and22921 if (block.wantSafety() and !dest_ty.isAnyError(mod) and
22714 dest_ty.toIntern() != .adhoc_inferred_error_set_type and22922 dest_ty.toIntern() != .adhoc_inferred_error_set_type and
22715 sema.mod.backendSupportsFeature(.error_set_has_value))22923 mod.backendSupportsFeature(.error_set_has_value))
22716 {22924 {
22717 if (dest_tag == .ErrorUnion) {22925 if (dest_tag == .ErrorUnion) {
22718 const err_code = try sema.analyzeErrUnionCode(block, operand_src, operand);22926 const err_code = try sema.analyzeErrUnionCode(block, operand_src, operand);
22719 const err_int = try block.addBitCast(err_int_ty, err_code);22927 const err_int = try block.addBitCast(err_int_ty, err_code);
22720 const zero_err = try mod.intRef(try mod.errorIntType(), 0);22928 const zero_err = try pt.intRef(try pt.errorIntType(), 0);
2272122929
22722 const is_zero = try block.addBinOp(.cmp_eq, err_int, zero_err);22930 const is_zero = try block.addBinOp(.cmp_eq, err_int, zero_err);
22723 if (disjoint) {22931 if (disjoint) {
...@@ -22786,7 +22994,8 @@ fn ptrCastFull(...@@ -22786,7 +22994,8 @@ fn ptrCastFull(
22786 dest_ty: Type,22994 dest_ty: Type,
22787 operation: []const u8,22995 operation: []const u8,
22788) CompileError!Air.Inst.Ref {22996) CompileError!Air.Inst.Ref {
22789 const mod = sema.mod;22997 const pt = sema.pt;
22998 const mod = pt.zcu;
22790 const operand_ty = sema.typeOf(operand);22999 const operand_ty = sema.typeOf(operand);
2279123000
22792 try sema.checkPtrType(block, src, dest_ty, true);23001 try sema.checkPtrType(block, src, dest_ty, true);
...@@ -22795,8 +23004,8 @@ fn ptrCastFull(...@@ -22795,8 +23004,8 @@ fn ptrCastFull(
22795 const src_info = operand_ty.ptrInfo(mod);23004 const src_info = operand_ty.ptrInfo(mod);
22796 const dest_info = dest_ty.ptrInfo(mod);23005 const dest_info = dest_ty.ptrInfo(mod);
2279723006
22798 try Type.fromInterned(src_info.child).resolveLayout(mod);23007 try Type.fromInterned(src_info.child).resolveLayout(pt);
22799 try Type.fromInterned(dest_info.child).resolveLayout(mod);23008 try Type.fromInterned(dest_info.child).resolveLayout(pt);
2280023009
22801 const src_slice_like = src_info.flags.size == .Slice or23010 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);23011 (src_info.flags.size == .One and Type.fromInterned(src_info.child).zigTypeTag(mod) == .Array);
...@@ -22810,12 +23019,12 @@ fn ptrCastFull(...@@ -22810,12 +23019,12 @@ fn ptrCastFull(
2281023019
22811 if (dest_info.flags.size == .Slice) {23020 if (dest_info.flags.size == .Slice) {
22812 const src_elem_size = switch (src_info.flags.size) {23021 const src_elem_size = switch (src_info.flags.size) {
22813 .Slice => Type.fromInterned(src_info.child).abiSize(mod),23022 .Slice => Type.fromInterned(src_info.child).abiSize(pt),
22814 // pointer to array23023 // pointer to array
22815 .One => Type.fromInterned(src_info.child).childType(mod).abiSize(mod),23024 .One => Type.fromInterned(src_info.child).childType(mod).abiSize(pt),
22816 else => unreachable,23025 else => unreachable,
22817 };23026 };
22818 const dest_elem_size = Type.fromInterned(dest_info.child).abiSize(mod);23027 const dest_elem_size = Type.fromInterned(dest_info.child).abiSize(pt);
22819 if (src_elem_size != dest_elem_size) {23028 if (src_elem_size != dest_elem_size) {
22820 return sema.fail(block, src, "TODO: implement {s} between slices changing the length", .{operation});23029 return sema.fail(block, src, "TODO: implement {s} between slices changing the length", .{operation});
22821 }23030 }
...@@ -22867,8 +23076,7 @@ fn ptrCastFull(...@@ -22867,8 +23076,7 @@ fn ptrCastFull(
22867 if (imc_res == .ok) break :check_child;23076 if (imc_res == .ok) break :check_child;
22868 return sema.failWithOwnedErrorMsg(block, msg: {23077 return sema.failWithOwnedErrorMsg(block, msg: {
22869 const msg = try sema.errMsg(src, "pointer element type '{}' cannot coerce into element type '{}'", .{23078 const msg = try sema.errMsg(src, "pointer element type '{}' cannot coerce into element type '{}'", .{
22870 src_child.fmt(mod),23079 src_child.fmt(pt), dest_child.fmt(pt),
22871 dest_child.fmt(mod),
22872 });23080 });
22873 errdefer msg.destroy(sema.gpa);23081 errdefer msg.destroy(sema.gpa);
22874 try imc_res.report(sema, src, msg);23082 try imc_res.report(sema, src, msg);
...@@ -22881,26 +23089,26 @@ fn ptrCastFull(...@@ -22881,26 +23089,26 @@ fn ptrCastFull(
22881 if (dest_info.sentinel == .none) break :check_sent;23089 if (dest_info.sentinel == .none) break :check_sent;
22882 if (src_info.flags.size == .C) break :check_sent;23090 if (src_info.flags.size == .C) break :check_sent;
22883 if (src_info.sentinel != .none) {23091 if (src_info.sentinel != .none) {
22884 const coerced_sent = try mod.intern_pool.getCoerced(sema.gpa, src_info.sentinel, dest_info.child);23092 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;23093 if (dest_info.sentinel == coerced_sent) break :check_sent;
22886 }23094 }
22887 if (src_slice_like and src_info.flags.size == .One and dest_info.flags.size == .Slice) {23095 if (src_slice_like and src_info.flags.size == .One and dest_info.flags.size == .Slice) {
22888 // [*]nT -> []T23096 // [*]nT -> []T
22889 const arr_ty = Type.fromInterned(src_info.child);23097 const arr_ty = Type.fromInterned(src_info.child);
22890 if (arr_ty.sentinel(mod)) |src_sentinel| {23098 if (arr_ty.sentinel(mod)) |src_sentinel| {
22891 const coerced_sent = try mod.intern_pool.getCoerced(sema.gpa, src_sentinel.toIntern(), dest_info.child);23099 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;23100 if (dest_info.sentinel == coerced_sent) break :check_sent;
22893 }23101 }
22894 }23102 }
22895 return sema.failWithOwnedErrorMsg(block, msg: {23103 return sema.failWithOwnedErrorMsg(block, msg: {
22896 const msg = if (src_info.sentinel == .none) blk: {23104 const msg = if (src_info.sentinel == .none) blk: {
22897 break :blk try sema.errMsg(src, "destination pointer requires '{}' sentinel", .{23105 break :blk try sema.errMsg(src, "destination pointer requires '{}' sentinel", .{
22898 Value.fromInterned(dest_info.sentinel).fmtValue(mod, sema),23106 Value.fromInterned(dest_info.sentinel).fmtValue(pt, sema),
22899 });23107 });
22900 } else blk: {23108 } else blk: {
22901 break :blk try sema.errMsg(src, "pointer sentinel '{}' cannot coerce into pointer sentinel '{}'", .{23109 break :blk try sema.errMsg(src, "pointer sentinel '{}' cannot coerce into pointer sentinel '{}'", .{
22902 Value.fromInterned(src_info.sentinel).fmtValue(mod, sema),23110 Value.fromInterned(src_info.sentinel).fmtValue(pt, sema),
22903 Value.fromInterned(dest_info.sentinel).fmtValue(mod, sema),23111 Value.fromInterned(dest_info.sentinel).fmtValue(pt, sema),
22904 });23112 });
22905 };23113 };
22906 errdefer msg.destroy(sema.gpa);23114 errdefer msg.destroy(sema.gpa);
...@@ -22941,8 +23149,8 @@ fn ptrCastFull(...@@ -22941,8 +23149,8 @@ fn ptrCastFull(
2294123149
22942 return sema.failWithOwnedErrorMsg(block, msg: {23150 return sema.failWithOwnedErrorMsg(block, msg: {
22943 const msg = try sema.errMsg(src, "'{}' could have null values which are illegal in type '{}'", .{23151 const msg = try sema.errMsg(src, "'{}' could have null values which are illegal in type '{}'", .{
22944 operand_ty.fmt(mod),23152 operand_ty.fmt(pt),
22945 dest_ty.fmt(mod),23153 dest_ty.fmt(pt),
22946 });23154 });
22947 errdefer msg.destroy(sema.gpa);23155 errdefer msg.destroy(sema.gpa);
22948 try sema.errNote(src, msg, "use @ptrCast to assert the pointer is not null", .{});23156 try sema.errNote(src, msg, "use @ptrCast to assert the pointer is not null", .{});
...@@ -22956,12 +23164,12 @@ fn ptrCastFull(...@@ -22956,12 +23164,12 @@ fn ptrCastFull(
22956 const src_align = if (src_info.flags.alignment != .none)23164 const src_align = if (src_info.flags.alignment != .none)
22957 src_info.flags.alignment23165 src_info.flags.alignment
22958 else23166 else
22959 Type.fromInterned(src_info.child).abiAlignment(mod);23167 Type.fromInterned(src_info.child).abiAlignment(pt);
2296023168
22961 const dest_align = if (dest_info.flags.alignment != .none)23169 const dest_align = if (dest_info.flags.alignment != .none)
22962 dest_info.flags.alignment23170 dest_info.flags.alignment
22963 else23171 else
22964 Type.fromInterned(dest_info.child).abiAlignment(mod);23172 Type.fromInterned(dest_info.child).abiAlignment(pt);
2296523173
22966 if (!flags.align_cast) {23174 if (!flags.align_cast) {
22967 if (dest_align.compare(.gt, src_align)) {23175 if (dest_align.compare(.gt, src_align)) {
...@@ -22969,10 +23177,10 @@ fn ptrCastFull(...@@ -22969,10 +23177,10 @@ fn ptrCastFull(
22969 const msg = try sema.errMsg(src, "{s} increases pointer alignment", .{operation});23177 const msg = try sema.errMsg(src, "{s} increases pointer alignment", .{operation});
22970 errdefer msg.destroy(sema.gpa);23178 errdefer msg.destroy(sema.gpa);
22971 try sema.errNote(operand_src, msg, "'{}' has alignment '{d}'", .{23179 try sema.errNote(operand_src, msg, "'{}' has alignment '{d}'", .{
22972 operand_ty.fmt(mod), src_align.toByteUnits() orelse 0,23180 operand_ty.fmt(pt), src_align.toByteUnits() orelse 0,
22973 });23181 });
22974 try sema.errNote(src, msg, "'{}' has alignment '{d}'", .{23182 try sema.errNote(src, msg, "'{}' has alignment '{d}'", .{
22975 dest_ty.fmt(mod), dest_align.toByteUnits() orelse 0,23183 dest_ty.fmt(pt), dest_align.toByteUnits() orelse 0,
22976 });23184 });
22977 try sema.errNote(src, msg, "use @alignCast to assert pointer alignment", .{});23185 try sema.errNote(src, msg, "use @alignCast to assert pointer alignment", .{});
22978 break :msg msg;23186 break :msg msg;
...@@ -22986,10 +23194,10 @@ fn ptrCastFull(...@@ -22986,10 +23194,10 @@ fn ptrCastFull(
22986 const msg = try sema.errMsg(src, "{s} changes pointer address space", .{operation});23194 const msg = try sema.errMsg(src, "{s} changes pointer address space", .{operation});
22987 errdefer msg.destroy(sema.gpa);23195 errdefer msg.destroy(sema.gpa);
22988 try sema.errNote(operand_src, msg, "'{}' has address space '{s}'", .{23196 try sema.errNote(operand_src, msg, "'{}' has address space '{s}'", .{
22989 operand_ty.fmt(mod), @tagName(src_info.flags.address_space),23197 operand_ty.fmt(pt), @tagName(src_info.flags.address_space),
22990 });23198 });
22991 try sema.errNote(src, msg, "'{}' has address space '{s}'", .{23199 try sema.errNote(src, msg, "'{}' has address space '{s}'", .{
22992 dest_ty.fmt(mod), @tagName(dest_info.flags.address_space),23200 dest_ty.fmt(pt), @tagName(dest_info.flags.address_space),
22993 });23201 });
22994 try sema.errNote(src, msg, "use @addrSpaceCast to cast pointer address space", .{});23202 try sema.errNote(src, msg, "use @addrSpaceCast to cast pointer address space", .{});
22995 break :msg msg;23203 break :msg msg;
...@@ -23044,9 +23252,9 @@ fn ptrCastFull(...@@ -23044,9 +23252,9 @@ fn ptrCastFull(
23044 // Only convert to a many-pointer at first23252 // Only convert to a many-pointer at first
23045 var info = dest_info;23253 var info = dest_info;
23046 info.flags.size = .Many;23254 info.flags.size = .Many;
23047 const ty = try mod.ptrTypeSema(info);23255 const ty = try pt.ptrTypeSema(info);
23048 if (dest_ty.zigTypeTag(mod) == .Optional) {23256 if (dest_ty.zigTypeTag(mod) == .Optional) {
23049 break :blk try mod.optionalType(ty.toIntern());23257 break :blk try pt.optionalType(ty.toIntern());
23050 } else {23258 } else {
23051 break :blk ty;23259 break :blk ty;
23052 }23260 }
...@@ -23059,10 +23267,10 @@ fn ptrCastFull(...@@ -23059,10 +23267,10 @@ fn ptrCastFull(
23059 return sema.failWithUseOfUndef(block, operand_src);23267 return sema.failWithUseOfUndef(block, operand_src);
23060 }23268 }
23061 if (!dest_ty.ptrAllowsZero(mod) and ptr_val.isNull(mod)) {23269 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)});23270 return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(pt)});
23063 }23271 }
23064 if (dest_align.compare(.gt, src_align)) {23272 if (dest_align.compare(.gt, src_align)) {
23065 if (try ptr_val.getUnsignedIntAdvanced(mod, .sema)) |addr| {23273 if (try ptr_val.getUnsignedIntAdvanced(pt, .sema)) |addr| {
23066 if (!dest_align.check(addr)) {23274 if (!dest_align.check(addr)) {
23067 return sema.fail(block, operand_src, "pointer address 0x{X} is not aligned to {d} bytes", .{23275 return sema.fail(block, operand_src, "pointer address 0x{X} is not aligned to {d} bytes", .{
23068 addr,23276 addr,
...@@ -23072,12 +23280,12 @@ fn ptrCastFull(...@@ -23072,12 +23280,12 @@ fn ptrCastFull(
23072 }23280 }
23073 }23281 }
23074 if (dest_info.flags.size == .Slice and src_info.flags.size != .Slice) {23282 if (dest_info.flags.size == .Slice and src_info.flags.size != .Slice) {
23075 if (ptr_val.isUndef(mod)) return mod.undefRef(dest_ty);23283 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));23284 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;23285 const ptr_val_key = mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr;
23078 return Air.internedToRef((try mod.intern(.{ .slice = .{23286 return Air.internedToRef((try pt.intern(.{ .slice = .{
23079 .ty = dest_ty.toIntern(),23287 .ty = dest_ty.toIntern(),
23080 .ptr = try mod.intern(.{ .ptr = .{23288 .ptr = try pt.intern(.{ .ptr = .{
23081 .ty = dest_ty.slicePtrFieldType(mod).toIntern(),23289 .ty = dest_ty.slicePtrFieldType(mod).toIntern(),
23082 .base_addr = ptr_val_key.base_addr,23290 .base_addr = ptr_val_key.base_addr,
23083 .byte_offset = ptr_val_key.byte_offset,23291 .byte_offset = ptr_val_key.byte_offset,
...@@ -23086,7 +23294,7 @@ fn ptrCastFull(...@@ -23086,7 +23294,7 @@ fn ptrCastFull(
23086 } })));23294 } })));
23087 } else {23295 } else {
23088 assert(dest_ptr_ty.eql(dest_ty, mod));23296 assert(dest_ptr_ty.eql(dest_ty, mod));
23089 return Air.internedToRef((try mod.getCoerced(ptr_val, dest_ty)).toIntern());23297 return Air.internedToRef((try pt.getCoerced(ptr_val, dest_ty)).toIntern());
23090 }23298 }
23091 }23299 }
23092 }23300 }
...@@ -23112,7 +23320,7 @@ fn ptrCastFull(...@@ -23112,7 +23320,7 @@ fn ptrCastFull(
23112 try sema.typeHasRuntimeBits(Type.fromInterned(dest_info.child)))23320 try sema.typeHasRuntimeBits(Type.fromInterned(dest_info.child)))
23113 {23321 {
23114 const align_bytes_minus_1 = dest_align.toByteUnits().? - 1;23322 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());23323 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);23324 const ptr_int = try block.addUnOp(.int_from_ptr, ptr);
23117 const remainder = try block.addBinOp(.bit_and, ptr_int, align_minus_1);23325 const remainder = try block.addBinOp(.bit_and, ptr_int, align_minus_1);
23118 const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize);23326 const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize);
...@@ -23129,9 +23337,9 @@ fn ptrCastFull(...@@ -23129,9 +23337,9 @@ fn ptrCastFull(
23129 // We can't change address spaces with a bitcast, so this requires two instructions23337 // We can't change address spaces with a bitcast, so this requires two instructions
23130 var intermediate_info = src_info;23338 var intermediate_info = src_info;
23131 intermediate_info.flags.address_space = dest_info.flags.address_space;23339 intermediate_info.flags.address_space = dest_info.flags.address_space;
23132 const intermediate_ptr_ty = try mod.ptrTypeSema(intermediate_info);23340 const intermediate_ptr_ty = try pt.ptrTypeSema(intermediate_info);
23133 const intermediate_ty = if (dest_ptr_ty.zigTypeTag(mod) == .Optional) blk: {23341 const intermediate_ty = if (dest_ptr_ty.zigTypeTag(mod) == .Optional) blk: {
23134 break :blk try mod.optionalType(intermediate_ptr_ty.toIntern());23342 break :blk try pt.optionalType(intermediate_ptr_ty.toIntern());
23135 } else intermediate_ptr_ty;23343 } else intermediate_ptr_ty;
23136 const intermediate = try block.addInst(.{23344 const intermediate = try block.addInst(.{
23137 .tag = .addrspace_cast,23345 .tag = .addrspace_cast,
...@@ -23152,7 +23360,7 @@ fn ptrCastFull(...@@ -23152,7 +23360,7 @@ fn ptrCastFull(
23152 if (dest_info.flags.size == .Slice and src_info.flags.size != .Slice) {23360 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 length23361 // 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-like23362 // 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());23363 const arr_len = Air.internedToRef((try pt.intValue(Type.usize, Type.fromInterned(src_info.child).arrayLen(mod))).toIntern());
23156 return block.addInst(.{23364 return block.addInst(.{
23157 .tag = .slice,23365 .tag = .slice,
23158 .data = .{ .ty_pl = .{23366 .data = .{ .ty_pl = .{
...@@ -23171,7 +23379,8 @@ fn ptrCastFull(...@@ -23171,7 +23379,8 @@ fn ptrCastFull(
23171}23379}
2317223380
23173fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {23381fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
23174 const mod = sema.mod;23382 const pt = sema.pt;
23383 const mod = pt.zcu;
23175 const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?;23384 const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?;
23176 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));23385 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));
23177 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;23386 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
...@@ -23186,15 +23395,15 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst...@@ -23186,15 +23395,15 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
23186 if (flags.volatile_cast) ptr_info.flags.is_volatile = false;23395 if (flags.volatile_cast) ptr_info.flags.is_volatile = false;
2318723396
23188 const dest_ty = blk: {23397 const dest_ty = blk: {
23189 const dest_ty = try mod.ptrTypeSema(ptr_info);23398 const dest_ty = try pt.ptrTypeSema(ptr_info);
23190 if (operand_ty.zigTypeTag(mod) == .Optional) {23399 if (operand_ty.zigTypeTag(mod) == .Optional) {
23191 break :blk try mod.optionalType(dest_ty.toIntern());23400 break :blk try pt.optionalType(dest_ty.toIntern());
23192 }23401 }
23193 break :blk dest_ty;23402 break :blk dest_ty;
23194 };23403 };
2319523404
23196 if (try sema.resolveValue(operand)) |operand_val| {23405 if (try sema.resolveValue(operand)) |operand_val| {
23197 return Air.internedToRef((try mod.getCoerced(operand_val, dest_ty)).toIntern());23406 return Air.internedToRef((try pt.getCoerced(operand_val, dest_ty)).toIntern());
23198 }23407 }
2319923408
23200 try sema.requireRuntimeBlock(block, src, null);23409 try sema.requireRuntimeBlock(block, src, null);
...@@ -23204,7 +23413,8 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst...@@ -23204,7 +23413,8 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
23204}23413}
2320523414
23206fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {23415fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
23207 const mod = sema.mod;23416 const pt = sema.pt;
23417 const mod = pt.zcu;
23208 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;23418 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
23209 const src = block.nodeOffset(inst_data.src_node);23419 const src = block.nodeOffset(inst_data.src_node);
23210 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);23420 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
...@@ -23218,7 +23428,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -23218,7 +23428,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
23218 const operand_is_vector = operand_ty.zigTypeTag(mod) == .Vector;23428 const operand_is_vector = operand_ty.zigTypeTag(mod) == .Vector;
23219 const dest_is_vector = dest_ty.zigTypeTag(mod) == .Vector;23429 const dest_is_vector = dest_ty.zigTypeTag(mod) == .Vector;
23220 if (operand_is_vector != dest_is_vector) {23430 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) });23431 return sema.fail(block, operand_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(pt), operand_ty.fmt(pt) });
23222 }23432 }
2322323433
23224 if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeInt) {23434 if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeInt) {
...@@ -23239,7 +23449,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -23239,7 +23449,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2323923449
23240 if (operand_info.signedness != dest_info.signedness) {23450 if (operand_info.signedness != dest_info.signedness) {
23241 return sema.fail(block, operand_src, "expected {s} integer type, found '{}'", .{23451 return sema.fail(block, operand_src, "expected {s} integer type, found '{}'", .{
23242 @tagName(dest_info.signedness), operand_ty.fmt(mod),23452 @tagName(dest_info.signedness), operand_ty.fmt(pt),
23243 });23453 });
23244 }23454 }
23245 if (operand_info.bits < dest_info.bits) {23455 if (operand_info.bits < dest_info.bits) {
...@@ -23247,7 +23457,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -23247,7 +23457,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
23247 const msg = try sema.errMsg(23457 const msg = try sema.errMsg(
23248 src,23458 src,
23249 "destination type '{}' has more bits than source type '{}'",23459 "destination type '{}' has more bits than source type '{}'",
23250 .{ dest_ty.fmt(mod), operand_ty.fmt(mod) },23460 .{ dest_ty.fmt(pt), operand_ty.fmt(pt) },
23251 );23461 );
23252 errdefer msg.destroy(sema.gpa);23462 errdefer msg.destroy(sema.gpa);
23253 try sema.errNote(src, msg, "destination type has {d} bits", .{23463 try sema.errNote(src, msg, "destination type has {d} bits", .{
...@@ -23263,20 +23473,20 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -23263,20 +23473,20 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
23263 }23473 }
2326423474
23265 if (try sema.resolveValueIntable(operand)) |val| {23475 if (try sema.resolveValueIntable(operand)) |val| {
23266 if (val.isUndef(mod)) return mod.undefRef(dest_ty);23476 if (val.isUndef(mod)) return pt.undefRef(dest_ty);
23267 if (!dest_is_vector) {23477 if (!dest_is_vector) {
23268 return Air.internedToRef((try mod.getCoerced(23478 return Air.internedToRef((try pt.getCoerced(
23269 try val.intTrunc(operand_ty, sema.arena, dest_info.signedness, dest_info.bits, mod),23479 try val.intTrunc(operand_ty, sema.arena, dest_info.signedness, dest_info.bits, pt),
23270 dest_ty,23480 dest_ty,
23271 )).toIntern());23481 )).toIntern());
23272 }23482 }
23273 const elems = try sema.arena.alloc(InternPool.Index, operand_ty.vectorLen(mod));23483 const elems = try sema.arena.alloc(InternPool.Index, operand_ty.vectorLen(mod));
23274 for (elems, 0..) |*elem, i| {23484 for (elems, 0..) |*elem, i| {
23275 const elem_val = try val.elemValue(mod, i);23485 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);23486 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();23487 elem.* = (try pt.getCoerced(uncoerced_elem, dest_scalar_ty)).toIntern();
23278 }23488 }
23279 return Air.internedToRef((try mod.intern(.{ .aggregate = .{23489 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
23280 .ty = dest_ty.toIntern(),23490 .ty = dest_ty.toIntern(),
23281 .storage = .{ .elems = elems },23491 .storage = .{ .elems = elems },
23282 } })));23492 } })));
...@@ -23291,9 +23501,10 @@ fn zirBitCount(...@@ -23291,9 +23501,10 @@ fn zirBitCount(
23291 block: *Block,23501 block: *Block,
23292 inst: Zir.Inst.Index,23502 inst: Zir.Inst.Index,
23293 air_tag: Air.Inst.Tag,23503 air_tag: Air.Inst.Tag,
23294 comptime comptimeOp: fn (val: Value, ty: Type, mod: *Module) u64,23504 comptime comptimeOp: fn (val: Value, ty: Type, pt: Zcu.PerThread) u64,
23295) CompileError!Air.Inst.Ref {23505) CompileError!Air.Inst.Ref {
23296 const mod = sema.mod;23506 const pt = sema.pt;
23507 const mod = pt.zcu;
23297 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;23508 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
23298 const src = block.nodeOffset(inst_data.src_node);23509 const src = block.nodeOffset(inst_data.src_node);
23299 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);23510 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
...@@ -23306,25 +23517,25 @@ fn zirBitCount(...@@ -23306,25 +23517,25 @@ fn zirBitCount(
23306 return Air.internedToRef(val.toIntern());23517 return Air.internedToRef(val.toIntern());
23307 }23518 }
2330823519
23309 const result_scalar_ty = try mod.smallestUnsignedInt(bits);23520 const result_scalar_ty = try pt.smallestUnsignedInt(bits);
23310 switch (operand_ty.zigTypeTag(mod)) {23521 switch (operand_ty.zigTypeTag(mod)) {
23311 .Vector => {23522 .Vector => {
23312 const vec_len = operand_ty.vectorLen(mod);23523 const vec_len = operand_ty.vectorLen(mod);
23313 const result_ty = try mod.vectorType(.{23524 const result_ty = try pt.vectorType(.{
23314 .len = vec_len,23525 .len = vec_len,
23315 .child = result_scalar_ty.toIntern(),23526 .child = result_scalar_ty.toIntern(),
23316 });23527 });
23317 if (try sema.resolveValue(operand)) |val| {23528 if (try sema.resolveValue(operand)) |val| {
23318 if (val.isUndef(mod)) return mod.undefRef(result_ty);23529 if (val.isUndef(mod)) return pt.undefRef(result_ty);
2331923530
23320 const elems = try sema.arena.alloc(InternPool.Index, vec_len);23531 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
23321 const scalar_ty = operand_ty.scalarType(mod);23532 const scalar_ty = operand_ty.scalarType(mod);
23322 for (elems, 0..) |*elem, i| {23533 for (elems, 0..) |*elem, i| {
23323 const elem_val = try val.elemValue(mod, i);23534 const elem_val = try val.elemValue(pt, i);
23324 const count = comptimeOp(elem_val, scalar_ty, mod);23535 const count = comptimeOp(elem_val, scalar_ty, pt);
23325 elem.* = (try mod.intValue(result_scalar_ty, count)).toIntern();23536 elem.* = (try pt.intValue(result_scalar_ty, count)).toIntern();
23326 }23537 }
23327 return Air.internedToRef((try mod.intern(.{ .aggregate = .{23538 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
23328 .ty = result_ty.toIntern(),23539 .ty = result_ty.toIntern(),
23329 .storage = .{ .elems = elems },23540 .storage = .{ .elems = elems },
23330 } })));23541 } })));
...@@ -23335,8 +23546,8 @@ fn zirBitCount(...@@ -23335,8 +23546,8 @@ fn zirBitCount(
23335 },23546 },
23336 .Int => {23547 .Int => {
23337 if (try sema.resolveValueResolveLazy(operand)) |val| {23548 if (try sema.resolveValueResolveLazy(operand)) |val| {
23338 if (val.isUndef(mod)) return mod.undefRef(result_scalar_ty);23549 if (val.isUndef(mod)) return pt.undefRef(result_scalar_ty);
23339 return mod.intRef(result_scalar_ty, comptimeOp(val, operand_ty, mod));23550 return pt.intRef(result_scalar_ty, comptimeOp(val, operand_ty, pt));
23340 } else {23551 } else {
23341 try sema.requireRuntimeBlock(block, src, operand_src);23552 try sema.requireRuntimeBlock(block, src, operand_src);
23342 return block.addTyOp(air_tag, result_scalar_ty, operand);23553 return block.addTyOp(air_tag, result_scalar_ty, operand);
...@@ -23347,7 +23558,8 @@ fn zirBitCount(...@@ -23347,7 +23558,8 @@ fn zirBitCount(
23347}23558}
2334823559
23349fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {23560fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
23350 const mod = sema.mod;23561 const pt = sema.pt;
23562 const mod = pt.zcu;
23351 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;23563 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
23352 const src = block.nodeOffset(inst_data.src_node);23564 const src = block.nodeOffset(inst_data.src_node);
23353 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);23565 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
...@@ -23360,7 +23572,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -23360,7 +23572,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
23360 block,23572 block,
23361 operand_src,23573 operand_src,
23362 "@byteSwap requires the number of bits to be evenly divisible by 8, but {} has {} bits",23574 "@byteSwap requires the number of bits to be evenly divisible by 8, but {} has {} bits",
23363 .{ scalar_ty.fmt(mod), bits },23575 .{ scalar_ty.fmt(pt), bits },
23364 );23576 );
23365 }23577 }
2336623578
...@@ -23371,8 +23583,8 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -23371,8 +23583,8 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
23371 switch (operand_ty.zigTypeTag(mod)) {23583 switch (operand_ty.zigTypeTag(mod)) {
23372 .Int => {23584 .Int => {
23373 const runtime_src = if (try sema.resolveValue(operand)) |val| {23585 const runtime_src = if (try sema.resolveValue(operand)) |val| {
23374 if (val.isUndef(mod)) return mod.undefRef(operand_ty);23586 if (val.isUndef(mod)) return pt.undefRef(operand_ty);
23375 const result_val = try val.byteSwap(operand_ty, mod, sema.arena);23587 const result_val = try val.byteSwap(operand_ty, pt, sema.arena);
23376 return Air.internedToRef(result_val.toIntern());23588 return Air.internedToRef(result_val.toIntern());
23377 } else operand_src;23589 } else operand_src;
2337823590
...@@ -23382,15 +23594,15 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -23382,15 +23594,15 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
23382 .Vector => {23594 .Vector => {
23383 const runtime_src = if (try sema.resolveValue(operand)) |val| {23595 const runtime_src = if (try sema.resolveValue(operand)) |val| {
23384 if (val.isUndef(mod))23596 if (val.isUndef(mod))
23385 return mod.undefRef(operand_ty);23597 return pt.undefRef(operand_ty);
2338623598
23387 const vec_len = operand_ty.vectorLen(mod);23599 const vec_len = operand_ty.vectorLen(mod);
23388 const elems = try sema.arena.alloc(InternPool.Index, vec_len);23600 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
23389 for (elems, 0..) |*elem, i| {23601 for (elems, 0..) |*elem, i| {
23390 const elem_val = try val.elemValue(mod, i);23602 const elem_val = try val.elemValue(pt, i);
23391 elem.* = (try elem_val.byteSwap(scalar_ty, mod, sema.arena)).toIntern();23603 elem.* = (try elem_val.byteSwap(scalar_ty, pt, sema.arena)).toIntern();
23392 }23604 }
23393 return Air.internedToRef((try mod.intern(.{ .aggregate = .{23605 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
23394 .ty = operand_ty.toIntern(),23606 .ty = operand_ty.toIntern(),
23395 .storage = .{ .elems = elems },23607 .storage = .{ .elems = elems },
23396 } })));23608 } })));
...@@ -23415,12 +23627,13 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -23415,12 +23627,13 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
23415 return Air.internedToRef(val.toIntern());23627 return Air.internedToRef(val.toIntern());
23416 }23628 }
2341723629
23418 const mod = sema.mod;23630 const pt = sema.pt;
23631 const mod = pt.zcu;
23419 switch (operand_ty.zigTypeTag(mod)) {23632 switch (operand_ty.zigTypeTag(mod)) {
23420 .Int => {23633 .Int => {
23421 const runtime_src = if (try sema.resolveValue(operand)) |val| {23634 const runtime_src = if (try sema.resolveValue(operand)) |val| {
23422 if (val.isUndef(mod)) return mod.undefRef(operand_ty);23635 if (val.isUndef(mod)) return pt.undefRef(operand_ty);
23423 const result_val = try val.bitReverse(operand_ty, mod, sema.arena);23636 const result_val = try val.bitReverse(operand_ty, pt, sema.arena);
23424 return Air.internedToRef(result_val.toIntern());23637 return Air.internedToRef(result_val.toIntern());
23425 } else operand_src;23638 } else operand_src;
2342623639
...@@ -23430,15 +23643,15 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -23430,15 +23643,15 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
23430 .Vector => {23643 .Vector => {
23431 const runtime_src = if (try sema.resolveValue(operand)) |val| {23644 const runtime_src = if (try sema.resolveValue(operand)) |val| {
23432 if (val.isUndef(mod))23645 if (val.isUndef(mod))
23433 return mod.undefRef(operand_ty);23646 return pt.undefRef(operand_ty);
2343423647
23435 const vec_len = operand_ty.vectorLen(mod);23648 const vec_len = operand_ty.vectorLen(mod);
23436 const elems = try sema.arena.alloc(InternPool.Index, vec_len);23649 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
23437 for (elems, 0..) |*elem, i| {23650 for (elems, 0..) |*elem, i| {
23438 const elem_val = try val.elemValue(mod, i);23651 const elem_val = try val.elemValue(pt, i);
23439 elem.* = (try elem_val.bitReverse(scalar_ty, mod, sema.arena)).toIntern();23652 elem.* = (try elem_val.bitReverse(scalar_ty, pt, sema.arena)).toIntern();
23440 }23653 }
23441 return Air.internedToRef((try mod.intern(.{ .aggregate = .{23654 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
23442 .ty = operand_ty.toIntern(),23655 .ty = operand_ty.toIntern(),
23443 .storage = .{ .elems = elems },23656 .storage = .{ .elems = elems },
23444 } })));23657 } })));
...@@ -23453,13 +23666,13 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -23453,13 +23666,13 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2345323666
23454fn zirBitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {23667fn zirBitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
23455 const offset = try sema.bitOffsetOf(block, inst);23668 const offset = try sema.bitOffsetOf(block, inst);
23456 return sema.mod.intRef(Type.comptime_int, offset);23669 return sema.pt.intRef(Type.comptime_int, offset);
23457}23670}
2345823671
23459fn zirOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {23672fn zirOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
23460 const offset = try sema.bitOffsetOf(block, inst);23673 const offset = try sema.bitOffsetOf(block, inst);
23461 // TODO reminder to make this a compile error for packed structs23674 // TODO reminder to make this a compile error for packed structs
23462 return sema.mod.intRef(Type.comptime_int, offset / 8);23675 return sema.pt.intRef(Type.comptime_int, offset / 8);
23463}23676}
2346423677
23465fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u64 {23678fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u64 {
...@@ -23474,12 +23687,13 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -23474,12 +23687,13 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
23474 .needed_comptime_reason = "name of field must be comptime-known",23687 .needed_comptime_reason = "name of field must be comptime-known",
23475 });23688 });
2347623689
23477 const mod = sema.mod;23690 const pt = sema.pt;
23691 const mod = pt.zcu;
23478 const ip = &mod.intern_pool;23692 const ip = &mod.intern_pool;
23479 try ty.resolveLayout(mod);23693 try ty.resolveLayout(pt);
23480 switch (ty.zigTypeTag(mod)) {23694 switch (ty.zigTypeTag(mod)) {
23481 .Struct => {},23695 .Struct => {},
23482 else => return sema.fail(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(mod)}),23696 else => return sema.fail(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(pt)}),
23483 }23697 }
2348423698
23485 const field_index = if (ty.isTuple(mod)) blk: {23699 const field_index = if (ty.isTuple(mod)) blk: {
...@@ -23502,28 +23716,30 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -23502,28 +23716,30 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
23502 return bit_sum;23716 return bit_sum;
23503 }23717 }
23504 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);23718 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
23505 bit_sum += field_ty.bitSize(mod);23719 bit_sum += field_ty.bitSize(pt);
23506 } else unreachable;23720 } else unreachable;
23507 },23721 },
23508 else => return ty.structFieldOffset(field_index, mod) * 8,23722 else => return ty.structFieldOffset(field_index, pt) * 8,
23509 }23723 }
23510}23724}
2351123725
23512fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {23726fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
23513 const mod = sema.mod;23727 const pt = sema.pt;
23728 const mod = pt.zcu;
23514 switch (ty.zigTypeTag(mod)) {23729 switch (ty.zigTypeTag(mod)) {
23515 .Struct, .Enum, .Union, .Opaque => return,23730 .Struct, .Enum, .Union, .Opaque => return,
23516 else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty.fmt(mod)}),23731 else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty.fmt(pt)}),
23517 }23732 }
23518}23733}
2351923734
23520/// Returns `true` if the type was a comptime_int.23735/// Returns `true` if the type was a comptime_int.
23521fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {23736fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {
23522 const mod = sema.mod;23737 const pt = sema.pt;
23738 const mod = pt.zcu;
23523 switch (try ty.zigTypeTagOrPoison(mod)) {23739 switch (try ty.zigTypeTagOrPoison(mod)) {
23524 .ComptimeInt => return true,23740 .ComptimeInt => return true,
23525 .Int => return false,23741 .Int => return false,
23526 else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty.fmt(mod)}),23742 else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty.fmt(pt)}),
23527 }23743 }
23528}23744}
2352923745
...@@ -23533,7 +23749,8 @@ fn checkInvalidPtrArithmetic(...@@ -23533,7 +23749,8 @@ fn checkInvalidPtrArithmetic(
23533 src: LazySrcLoc,23749 src: LazySrcLoc,
23534 ty: Type,23750 ty: Type,
23535) CompileError!void {23751) CompileError!void {
23536 const mod = sema.mod;23752 const pt = sema.pt;
23753 const mod = pt.zcu;
23537 switch (try ty.zigTypeTagOrPoison(mod)) {23754 switch (try ty.zigTypeTagOrPoison(mod)) {
23538 .Pointer => switch (ty.ptrSize(mod)) {23755 .Pointer => switch (ty.ptrSize(mod)) {
23539 .One, .Slice => return,23756 .One, .Slice => return,
...@@ -23573,7 +23790,8 @@ fn checkPtrOperand(...@@ -23573,7 +23790,8 @@ fn checkPtrOperand(
23573 ty_src: LazySrcLoc,23790 ty_src: LazySrcLoc,
23574 ty: Type,23791 ty: Type,
23575) CompileError!void {23792) CompileError!void {
23576 const mod = sema.mod;23793 const pt = sema.pt;
23794 const mod = pt.zcu;
23577 switch (ty.zigTypeTag(mod)) {23795 switch (ty.zigTypeTag(mod)) {
23578 .Pointer => return,23796 .Pointer => return,
23579 .Fn => {23797 .Fn => {
...@@ -23581,7 +23799,7 @@ fn checkPtrOperand(...@@ -23581,7 +23799,7 @@ fn checkPtrOperand(
23581 const msg = try sema.errMsg(23799 const msg = try sema.errMsg(
23582 ty_src,23800 ty_src,
23583 "expected pointer, found '{}'",23801 "expected pointer, found '{}'",
23584 .{ty.fmt(mod)},23802 .{ty.fmt(pt)},
23585 );23803 );
23586 errdefer msg.destroy(sema.gpa);23804 errdefer msg.destroy(sema.gpa);
2358723805
...@@ -23594,7 +23812,7 @@ fn checkPtrOperand(...@@ -23594,7 +23812,7 @@ fn checkPtrOperand(
23594 .Optional => if (ty.childType(mod).zigTypeTag(mod) == .Pointer) return,23812 .Optional => if (ty.childType(mod).zigTypeTag(mod) == .Pointer) return,
23595 else => {},23813 else => {},
23596 }23814 }
23597 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(mod)});23815 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(pt)});
23598}23816}
2359923817
23600fn checkPtrType(23818fn checkPtrType(
...@@ -23604,7 +23822,8 @@ fn checkPtrType(...@@ -23604,7 +23822,8 @@ fn checkPtrType(
23604 ty: Type,23822 ty: Type,
23605 allow_slice: bool,23823 allow_slice: bool,
23606) CompileError!void {23824) CompileError!void {
23607 const mod = sema.mod;23825 const pt = sema.pt;
23826 const mod = pt.zcu;
23608 switch (ty.zigTypeTag(mod)) {23827 switch (ty.zigTypeTag(mod)) {
23609 .Pointer => if (allow_slice or !ty.isSlice(mod)) return,23828 .Pointer => if (allow_slice or !ty.isSlice(mod)) return,
23610 .Fn => {23829 .Fn => {
...@@ -23612,7 +23831,7 @@ fn checkPtrType(...@@ -23612,7 +23831,7 @@ fn checkPtrType(
23612 const msg = try sema.errMsg(23831 const msg = try sema.errMsg(
23613 ty_src,23832 ty_src,
23614 "expected pointer type, found '{}'",23833 "expected pointer type, found '{}'",
23615 .{ty.fmt(mod)},23834 .{ty.fmt(pt)},
23616 );23835 );
23617 errdefer msg.destroy(sema.gpa);23836 errdefer msg.destroy(sema.gpa);
2361823837
...@@ -23625,7 +23844,7 @@ fn checkPtrType(...@@ -23625,7 +23844,7 @@ fn checkPtrType(
23625 .Optional => if (ty.childType(mod).zigTypeTag(mod) == .Pointer) return,23844 .Optional => if (ty.childType(mod).zigTypeTag(mod) == .Pointer) return,
23626 else => {},23845 else => {},
23627 }23846 }
23628 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(mod)});23847 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(pt)});
23629}23848}
2363023849
23631fn checkVectorElemType(23850fn checkVectorElemType(
...@@ -23634,13 +23853,14 @@ fn checkVectorElemType(...@@ -23634,13 +23853,14 @@ fn checkVectorElemType(
23634 ty_src: LazySrcLoc,23853 ty_src: LazySrcLoc,
23635 ty: Type,23854 ty: Type,
23636) CompileError!void {23855) CompileError!void {
23637 const mod = sema.mod;23856 const pt = sema.pt;
23857 const mod = pt.zcu;
23638 switch (ty.zigTypeTag(mod)) {23858 switch (ty.zigTypeTag(mod)) {
23639 .Int, .Float, .Bool => return,23859 .Int, .Float, .Bool => return,
23640 .Optional, .Pointer => if (ty.isPtrAtRuntime(mod)) return,23860 .Optional, .Pointer => if (ty.isPtrAtRuntime(mod)) return,
23641 else => {},23861 else => {},
23642 }23862 }
23643 return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty.fmt(mod)});23863 return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty.fmt(pt)});
23644}23864}
2364523865
23646fn checkFloatType(23866fn checkFloatType(
...@@ -23649,10 +23869,11 @@ fn checkFloatType(...@@ -23649,10 +23869,11 @@ fn checkFloatType(
23649 ty_src: LazySrcLoc,23869 ty_src: LazySrcLoc,
23650 ty: Type,23870 ty: Type,
23651) CompileError!void {23871) CompileError!void {
23652 const mod = sema.mod;23872 const pt = sema.pt;
23873 const mod = pt.zcu;
23653 switch (ty.zigTypeTag(mod)) {23874 switch (ty.zigTypeTag(mod)) {
23654 .ComptimeInt, .ComptimeFloat, .Float => {},23875 .ComptimeInt, .ComptimeFloat, .Float => {},
23655 else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty.fmt(mod)}),23876 else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty.fmt(pt)}),
23656 }23877 }
23657}23878}
2365823879
...@@ -23662,14 +23883,15 @@ fn checkNumericType(...@@ -23662,14 +23883,15 @@ fn checkNumericType(
23662 ty_src: LazySrcLoc,23883 ty_src: LazySrcLoc,
23663 ty: Type,23884 ty: Type,
23664) CompileError!void {23885) CompileError!void {
23665 const mod = sema.mod;23886 const pt = sema.pt;
23887 const mod = pt.zcu;
23666 switch (ty.zigTypeTag(mod)) {23888 switch (ty.zigTypeTag(mod)) {
23667 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},23889 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},
23668 .Vector => switch (ty.childType(mod).zigTypeTag(mod)) {23890 .Vector => switch (ty.childType(mod).zigTypeTag(mod)) {
23669 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},23891 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},
23670 else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}),23892 else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}),
23671 },23893 },
23672 else => return sema.fail(block, ty_src, "expected number, found '{}'", .{ty.fmt(mod)}),23894 else => return sema.fail(block, ty_src, "expected number, found '{}'", .{ty.fmt(pt)}),
23673 }23895 }
23674}23896}
2367523897
...@@ -23683,7 +23905,8 @@ fn checkAtomicPtrOperand(...@@ -23683,7 +23905,8 @@ fn checkAtomicPtrOperand(
23683 ptr_src: LazySrcLoc,23905 ptr_src: LazySrcLoc,
23684 ptr_const: bool,23906 ptr_const: bool,
23685) CompileError!Air.Inst.Ref {23907) CompileError!Air.Inst.Ref {
23686 const mod = sema.mod;23908 const pt = sema.pt;
23909 const mod = pt.zcu;
23687 var diag: Module.AtomicPtrAlignmentDiagnostics = .{};23910 var diag: Module.AtomicPtrAlignmentDiagnostics = .{};
23688 const alignment = mod.atomicPtrAlignment(elem_ty, &diag) catch |err| switch (err) {23911 const alignment = mod.atomicPtrAlignment(elem_ty, &diag) catch |err| switch (err) {
23689 error.OutOfMemory => return error.OutOfMemory,23912 error.OutOfMemory => return error.OutOfMemory,
...@@ -23703,7 +23926,7 @@ fn checkAtomicPtrOperand(...@@ -23703,7 +23926,7 @@ fn checkAtomicPtrOperand(
23703 block,23926 block,
23704 elem_ty_src,23927 elem_ty_src,
23705 "expected bool, integer, float, enum, or pointer type; found '{}'",23928 "expected bool, integer, float, enum, or pointer type; found '{}'",
23706 .{elem_ty.fmt(mod)},23929 .{elem_ty.fmt(pt)},
23707 ),23930 ),
23708 };23931 };
2370923932
...@@ -23719,7 +23942,7 @@ fn checkAtomicPtrOperand(...@@ -23719,7 +23942,7 @@ fn checkAtomicPtrOperand(
23719 const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison(mod)) {23942 const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison(mod)) {
23720 .Pointer => ptr_ty.ptrInfo(mod),23943 .Pointer => ptr_ty.ptrInfo(mod),
23721 else => {23944 else => {
23722 const wanted_ptr_ty = try mod.ptrTypeSema(wanted_ptr_data);23945 const wanted_ptr_ty = try pt.ptrTypeSema(wanted_ptr_data);
23723 _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);23946 _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);
23724 unreachable;23947 unreachable;
23725 },23948 },
...@@ -23729,7 +23952,7 @@ fn checkAtomicPtrOperand(...@@ -23729,7 +23952,7 @@ fn checkAtomicPtrOperand(
23729 wanted_ptr_data.flags.is_allowzero = ptr_data.flags.is_allowzero;23952 wanted_ptr_data.flags.is_allowzero = ptr_data.flags.is_allowzero;
23730 wanted_ptr_data.flags.is_volatile = ptr_data.flags.is_volatile;23953 wanted_ptr_data.flags.is_volatile = ptr_data.flags.is_volatile;
2373123954
23732 const wanted_ptr_ty = try mod.ptrTypeSema(wanted_ptr_data);23955 const wanted_ptr_ty = try pt.ptrTypeSema(wanted_ptr_data);
23733 const casted_ptr = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);23956 const casted_ptr = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);
2373423957
23735 return casted_ptr;23958 return casted_ptr;
...@@ -23754,7 +23977,8 @@ fn checkIntOrVector(...@@ -23754,7 +23977,8 @@ fn checkIntOrVector(
23754 operand: Air.Inst.Ref,23977 operand: Air.Inst.Ref,
23755 operand_src: LazySrcLoc,23978 operand_src: LazySrcLoc,
23756) CompileError!Type {23979) CompileError!Type {
23757 const mod = sema.mod;23980 const pt = sema.pt;
23981 const mod = pt.zcu;
23758 const operand_ty = sema.typeOf(operand);23982 const operand_ty = sema.typeOf(operand);
23759 switch (try operand_ty.zigTypeTagOrPoison(mod)) {23983 switch (try operand_ty.zigTypeTagOrPoison(mod)) {
23760 .Int => return operand_ty,23984 .Int => return operand_ty,
...@@ -23763,12 +23987,12 @@ fn checkIntOrVector(...@@ -23763,12 +23987,12 @@ fn checkIntOrVector(
23763 switch (try elem_ty.zigTypeTagOrPoison(mod)) {23987 switch (try elem_ty.zigTypeTagOrPoison(mod)) {
23764 .Int => return elem_ty,23988 .Int => return elem_ty,
23765 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{23989 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
23766 elem_ty.fmt(mod),23990 elem_ty.fmt(pt),
23767 }),23991 }),
23768 }23992 }
23769 },23993 },
23770 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{23994 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{
23771 operand_ty.fmt(mod),23995 operand_ty.fmt(pt),
23772 }),23996 }),
23773 }23997 }
23774}23998}
...@@ -23779,7 +24003,8 @@ fn checkIntOrVectorAllowComptime(...@@ -23779,7 +24003,8 @@ fn checkIntOrVectorAllowComptime(
23779 operand_ty: Type,24003 operand_ty: Type,
23780 operand_src: LazySrcLoc,24004 operand_src: LazySrcLoc,
23781) CompileError!Type {24005) CompileError!Type {
23782 const mod = sema.mod;24006 const pt = sema.pt;
24007 const mod = pt.zcu;
23783 switch (try operand_ty.zigTypeTagOrPoison(mod)) {24008 switch (try operand_ty.zigTypeTagOrPoison(mod)) {
23784 .Int, .ComptimeInt => return operand_ty,24009 .Int, .ComptimeInt => return operand_ty,
23785 .Vector => {24010 .Vector => {
...@@ -23787,12 +24012,12 @@ fn checkIntOrVectorAllowComptime(...@@ -23787,12 +24012,12 @@ fn checkIntOrVectorAllowComptime(
23787 switch (try elem_ty.zigTypeTagOrPoison(mod)) {24012 switch (try elem_ty.zigTypeTagOrPoison(mod)) {
23788 .Int, .ComptimeInt => return elem_ty,24013 .Int, .ComptimeInt => return elem_ty,
23789 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{24014 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
23790 elem_ty.fmt(mod),24015 elem_ty.fmt(pt),
23791 }),24016 }),
23792 }24017 }
23793 },24018 },
23794 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{24019 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{
23795 operand_ty.fmt(mod),24020 operand_ty.fmt(pt),
23796 }),24021 }),
23797 }24022 }
23798}24023}
...@@ -23819,7 +24044,8 @@ fn checkSimdBinOp(...@@ -23819,7 +24044,8 @@ fn checkSimdBinOp(
23819 lhs_src: LazySrcLoc,24044 lhs_src: LazySrcLoc,
23820 rhs_src: LazySrcLoc,24045 rhs_src: LazySrcLoc,
23821) CompileError!SimdBinOp {24046) CompileError!SimdBinOp {
23822 const mod = sema.mod;24047 const pt = sema.pt;
24048 const mod = pt.zcu;
23823 const lhs_ty = sema.typeOf(uncasted_lhs);24049 const lhs_ty = sema.typeOf(uncasted_lhs);
23824 const rhs_ty = sema.typeOf(uncasted_rhs);24050 const rhs_ty = sema.typeOf(uncasted_rhs);
2382524051
...@@ -23851,7 +24077,8 @@ fn checkVectorizableBinaryOperands(...@@ -23851,7 +24077,8 @@ fn checkVectorizableBinaryOperands(
23851 lhs_src: LazySrcLoc,24077 lhs_src: LazySrcLoc,
23852 rhs_src: LazySrcLoc,24078 rhs_src: LazySrcLoc,
23853) CompileError!void {24079) CompileError!void {
23854 const mod = sema.mod;24080 const pt = sema.pt;
24081 const mod = pt.zcu;
23855 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);24082 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
23856 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);24083 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);
23857 if (lhs_zig_ty_tag != .Vector and rhs_zig_ty_tag != .Vector) return;24084 if (lhs_zig_ty_tag != .Vector and rhs_zig_ty_tag != .Vector) return;
...@@ -23881,7 +24108,7 @@ fn checkVectorizableBinaryOperands(...@@ -23881,7 +24108,7 @@ fn checkVectorizableBinaryOperands(
23881 } else {24108 } else {
23882 const msg = msg: {24109 const msg = msg: {
23883 const msg = try sema.errMsg(src, "mixed scalar and vector operands: '{}' and '{}'", .{24110 const msg = try sema.errMsg(src, "mixed scalar and vector operands: '{}' and '{}'", .{
23884 lhs_ty.fmt(mod), rhs_ty.fmt(mod),24111 lhs_ty.fmt(pt), rhs_ty.fmt(pt),
23885 });24112 });
23886 errdefer msg.destroy(sema.gpa);24113 errdefer msg.destroy(sema.gpa);
23887 if (lhs_is_vector) {24114 if (lhs_is_vector) {
...@@ -23903,10 +24130,11 @@ fn resolveExportOptions(...@@ -23903,10 +24130,11 @@ fn resolveExportOptions(
23903 src: LazySrcLoc,24130 src: LazySrcLoc,
23904 zir_ref: Zir.Inst.Ref,24131 zir_ref: Zir.Inst.Ref,
23905) CompileError!Module.Export.Options {24132) CompileError!Module.Export.Options {
23906 const mod = sema.mod;24133 const pt = sema.pt;
24134 const mod = pt.zcu;
23907 const gpa = sema.gpa;24135 const gpa = sema.gpa;
23908 const ip = &mod.intern_pool;24136 const ip = &mod.intern_pool;
23909 const export_options_ty = try mod.getBuiltinType("ExportOptions");24137 const export_options_ty = try pt.getBuiltinType("ExportOptions");
23910 const air_ref = try sema.resolveInst(zir_ref);24138 const air_ref = try sema.resolveInst(zir_ref);
23911 const options = try sema.coerce(block, export_options_ty, air_ref, src);24139 const options = try sema.coerce(block, export_options_ty, air_ref, src);
2391224140
...@@ -23969,12 +24197,12 @@ fn resolveBuiltinEnum(...@@ -23969,12 +24197,12 @@ fn resolveBuiltinEnum(
23969 comptime name: []const u8,24197 comptime name: []const u8,
23970 reason: NeededComptimeReason,24198 reason: NeededComptimeReason,
23971) CompileError!@field(std.builtin, name) {24199) CompileError!@field(std.builtin, name) {
23972 const mod = sema.mod;24200 const pt = sema.pt;
23973 const ty = try mod.getBuiltinType(name);24201 const ty = try pt.getBuiltinType(name);
23974 const air_ref = try sema.resolveInst(zir_ref);24202 const air_ref = try sema.resolveInst(zir_ref);
23975 const coerced = try sema.coerce(block, ty, air_ref, src);24203 const coerced = try sema.coerce(block, ty, air_ref, src);
23976 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);24204 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);
23977 return mod.toEnum(@field(std.builtin, name), val);24205 return pt.zcu.toEnum(@field(std.builtin, name), val);
23978}24206}
2397924207
23980fn resolveAtomicOrder(24208fn resolveAtomicOrder(
...@@ -24003,7 +24231,8 @@ fn zirCmpxchg(...@@ -24003,7 +24231,8 @@ fn zirCmpxchg(
24003 block: *Block,24231 block: *Block,
24004 extended: Zir.Inst.Extended.InstData,24232 extended: Zir.Inst.Extended.InstData,
24005) CompileError!Air.Inst.Ref {24233) CompileError!Air.Inst.Ref {
24006 const mod = sema.mod;24234 const pt = sema.pt;
24235 const mod = pt.zcu;
24007 const extra = sema.code.extraData(Zir.Inst.Cmpxchg, extended.operand).data;24236 const extra = sema.code.extraData(Zir.Inst.Cmpxchg, extended.operand).data;
24008 const air_tag: Air.Inst.Tag = switch (extended.small) {24237 const air_tag: Air.Inst.Tag = switch (extended.small) {
24009 0 => .cmpxchg_weak,24238 0 => .cmpxchg_weak,
...@@ -24026,7 +24255,7 @@ fn zirCmpxchg(...@@ -24026,7 +24255,7 @@ fn zirCmpxchg(
24026 block,24255 block,
24027 elem_ty_src,24256 elem_ty_src,
24028 "expected bool, integer, enum, or pointer type; found '{}'",24257 "expected bool, integer, enum, or pointer type; found '{}'",
24029 .{elem_ty.fmt(mod)},24258 .{elem_ty.fmt(pt)},
24030 );24259 );
24031 }24260 }
24032 const uncasted_ptr = try sema.resolveInst(extra.ptr);24261 const uncasted_ptr = try sema.resolveInst(extra.ptr);
...@@ -24052,11 +24281,11 @@ fn zirCmpxchg(...@@ -24052,11 +24281,11 @@ fn zirCmpxchg(
24052 return sema.fail(block, failure_order_src, "failure atomic ordering must not be release or acq_rel", .{});24281 return sema.fail(block, failure_order_src, "failure atomic ordering must not be release or acq_rel", .{});
24053 }24282 }
2405424283
24055 const result_ty = try mod.optionalType(elem_ty.toIntern());24284 const result_ty = try pt.optionalType(elem_ty.toIntern());
2405624285
24057 // special case zero bit types24286 // special case zero bit types
24058 if ((try sema.typeHasOnePossibleValue(elem_ty)) != null) {24287 if ((try sema.typeHasOnePossibleValue(elem_ty)) != null) {
24059 return Air.internedToRef((try mod.intern(.{ .opt = .{24288 return Air.internedToRef((try pt.intern(.{ .opt = .{
24060 .ty = result_ty.toIntern(),24289 .ty = result_ty.toIntern(),
24061 .val = .none,24290 .val = .none,
24062 } })));24291 } })));
...@@ -24068,11 +24297,11 @@ fn zirCmpxchg(...@@ -24068,11 +24297,11 @@ fn zirCmpxchg(
24068 if (expected_val.isUndef(mod) or new_val.isUndef(mod)) {24297 if (expected_val.isUndef(mod) or new_val.isUndef(mod)) {
24069 // TODO: this should probably cause the memory stored at the pointer24298 // TODO: this should probably cause the memory stored at the pointer
24070 // to become undef as well24299 // to become undef as well
24071 return mod.undefRef(result_ty);24300 return pt.undefRef(result_ty);
24072 }24301 }
24073 const ptr_ty = sema.typeOf(ptr);24302 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;24303 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 = .{24304 const result_val = try pt.intern(.{ .opt = .{
24076 .ty = result_ty.toIntern(),24305 .ty = result_ty.toIntern(),
24077 .val = if (stored_val.eql(expected_val, elem_ty, mod)) blk: {24306 .val = if (stored_val.eql(expected_val, elem_ty, mod)) blk: {
24078 try sema.storePtr(block, src, ptr, new_value);24307 try sema.storePtr(block, src, ptr, new_value);
...@@ -24103,17 +24332,18 @@ fn zirCmpxchg(...@@ -24103,17 +24332,18 @@ fn zirCmpxchg(
24103}24332}
2410424333
24105fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {24334fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
24106 const mod = sema.mod;24335 const pt = sema.pt;
24336 const mod = pt.zcu;
24107 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;24337 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;24338 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
24109 const src = block.nodeOffset(inst_data.src_node);24339 const src = block.nodeOffset(inst_data.src_node);
24110 const scalar_src = block.builtinCallArgSrc(inst_data.src_node, 0);24340 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");24341 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@splat");
2411224342
24113 if (!dest_ty.isVector(mod)) return sema.fail(block, src, "expected vector type, found '{}'", .{dest_ty.fmt(mod)});24343 if (!dest_ty.isVector(mod)) return sema.fail(block, src, "expected vector type, found '{}'", .{dest_ty.fmt(pt)});
2411424344
24115 if (!dest_ty.hasRuntimeBits(mod)) {24345 if (!dest_ty.hasRuntimeBits(pt)) {
24116 const empty_aggregate = try mod.intern(.{ .aggregate = .{24346 const empty_aggregate = try pt.intern(.{ .aggregate = .{
24117 .ty = dest_ty.toIntern(),24347 .ty = dest_ty.toIntern(),
24118 .storage = .{ .elems = &[_]InternPool.Index{} },24348 .storage = .{ .elems = &[_]InternPool.Index{} },
24119 } });24349 } });
...@@ -24124,7 +24354,7 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -24124,7 +24354,7 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
24124 const scalar_ty = dest_ty.childType(mod);24354 const scalar_ty = dest_ty.childType(mod);
24125 const scalar = try sema.coerce(block, scalar_ty, operand, scalar_src);24355 const scalar = try sema.coerce(block, scalar_ty, operand, scalar_src);
24126 if (try sema.resolveValue(scalar)) |scalar_val| {24356 if (try sema.resolveValue(scalar)) |scalar_val| {
24127 if (scalar_val.isUndef(mod)) return mod.undefRef(dest_ty);24357 if (scalar_val.isUndef(mod)) return pt.undefRef(dest_ty);
24128 return Air.internedToRef((try sema.splat(dest_ty, scalar_val)).toIntern());24358 return Air.internedToRef((try sema.splat(dest_ty, scalar_val)).toIntern());
24129 }24359 }
2413024360
...@@ -24142,10 +24372,11 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -24142,10 +24372,11 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
24142 });24372 });
24143 const operand = try sema.resolveInst(extra.rhs);24373 const operand = try sema.resolveInst(extra.rhs);
24144 const operand_ty = sema.typeOf(operand);24374 const operand_ty = sema.typeOf(operand);
24145 const mod = sema.mod;24375 const pt = sema.pt;
24376 const mod = pt.zcu;
2414624377
24147 if (operand_ty.zigTypeTag(mod) != .Vector) {24378 if (operand_ty.zigTypeTag(mod) != .Vector) {
24148 return sema.fail(block, operand_src, "expected vector, found '{}'", .{operand_ty.fmt(mod)});24379 return sema.fail(block, operand_src, "expected vector, found '{}'", .{operand_ty.fmt(pt)});
24149 }24380 }
2415024381
24151 const scalar_ty = operand_ty.childType(mod);24382 const scalar_ty = operand_ty.childType(mod);
...@@ -24155,13 +24386,13 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -24155,13 +24386,13 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
24155 .And, .Or, .Xor => switch (scalar_ty.zigTypeTag(mod)) {24386 .And, .Or, .Xor => switch (scalar_ty.zigTypeTag(mod)) {
24156 .Int, .Bool => {},24387 .Int, .Bool => {},
24157 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or boolean operand; found '{}'", .{24388 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or boolean operand; found '{}'", .{
24158 @tagName(operation), operand_ty.fmt(mod),24389 @tagName(operation), operand_ty.fmt(pt),
24159 }),24390 }),
24160 },24391 },
24161 .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag(mod)) {24392 .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag(mod)) {
24162 .Int, .Float => {},24393 .Int, .Float => {},
24163 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or float operand; found '{}'", .{24394 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or float operand; found '{}'", .{
24164 @tagName(operation), operand_ty.fmt(mod),24395 @tagName(operation), operand_ty.fmt(pt),
24165 }),24396 }),
24166 },24397 },
24167 }24398 }
...@@ -24174,20 +24405,20 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -24174,20 +24405,20 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
24174 }24405 }
2417524406
24176 if (try sema.resolveValue(operand)) |operand_val| {24407 if (try sema.resolveValue(operand)) |operand_val| {
24177 if (operand_val.isUndef(mod)) return mod.undefRef(scalar_ty);24408 if (operand_val.isUndef(mod)) return pt.undefRef(scalar_ty);
2417824409
24179 var accum: Value = try operand_val.elemValue(mod, 0);24410 var accum: Value = try operand_val.elemValue(pt, 0);
24180 var i: u32 = 1;24411 var i: u32 = 1;
24181 while (i < vec_len) : (i += 1) {24412 while (i < vec_len) : (i += 1) {
24182 const elem_val = try operand_val.elemValue(mod, i);24413 const elem_val = try operand_val.elemValue(pt, i);
24183 switch (operation) {24414 switch (operation) {
24184 .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena, mod),24415 .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),24416 .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),24417 .Xor => accum = try accum.bitwiseXor(elem_val, scalar_ty, sema.arena, pt),
24187 .Min => accum = accum.numberMin(elem_val, mod),24418 .Min => accum = accum.numberMin(elem_val, pt),
24188 .Max => accum = accum.numberMax(elem_val, mod),24419 .Max => accum = accum.numberMax(elem_val, pt),
24189 .Add => accum = try sema.numberAddWrapScalar(accum, elem_val, scalar_ty),24420 .Add => accum = try sema.numberAddWrapScalar(accum, elem_val, scalar_ty),
24190 .Mul => accum = try accum.numberMulWrap(elem_val, scalar_ty, sema.arena, mod),24421 .Mul => accum = try accum.numberMulWrap(elem_val, scalar_ty, sema.arena, pt),
24191 }24422 }
24192 }24423 }
24193 return Air.internedToRef(accum.toIntern());24424 return Air.internedToRef(accum.toIntern());
...@@ -24204,7 +24435,8 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -24204,7 +24435,8 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
24204}24435}
2420524436
24206fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {24437fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
24207 const mod = sema.mod;24438 const pt = sema.pt;
24439 const mod = pt.zcu;
24208 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;24440 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;24441 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);24442 const elem_ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);
...@@ -24219,9 +24451,9 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -24219,9 +24451,9 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2421924451
24220 const mask_len = switch (sema.typeOf(mask).zigTypeTag(mod)) {24452 const mask_len = switch (sema.typeOf(mask).zigTypeTag(mod)) {
24221 .Array, .Vector => sema.typeOf(mask).arrayLen(mod),24453 .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)}),24454 else => return sema.fail(block, mask_src, "expected vector or array, found '{}'", .{sema.typeOf(mask).fmt(pt)}),
24223 };24455 };
24224 mask_ty = try mod.vectorType(.{24456 mask_ty = try pt.vectorType(.{
24225 .len = @intCast(mask_len),24457 .len = @intCast(mask_len),
24226 .child = .i32_type,24458 .child = .i32_type,
24227 });24459 });
...@@ -24242,51 +24474,51 @@ fn analyzeShuffle(...@@ -24242,51 +24474,51 @@ fn analyzeShuffle(
24242 mask: Value,24474 mask: Value,
24243 mask_len: u32,24475 mask_len: u32,
24244) CompileError!Air.Inst.Ref {24476) CompileError!Air.Inst.Ref {
24245 const mod = sema.mod;24477 const pt = sema.pt;
24246 const a_src = block.builtinCallArgSrc(src_node, 1);24478 const a_src = block.builtinCallArgSrc(src_node, 1);
24247 const b_src = block.builtinCallArgSrc(src_node, 2);24479 const b_src = block.builtinCallArgSrc(src_node, 2);
24248 const mask_src = block.builtinCallArgSrc(src_node, 3);24480 const mask_src = block.builtinCallArgSrc(src_node, 3);
24249 var a = a_arg;24481 var a = a_arg;
24250 var b = b_arg;24482 var b = b_arg;
2425124483
24252 const res_ty = try mod.vectorType(.{24484 const res_ty = try pt.vectorType(.{
24253 .len = mask_len,24485 .len = mask_len,
24254 .child = elem_ty.toIntern(),24486 .child = elem_ty.toIntern(),
24255 });24487 });
2425624488
24257 const maybe_a_len = switch (sema.typeOf(a).zigTypeTag(mod)) {24489 const maybe_a_len = switch (sema.typeOf(a).zigTypeTag(pt.zcu)) {
24258 .Array, .Vector => sema.typeOf(a).arrayLen(mod),24490 .Array, .Vector => sema.typeOf(a).arrayLen(pt.zcu),
24259 .Undefined => null,24491 .Undefined => null,
24260 else => return sema.fail(block, a_src, "expected vector or array with element type '{}', found '{}'", .{24492 else => return sema.fail(block, a_src, "expected vector or array with element type '{}', found '{}'", .{
24261 elem_ty.fmt(sema.mod),24493 elem_ty.fmt(pt),
24262 sema.typeOf(a).fmt(sema.mod),24494 sema.typeOf(a).fmt(pt),
24263 }),24495 }),
24264 };24496 };
24265 const maybe_b_len = switch (sema.typeOf(b).zigTypeTag(mod)) {24497 const maybe_b_len = switch (sema.typeOf(b).zigTypeTag(pt.zcu)) {
24266 .Array, .Vector => sema.typeOf(b).arrayLen(mod),24498 .Array, .Vector => sema.typeOf(b).arrayLen(pt.zcu),
24267 .Undefined => null,24499 .Undefined => null,
24268 else => return sema.fail(block, b_src, "expected vector or array with element type '{}', found '{}'", .{24500 else => return sema.fail(block, b_src, "expected vector or array with element type '{}', found '{}'", .{
24269 elem_ty.fmt(sema.mod),24501 elem_ty.fmt(pt),
24270 sema.typeOf(b).fmt(sema.mod),24502 sema.typeOf(b).fmt(pt),
24271 }),24503 }),
24272 };24504 };
24273 if (maybe_a_len == null and maybe_b_len == null) {24505 if (maybe_a_len == null and maybe_b_len == null) {
24274 return mod.undefRef(res_ty);24506 return pt.undefRef(res_ty);
24275 }24507 }
24276 const a_len: u32 = @intCast(maybe_a_len orelse maybe_b_len.?);24508 const a_len: u32 = @intCast(maybe_a_len orelse maybe_b_len.?);
24277 const b_len: u32 = @intCast(maybe_b_len orelse a_len);24509 const b_len: u32 = @intCast(maybe_b_len orelse a_len);
2427824510
24279 const a_ty = try mod.vectorType(.{24511 const a_ty = try pt.vectorType(.{
24280 .len = a_len,24512 .len = a_len,
24281 .child = elem_ty.toIntern(),24513 .child = elem_ty.toIntern(),
24282 });24514 });
24283 const b_ty = try mod.vectorType(.{24515 const b_ty = try pt.vectorType(.{
24284 .len = b_len,24516 .len = b_len,
24285 .child = elem_ty.toIntern(),24517 .child = elem_ty.toIntern(),
24286 });24518 });
2428724519
24288 if (maybe_a_len == null) a = try mod.undefRef(a_ty) else a = try sema.coerce(block, a_ty, a, a_src);24520 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);24521 if (maybe_b_len == null) b = try pt.undefRef(b_ty) else b = try sema.coerce(block, b_ty, b, b_src);
2429024522
24291 const operand_info = [2]std.meta.Tuple(&.{ u64, LazySrcLoc, Type }){24523 const operand_info = [2]std.meta.Tuple(&.{ u64, LazySrcLoc, Type }){
24292 .{ a_len, a_src, a_ty },24524 .{ a_len, a_src, a_ty },
...@@ -24294,10 +24526,10 @@ fn analyzeShuffle(...@@ -24294,10 +24526,10 @@ fn analyzeShuffle(
24294 };24526 };
2429524527
24296 for (0..@intCast(mask_len)) |i| {24528 for (0..@intCast(mask_len)) |i| {
24297 const elem = try mask.elemValue(sema.mod, i);24529 const elem = try mask.elemValue(pt, i);
24298 if (elem.isUndef(mod)) continue;24530 if (elem.isUndef(pt.zcu)) continue;
24299 const elem_resolved = try sema.resolveLazyValue(elem);24531 const elem_resolved = try sema.resolveLazyValue(elem);
24300 const int = elem_resolved.toSignedInt(mod);24532 const int = elem_resolved.toSignedInt(pt);
24301 var unsigned: u32 = undefined;24533 var unsigned: u32 = undefined;
24302 var chosen: u32 = undefined;24534 var chosen: u32 = undefined;
24303 if (int >= 0) {24535 if (int >= 0) {
...@@ -24314,7 +24546,7 @@ fn analyzeShuffle(...@@ -24314,7 +24546,7 @@ fn analyzeShuffle(
2431424546
24315 try sema.errNote(operand_info[chosen][1], msg, "selected index '{d}' out of bounds of '{}'", .{24547 try sema.errNote(operand_info[chosen][1], msg, "selected index '{d}' out of bounds of '{}'", .{
24316 unsigned,24548 unsigned,
24317 operand_info[chosen][2].fmt(sema.mod),24549 operand_info[chosen][2].fmt(pt),
24318 });24550 });
2431924551
24320 if (chosen == 0) {24552 if (chosen == 0) {
...@@ -24331,16 +24563,16 @@ fn analyzeShuffle(...@@ -24331,16 +24563,16 @@ fn analyzeShuffle(
24331 if (try sema.resolveValue(b)) |b_val| {24563 if (try sema.resolveValue(b)) |b_val| {
24332 const values = try sema.arena.alloc(InternPool.Index, mask_len);24564 const values = try sema.arena.alloc(InternPool.Index, mask_len);
24333 for (values, 0..) |*value, i| {24565 for (values, 0..) |*value, i| {
24334 const mask_elem_val = try mask.elemValue(sema.mod, i);24566 const mask_elem_val = try mask.elemValue(pt, i);
24335 if (mask_elem_val.isUndef(mod)) {24567 if (mask_elem_val.isUndef(pt.zcu)) {
24336 value.* = try mod.intern(.{ .undef = elem_ty.toIntern() });24568 value.* = try pt.intern(.{ .undef = elem_ty.toIntern() });
24337 continue;24569 continue;
24338 }24570 }
24339 const int = mask_elem_val.toSignedInt(mod);24571 const int = mask_elem_val.toSignedInt(pt);
24340 const unsigned: u32 = @intCast(if (int >= 0) int else ~int);24572 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();24573 values[i] = (try (if (int >= 0) a_val else b_val).elemValue(pt, unsigned)).toIntern();
24342 }24574 }
24343 return Air.internedToRef((try mod.intern(.{ .aggregate = .{24575 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
24344 .ty = res_ty.toIntern(),24576 .ty = res_ty.toIntern(),
24345 .storage = .{ .elems = values },24577 .storage = .{ .elems = values },
24346 } })));24578 } })));
...@@ -24359,21 +24591,21 @@ fn analyzeShuffle(...@@ -24359,21 +24591,21 @@ fn analyzeShuffle(
2435924591
24360 const expand_mask_values = try sema.arena.alloc(InternPool.Index, max_len);24592 const expand_mask_values = try sema.arena.alloc(InternPool.Index, max_len);
24361 for (@intCast(0)..@intCast(min_len)) |i| {24593 for (@intCast(0)..@intCast(min_len)) |i| {
24362 expand_mask_values[i] = (try mod.intValue(Type.comptime_int, i)).toIntern();24594 expand_mask_values[i] = (try pt.intValue(Type.comptime_int, i)).toIntern();
24363 }24595 }
24364 for (@intCast(min_len)..@intCast(max_len)) |i| {24596 for (@intCast(min_len)..@intCast(max_len)) |i| {
24365 expand_mask_values[i] = (try mod.intValue(Type.comptime_int, -1)).toIntern();24597 expand_mask_values[i] = (try pt.intValue(Type.comptime_int, -1)).toIntern();
24366 }24598 }
24367 const expand_mask = try mod.intern(.{ .aggregate = .{24599 const expand_mask = try pt.intern(.{ .aggregate = .{
24368 .ty = (try mod.vectorType(.{ .len = @intCast(max_len), .child = .comptime_int_type })).toIntern(),24600 .ty = (try pt.vectorType(.{ .len = @intCast(max_len), .child = .comptime_int_type })).toIntern(),
24369 .storage = .{ .elems = expand_mask_values },24601 .storage = .{ .elems = expand_mask_values },
24370 } });24602 } });
2437124603
24372 if (a_len < b_len) {24604 if (a_len < b_len) {
24373 const undef = try mod.undefRef(a_ty);24605 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));24606 a = try sema.analyzeShuffle(block, src_node, elem_ty, a, undef, Value.fromInterned(expand_mask), @intCast(max_len));
24375 } else {24607 } else {
24376 const undef = try mod.undefRef(b_ty);24608 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));24609 b = try sema.analyzeShuffle(block, src_node, elem_ty, b, undef, Value.fromInterned(expand_mask), @intCast(max_len));
24378 }24610 }
24379 }24611 }
...@@ -24393,7 +24625,8 @@ fn analyzeShuffle(...@@ -24393,7 +24625,8 @@ fn analyzeShuffle(
24393}24625}
2439424626
24395fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {24627fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
24396 const mod = sema.mod;24628 const pt = sema.pt;
24629 const mod = pt.zcu;
24397 const extra = sema.code.extraData(Zir.Inst.Select, extended.operand).data;24630 const extra = sema.code.extraData(Zir.Inst.Select, extended.operand).data;
2439824631
24399 const src = block.nodeOffset(extra.node);24632 const src = block.nodeOffset(extra.node);
...@@ -24409,17 +24642,17 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -24409,17 +24642,17 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
2440924642
24410 const vec_len_u64 = switch (try pred_ty.zigTypeTagOrPoison(mod)) {24643 const vec_len_u64 = switch (try pred_ty.zigTypeTagOrPoison(mod)) {
24411 .Vector, .Array => pred_ty.arrayLen(mod),24644 .Vector, .Array => pred_ty.arrayLen(mod),
24412 else => return sema.fail(block, pred_src, "expected vector or array, found '{}'", .{pred_ty.fmt(mod)}),24645 else => return sema.fail(block, pred_src, "expected vector or array, found '{}'", .{pred_ty.fmt(pt)}),
24413 };24646 };
24414 const vec_len: u32 = @intCast(try sema.usizeCast(block, pred_src, vec_len_u64));24647 const vec_len: u32 = @intCast(try sema.usizeCast(block, pred_src, vec_len_u64));
2441524648
24416 const bool_vec_ty = try mod.vectorType(.{24649 const bool_vec_ty = try pt.vectorType(.{
24417 .len = vec_len,24650 .len = vec_len,
24418 .child = .bool_type,24651 .child = .bool_type,
24419 });24652 });
24420 const pred = try sema.coerce(block, bool_vec_ty, pred_uncoerced, pred_src);24653 const pred = try sema.coerce(block, bool_vec_ty, pred_uncoerced, pred_src);
2442124654
24422 const vec_ty = try mod.vectorType(.{24655 const vec_ty = try pt.vectorType(.{
24423 .len = vec_len,24656 .len = vec_len,
24424 .child = elem_ty.toIntern(),24657 .child = elem_ty.toIntern(),
24425 });24658 });
...@@ -24431,23 +24664,23 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -24431,23 +24664,23 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
24431 const maybe_b = try sema.resolveValue(b);24664 const maybe_b = try sema.resolveValue(b);
2443224665
24433 const runtime_src = if (maybe_pred) |pred_val| rs: {24666 const runtime_src = if (maybe_pred) |pred_val| rs: {
24434 if (pred_val.isUndef(mod)) return mod.undefRef(vec_ty);24667 if (pred_val.isUndef(mod)) return pt.undefRef(vec_ty);
2443524668
24436 if (maybe_a) |a_val| {24669 if (maybe_a) |a_val| {
24437 if (a_val.isUndef(mod)) return mod.undefRef(vec_ty);24670 if (a_val.isUndef(mod)) return pt.undefRef(vec_ty);
2443824671
24439 if (maybe_b) |b_val| {24672 if (maybe_b) |b_val| {
24440 if (b_val.isUndef(mod)) return mod.undefRef(vec_ty);24673 if (b_val.isUndef(mod)) return pt.undefRef(vec_ty);
2444124674
24442 const elems = try sema.gpa.alloc(InternPool.Index, vec_len);24675 const elems = try sema.gpa.alloc(InternPool.Index, vec_len);
24443 defer sema.gpa.free(elems);24676 defer sema.gpa.free(elems);
24444 for (elems, 0..) |*elem, i| {24677 for (elems, 0..) |*elem, i| {
24445 const pred_elem_val = try pred_val.elemValue(mod, i);24678 const pred_elem_val = try pred_val.elemValue(pt, i);
24446 const should_choose_a = pred_elem_val.toBool();24679 const should_choose_a = pred_elem_val.toBool();
24447 elem.* = (try (if (should_choose_a) a_val else b_val).elemValue(mod, i)).toIntern();24680 elem.* = (try (if (should_choose_a) a_val else b_val).elemValue(pt, i)).toIntern();
24448 }24681 }
2444924682
24450 return Air.internedToRef((try mod.intern(.{ .aggregate = .{24683 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
24451 .ty = vec_ty.toIntern(),24684 .ty = vec_ty.toIntern(),
24452 .storage = .{ .elems = elems },24685 .storage = .{ .elems = elems },
24453 } })));24686 } })));
...@@ -24456,16 +24689,16 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -24456,16 +24689,16 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
24456 }24689 }
24457 } else {24690 } else {
24458 if (maybe_b) |b_val| {24691 if (maybe_b) |b_val| {
24459 if (b_val.isUndef(mod)) return mod.undefRef(vec_ty);24692 if (b_val.isUndef(mod)) return pt.undefRef(vec_ty);
24460 }24693 }
24461 break :rs a_src;24694 break :rs a_src;
24462 }24695 }
24463 } else rs: {24696 } else rs: {
24464 if (maybe_a) |a_val| {24697 if (maybe_a) |a_val| {
24465 if (a_val.isUndef(mod)) return mod.undefRef(vec_ty);24698 if (a_val.isUndef(mod)) return pt.undefRef(vec_ty);
24466 }24699 }
24467 if (maybe_b) |b_val| {24700 if (maybe_b) |b_val| {
24468 if (b_val.isUndef(mod)) return mod.undefRef(vec_ty);24701 if (b_val.isUndef(mod)) return pt.undefRef(vec_ty);
24469 }24702 }
24470 break :rs pred_src;24703 break :rs pred_src;
24471 };24704 };
...@@ -24531,7 +24764,8 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -24531,7 +24764,8 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
24531}24764}
2453224765
24533fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {24766fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
24534 const mod = sema.mod;24767 const pt = sema.pt;
24768 const mod = pt.zcu;
24535 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;24769 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;24770 const extra = sema.code.extraData(Zir.Inst.AtomicRmw, inst_data.payload_index).data;
24537 const src = block.nodeOffset(inst_data.src_node);24771 const src = block.nodeOffset(inst_data.src_node);
...@@ -24588,12 +24822,12 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -24588,12 +24822,12 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
24588 .Xchg => operand_val,24822 .Xchg => operand_val,
24589 .Add => try sema.numberAddWrapScalar(stored_val, operand_val, elem_ty),24823 .Add => try sema.numberAddWrapScalar(stored_val, operand_val, elem_ty),
24590 .Sub => try sema.numberSubWrapScalar(stored_val, operand_val, elem_ty),24824 .Sub => try sema.numberSubWrapScalar(stored_val, operand_val, elem_ty),
24591 .And => try stored_val.bitwiseAnd (operand_val, elem_ty, sema.arena, mod),24825 .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),24826 .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),24827 .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),24828 .Xor => try stored_val.bitwiseXor (operand_val, elem_ty, sema.arena, pt),
24595 .Max => stored_val.numberMax (operand_val, mod),24829 .Max => stored_val.numberMax (operand_val, pt),
24596 .Min => stored_val.numberMin (operand_val, mod),24830 .Min => stored_val.numberMin (operand_val, pt),
24597 // zig fmt: on24831 // zig fmt: on
24598 };24832 };
24599 try sema.storePtrVal(block, src, ptr_val, new_val, elem_ty);24833 try sema.storePtrVal(block, src, ptr_val, new_val, elem_ty);
...@@ -24669,36 +24903,37 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -24669,36 +24903,37 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
24669 const maybe_mulend1 = try sema.resolveValue(mulend1);24903 const maybe_mulend1 = try sema.resolveValue(mulend1);
24670 const maybe_mulend2 = try sema.resolveValue(mulend2);24904 const maybe_mulend2 = try sema.resolveValue(mulend2);
24671 const maybe_addend = try sema.resolveValue(addend);24905 const maybe_addend = try sema.resolveValue(addend);
24672 const mod = sema.mod;24906 const pt = sema.pt;
24907 const mod = pt.zcu;
2467324908
24674 switch (ty.scalarType(mod).zigTypeTag(mod)) {24909 switch (ty.scalarType(mod).zigTypeTag(mod)) {
24675 .ComptimeFloat, .Float => {},24910 .ComptimeFloat, .Float => {},
24676 else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty.fmt(sema.mod)}),24911 else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty.fmt(pt)}),
24677 }24912 }
2467824913
24679 const runtime_src = if (maybe_mulend1) |mulend1_val| rs: {24914 const runtime_src = if (maybe_mulend1) |mulend1_val| rs: {
24680 if (maybe_mulend2) |mulend2_val| {24915 if (maybe_mulend2) |mulend2_val| {
24681 if (mulend2_val.isUndef(mod)) return mod.undefRef(ty);24916 if (mulend2_val.isUndef(mod)) return pt.undefRef(ty);
2468224917
24683 if (maybe_addend) |addend_val| {24918 if (maybe_addend) |addend_val| {
24684 if (addend_val.isUndef(mod)) return mod.undefRef(ty);24919 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);24920 const result_val = try Value.mulAdd(ty, mulend1_val, mulend2_val, addend_val, sema.arena, pt);
24686 return Air.internedToRef(result_val.toIntern());24921 return Air.internedToRef(result_val.toIntern());
24687 } else {24922 } else {
24688 break :rs addend_src;24923 break :rs addend_src;
24689 }24924 }
24690 } else {24925 } else {
24691 if (maybe_addend) |addend_val| {24926 if (maybe_addend) |addend_val| {
24692 if (addend_val.isUndef(mod)) return mod.undefRef(ty);24927 if (addend_val.isUndef(mod)) return pt.undefRef(ty);
24693 }24928 }
24694 break :rs mulend2_src;24929 break :rs mulend2_src;
24695 }24930 }
24696 } else rs: {24931 } else rs: {
24697 if (maybe_mulend2) |mulend2_val| {24932 if (maybe_mulend2) |mulend2_val| {
24698 if (mulend2_val.isUndef(mod)) return mod.undefRef(ty);24933 if (mulend2_val.isUndef(mod)) return pt.undefRef(ty);
24699 }24934 }
24700 if (maybe_addend) |addend_val| {24935 if (maybe_addend) |addend_val| {
24701 if (addend_val.isUndef(mod)) return mod.undefRef(ty);24936 if (addend_val.isUndef(mod)) return pt.undefRef(ty);
24702 }24937 }
24703 break :rs mulend1_src;24938 break :rs mulend1_src;
24704 };24939 };
...@@ -24720,7 +24955,8 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -24720,7 +24955,8 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
24720 const tracy = trace(@src());24955 const tracy = trace(@src());
24721 defer tracy.end();24956 defer tracy.end();
2472224957
24723 const mod = sema.mod;24958 const pt = sema.pt;
24959 const mod = pt.zcu;
24724 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;24960 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
24725 const modifier_src = block.builtinCallArgSrc(inst_data.src_node, 0);24961 const modifier_src = block.builtinCallArgSrc(inst_data.src_node, 0);
24726 const func_src = block.builtinCallArgSrc(inst_data.src_node, 1);24962 const func_src = block.builtinCallArgSrc(inst_data.src_node, 1);
...@@ -24730,7 +24966,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -24730,7 +24966,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;24966 const extra = sema.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data;
24731 const func = try sema.resolveInst(extra.callee);24967 const func = try sema.resolveInst(extra.callee);
2473224968
24733 const modifier_ty = try mod.getBuiltinType("CallModifier");24969 const modifier_ty = try pt.getBuiltinType("CallModifier");
24734 const air_ref = try sema.resolveInst(extra.modifier);24970 const air_ref = try sema.resolveInst(extra.modifier);
24735 const modifier_ref = try sema.coerce(block, modifier_ty, air_ref, modifier_src);24971 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, .{24972 const modifier_val = try sema.resolveConstDefinedValue(block, modifier_src, modifier_ref, .{
...@@ -24783,7 +25019,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -24783,7 +25019,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
2478325019
24784 const args_ty = sema.typeOf(args);25020 const args_ty = sema.typeOf(args);
24785 if (!args_ty.isTuple(mod) and args_ty.toIntern() != .empty_struct_type) {25021 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)});25022 return sema.fail(block, args_src, "expected a tuple, found '{}'", .{args_ty.fmt(pt)});
24787 }25023 }
2478825024
24789 const resolved_args: []Air.Inst.Ref = try sema.arena.alloc(Air.Inst.Ref, args_ty.structFieldCount(mod));25025 const resolved_args: []Air.Inst.Ref = try sema.arena.alloc(Air.Inst.Ref, args_ty.structFieldCount(mod));
...@@ -24812,7 +25048,8 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -24812,7 +25048,8 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
24812}25048}
2481325049
24814fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {25050fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
24815 const zcu = sema.mod;25051 const pt = sema.pt;
25052 const zcu = pt.zcu;
24816 const ip = &zcu.intern_pool;25053 const ip = &zcu.intern_pool;
2481725054
24818 const extra = sema.code.extraData(Zir.Inst.FieldParentPtr, extended.operand).data;25055 const extra = sema.code.extraData(Zir.Inst.FieldParentPtr, extended.operand).data;
...@@ -24827,14 +25064,14 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24827,14 +25064,14 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24827 try sema.checkPtrType(block, inst_src, parent_ptr_ty, true);25064 try sema.checkPtrType(block, inst_src, parent_ptr_ty, true);
24828 const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu);25065 const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu);
24829 if (parent_ptr_info.flags.size != .One) {25066 if (parent_ptr_info.flags.size != .One) {
24830 return sema.fail(block, inst_src, "expected single pointer type, found '{}'", .{parent_ptr_ty.fmt(zcu)});25067 return sema.fail(block, inst_src, "expected single pointer type, found '{}'", .{parent_ptr_ty.fmt(pt)});
24831 }25068 }
24832 const parent_ty = Type.fromInterned(parent_ptr_info.child);25069 const parent_ty = Type.fromInterned(parent_ptr_info.child);
24833 switch (parent_ty.zigTypeTag(zcu)) {25070 switch (parent_ty.zigTypeTag(zcu)) {
24834 .Struct, .Union => {},25071 .Struct, .Union => {},
24835 else => return sema.fail(block, inst_src, "expected pointer to struct or union type, found '{}'", .{parent_ptr_ty.fmt(zcu)}),25072 else => return sema.fail(block, inst_src, "expected pointer to struct or union type, found '{}'", .{parent_ptr_ty.fmt(pt)}),
24836 }25073 }
24837 try parent_ty.resolveLayout(zcu);25074 try parent_ty.resolveLayout(pt);
2483825075
24839 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{25076 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{
24840 .needed_comptime_reason = "field name must be comptime-known",25077 .needed_comptime_reason = "field name must be comptime-known",
...@@ -24865,7 +25102,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24865,7 +25102,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24865 var actual_parent_ptr_info: InternPool.Key.PtrType = .{25102 var actual_parent_ptr_info: InternPool.Key.PtrType = .{
24866 .child = parent_ty.toIntern(),25103 .child = parent_ty.toIntern(),
24867 .flags = .{25104 .flags = .{
24868 .alignment = try parent_ptr_ty.ptrAlignmentAdvanced(zcu, .sema),25105 .alignment = try parent_ptr_ty.ptrAlignmentAdvanced(pt, .sema),
24869 .is_const = field_ptr_info.flags.is_const,25106 .is_const = field_ptr_info.flags.is_const,
24870 .is_volatile = field_ptr_info.flags.is_volatile,25107 .is_volatile = field_ptr_info.flags.is_volatile,
24871 .is_allowzero = field_ptr_info.flags.is_allowzero,25108 .is_allowzero = field_ptr_info.flags.is_allowzero,
...@@ -24877,7 +25114,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24877,7 +25114,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24877 var actual_field_ptr_info: InternPool.Key.PtrType = .{25114 var actual_field_ptr_info: InternPool.Key.PtrType = .{
24878 .child = field_ty.toIntern(),25115 .child = field_ty.toIntern(),
24879 .flags = .{25116 .flags = .{
24880 .alignment = try field_ptr_ty.ptrAlignmentAdvanced(zcu, .sema),25117 .alignment = try field_ptr_ty.ptrAlignmentAdvanced(pt, .sema),
24881 .is_const = field_ptr_info.flags.is_const,25118 .is_const = field_ptr_info.flags.is_const,
24882 .is_volatile = field_ptr_info.flags.is_volatile,25119 .is_volatile = field_ptr_info.flags.is_volatile,
24883 .is_allowzero = field_ptr_info.flags.is_allowzero,25120 .is_allowzero = field_ptr_info.flags.is_allowzero,
...@@ -24888,13 +25125,13 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24888,13 +25125,13 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24888 switch (parent_ty.containerLayout(zcu)) {25125 switch (parent_ty.containerLayout(zcu)) {
24889 .auto => {25126 .auto => {
24890 actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(25127 actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(
24891 if (zcu.typeToStruct(parent_ty)) |struct_obj| try zcu.structFieldAlignmentAdvanced(25128 if (zcu.typeToStruct(parent_ty)) |struct_obj| try pt.structFieldAlignmentAdvanced(
24892 struct_obj.fieldAlign(ip, field_index),25129 struct_obj.fieldAlign(ip, field_index),
24893 field_ty,25130 field_ty,
24894 struct_obj.layout,25131 struct_obj.layout,
24895 .sema,25132 .sema,
24896 ) else if (zcu.typeToUnion(parent_ty)) |union_obj|25133 ) else if (zcu.typeToUnion(parent_ty)) |union_obj|
24897 try zcu.unionFieldNormalAlignmentAdvanced(union_obj, field_index, .sema)25134 try pt.unionFieldNormalAlignmentAdvanced(union_obj, field_index, .sema)
24898 else25135 else
24899 actual_field_ptr_info.flags.alignment,25136 actual_field_ptr_info.flags.alignment,
24900 );25137 );
...@@ -24903,7 +25140,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24903,7 +25140,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 };25140 actual_field_ptr_info.packed_offset = .{ .bit_offset = 0, .host_size = 0 };
24904 },25141 },
24905 .@"extern" => {25142 .@"extern" => {
24906 const field_offset = parent_ty.structFieldOffset(field_index, zcu);25143 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)25144 actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(if (field_offset > 0)
24908 Alignment.fromLog2Units(@ctz(field_offset))25145 Alignment.fromLog2Units(@ctz(field_offset))
24909 else25146 else
...@@ -24914,7 +25151,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24914,7 +25151,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24914 },25151 },
24915 .@"packed" => {25152 .@"packed" => {
24916 const byte_offset = std.math.divExact(u32, @abs(@as(i32, actual_parent_ptr_info.packed_offset.bit_offset) +25153 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) -25154 (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) catch25155 actual_field_ptr_info.packed_offset.bit_offset), 8) catch
24919 return sema.fail(block, inst_src, "pointer bit-offset mismatch", .{});25156 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)25157 actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(if (byte_offset > 0)
...@@ -24924,16 +25161,16 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24924,16 +25161,16 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24924 },25161 },
24925 }25162 }
2492625163
24927 const actual_field_ptr_ty = try zcu.ptrTypeSema(actual_field_ptr_info);25164 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);25165 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);25166 const actual_parent_ptr_ty = try pt.ptrTypeSema(actual_parent_ptr_info);
2493025167
24931 const result = if (try sema.resolveDefinedValue(block, field_ptr_src, casted_field_ptr)) |field_ptr_val| result: {25168 const result = if (try sema.resolveDefinedValue(block, field_ptr_src, casted_field_ptr)) |field_ptr_val| result: {
24932 switch (parent_ty.zigTypeTag(zcu)) {25169 switch (parent_ty.zigTypeTag(zcu)) {
24933 .Struct => switch (parent_ty.containerLayout(zcu)) {25170 .Struct => switch (parent_ty.containerLayout(zcu)) {
24934 .auto => {},25171 .auto => {},
24935 .@"extern" => {25172 .@"extern" => {
24936 const byte_offset = parent_ty.structFieldOffset(field_index, zcu);25173 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);25174 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());25175 break :result Air.internedToRef(parent_ptr_val.toIntern());
24939 },25176 },
...@@ -24941,7 +25178,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24941,7 +25178,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.25178 // Logic lifted from type computation above - I'm just assuming it's correct.
24942 // `catch unreachable` since error case handled above.25179 // `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) +25180 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) -25181 pt.structPackedFieldBitOffset(zcu.typeToStruct(parent_ty).?, field_index) -
24945 actual_field_ptr_info.packed_offset.bit_offset), 8) catch unreachable;25182 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);25183 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());25184 break :result Air.internedToRef(parent_ptr_val.toIntern());
...@@ -24951,7 +25188,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24951,7 +25188,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24951 .auto => {},25188 .auto => {},
24952 .@"extern", .@"packed" => {25189 .@"extern", .@"packed" => {
24953 // For an extern or packed union, just coerce the pointer.25190 // 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);25191 const parent_ptr_val = try pt.getCoerced(field_ptr_val, actual_parent_ptr_ty);
24955 break :result Air.internedToRef(parent_ptr_val.toIntern());25192 break :result Air.internedToRef(parent_ptr_val.toIntern());
24956 },25193 },
24957 },25194 },
...@@ -24980,7 +25217,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24980,7 +25217,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
2498025217
24981 if (field.index != field_index) {25218 if (field.index != field_index) {
24982 return sema.fail(block, inst_src, "field '{}' has index '{d}' but pointer value is index '{d}' of struct '{}'", .{25219 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),25220 field_name.fmt(ip), field_index, field.index, parent_ty.fmt(pt),
24984 });25221 });
24985 }25222 }
24986 break :result try sema.coerce(block, actual_parent_ptr_ty, Air.internedToRef(field.base), inst_src);25223 break :result try sema.coerce(block, actual_parent_ptr_ty, Air.internedToRef(field.base), inst_src);
...@@ -25001,8 +25238,9 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -25001,8 +25238,9 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
25001}25238}
2500225239
25003fn ptrSubtract(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, byte_subtract: u64, new_ty: Type) !Value {25240fn ptrSubtract(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, byte_subtract: u64, new_ty: Type) !Value {
25004 const zcu = sema.mod;25241 const pt = sema.pt;
25005 if (byte_subtract == 0) return zcu.getCoerced(ptr_val, new_ty);25242 const zcu = pt.zcu;
25243 if (byte_subtract == 0) return pt.getCoerced(ptr_val, new_ty);
25006 var ptr = switch (zcu.intern_pool.indexToKey(ptr_val.toIntern())) {25244 var ptr = switch (zcu.intern_pool.indexToKey(ptr_val.toIntern())) {
25007 .undef => return sema.failWithUseOfUndef(block, src),25245 .undef => return sema.failWithUseOfUndef(block, src),
25008 .ptr => |ptr| ptr,25246 .ptr => |ptr| ptr,
...@@ -25018,7 +25256,7 @@ fn ptrSubtract(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, byte...@@ -25018,7 +25256,7 @@ fn ptrSubtract(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, byte
25018 }25256 }
25019 ptr.byte_offset -= byte_subtract;25257 ptr.byte_offset -= byte_subtract;
25020 ptr.ty = new_ty.toIntern();25258 ptr.ty = new_ty.toIntern();
25021 return Value.fromInterned(try zcu.intern(.{ .ptr = ptr }));25259 return Value.fromInterned(try pt.intern(.{ .ptr = ptr }));
25022}25260}
2502325261
25024fn zirMinMax(25262fn zirMinMax(
...@@ -25072,7 +25310,8 @@ fn analyzeMinMax(...@@ -25072,7 +25310,8 @@ fn analyzeMinMax(
25072) CompileError!Air.Inst.Ref {25310) CompileError!Air.Inst.Ref {
25073 assert(operands.len == operand_srcs.len);25311 assert(operands.len == operand_srcs.len);
25074 assert(operands.len > 0);25312 assert(operands.len > 0);
25075 const mod = sema.mod;25313 const pt = sema.pt;
25314 const mod = pt.zcu;
2507625315
25077 if (operands.len == 1) return operands[0];25316 if (operands.len == 1) return operands[0];
2507825317
...@@ -25115,15 +25354,15 @@ fn analyzeMinMax(...@@ -25115,15 +25354,15 @@ fn analyzeMinMax(
25115 break :refine_bounds;25354 break :refine_bounds;
25116 }25355 }
25117 const scalar_bounds: ?[2]Value = bounds: {25356 const scalar_bounds: ?[2]Value = bounds: {
25118 if (!ty.isVector(mod)) break :bounds try uncoerced_val.intValueBounds(mod);25357 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;25358 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));25359 const len = try sema.usizeCast(block, src, ty.vectorLen(mod));
25121 for (1..len) |i| {25360 for (1..len) |i| {
25122 const elem = try uncoerced_val.elemValue(mod, i);25361 const elem = try uncoerced_val.elemValue(pt, i);
25123 const elem_bounds = try elem.intValueBounds(mod) orelse break :bounds null;25362 const elem_bounds = try elem.intValueBounds(pt) orelse break :bounds null;
25124 cur_bounds = .{25363 cur_bounds = .{
25125 Value.numberMin(elem_bounds[0], cur_bounds[0], mod),25364 Value.numberMin(elem_bounds[0], cur_bounds[0], pt),
25126 Value.numberMax(elem_bounds[1], cur_bounds[1], mod),25365 Value.numberMax(elem_bounds[1], cur_bounds[1], pt),
25127 };25366 };
25128 }25367 }
25129 break :bounds cur_bounds;25368 break :bounds cur_bounds;
...@@ -25134,8 +25373,8 @@ fn analyzeMinMax(...@@ -25134,8 +25373,8 @@ fn analyzeMinMax(
25134 cur_max_scalar = bounds[1];25373 cur_max_scalar = bounds[1];
25135 bounds_status = .defined;25374 bounds_status = .defined;
25136 } else {25375 } else {
25137 cur_min_scalar = opFunc(cur_min_scalar, bounds[0], mod);25376 cur_min_scalar = opFunc(cur_min_scalar, bounds[0], pt);
25138 cur_max_scalar = opFunc(cur_max_scalar, bounds[1], mod);25377 cur_max_scalar = opFunc(cur_max_scalar, bounds[1], pt);
25139 }25378 }
25140 }25379 }
25141 },25380 },
...@@ -25153,18 +25392,18 @@ fn analyzeMinMax(...@@ -25153,18 +25392,18 @@ fn analyzeMinMax(
25153 const operand_val = try sema.resolveLazyValue(simd_op.rhs_val.?); // we checked the operand was resolvable above25392 const operand_val = try sema.resolveLazyValue(simd_op.rhs_val.?); // we checked the operand was resolvable above
2515425393
25155 const vec_len = simd_op.len orelse {25394 const vec_len = simd_op.len orelse {
25156 const result_val = opFunc(cur_val, operand_val, mod);25395 const result_val = opFunc(cur_val, operand_val, pt);
25157 cur_minmax = Air.internedToRef(result_val.toIntern());25396 cur_minmax = Air.internedToRef(result_val.toIntern());
25158 continue;25397 continue;
25159 };25398 };
25160 const elems = try sema.arena.alloc(InternPool.Index, vec_len);25399 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
25161 for (elems, 0..) |*elem, i| {25400 for (elems, 0..) |*elem, i| {
25162 const lhs_elem_val = try cur_val.elemValue(mod, i);25401 const lhs_elem_val = try cur_val.elemValue(pt, i);
25163 const rhs_elem_val = try operand_val.elemValue(mod, i);25402 const rhs_elem_val = try operand_val.elemValue(pt, i);
25164 const uncoerced_elem = opFunc(lhs_elem_val, rhs_elem_val, mod);25403 const uncoerced_elem = opFunc(lhs_elem_val, rhs_elem_val, pt);
25165 elem.* = (try mod.getCoerced(uncoerced_elem, simd_op.scalar_ty)).toIntern();25404 elem.* = (try pt.getCoerced(uncoerced_elem, simd_op.scalar_ty)).toIntern();
25166 }25405 }
25167 cur_minmax = Air.internedToRef((try mod.intern(.{ .aggregate = .{25406 cur_minmax = Air.internedToRef((try pt.intern(.{ .aggregate = .{
25168 .ty = simd_op.result_ty.toIntern(),25407 .ty = simd_op.result_ty.toIntern(),
25169 .storage = .{ .elems = elems },25408 .storage = .{ .elems = elems },
25170 } })));25409 } })));
...@@ -25191,8 +25430,8 @@ fn analyzeMinMax(...@@ -25191,8 +25430,8 @@ fn analyzeMinMax(
2519125430
25192 assert(bounds_status == .defined); // there was a non-comptime-int integral comptime-known arg25431 assert(bounds_status == .defined); // there was a non-comptime-int integral comptime-known arg
2519325432
25194 const refined_scalar_ty = try mod.intFittingRange(cur_min_scalar, cur_max_scalar);25433 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(.{25434 const refined_ty = if (orig_ty.isVector(mod)) try pt.vectorType(.{
25196 .len = orig_ty.vectorLen(mod),25435 .len = orig_ty.vectorLen(mod),
25197 .child = refined_scalar_ty.toIntern(),25436 .child = refined_scalar_ty.toIntern(),
25198 }) else refined_scalar_ty;25437 }) else refined_scalar_ty;
...@@ -25226,8 +25465,8 @@ fn analyzeMinMax(...@@ -25226,8 +25465,8 @@ fn analyzeMinMax(
25226 runtime_known.unset(0); // don't look at this operand in the loop below25465 runtime_known.unset(0); // don't look at this operand in the loop below
25227 const scalar_ty = sema.typeOf(cur_minmax.?).scalarType(mod);25466 const scalar_ty = sema.typeOf(cur_minmax.?).scalarType(mod);
25228 if (scalar_ty.isInt(mod)) {25467 if (scalar_ty.isInt(mod)) {
25229 cur_min_scalar = try scalar_ty.minInt(mod, scalar_ty);25468 cur_min_scalar = try scalar_ty.minInt(pt, scalar_ty);
25230 cur_max_scalar = try scalar_ty.maxInt(mod, scalar_ty);25469 cur_max_scalar = try scalar_ty.maxInt(pt, scalar_ty);
25231 bounds_status = .defined;25470 bounds_status = .defined;
25232 } else {25471 } else {
25233 bounds_status = .non_integral;25472 bounds_status = .non_integral;
...@@ -25242,7 +25481,7 @@ fn analyzeMinMax(...@@ -25242,7 +25481,7 @@ fn analyzeMinMax(
25242 const rhs_src = operand_srcs[idx];25481 const rhs_src = operand_srcs[idx];
25243 const simd_op = try sema.checkSimdBinOp(block, src, lhs, rhs, lhs_src, rhs_src);25482 const simd_op = try sema.checkSimdBinOp(block, src, lhs, rhs, lhs_src, rhs_src);
25244 if (known_undef) {25483 if (known_undef) {
25245 cur_minmax = try mod.undefRef(simd_op.result_ty);25484 cur_minmax = try pt.undefRef(simd_op.result_ty);
25246 } else {25485 } else {
25247 cur_minmax = try block.addBinOp(air_tag, simd_op.lhs, simd_op.rhs);25486 cur_minmax = try block.addBinOp(air_tag, simd_op.lhs, simd_op.rhs);
25248 }25487 }
...@@ -25254,15 +25493,15 @@ fn analyzeMinMax(...@@ -25254,15 +25493,15 @@ fn analyzeMinMax(
25254 bounds_status = .non_integral;25493 bounds_status = .non_integral;
25255 break :refine_bounds;25494 break :refine_bounds;
25256 }25495 }
25257 const scalar_min = try scalar_ty.minInt(mod, scalar_ty);25496 const scalar_min = try scalar_ty.minInt(pt, scalar_ty);
25258 const scalar_max = try scalar_ty.maxInt(mod, scalar_ty);25497 const scalar_max = try scalar_ty.maxInt(pt, scalar_ty);
25259 if (bounds_status == .unknown) {25498 if (bounds_status == .unknown) {
25260 cur_min_scalar = scalar_min;25499 cur_min_scalar = scalar_min;
25261 cur_max_scalar = scalar_max;25500 cur_max_scalar = scalar_max;
25262 bounds_status = .defined;25501 bounds_status = .defined;
25263 } else {25502 } else {
25264 cur_min_scalar = opFunc(cur_min_scalar, scalar_min, mod);25503 cur_min_scalar = opFunc(cur_min_scalar, scalar_min, pt);
25265 cur_max_scalar = opFunc(cur_max_scalar, scalar_max, mod);25504 cur_max_scalar = opFunc(cur_max_scalar, scalar_max, pt);
25266 }25505 }
25267 },25506 },
25268 .non_integral => {},25507 .non_integral => {},
...@@ -25276,8 +25515,8 @@ fn analyzeMinMax(...@@ -25276,8 +25515,8 @@ fn analyzeMinMax(
25276 return cur_minmax.?;25515 return cur_minmax.?;
25277 }25516 }
25278 assert(bounds_status == .defined); // there were integral runtime operands25517 assert(bounds_status == .defined); // there were integral runtime operands
25279 const refined_scalar_ty = try mod.intFittingRange(cur_min_scalar, cur_max_scalar);25518 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(.{25519 const refined_ty = if (unrefined_ty.isVector(mod)) try pt.vectorType(.{
25281 .len = unrefined_ty.vectorLen(mod),25520 .len = unrefined_ty.vectorLen(mod),
25282 .child = refined_scalar_ty.toIntern(),25521 .child = refined_scalar_ty.toIntern(),
25283 }) else refined_scalar_ty;25522 }) else refined_scalar_ty;
...@@ -25291,15 +25530,16 @@ fn analyzeMinMax(...@@ -25291,15 +25530,16 @@ fn analyzeMinMax(
25291}25530}
2529225531
25293fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !Air.Inst.Ref {25532fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !Air.Inst.Ref {
25294 const mod = sema.mod;25533 const pt = sema.pt;
25534 const mod = pt.zcu;
25295 const ptr_ty = sema.typeOf(ptr);25535 const ptr_ty = sema.typeOf(ptr);
25296 const info = ptr_ty.ptrInfo(mod);25536 const info = ptr_ty.ptrInfo(mod);
25297 if (info.flags.size == .One) {25537 if (info.flags.size == .One) {
25298 // Already an array pointer.25538 // Already an array pointer.
25299 return ptr;25539 return ptr;
25300 }25540 }
25301 const new_ty = try mod.ptrTypeSema(.{25541 const new_ty = try pt.ptrTypeSema(.{
25302 .child = (try mod.arrayType(.{25542 .child = (try pt.arrayType(.{
25303 .len = len,25543 .len = len,
25304 .sentinel = info.sentinel,25544 .sentinel = info.sentinel,
25305 .child = info.child,25545 .child = info.child,
...@@ -25331,8 +25571,9 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25331,8 +25571,9 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25331 const src_ty = sema.typeOf(src_ptr);25571 const src_ty = sema.typeOf(src_ptr);
25332 const dest_len = try indexablePtrLenOrNone(sema, block, dest_src, dest_ptr);25572 const dest_len = try indexablePtrLenOrNone(sema, block, dest_src, dest_ptr);
25333 const src_len = try indexablePtrLenOrNone(sema, block, src_src, src_ptr);25573 const src_len = try indexablePtrLenOrNone(sema, block, src_src, src_ptr);
25334 const target = sema.mod.getTarget();25574 const pt = sema.pt;
25335 const mod = sema.mod;25575 const mod = pt.zcu;
25576 const target = mod.getTarget();
2533625577
25337 if (dest_ty.isConstPtr(mod)) {25578 if (dest_ty.isConstPtr(mod)) {
25338 return sema.fail(block, dest_src, "cannot memcpy to constant pointer", .{});25579 return sema.fail(block, dest_src, "cannot memcpy to constant pointer", .{});
...@@ -25343,10 +25584,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25343,10 +25584,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25343 const msg = try sema.errMsg(src, "unknown @memcpy length", .{});25584 const msg = try sema.errMsg(src, "unknown @memcpy length", .{});
25344 errdefer msg.destroy(sema.gpa);25585 errdefer msg.destroy(sema.gpa);
25345 try sema.errNote(dest_src, msg, "destination type '{}' provides no length", .{25586 try sema.errNote(dest_src, msg, "destination type '{}' provides no length", .{
25346 dest_ty.fmt(sema.mod),25587 dest_ty.fmt(pt),
25347 });25588 });
25348 try sema.errNote(src_src, msg, "source type '{}' provides no length", .{25589 try sema.errNote(src_src, msg, "source type '{}' provides no length", .{
25349 src_ty.fmt(sema.mod),25590 src_ty.fmt(pt),
25350 });25591 });
25351 break :msg msg;25592 break :msg msg;
25352 };25593 };
...@@ -25365,10 +25606,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25365,10 +25606,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25365 const msg = try sema.errMsg(src, "non-matching @memcpy lengths", .{});25606 const msg = try sema.errMsg(src, "non-matching @memcpy lengths", .{});
25366 errdefer msg.destroy(sema.gpa);25607 errdefer msg.destroy(sema.gpa);
25367 try sema.errNote(dest_src, msg, "length {} here", .{25608 try sema.errNote(dest_src, msg, "length {} here", .{
25368 dest_len_val.fmtValue(sema.mod, sema),25609 dest_len_val.fmtValue(pt, sema),
25369 });25610 });
25370 try sema.errNote(src_src, msg, "length {} here", .{25611 try sema.errNote(src_src, msg, "length {} here", .{
25371 src_len_val.fmtValue(sema.mod, sema),25612 src_len_val.fmtValue(pt, sema),
25372 });25613 });
25373 break :msg msg;25614 break :msg msg;
25374 };25615 };
...@@ -25397,10 +25638,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25397,10 +25638,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: {25638 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;25639 if (!sema.isComptimeMutablePtr(dest_ptr_val)) break :rs dest_src;
25399 if (try sema.resolveDefinedValue(block, src_src, src_ptr)) |_| {25640 if (try sema.resolveDefinedValue(block, src_src, src_ptr)) |_| {
25400 const len_u64 = (try len_val.?.getUnsignedIntAdvanced(mod, .sema)).?;25641 const len_u64 = (try len_val.?.getUnsignedIntAdvanced(pt, .sema)).?;
25401 const len = try sema.usizeCast(block, dest_src, len_u64);25642 const len = try sema.usizeCast(block, dest_src, len_u64);
25402 for (0..len) |i| {25643 for (0..len) |i| {
25403 const elem_index = try mod.intRef(Type.usize, i);25644 const elem_index = try pt.intRef(Type.usize, i);
25404 const dest_elem_ptr = try sema.elemPtrOneLayerOnly(25645 const dest_elem_ptr = try sema.elemPtrOneLayerOnly(
25405 block,25646 block,
25406 src,25647 src,
...@@ -25456,7 +25697,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25456,7 +25697,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25456 var new_dest_ptr = dest_ptr;25697 var new_dest_ptr = dest_ptr;
25457 var new_src_ptr = src_ptr;25698 var new_src_ptr = src_ptr;
25458 if (len_val) |val| {25699 if (len_val) |val| {
25459 const len = try val.toUnsignedIntSema(mod);25700 const len = try val.toUnsignedIntSema(pt);
25460 if (len == 0) {25701 if (len == 0) {
25461 // This AIR instruction guarantees length > 0 if it is comptime-known.25702 // This AIR instruction guarantees length > 0 if it is comptime-known.
25462 return;25703 return;
...@@ -25503,7 +25744,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25503,7 +25744,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25503 assert(dest_manyptr_ty_key.flags.size == .One);25744 assert(dest_manyptr_ty_key.flags.size == .One);
25504 dest_manyptr_ty_key.child = dest_elem_ty.toIntern();25745 dest_manyptr_ty_key.child = dest_elem_ty.toIntern();
25505 dest_manyptr_ty_key.flags.size = .Many;25746 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);25747 break :ptr try sema.coerceCompatiblePtrs(block, try pt.ptrTypeSema(dest_manyptr_ty_key), new_dest_ptr, dest_src);
25507 } else new_dest_ptr;25748 } else new_dest_ptr;
2550825749
25509 const new_src_ptr_ty = sema.typeOf(new_src_ptr);25750 const new_src_ptr_ty = sema.typeOf(new_src_ptr);
...@@ -25514,7 +25755,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25514,7 +25755,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25514 assert(src_manyptr_ty_key.flags.size == .One);25755 assert(src_manyptr_ty_key.flags.size == .One);
25515 src_manyptr_ty_key.child = src_elem_ty.toIntern();25756 src_manyptr_ty_key.child = src_elem_ty.toIntern();
25516 src_manyptr_ty_key.flags.size = .Many;25757 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);25758 break :ptr try sema.coerceCompatiblePtrs(block, try pt.ptrTypeSema(src_manyptr_ty_key), new_src_ptr, src_src);
25518 } else new_src_ptr;25759 } else new_src_ptr;
2551925760
25520 // ok1: dest >= src + len25761 // ok1: dest >= src + len
...@@ -25537,7 +25778,8 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25537,7 +25778,8 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25537}25778}
2553825779
25539fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {25780fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
25540 const mod = sema.mod;25781 const pt = sema.pt;
25782 const mod = pt.zcu;
25541 const gpa = sema.gpa;25783 const gpa = sema.gpa;
25542 const ip = &mod.intern_pool;25784 const ip = &mod.intern_pool;
25543 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;25785 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
...@@ -25569,7 +25811,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25569,7 +25811,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25569 const msg = try sema.errMsg(src, "unknown @memset length", .{});25811 const msg = try sema.errMsg(src, "unknown @memset length", .{});
25570 errdefer msg.destroy(sema.gpa);25812 errdefer msg.destroy(sema.gpa);
25571 try sema.errNote(dest_src, msg, "destination type '{}' provides no length", .{25813 try sema.errNote(dest_src, msg, "destination type '{}' provides no length", .{
25572 dest_ptr_ty.fmt(mod),25814 dest_ptr_ty.fmt(pt),
25573 });25815 });
25574 break :msg msg;25816 break :msg msg;
25575 });25817 });
...@@ -25581,7 +25823,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25581,7 +25823,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25581 const ptr_val = try sema.resolveDefinedValue(block, dest_src, dest_ptr) orelse break :rs dest_src;25823 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);25824 const len_air_ref = try sema.fieldVal(block, src, dest_ptr, try ip.getOrPutString(gpa, "len", .no_embedded_nulls), dest_src);
25583 const len_val = (try sema.resolveDefinedValue(block, dest_src, len_air_ref)) orelse break :rs dest_src;25825 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)).?;25826 const len_u64 = (try len_val.getUnsignedIntAdvanced(pt, .sema)).?;
25585 const len = try sema.usizeCast(block, dest_src, len_u64);25827 const len = try sema.usizeCast(block, dest_src, len_u64);
25586 if (len == 0) {25828 if (len == 0) {
25587 // This AIR instruction guarantees length > 0 if it is comptime-known.25829 // This AIR instruction guarantees length > 0 if it is comptime-known.
...@@ -25590,22 +25832,22 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25590,22 +25832,22 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2559025832
25591 if (!sema.isComptimeMutablePtr(ptr_val)) break :rs dest_src;25833 if (!sema.isComptimeMutablePtr(ptr_val)) break :rs dest_src;
25592 const elem_val = try sema.resolveValue(elem) orelse break :rs value_src;25834 const elem_val = try sema.resolveValue(elem) orelse break :rs value_src;
25593 const array_ty = try mod.arrayType(.{25835 const array_ty = try pt.arrayType(.{
25594 .child = dest_elem_ty.toIntern(),25836 .child = dest_elem_ty.toIntern(),
25595 .len = len_u64,25837 .len = len_u64,
25596 });25838 });
25597 const array_val = Value.fromInterned((try mod.intern(.{ .aggregate = .{25839 const array_val = Value.fromInterned(try pt.intern(.{ .aggregate = .{
25598 .ty = array_ty.toIntern(),25840 .ty = array_ty.toIntern(),
25599 .storage = .{ .repeated_elem = elem_val.toIntern() },25841 .storage = .{ .repeated_elem = elem_val.toIntern() },
25600 } })));25842 } }));
25601 const array_ptr_ty = ty: {25843 const array_ptr_ty = ty: {
25602 var info = dest_ptr_ty.ptrInfo(mod);25844 var info = dest_ptr_ty.ptrInfo(mod);
25603 info.flags.size = .One;25845 info.flags.size = .One;
25604 info.child = array_ty.toIntern();25846 info.child = array_ty.toIntern();
25605 break :ty try mod.ptrType(info);25847 break :ty try pt.ptrType(info);
25606 };25848 };
25607 const raw_ptr_val = if (dest_ptr_ty.isSlice(mod)) ptr_val.slicePtr(mod) else ptr_val;25849 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);25850 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);25851 return sema.storePtrVal(block, src, array_ptr_val, array_val, array_ty);
25610 };25852 };
2561125853
...@@ -25658,7 +25900,8 @@ fn zirVarExtended(...@@ -25658,7 +25900,8 @@ fn zirVarExtended(
25658 block: *Block,25900 block: *Block,
25659 extended: Zir.Inst.Extended.InstData,25901 extended: Zir.Inst.Extended.InstData,
25660) CompileError!Air.Inst.Ref {25902) CompileError!Air.Inst.Ref {
25661 const mod = sema.mod;25903 const pt = sema.pt;
25904 const mod = pt.zcu;
25662 const extra = sema.code.extraData(Zir.Inst.ExtendedVar, extended.operand);25905 const extra = sema.code.extraData(Zir.Inst.ExtendedVar, extended.operand);
25663 const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 });25906 const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 });
25664 const init_src = block.src(.{ .node_offset_var_decl_init = 0 });25907 const init_src = block.src(.{ .node_offset_var_decl_init = 0 });
...@@ -25705,7 +25948,7 @@ fn zirVarExtended(...@@ -25705,7 +25948,7 @@ fn zirVarExtended(
2570525948
25706 try sema.validateVarType(block, ty_src, var_ty, small.is_extern);25949 try sema.validateVarType(block, ty_src, var_ty, small.is_extern);
2570725950
25708 return Air.internedToRef((try mod.intern(.{ .variable = .{25951 return Air.internedToRef((try pt.intern(.{ .variable = .{
25709 .ty = var_ty.toIntern(),25952 .ty = var_ty.toIntern(),
25710 .init = init_val,25953 .init = init_val,
25711 .decl = sema.owner_decl_index,25954 .decl = sema.owner_decl_index,
...@@ -25721,7 +25964,8 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -25721,7 +25964,8 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
25721 const tracy = trace(@src());25964 const tracy = trace(@src());
25722 defer tracy.end();25965 defer tracy.end();
2572325966
25724 const mod = sema.mod;25967 const pt = sema.pt;
25968 const mod = pt.zcu;
25725 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;25969 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);25970 const extra = sema.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index);
25727 const target = mod.getTarget();25971 const target = mod.getTarget();
...@@ -25761,7 +26005,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -25761,7 +26005,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
25761 if (val.isGenericPoison()) {26005 if (val.isGenericPoison()) {
25762 break :blk null;26006 break :blk null;
25763 }26007 }
25764 const alignment = try sema.validateAlignAllowZero(block, align_src, try val.toUnsignedIntSema(mod));26008 const alignment = try sema.validateAlignAllowZero(block, align_src, try val.toUnsignedIntSema(pt));
25765 const default = target_util.defaultFunctionAlignment(target);26009 const default = target_util.defaultFunctionAlignment(target);
25766 break :blk if (alignment == default) .none else alignment;26010 break :blk if (alignment == default) .none else alignment;
25767 } else if (extra.data.bits.has_align_ref) blk: {26011 } else if (extra.data.bits.has_align_ref) blk: {
...@@ -25781,7 +26025,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -25781,7 +26025,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
25781 error.GenericPoison => break :blk null,26025 error.GenericPoison => break :blk null,
25782 else => |e| return e,26026 else => |e| return e,
25783 };26027 };
25784 const alignment = try sema.validateAlignAllowZero(block, align_src, try align_val.toUnsignedIntSema(mod));26028 const alignment = try sema.validateAlignAllowZero(block, align_src, try align_val.toUnsignedIntSema(pt));
25785 const default = target_util.defaultFunctionAlignment(target);26029 const default = target_util.defaultFunctionAlignment(target);
25786 break :blk if (alignment == default) .none else alignment;26030 break :blk if (alignment == default) .none else alignment;
25787 } else .none;26031 } else .none;
...@@ -25857,7 +26101,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -25857,7 +26101,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
25857 const body = sema.code.bodySlice(extra_index, body_len);26101 const body = sema.code.bodySlice(extra_index, body_len);
25858 extra_index += body.len;26102 extra_index += body.len;
2585926103
25860 const cc_ty = try mod.getBuiltinType("CallingConvention");26104 const cc_ty = try pt.getBuiltinType("CallingConvention");
25861 const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, .{26105 const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, .{
25862 .needed_comptime_reason = "calling convention must be comptime-known",26106 .needed_comptime_reason = "calling convention must be comptime-known",
25863 });26107 });
...@@ -25986,7 +26230,8 @@ fn zirCDefine(...@@ -25986,7 +26230,8 @@ fn zirCDefine(
25986 block: *Block,26230 block: *Block,
25987 extended: Zir.Inst.Extended.InstData,26231 extended: Zir.Inst.Extended.InstData,
25988) CompileError!Air.Inst.Ref {26232) CompileError!Air.Inst.Ref {
25989 const mod = sema.mod;26233 const pt = sema.pt;
26234 const mod = pt.zcu;
25990 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;26235 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
25991 const name_src = block.builtinCallArgSrc(extra.node, 0);26236 const name_src = block.builtinCallArgSrc(extra.node, 0);
25992 const val_src = block.builtinCallArgSrc(extra.node, 1);26237 const val_src = block.builtinCallArgSrc(extra.node, 1);
...@@ -26014,7 +26259,7 @@ fn zirWasmMemorySize(...@@ -26014,7 +26259,7 @@ fn zirWasmMemorySize(
26014 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;26259 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
26015 const index_src = block.builtinCallArgSrc(extra.node, 0);26260 const index_src = block.builtinCallArgSrc(extra.node, 0);
26016 const builtin_src = block.nodeOffset(extra.node);26261 const builtin_src = block.nodeOffset(extra.node);
26017 const target = sema.mod.getTarget();26262 const target = sema.pt.zcu.getTarget();
26018 if (!target.isWasm()) {26263 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)});26264 return sema.fail(block, builtin_src, "builtin @wasmMemorySize is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)});
26020 }26265 }
...@@ -26041,7 +26286,7 @@ fn zirWasmMemoryGrow(...@@ -26041,7 +26286,7 @@ fn zirWasmMemoryGrow(
26041 const builtin_src = block.nodeOffset(extra.node);26286 const builtin_src = block.nodeOffset(extra.node);
26042 const index_src = block.builtinCallArgSrc(extra.node, 0);26287 const index_src = block.builtinCallArgSrc(extra.node, 0);
26043 const delta_src = block.builtinCallArgSrc(extra.node, 1);26288 const delta_src = block.builtinCallArgSrc(extra.node, 1);
26044 const target = sema.mod.getTarget();26289 const target = sema.pt.zcu.getTarget();
26045 if (!target.isWasm()) {26290 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)});26291 return sema.fail(block, builtin_src, "builtin @wasmMemoryGrow is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)});
26047 }26292 }
...@@ -26067,10 +26312,11 @@ fn resolvePrefetchOptions(...@@ -26067,10 +26312,11 @@ fn resolvePrefetchOptions(
26067 src: LazySrcLoc,26312 src: LazySrcLoc,
26068 zir_ref: Zir.Inst.Ref,26313 zir_ref: Zir.Inst.Ref,
26069) CompileError!std.builtin.PrefetchOptions {26314) CompileError!std.builtin.PrefetchOptions {
26070 const mod = sema.mod;26315 const pt = sema.pt;
26316 const mod = pt.zcu;
26071 const gpa = sema.gpa;26317 const gpa = sema.gpa;
26072 const ip = &mod.intern_pool;26318 const ip = &mod.intern_pool;
26073 const options_ty = try mod.getBuiltinType("PrefetchOptions");26319 const options_ty = try pt.getBuiltinType("PrefetchOptions");
26074 const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);26320 const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);
2607526321
26076 const rw_src = block.src(.{ .init_field_rw = src.offset.node_offset_builtin_call_arg.builtin_call_node });26322 const rw_src = block.src(.{ .init_field_rw = src.offset.node_offset_builtin_call_arg.builtin_call_node });
...@@ -26094,7 +26340,7 @@ fn resolvePrefetchOptions(...@@ -26094,7 +26340,7 @@ fn resolvePrefetchOptions(
2609426340
26095 return std.builtin.PrefetchOptions{26341 return std.builtin.PrefetchOptions{
26096 .rw = mod.toEnum(std.builtin.PrefetchOptions.Rw, rw_val),26342 .rw = mod.toEnum(std.builtin.PrefetchOptions.Rw, rw_val),
26097 .locality = @intCast(try locality_val.toUnsignedIntSema(mod)),26343 .locality = @intCast(try locality_val.toUnsignedIntSema(pt)),
26098 .cache = mod.toEnum(std.builtin.PrefetchOptions.Cache, cache_val),26344 .cache = mod.toEnum(std.builtin.PrefetchOptions.Cache, cache_val),
26099 };26345 };
26100}26346}
...@@ -26138,11 +26384,12 @@ fn resolveExternOptions(...@@ -26138,11 +26384,12 @@ fn resolveExternOptions(
26138 linkage: std.builtin.GlobalLinkage = .strong,26384 linkage: std.builtin.GlobalLinkage = .strong,
26139 is_thread_local: bool = false,26385 is_thread_local: bool = false,
26140} {26386} {
26141 const mod = sema.mod;26387 const pt = sema.pt;
26388 const mod = pt.zcu;
26142 const gpa = sema.gpa;26389 const gpa = sema.gpa;
26143 const ip = &mod.intern_pool;26390 const ip = &mod.intern_pool;
26144 const options_inst = try sema.resolveInst(zir_ref);26391 const options_inst = try sema.resolveInst(zir_ref);
26145 const extern_options_ty = try mod.getBuiltinType("ExternOptions");26392 const extern_options_ty = try pt.getBuiltinType("ExternOptions");
26146 const options = try sema.coerce(block, extern_options_ty, options_inst, src);26393 const options = try sema.coerce(block, extern_options_ty, options_inst, src);
2614726394
26148 const name_src = block.src(.{ .init_field_name = src.offset.node_offset_builtin_call_arg.builtin_call_node });26395 const name_src = block.src(.{ .init_field_name = src.offset.node_offset_builtin_call_arg.builtin_call_node });
...@@ -26203,7 +26450,8 @@ fn zirBuiltinExtern(...@@ -26203,7 +26450,8 @@ fn zirBuiltinExtern(
26203 block: *Block,26450 block: *Block,
26204 extended: Zir.Inst.Extended.InstData,26451 extended: Zir.Inst.Extended.InstData,
26205) CompileError!Air.Inst.Ref {26452) CompileError!Air.Inst.Ref {
26206 const mod = sema.mod;26453 const pt = sema.pt;
26454 const mod = pt.zcu;
26207 const ip = &mod.intern_pool;26455 const ip = &mod.intern_pool;
26208 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;26456 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
26209 const ty_src = block.builtinCallArgSrc(extra.node, 0);26457 const ty_src = block.builtinCallArgSrc(extra.node, 0);
...@@ -26215,7 +26463,7 @@ fn zirBuiltinExtern(...@@ -26215,7 +26463,7 @@ fn zirBuiltinExtern(
26215 }26463 }
26216 if (!try sema.validateExternType(ty, .other)) {26464 if (!try sema.validateExternType(ty, .other)) {
26217 const msg = msg: {26465 const msg = msg: {
26218 const msg = try sema.errMsg(ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(mod)});26466 const msg = try sema.errMsg(ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(pt)});
26219 errdefer msg.destroy(sema.gpa);26467 errdefer msg.destroy(sema.gpa);
26220 try sema.explainWhyTypeIsNotExtern(msg, ty_src, ty, .other);26468 try sema.explainWhyTypeIsNotExtern(msg, ty_src, ty, .other);
26221 break :msg msg;26469 break :msg msg;
...@@ -26226,7 +26474,7 @@ fn zirBuiltinExtern(...@@ -26226,7 +26474,7 @@ fn zirBuiltinExtern(
26226 const options = try sema.resolveExternOptions(block, options_src, extra.rhs);26474 const options = try sema.resolveExternOptions(block, options_src, extra.rhs);
2622726475
26228 if (options.linkage == .weak and !ty.ptrAllowsZero(mod)) {26476 if (options.linkage == .weak and !ty.ptrAllowsZero(mod)) {
26229 ty = try mod.optionalType(ty.toIntern());26477 ty = try pt.optionalType(ty.toIntern());
26230 }26478 }
26231 const ptr_info = ty.ptrInfo(mod);26479 const ptr_info = ty.ptrInfo(mod);
2623226480
...@@ -26237,13 +26485,13 @@ fn zirBuiltinExtern(...@@ -26237,13 +26485,13 @@ fn zirBuiltinExtern(
26237 new_decl_index,26485 new_decl_index,
26238 Value.fromInterned(26486 Value.fromInterned(
26239 if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn)26487 if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn)
26240 try ip.getExternFunc(sema.gpa, .{26488 try ip.getExternFunc(sema.gpa, pt.tid, .{
26241 .ty = ptr_info.child,26489 .ty = ptr_info.child,
26242 .decl = new_decl_index,26490 .decl = new_decl_index,
26243 .lib_name = options.library_name,26491 .lib_name = options.library_name,
26244 })26492 })
26245 else26493 else
26246 try mod.intern(.{ .variable = .{26494 try pt.intern(.{ .variable = .{
26247 .ty = ptr_info.child,26495 .ty = ptr_info.child,
26248 .init = .none,26496 .init = .none,
26249 .decl = new_decl_index,26497 .decl = new_decl_index,
...@@ -26259,9 +26507,9 @@ fn zirBuiltinExtern(...@@ -26259,9 +26507,9 @@ fn zirBuiltinExtern(
26259 new_decl.owns_tv = true;26507 new_decl.owns_tv = true;
26260 // Note that this will queue the anon decl for codegen, so that the backend can26508 // Note that this will queue the anon decl for codegen, so that the backend can
26261 // correctly handle the extern, including duplicate detection.26509 // correctly handle the extern, including duplicate detection.
26262 try mod.finalizeAnonDecl(new_decl_index);26510 try pt.finalizeAnonDecl(new_decl_index);
2626326511
26264 return Air.internedToRef((try mod.getCoerced(Value.fromInterned((try mod.intern(.{ .ptr = .{26512 return Air.internedToRef((try pt.getCoerced(Value.fromInterned(try pt.intern(.{ .ptr = .{
26265 .ty = switch (ip.indexToKey(ty.toIntern())) {26513 .ty = switch (ip.indexToKey(ty.toIntern())) {
26266 .ptr_type => ty.toIntern(),26514 .ptr_type => ty.toIntern(),
26267 .opt_type => |child_type| child_type,26515 .opt_type => |child_type| child_type,
...@@ -26269,7 +26517,7 @@ fn zirBuiltinExtern(...@@ -26269,7 +26517,7 @@ fn zirBuiltinExtern(
26269 },26517 },
26270 .base_addr = .{ .decl = new_decl_index },26518 .base_addr = .{ .decl = new_decl_index },
26271 .byte_offset = 0,26519 .byte_offset = 0,
26272 } }))), ty)).toIntern());26520 } })), ty)).toIntern());
26273}26521}
2627426522
26275fn zirWorkItem(26523fn zirWorkItem(
...@@ -26281,7 +26529,7 @@ fn zirWorkItem(...@@ -26281,7 +26529,7 @@ fn zirWorkItem(
26281 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;26529 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
26282 const dimension_src = block.builtinCallArgSrc(extra.node, 0);26530 const dimension_src = block.builtinCallArgSrc(extra.node, 0);
26283 const builtin_src = block.nodeOffset(extra.node);26531 const builtin_src = block.nodeOffset(extra.node);
26284 const target = sema.mod.getTarget();26532 const target = sema.pt.zcu.getTarget();
2628526533
26286 switch (target.cpu.arch) {26534 switch (target.cpu.arch) {
26287 // TODO: Allow for other GPU targets.26535 // TODO: Allow for other GPU targets.
...@@ -26344,11 +26592,12 @@ fn validateVarType(...@@ -26344,11 +26592,12 @@ fn validateVarType(
26344 var_ty: Type,26592 var_ty: Type,
26345 is_extern: bool,26593 is_extern: bool,
26346) CompileError!void {26594) CompileError!void {
26347 const mod = sema.mod;26595 const pt = sema.pt;
26596 const mod = pt.zcu;
26348 if (is_extern) {26597 if (is_extern) {
26349 if (!try sema.validateExternType(var_ty, .other)) {26598 if (!try sema.validateExternType(var_ty, .other)) {
26350 const msg = msg: {26599 const msg = msg: {
26351 const msg = try sema.errMsg(src, "extern variable cannot have type '{}'", .{var_ty.fmt(mod)});26600 const msg = try sema.errMsg(src, "extern variable cannot have type '{}'", .{var_ty.fmt(pt)});
26352 errdefer msg.destroy(sema.gpa);26601 errdefer msg.destroy(sema.gpa);
26353 try sema.explainWhyTypeIsNotExtern(msg, src, var_ty, .other);26602 try sema.explainWhyTypeIsNotExtern(msg, src, var_ty, .other);
26354 break :msg msg;26603 break :msg msg;
...@@ -26361,7 +26610,7 @@ fn validateVarType(...@@ -26361,7 +26610,7 @@ fn validateVarType(
26361 block,26610 block,
26362 src,26611 src,
26363 "non-extern variable with opaque type '{}'",26612 "non-extern variable with opaque type '{}'",
26364 .{var_ty.fmt(mod)},26613 .{var_ty.fmt(pt)},
26365 );26614 );
26366 }26615 }
26367 }26616 }
...@@ -26369,7 +26618,7 @@ fn validateVarType(...@@ -26369,7 +26618,7 @@ fn validateVarType(
26369 if (!try sema.typeRequiresComptime(var_ty)) return;26618 if (!try sema.typeRequiresComptime(var_ty)) return;
2637026619
26371 const msg = msg: {26620 const msg = msg: {
26372 const msg = try sema.errMsg(src, "variable of type '{}' must be const or comptime", .{var_ty.fmt(mod)});26621 const msg = try sema.errMsg(src, "variable of type '{}' must be const or comptime", .{var_ty.fmt(pt)});
26373 errdefer msg.destroy(sema.gpa);26622 errdefer msg.destroy(sema.gpa);
2637426623
26375 try sema.explainWhyTypeIsComptime(msg, src, var_ty);26624 try sema.explainWhyTypeIsComptime(msg, src, var_ty);
...@@ -26393,7 +26642,7 @@ fn explainWhyTypeIsComptime(...@@ -26393,7 +26642,7 @@ fn explainWhyTypeIsComptime(
26393 var type_set = TypeSet{};26642 var type_set = TypeSet{};
26394 defer type_set.deinit(sema.gpa);26643 defer type_set.deinit(sema.gpa);
2639526644
26396 try ty.resolveFully(sema.mod);26645 try ty.resolveFully(sema.pt);
26397 return sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty, &type_set);26646 return sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty, &type_set);
26398}26647}
2639926648
...@@ -26404,7 +26653,8 @@ fn explainWhyTypeIsComptimeInner(...@@ -26404,7 +26653,8 @@ fn explainWhyTypeIsComptimeInner(
26404 ty: Type,26653 ty: Type,
26405 type_set: *TypeSet,26654 type_set: *TypeSet,
26406) CompileError!void {26655) CompileError!void {
26407 const mod = sema.mod;26656 const pt = sema.pt;
26657 const mod = pt.zcu;
26408 const ip = &mod.intern_pool;26658 const ip = &mod.intern_pool;
26409 switch (ty.zigTypeTag(mod)) {26659 switch (ty.zigTypeTag(mod)) {
26410 .Bool,26660 .Bool,
...@@ -26418,9 +26668,7 @@ fn explainWhyTypeIsComptimeInner(...@@ -26418,9 +26668,7 @@ fn explainWhyTypeIsComptimeInner(
26418 => return,26668 => return,
2641926669
26420 .Fn => {26670 .Fn => {
26421 try sema.errNote(src_loc, msg, "use '*const {}' for a function pointer type", .{26671 try sema.errNote(src_loc, msg, "use '*const {}' for a function pointer type", .{ty.fmt(pt)});
26422 ty.fmt(sema.mod),
26423 });
26424 },26672 },
2642526673
26426 .Type => {26674 .Type => {
...@@ -26436,7 +26684,7 @@ fn explainWhyTypeIsComptimeInner(...@@ -26436,7 +26684,7 @@ fn explainWhyTypeIsComptimeInner(
26436 => return,26684 => return,
2643726685
26438 .Opaque => {26686 .Opaque => {
26439 try sema.errNote(src_loc, msg, "opaque type '{}' has undefined size", .{ty.fmt(sema.mod)});26687 try sema.errNote(src_loc, msg, "opaque type '{}' has undefined size", .{ty.fmt(pt)});
26440 },26688 },
2644126689
26442 .Array, .Vector => {26690 .Array, .Vector => {
...@@ -26453,7 +26701,7 @@ fn explainWhyTypeIsComptimeInner(...@@ -26453,7 +26701,7 @@ fn explainWhyTypeIsComptimeInner(
26453 .Inline => try sema.errNote(src_loc, msg, "function has inline calling convention", .{}),26701 .Inline => try sema.errNote(src_loc, msg, "function has inline calling convention", .{}),
26454 else => {},26702 else => {},
26455 }26703 }
26456 if (Type.fromInterned(fn_info.return_type).comptimeOnly(mod)) {26704 if (Type.fromInterned(fn_info.return_type).comptimeOnly(pt)) {
26457 try sema.errNote(src_loc, msg, "function has a comptime-only return type", .{});26705 try sema.errNote(src_loc, msg, "function has a comptime-only return type", .{});
26458 }26706 }
26459 return;26707 return;
...@@ -26526,7 +26774,8 @@ fn validateExternType(...@@ -26526,7 +26774,8 @@ fn validateExternType(
26526 ty: Type,26774 ty: Type,
26527 position: ExternPosition,26775 position: ExternPosition,
26528) !bool {26776) !bool {
26529 const mod = sema.mod;26777 const pt = sema.pt;
26778 const mod = pt.zcu;
26530 switch (ty.zigTypeTag(mod)) {26779 switch (ty.zigTypeTag(mod)) {
26531 .Type,26780 .Type,
26532 .ComptimeFloat,26781 .ComptimeFloat,
...@@ -26557,7 +26806,7 @@ fn validateExternType(...@@ -26557,7 +26806,7 @@ fn validateExternType(
26557 },26806 },
26558 .Fn => {26807 .Fn => {
26559 if (position != .other) return false;26808 if (position != .other) return false;
26560 const target = sema.mod.getTarget();26809 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.26810 // 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.26811 // 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)) {26812 if (ty.fnCallingConvention(mod) == .Kernel and (target.cpu.arch == .nvptx or target.cpu.arch == .nvptx64)) {
...@@ -26571,7 +26820,7 @@ fn validateExternType(...@@ -26571,7 +26820,7 @@ fn validateExternType(
26571 .Struct, .Union => switch (ty.containerLayout(mod)) {26820 .Struct, .Union => switch (ty.containerLayout(mod)) {
26572 .@"extern" => return true,26821 .@"extern" => return true,
26573 .@"packed" => {26822 .@"packed" => {
26574 const bit_size = try ty.bitSizeAdvanced(mod, .sema);26823 const bit_size = try ty.bitSizeAdvanced(pt, .sema);
26575 switch (bit_size) {26824 switch (bit_size) {
26576 0, 8, 16, 32, 64, 128 => return true,26825 0, 8, 16, 32, 64, 128 => return true,
26577 else => return false,26826 else => return false,
...@@ -26595,7 +26844,8 @@ fn explainWhyTypeIsNotExtern(...@@ -26595,7 +26844,8 @@ fn explainWhyTypeIsNotExtern(
26595 ty: Type,26844 ty: Type,
26596 position: ExternPosition,26845 position: ExternPosition,
26597) CompileError!void {26846) CompileError!void {
26598 const mod = sema.mod;26847 const pt = sema.pt;
26848 const mod = pt.zcu;
26599 switch (ty.zigTypeTag(mod)) {26849 switch (ty.zigTypeTag(mod)) {
26600 .Opaque,26850 .Opaque,
26601 .Bool,26851 .Bool,
...@@ -26622,7 +26872,7 @@ fn explainWhyTypeIsNotExtern(...@@ -26622,7 +26872,7 @@ fn explainWhyTypeIsNotExtern(
26622 if (!ty.isConstPtr(mod) and pointee_ty.zigTypeTag(mod) == .Fn) {26872 if (!ty.isConstPtr(mod) and pointee_ty.zigTypeTag(mod) == .Fn) {
26623 try sema.errNote(src_loc, msg, "pointer to extern function must be 'const'", .{});26873 try sema.errNote(src_loc, msg, "pointer to extern function must be 'const'", .{});
26624 } else if (try sema.typeRequiresComptime(ty)) {26874 } else if (try sema.typeRequiresComptime(ty)) {
26625 try sema.errNote(src_loc, msg, "pointer to comptime-only type '{}'", .{pointee_ty.fmt(sema.mod)});26875 try sema.errNote(src_loc, msg, "pointer to comptime-only type '{}'", .{pointee_ty.fmt(pt)});
26626 try sema.explainWhyTypeIsComptime(msg, src_loc, ty);26876 try sema.explainWhyTypeIsComptime(msg, src_loc, ty);
26627 }26877 }
26628 try sema.explainWhyTypeIsNotExtern(msg, src_loc, pointee_ty, .other);26878 try sema.explainWhyTypeIsNotExtern(msg, src_loc, pointee_ty, .other);
...@@ -26650,7 +26900,7 @@ fn explainWhyTypeIsNotExtern(...@@ -26650,7 +26900,7 @@ fn explainWhyTypeIsNotExtern(
26650 },26900 },
26651 .Enum => {26901 .Enum => {
26652 const tag_ty = ty.intTagType(mod);26902 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)});26903 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);26904 try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position);
26655 },26905 },
26656 .Struct => try sema.errNote(src_loc, msg, "only extern structs and ABI sized packed structs are extern compatible", .{}),26906 .Struct => try sema.errNote(src_loc, msg, "only extern structs and ABI sized packed structs are extern compatible", .{}),
...@@ -26671,7 +26921,8 @@ fn explainWhyTypeIsNotExtern(...@@ -26671,7 +26921,8 @@ fn explainWhyTypeIsNotExtern(
26671/// Returns true if `ty` is allowed in packed types.26921/// 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.26922/// 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 {26923fn validatePackedType(sema: *Sema, ty: Type) !bool {
26674 const zcu = sema.mod;26924 const pt = sema.pt;
26925 const zcu = pt.zcu;
26675 return switch (ty.zigTypeTag(zcu)) {26926 return switch (ty.zigTypeTag(zcu)) {
26676 .Type,26927 .Type,
26677 .ComptimeFloat,26928 .ComptimeFloat,
...@@ -26710,7 +26961,8 @@ fn explainWhyTypeIsNotPacked(...@@ -26710,7 +26961,8 @@ fn explainWhyTypeIsNotPacked(
26710 src_loc: LazySrcLoc,26961 src_loc: LazySrcLoc,
26711 ty: Type,26962 ty: Type,
26712) CompileError!void {26963) CompileError!void {
26713 const mod = sema.mod;26964 const pt = sema.pt;
26965 const mod = pt.zcu;
26714 switch (ty.zigTypeTag(mod)) {26966 switch (ty.zigTypeTag(mod)) {
26715 .Void,26967 .Void,
26716 .Bool,26968 .Bool,
...@@ -26750,10 +27002,11 @@ fn explainWhyTypeIsNotPacked(...@@ -26750,10 +27002,11 @@ fn explainWhyTypeIsNotPacked(
26750}27002}
2675127003
26752fn prepareSimplePanic(sema: *Sema) !void {27004fn prepareSimplePanic(sema: *Sema) !void {
26753 const mod = sema.mod;27005 const pt = sema.pt;
27006 const mod = pt.zcu;
2675427007
26755 if (mod.panic_func_index == .none) {27008 if (mod.panic_func_index == .none) {
26756 const decl_index = (try mod.getBuiltinDecl("panic"));27009 const decl_index = (try pt.getBuiltinDecl("panic"));
26757 // decl_index may be an alias; we must find the decl that actually27010 // decl_index may be an alias; we must find the decl that actually
26758 // owns the function.27011 // owns the function.
26759 try sema.ensureDeclAnalyzed(decl_index);27012 try sema.ensureDeclAnalyzed(decl_index);
...@@ -26766,17 +27019,17 @@ fn prepareSimplePanic(sema: *Sema) !void {...@@ -26766,17 +27019,17 @@ fn prepareSimplePanic(sema: *Sema) !void {
26766 }27019 }
2676727020
26768 if (mod.null_stack_trace == .none) {27021 if (mod.null_stack_trace == .none) {
26769 const stack_trace_ty = try mod.getBuiltinType("StackTrace");27022 const stack_trace_ty = try pt.getBuiltinType("StackTrace");
26770 try stack_trace_ty.resolveFields(mod);27023 try stack_trace_ty.resolveFields(pt);
26771 const target = mod.getTarget();27024 const target = mod.getTarget();
26772 const ptr_stack_trace_ty = try mod.ptrTypeSema(.{27025 const ptr_stack_trace_ty = try pt.ptrTypeSema(.{
26773 .child = stack_trace_ty.toIntern(),27026 .child = stack_trace_ty.toIntern(),
26774 .flags = .{27027 .flags = .{
26775 .address_space = target_util.defaultAddressSpace(target, .global_constant),27028 .address_space = target_util.defaultAddressSpace(target, .global_constant),
26776 },27029 },
26777 });27030 });
26778 const opt_ptr_stack_trace_ty = try mod.optionalType(ptr_stack_trace_ty.toIntern());27031 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
26779 mod.null_stack_trace = try mod.intern(.{ .opt = .{27032 mod.null_stack_trace = try pt.intern(.{ .opt = .{
26780 .ty = opt_ptr_stack_trace_ty.toIntern(),27033 .ty = opt_ptr_stack_trace_ty.toIntern(),
26781 .val = .none,27034 .val = .none,
26782 } });27035 } });
...@@ -26787,13 +27040,14 @@ fn prepareSimplePanic(sema: *Sema) !void {...@@ -26787,13 +27040,14 @@ fn prepareSimplePanic(sema: *Sema) !void {
26787/// instructions. This function ensures the panic function will be available to27040/// instructions. This function ensures the panic function will be available to
26788/// be called during that time.27041/// be called during that time.
26789fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternPool.DeclIndex {27042fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternPool.DeclIndex {
26790 const mod = sema.mod;27043 const pt = sema.pt;
27044 const mod = pt.zcu;
26791 const gpa = sema.gpa;27045 const gpa = sema.gpa;
26792 if (mod.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x;27046 if (mod.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x;
2679327047
26794 try sema.prepareSimplePanic();27048 try sema.prepareSimplePanic();
2679527049
26796 const panic_messages_ty = try mod.getBuiltinType("panic_messages");27050 const panic_messages_ty = try pt.getBuiltinType("panic_messages");
26797 const msg_decl_index = (sema.namespaceLookup(27051 const msg_decl_index = (sema.namespaceLookup(
26798 block,27052 block,
26799 LazySrcLoc.unneeded,27053 LazySrcLoc.unneeded,
...@@ -26892,7 +27146,8 @@ fn addSafetyCheckExtra(...@@ -26892,7 +27146,8 @@ fn addSafetyCheckExtra(
26892}27146}
2689327147
26894fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.Ref, operation: CallOperation) !void {27148fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.Ref, operation: CallOperation) !void {
26895 const mod = sema.mod;27149 const pt = sema.pt;
27150 const mod = pt.zcu;
2689627151
26897 if (!mod.backendSupportsFeature(.panic_fn)) {27152 if (!mod.backendSupportsFeature(.panic_fn)) {
26898 _ = try block.addNoOp(.trap);27153 _ = try block.addNoOp(.trap);
...@@ -26905,8 +27160,8 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst....@@ -26905,8 +27160,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);27160 const panic_fn = try sema.analyzeDeclVal(block, src, panic_func.owner_decl);
26906 const null_stack_trace = Air.internedToRef(mod.null_stack_trace);27161 const null_stack_trace = Air.internedToRef(mod.null_stack_trace);
2690727162
26908 const opt_usize_ty = try mod.optionalType(.usize_type);27163 const opt_usize_ty = try pt.optionalType(.usize_type);
26909 const null_ret_addr = Air.internedToRef((try mod.intern(.{ .opt = .{27164 const null_ret_addr = Air.internedToRef((try pt.intern(.{ .opt = .{
26910 .ty = opt_usize_ty.toIntern(),27165 .ty = opt_usize_ty.toIntern(),
26911 .val = .none,27166 .val = .none,
26912 } })));27167 } })));
...@@ -26921,9 +27176,10 @@ fn panicUnwrapError(...@@ -26921,9 +27176,10 @@ fn panicUnwrapError(
26921 unwrap_err_tag: Air.Inst.Tag,27176 unwrap_err_tag: Air.Inst.Tag,
26922 is_non_err_tag: Air.Inst.Tag,27177 is_non_err_tag: Air.Inst.Tag,
26923) !void {27178) !void {
27179 const pt = sema.pt;
26924 assert(!parent_block.is_comptime);27180 assert(!parent_block.is_comptime);
26925 const ok = try parent_block.addUnOp(is_non_err_tag, operand);27181 const ok = try parent_block.addUnOp(is_non_err_tag, operand);
26926 if (!sema.mod.comp.formatted_panics) {27182 if (!pt.zcu.comp.formatted_panics) {
26927 return sema.addSafetyCheck(parent_block, src, ok, .unwrap_error);27183 return sema.addSafetyCheck(parent_block, src, ok, .unwrap_error);
26928 }27184 }
26929 const gpa = sema.gpa;27185 const gpa = sema.gpa;
...@@ -26942,10 +27198,10 @@ fn panicUnwrapError(...@@ -26942,10 +27198,10 @@ fn panicUnwrapError(
26942 defer fail_block.instructions.deinit(gpa);27198 defer fail_block.instructions.deinit(gpa);
2694327199
26944 {27200 {
26945 if (!sema.mod.backendSupportsFeature(.panic_unwrap_error)) {27201 if (!pt.zcu.backendSupportsFeature(.panic_unwrap_error)) {
26946 _ = try fail_block.addNoOp(.trap);27202 _ = try fail_block.addNoOp(.trap);
26947 } else {27203 } else {
26948 const panic_fn = try sema.mod.getBuiltin("panicUnwrapError");27204 const panic_fn = try sema.pt.getBuiltin("panicUnwrapError");
26949 const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand);27205 const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand);
26950 const err_return_trace = try sema.getErrorReturnTrace(&fail_block);27206 const err_return_trace = try sema.getErrorReturnTrace(&fail_block);
26951 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };27207 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };
...@@ -26965,7 +27221,7 @@ fn panicIndexOutOfBounds(...@@ -26965,7 +27221,7 @@ fn panicIndexOutOfBounds(
26965) !void {27221) !void {
26966 assert(!parent_block.is_comptime);27222 assert(!parent_block.is_comptime);
26967 const ok = try parent_block.addBinOp(cmp_op, index, len);27223 const ok = try parent_block.addBinOp(cmp_op, index, len);
26968 if (!sema.mod.comp.formatted_panics) {27224 if (!sema.pt.zcu.comp.formatted_panics) {
26969 return sema.addSafetyCheck(parent_block, src, ok, .index_out_of_bounds);27225 return sema.addSafetyCheck(parent_block, src, ok, .index_out_of_bounds);
26970 }27226 }
26971 try sema.safetyCheckFormatted(parent_block, src, ok, "panicOutOfBounds", &.{ index, len });27227 try sema.safetyCheckFormatted(parent_block, src, ok, "panicOutOfBounds", &.{ index, len });
...@@ -26980,7 +27236,7 @@ fn panicInactiveUnionField(...@@ -26980,7 +27236,7 @@ fn panicInactiveUnionField(
26980) !void {27236) !void {
26981 assert(!parent_block.is_comptime);27237 assert(!parent_block.is_comptime);
26982 const ok = try parent_block.addBinOp(.cmp_eq, active_tag, wanted_tag);27238 const ok = try parent_block.addBinOp(.cmp_eq, active_tag, wanted_tag);
26983 if (!sema.mod.comp.formatted_panics) {27239 if (!sema.pt.zcu.comp.formatted_panics) {
26984 return sema.addSafetyCheck(parent_block, src, ok, .inactive_union_field);27240 return sema.addSafetyCheck(parent_block, src, ok, .inactive_union_field);
26985 }27241 }
26986 try sema.safetyCheckFormatted(parent_block, src, ok, "panicInactiveUnionField", &.{ active_tag, wanted_tag });27242 try sema.safetyCheckFormatted(parent_block, src, ok, "panicInactiveUnionField", &.{ active_tag, wanted_tag });
...@@ -26996,7 +27252,8 @@ fn panicSentinelMismatch(...@@ -26996,7 +27252,8 @@ fn panicSentinelMismatch(
26996 sentinel_index: Air.Inst.Ref,27252 sentinel_index: Air.Inst.Ref,
26997) !void {27253) !void {
26998 assert(!parent_block.is_comptime);27254 assert(!parent_block.is_comptime);
26999 const mod = sema.mod;27255 const pt = sema.pt;
27256 const mod = pt.zcu;
27000 const expected_sentinel_val = maybe_sentinel orelse return;27257 const expected_sentinel_val = maybe_sentinel orelse return;
27001 const expected_sentinel = Air.internedToRef(expected_sentinel_val.toIntern());27258 const expected_sentinel = Air.internedToRef(expected_sentinel_val.toIntern());
2700227259
...@@ -27004,7 +27261,7 @@ fn panicSentinelMismatch(...@@ -27004,7 +27261,7 @@ fn panicSentinelMismatch(
27004 const actual_sentinel = if (ptr_ty.isSlice(mod))27261 const actual_sentinel = if (ptr_ty.isSlice(mod))
27005 try parent_block.addBinOp(.slice_elem_val, ptr, sentinel_index)27262 try parent_block.addBinOp(.slice_elem_val, ptr, sentinel_index)
27006 else blk: {27263 else blk: {
27007 const elem_ptr_ty = try ptr_ty.elemPtrType(null, mod);27264 const elem_ptr_ty = try ptr_ty.elemPtrType(null, pt);
27008 const sentinel_ptr = try parent_block.addPtrElemPtr(ptr, sentinel_index, elem_ptr_ty);27265 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);27266 break :blk try parent_block.addTyOp(.load, sentinel_ty, sentinel_ptr);
27010 };27267 };
...@@ -27022,13 +27279,13 @@ fn panicSentinelMismatch(...@@ -27022,13 +27279,13 @@ fn panicSentinelMismatch(
27022 } else if (sentinel_ty.isSelfComparable(mod, true))27279 } else if (sentinel_ty.isSelfComparable(mod, true))
27023 try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel)27280 try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel)
27024 else {27281 else {
27025 const panic_fn = try mod.getBuiltin("checkNonScalarSentinel");27282 const panic_fn = try pt.getBuiltin("checkNonScalarSentinel");
27026 const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel };27283 const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel };
27027 try sema.callBuiltin(parent_block, src, panic_fn, .auto, &args, .@"safety check");27284 try sema.callBuiltin(parent_block, src, panic_fn, .auto, &args, .@"safety check");
27028 return;27285 return;
27029 };27286 };
2703027287
27031 if (!sema.mod.comp.formatted_panics) {27288 if (!pt.zcu.comp.formatted_panics) {
27032 return sema.addSafetyCheck(parent_block, src, ok, .sentinel_mismatch);27289 return sema.addSafetyCheck(parent_block, src, ok, .sentinel_mismatch);
27033 }27290 }
27034 try sema.safetyCheckFormatted(parent_block, src, ok, "panicSentinelMismatch", &.{ expected_sentinel, actual_sentinel });27291 try sema.safetyCheckFormatted(parent_block, src, ok, "panicSentinelMismatch", &.{ expected_sentinel, actual_sentinel });
...@@ -27042,7 +27299,9 @@ fn safetyCheckFormatted(...@@ -27042,7 +27299,9 @@ fn safetyCheckFormatted(
27042 func: []const u8,27299 func: []const u8,
27043 args: []const Air.Inst.Ref,27300 args: []const Air.Inst.Ref,
27044) CompileError!void {27301) CompileError!void {
27045 assert(sema.mod.comp.formatted_panics);27302 const pt = sema.pt;
27303 const zcu = pt.zcu;
27304 assert(zcu.comp.formatted_panics);
27046 const gpa = sema.gpa;27305 const gpa = sema.gpa;
2704727306
27048 var fail_block: Block = .{27307 var fail_block: Block = .{
...@@ -27058,10 +27317,10 @@ fn safetyCheckFormatted(...@@ -27058,10 +27317,10 @@ fn safetyCheckFormatted(
2705827317
27059 defer fail_block.instructions.deinit(gpa);27318 defer fail_block.instructions.deinit(gpa);
2706027319
27061 if (!sema.mod.backendSupportsFeature(.safety_check_formatted)) {27320 if (!zcu.backendSupportsFeature(.safety_check_formatted)) {
27062 _ = try fail_block.addNoOp(.trap);27321 _ = try fail_block.addNoOp(.trap);
27063 } else {27322 } else {
27064 const panic_fn = try sema.mod.getBuiltin(func);27323 const panic_fn = try pt.getBuiltin(func);
27065 try sema.callBuiltin(&fail_block, src, panic_fn, .auto, args, .@"safety check");27324 try sema.callBuiltin(&fail_block, src, panic_fn, .auto, args, .@"safety check");
27066 }27325 }
27067 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);27326 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);
...@@ -27102,7 +27361,8 @@ fn fieldVal(...@@ -27102,7 +27361,8 @@ fn fieldVal(
27102 // When editing this function, note that there is corresponding logic to be edited27361 // 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.27362 // in `fieldPtr`. This function takes a value and returns a value.
2710427363
27105 const mod = sema.mod;27364 const pt = sema.pt;
27365 const mod = pt.zcu;
27106 const ip = &mod.intern_pool;27366 const ip = &mod.intern_pool;
27107 const object_src = src; // TODO better source location27367 const object_src = src; // TODO better source location
27108 const object_ty = sema.typeOf(object);27368 const object_ty = sema.typeOf(object);
...@@ -27120,10 +27380,10 @@ fn fieldVal(...@@ -27120,10 +27380,10 @@ fn fieldVal(
27120 switch (inner_ty.zigTypeTag(mod)) {27380 switch (inner_ty.zigTypeTag(mod)) {
27121 .Array => {27381 .Array => {
27122 if (field_name.eqlSlice("len", ip)) {27382 if (field_name.eqlSlice("len", ip)) {
27123 return Air.internedToRef((try mod.intValue(Type.usize, inner_ty.arrayLen(mod))).toIntern());27383 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) {27384 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {
27125 const ptr_info = object_ty.ptrInfo(mod);27385 const ptr_info = object_ty.ptrInfo(mod);
27126 const result_ty = try mod.ptrTypeSema(.{27386 const result_ty = try pt.ptrTypeSema(.{
27127 .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(),27387 .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(),
27128 .sentinel = if (inner_ty.sentinel(mod)) |s| s.toIntern() else .none,27388 .sentinel = if (inner_ty.sentinel(mod)) |s| s.toIntern() else .none,
27129 .flags = .{27389 .flags = .{
...@@ -27143,7 +27403,7 @@ fn fieldVal(...@@ -27143,7 +27403,7 @@ fn fieldVal(
27143 block,27403 block,
27144 field_name_src,27404 field_name_src,
27145 "no member named '{}' in '{}'",27405 "no member named '{}' in '{}'",
27146 .{ field_name.fmt(ip), object_ty.fmt(mod) },27406 .{ field_name.fmt(ip), object_ty.fmt(pt) },
27147 );27407 );
27148 }27408 }
27149 },27409 },
...@@ -27167,7 +27427,7 @@ fn fieldVal(...@@ -27167,7 +27427,7 @@ fn fieldVal(
27167 block,27427 block,
27168 field_name_src,27428 field_name_src,
27169 "no member named '{}' in '{}'",27429 "no member named '{}' in '{}'",
27170 .{ field_name.fmt(ip), object_ty.fmt(mod) },27430 .{ field_name.fmt(ip), object_ty.fmt(pt) },
27171 );27431 );
27172 }27432 }
27173 }27433 }
...@@ -27194,7 +27454,7 @@ fn fieldVal(...@@ -27194,7 +27454,7 @@ fn fieldVal(
27194 .error_set_type => |error_set_type| blk: {27454 .error_set_type => |error_set_type| blk: {
27195 if (error_set_type.nameIndex(ip, field_name) != null) break :blk;27455 if (error_set_type.nameIndex(ip, field_name) != null) break :blk;
27196 return sema.fail(block, src, "no error named '{}' in '{}'", .{27456 return sema.fail(block, src, "no error named '{}' in '{}'", .{
27197 field_name.fmt(ip), child_type.fmt(mod),27457 field_name.fmt(ip), child_type.fmt(pt),
27198 });27458 });
27199 },27459 },
27200 .inferred_error_set_type => {27460 .inferred_error_set_type => {
...@@ -27210,8 +27470,8 @@ fn fieldVal(...@@ -27210,8 +27470,8 @@ fn fieldVal(
27210 const error_set_type = if (!child_type.isAnyError(mod))27470 const error_set_type = if (!child_type.isAnyError(mod))
27211 child_type27471 child_type
27212 else27472 else
27213 try mod.singleErrorSetType(field_name);27473 try pt.singleErrorSetType(field_name);
27214 return Air.internedToRef((try mod.intern(.{ .err = .{27474 return Air.internedToRef((try pt.intern(.{ .err = .{
27215 .ty = error_set_type.toIntern(),27475 .ty = error_set_type.toIntern(),
27216 .name = field_name,27476 .name = field_name,
27217 } })));27477 } })));
...@@ -27220,11 +27480,11 @@ fn fieldVal(...@@ -27220,11 +27480,11 @@ fn fieldVal(
27220 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {27480 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {
27221 return inst;27481 return inst;
27222 }27482 }
27223 try child_type.resolveFields(mod);27483 try child_type.resolveFields(pt);
27224 if (child_type.unionTagType(mod)) |enum_ty| {27484 if (child_type.unionTagType(mod)) |enum_ty| {
27225 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index_usize| {27485 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index_usize| {
27226 const field_index: u32 = @intCast(field_index_usize);27486 const field_index: u32 = @intCast(field_index_usize);
27227 return Air.internedToRef((try mod.enumValueFieldIndex(enum_ty, field_index)).toIntern());27487 return Air.internedToRef((try pt.enumValueFieldIndex(enum_ty, field_index)).toIntern());
27228 }27488 }
27229 }27489 }
27230 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);27490 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
...@@ -27236,7 +27496,7 @@ fn fieldVal(...@@ -27236,7 +27496,7 @@ fn fieldVal(
27236 const field_index_usize = child_type.enumFieldIndex(field_name, mod) orelse27496 const field_index_usize = child_type.enumFieldIndex(field_name, mod) orelse
27237 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);27497 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
27238 const field_index: u32 = @intCast(field_index_usize);27498 const field_index: u32 = @intCast(field_index_usize);
27239 const enum_val = try mod.enumValueFieldIndex(child_type, field_index);27499 const enum_val = try pt.enumValueFieldIndex(child_type, field_index);
27240 return Air.internedToRef(enum_val.toIntern());27500 return Air.internedToRef(enum_val.toIntern());
27241 },27501 },
27242 .Struct, .Opaque => {27502 .Struct, .Opaque => {
...@@ -27247,7 +27507,7 @@ fn fieldVal(...@@ -27247,7 +27507,7 @@ fn fieldVal(
27247 },27507 },
27248 else => {27508 else => {
27249 const msg = msg: {27509 const msg = msg: {
27250 const msg = try sema.errMsg(src, "type '{}' has no members", .{child_type.fmt(mod)});27510 const msg = try sema.errMsg(src, "type '{}' has no members", .{child_type.fmt(pt)});
27251 errdefer msg.destroy(sema.gpa);27511 errdefer msg.destroy(sema.gpa);
27252 if (child_type.isSlice(mod)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{});27512 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", .{});27513 if (child_type.zigTypeTag(mod) == .Array) try sema.errNote(src, msg, "array values have 'len' member", .{});
...@@ -27288,13 +27548,14 @@ fn fieldPtr(...@@ -27288,13 +27548,14 @@ fn fieldPtr(
27288 // When editing this function, note that there is corresponding logic to be edited27548 // 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.27549 // in `fieldVal`. This function takes a pointer and returns a pointer.
2729027550
27291 const mod = sema.mod;27551 const pt = sema.pt;
27552 const mod = pt.zcu;
27292 const ip = &mod.intern_pool;27553 const ip = &mod.intern_pool;
27293 const object_ptr_src = src; // TODO better source location27554 const object_ptr_src = src; // TODO better source location
27294 const object_ptr_ty = sema.typeOf(object_ptr);27555 const object_ptr_ty = sema.typeOf(object_ptr);
27295 const object_ty = switch (object_ptr_ty.zigTypeTag(mod)) {27556 const object_ty = switch (object_ptr_ty.zigTypeTag(mod)) {
27296 .Pointer => object_ptr_ty.childType(mod),27557 .Pointer => object_ptr_ty.childType(mod),
27297 else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty.fmt(mod)}),27558 else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty.fmt(pt)}),
27298 };27559 };
2729927560
27300 // Zig allows dereferencing a single pointer during field lookup. Note that27561 // Zig allows dereferencing a single pointer during field lookup. Note that
...@@ -27310,11 +27571,11 @@ fn fieldPtr(...@@ -27310,11 +27571,11 @@ fn fieldPtr(
27310 switch (inner_ty.zigTypeTag(mod)) {27571 switch (inner_ty.zigTypeTag(mod)) {
27311 .Array => {27572 .Array => {
27312 if (field_name.eqlSlice("len", ip)) {27573 if (field_name.eqlSlice("len", ip)) {
27313 const int_val = try mod.intValue(Type.usize, inner_ty.arrayLen(mod));27574 const int_val = try pt.intValue(Type.usize, inner_ty.arrayLen(mod));
27314 return anonDeclRef(sema, int_val.toIntern());27575 return anonDeclRef(sema, int_val.toIntern());
27315 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {27576 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {
27316 const ptr_info = object_ty.ptrInfo(mod);27577 const ptr_info = object_ty.ptrInfo(mod);
27317 const new_ptr_ty = try mod.ptrTypeSema(.{27578 const new_ptr_ty = try pt.ptrTypeSema(.{
27318 .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(),27579 .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(),
27319 .sentinel = if (object_ty.sentinel(mod)) |s| s.toIntern() else .none,27580 .sentinel = if (object_ty.sentinel(mod)) |s| s.toIntern() else .none,
27320 .flags = .{27581 .flags = .{
...@@ -27329,7 +27590,7 @@ fn fieldPtr(...@@ -27329,7 +27590,7 @@ fn fieldPtr(
27329 .packed_offset = ptr_info.packed_offset,27590 .packed_offset = ptr_info.packed_offset,
27330 });27591 });
27331 const ptr_ptr_info = object_ptr_ty.ptrInfo(mod);27592 const ptr_ptr_info = object_ptr_ty.ptrInfo(mod);
27332 const result_ty = try mod.ptrTypeSema(.{27593 const result_ty = try pt.ptrTypeSema(.{
27333 .child = new_ptr_ty.toIntern(),27594 .child = new_ptr_ty.toIntern(),
27334 .sentinel = if (object_ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,27595 .sentinel = if (object_ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,
27335 .flags = .{27596 .flags = .{
...@@ -27348,7 +27609,7 @@ fn fieldPtr(...@@ -27348,7 +27609,7 @@ fn fieldPtr(
27348 block,27609 block,
27349 field_name_src,27610 field_name_src,
27350 "no member named '{}' in '{}'",27611 "no member named '{}' in '{}'",
27351 .{ field_name.fmt(ip), object_ty.fmt(mod) },27612 .{ field_name.fmt(ip), object_ty.fmt(pt) },
27352 );27613 );
27353 }27614 }
27354 },27615 },
...@@ -27363,7 +27624,7 @@ fn fieldPtr(...@@ -27363,7 +27624,7 @@ fn fieldPtr(
27363 if (field_name.eqlSlice("ptr", ip)) {27624 if (field_name.eqlSlice("ptr", ip)) {
27364 const slice_ptr_ty = inner_ty.slicePtrFieldType(mod);27625 const slice_ptr_ty = inner_ty.slicePtrFieldType(mod);
2736527626
27366 const result_ty = try mod.ptrTypeSema(.{27627 const result_ty = try pt.ptrTypeSema(.{
27367 .child = slice_ptr_ty.toIntern(),27628 .child = slice_ptr_ty.toIntern(),
27368 .flags = .{27629 .flags = .{
27369 .is_const = !attr_ptr_ty.ptrIsMutable(mod),27630 .is_const = !attr_ptr_ty.ptrIsMutable(mod),
...@@ -27373,7 +27634,7 @@ fn fieldPtr(...@@ -27373,7 +27634,7 @@ fn fieldPtr(
27373 });27634 });
2737427635
27375 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {27636 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {
27376 return Air.internedToRef((try val.ptrField(Value.slice_ptr_index, mod)).toIntern());27637 return Air.internedToRef((try val.ptrField(Value.slice_ptr_index, pt)).toIntern());
27377 }27638 }
27378 try sema.requireRuntimeBlock(block, src, null);27639 try sema.requireRuntimeBlock(block, src, null);
2737927640
...@@ -27381,7 +27642,7 @@ fn fieldPtr(...@@ -27381,7 +27642,7 @@ fn fieldPtr(
27381 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);27642 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);
27382 return field_ptr;27643 return field_ptr;
27383 } else if (field_name.eqlSlice("len", ip)) {27644 } else if (field_name.eqlSlice("len", ip)) {
27384 const result_ty = try mod.ptrTypeSema(.{27645 const result_ty = try pt.ptrTypeSema(.{
27385 .child = .usize_type,27646 .child = .usize_type,
27386 .flags = .{27647 .flags = .{
27387 .is_const = !attr_ptr_ty.ptrIsMutable(mod),27648 .is_const = !attr_ptr_ty.ptrIsMutable(mod),
...@@ -27391,7 +27652,7 @@ fn fieldPtr(...@@ -27391,7 +27652,7 @@ fn fieldPtr(
27391 });27652 });
2739227653
27393 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {27654 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {
27394 return Air.internedToRef((try val.ptrField(Value.slice_len_index, mod)).toIntern());27655 return Air.internedToRef((try val.ptrField(Value.slice_len_index, pt)).toIntern());
27395 }27656 }
27396 try sema.requireRuntimeBlock(block, src, null);27657 try sema.requireRuntimeBlock(block, src, null);
2739727658
...@@ -27403,7 +27664,7 @@ fn fieldPtr(...@@ -27403,7 +27664,7 @@ fn fieldPtr(
27403 block,27664 block,
27404 field_name_src,27665 field_name_src,
27405 "no member named '{}' in '{}'",27666 "no member named '{}' in '{}'",
27406 .{ field_name.fmt(ip), object_ty.fmt(mod) },27667 .{ field_name.fmt(ip), object_ty.fmt(pt) },
27407 );27668 );
27408 }27669 }
27409 },27670 },
...@@ -27433,7 +27694,7 @@ fn fieldPtr(...@@ -27433,7 +27694,7 @@ fn fieldPtr(
27433 break :blk;27694 break :blk;
27434 }27695 }
27435 return sema.fail(block, src, "no error named '{}' in '{}'", .{27696 return sema.fail(block, src, "no error named '{}' in '{}'", .{
27436 field_name.fmt(ip), child_type.fmt(mod),27697 field_name.fmt(ip), child_type.fmt(pt),
27437 });27698 });
27438 },27699 },
27439 .inferred_error_set_type => {27700 .inferred_error_set_type => {
...@@ -27449,8 +27710,8 @@ fn fieldPtr(...@@ -27449,8 +27710,8 @@ fn fieldPtr(
27449 const error_set_type = if (!child_type.isAnyError(mod))27710 const error_set_type = if (!child_type.isAnyError(mod))
27450 child_type27711 child_type
27451 else27712 else
27452 try mod.singleErrorSetType(field_name);27713 try pt.singleErrorSetType(field_name);
27453 return anonDeclRef(sema, try mod.intern(.{ .err = .{27714 return anonDeclRef(sema, try pt.intern(.{ .err = .{
27454 .ty = error_set_type.toIntern(),27715 .ty = error_set_type.toIntern(),
27455 .name = field_name,27716 .name = field_name,
27456 } }));27717 } }));
...@@ -27459,11 +27720,11 @@ fn fieldPtr(...@@ -27459,11 +27720,11 @@ fn fieldPtr(
27459 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {27720 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {
27460 return inst;27721 return inst;
27461 }27722 }
27462 try child_type.resolveFields(mod);27723 try child_type.resolveFields(pt);
27463 if (child_type.unionTagType(mod)) |enum_ty| {27724 if (child_type.unionTagType(mod)) |enum_ty| {
27464 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| {27725 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| {
27465 const field_index_u32: u32 = @intCast(field_index);27726 const field_index_u32: u32 = @intCast(field_index);
27466 const idx_val = try mod.enumValueFieldIndex(enum_ty, field_index_u32);27727 const idx_val = try pt.enumValueFieldIndex(enum_ty, field_index_u32);
27467 return anonDeclRef(sema, idx_val.toIntern());27728 return anonDeclRef(sema, idx_val.toIntern());
27468 }27729 }
27469 }27730 }
...@@ -27477,7 +27738,7 @@ fn fieldPtr(...@@ -27477,7 +27738,7 @@ fn fieldPtr(
27477 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);27738 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
27478 };27739 };
27479 const field_index_u32: u32 = @intCast(field_index);27740 const field_index_u32: u32 = @intCast(field_index);
27480 const idx_val = try mod.enumValueFieldIndex(child_type, field_index_u32);27741 const idx_val = try pt.enumValueFieldIndex(child_type, field_index_u32);
27481 return anonDeclRef(sema, idx_val.toIntern());27742 return anonDeclRef(sema, idx_val.toIntern());
27482 },27743 },
27483 .Struct, .Opaque => {27744 .Struct, .Opaque => {
...@@ -27486,7 +27747,7 @@ fn fieldPtr(...@@ -27486,7 +27747,7 @@ fn fieldPtr(
27486 }27747 }
27487 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);27748 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
27488 },27749 },
27489 else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(mod)}),27750 else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(pt)}),
27490 }27751 }
27491 },27752 },
27492 .Struct => {27753 .Struct => {
...@@ -27533,14 +27794,15 @@ fn fieldCallBind(...@@ -27533,14 +27794,15 @@ fn fieldCallBind(
27533 // When editing this function, note that there is corresponding logic to be edited27794 // 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.27795 // in `fieldVal`. This function takes a pointer and returns a pointer.
2753527796
27536 const mod = sema.mod;27797 const pt = sema.pt;
27798 const mod = pt.zcu;
27537 const ip = &mod.intern_pool;27799 const ip = &mod.intern_pool;
27538 const raw_ptr_src = src; // TODO better source location27800 const raw_ptr_src = src; // TODO better source location
27539 const raw_ptr_ty = sema.typeOf(raw_ptr);27801 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))27802 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)27803 raw_ptr_ty.childType(mod)
27542 else27804 else
27543 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(mod)});27805 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(pt)});
2754427806
27545 // Optionally dereference a second pointer to get the concrete type.27807 // 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;27808 const is_double_ptr = inner_ty.zigTypeTag(mod) == .Pointer and inner_ty.ptrSize(mod) == .One;
...@@ -27554,7 +27816,7 @@ fn fieldCallBind(...@@ -27554,7 +27816,7 @@ fn fieldCallBind(
27554 find_field: {27816 find_field: {
27555 switch (concrete_ty.zigTypeTag(mod)) {27817 switch (concrete_ty.zigTypeTag(mod)) {
27556 .Struct => {27818 .Struct => {
27557 try concrete_ty.resolveFields(mod);27819 try concrete_ty.resolveFields(pt);
27558 if (mod.typeToStruct(concrete_ty)) |struct_type| {27820 if (mod.typeToStruct(concrete_ty)) |struct_type| {
27559 const field_index = struct_type.nameIndex(ip, field_name) orelse27821 const field_index = struct_type.nameIndex(ip, field_name) orelse
27560 break :find_field;27822 break :find_field;
...@@ -27563,7 +27825,7 @@ fn fieldCallBind(...@@ -27563,7 +27825,7 @@ fn fieldCallBind(
27563 return sema.finishFieldCallBind(block, src, ptr_ty, field_ty, field_index, object_ptr);27825 return sema.finishFieldCallBind(block, src, ptr_ty, field_ty, field_index, object_ptr);
27564 } else if (concrete_ty.isTuple(mod)) {27826 } else if (concrete_ty.isTuple(mod)) {
27565 if (field_name.eqlSlice("len", ip)) {27827 if (field_name.eqlSlice("len", ip)) {
27566 return .{ .direct = try mod.intRef(Type.usize, concrete_ty.structFieldCount(mod)) };27828 return .{ .direct = try pt.intRef(Type.usize, concrete_ty.structFieldCount(mod)) };
27567 }27829 }
27568 if (field_name.toUnsigned(ip)) |field_index| {27830 if (field_name.toUnsigned(ip)) |field_index| {
27569 if (field_index >= concrete_ty.structFieldCount(mod)) break :find_field;27831 if (field_index >= concrete_ty.structFieldCount(mod)) break :find_field;
...@@ -27580,7 +27842,7 @@ fn fieldCallBind(...@@ -27580,7 +27842,7 @@ fn fieldCallBind(
27580 }27842 }
27581 },27843 },
27582 .Union => {27844 .Union => {
27583 try concrete_ty.resolveFields(mod);27845 try concrete_ty.resolveFields(pt);
27584 const union_obj = mod.typeToUnion(concrete_ty).?;27846 const union_obj = mod.typeToUnion(concrete_ty).?;
27585 _ = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse break :find_field;27847 _ = 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);27848 const field_ptr = try unionFieldPtr(sema, block, src, object_ptr, field_name, field_name_src, concrete_ty, false);
...@@ -27661,7 +27923,7 @@ fn fieldCallBind(...@@ -27661,7 +27923,7 @@ fn fieldCallBind(
27661 const msg = msg: {27923 const msg = msg: {
27662 const msg = try sema.errMsg(src, "no field or member function named '{}' in '{}'", .{27924 const msg = try sema.errMsg(src, "no field or member function named '{}' in '{}'", .{
27663 field_name.fmt(ip),27925 field_name.fmt(ip),
27664 concrete_ty.fmt(mod),27926 concrete_ty.fmt(pt),
27665 });27927 });
27666 errdefer msg.destroy(sema.gpa);27928 errdefer msg.destroy(sema.gpa);
27667 try sema.addDeclaredHereNote(msg, concrete_ty);27929 try sema.addDeclaredHereNote(msg, concrete_ty);
...@@ -27689,8 +27951,9 @@ fn finishFieldCallBind(...@@ -27689,8 +27951,9 @@ fn finishFieldCallBind(
27689 field_index: u32,27951 field_index: u32,
27690 object_ptr: Air.Inst.Ref,27952 object_ptr: Air.Inst.Ref,
27691) CompileError!ResolvedFieldCallee {27953) CompileError!ResolvedFieldCallee {
27692 const mod = sema.mod;27954 const pt = sema.pt;
27693 const ptr_field_ty = try mod.ptrTypeSema(.{27955 const mod = pt.zcu;
27956 const ptr_field_ty = try pt.ptrTypeSema(.{
27694 .child = field_ty.toIntern(),27957 .child = field_ty.toIntern(),
27695 .flags = .{27958 .flags = .{
27696 .is_const = !ptr_ty.ptrIsMutable(mod),27959 .is_const = !ptr_ty.ptrIsMutable(mod),
...@@ -27701,14 +27964,14 @@ fn finishFieldCallBind(...@@ -27701,14 +27964,14 @@ fn finishFieldCallBind(
27701 const container_ty = ptr_ty.childType(mod);27964 const container_ty = ptr_ty.childType(mod);
27702 if (container_ty.zigTypeTag(mod) == .Struct) {27965 if (container_ty.zigTypeTag(mod) == .Struct) {
27703 if (container_ty.structFieldIsComptime(field_index, mod)) {27966 if (container_ty.structFieldIsComptime(field_index, mod)) {
27704 try container_ty.resolveStructFieldInits(mod);27967 try container_ty.resolveStructFieldInits(pt);
27705 const default_val = (try container_ty.structFieldValueComptime(mod, field_index)).?;27968 const default_val = (try container_ty.structFieldValueComptime(pt, field_index)).?;
27706 return .{ .direct = Air.internedToRef(default_val.toIntern()) };27969 return .{ .direct = Air.internedToRef(default_val.toIntern()) };
27707 }27970 }
27708 }27971 }
2770927972
27710 if (try sema.resolveDefinedValue(block, src, object_ptr)) |struct_ptr_val| {27973 if (try sema.resolveDefinedValue(block, src, object_ptr)) |struct_ptr_val| {
27711 const ptr_val = try struct_ptr_val.ptrField(field_index, mod);27974 const ptr_val = try struct_ptr_val.ptrField(field_index, pt);
27712 const pointer = Air.internedToRef(ptr_val.toIntern());27975 const pointer = Air.internedToRef(ptr_val.toIntern());
27713 return .{ .direct = try sema.analyzeLoad(block, src, pointer, src) };27976 return .{ .direct = try sema.analyzeLoad(block, src, pointer, src) };
27714 }27977 }
...@@ -27725,7 +27988,8 @@ fn namespaceLookup(...@@ -27725,7 +27988,8 @@ fn namespaceLookup(
27725 opt_namespace: InternPool.OptionalNamespaceIndex,27988 opt_namespace: InternPool.OptionalNamespaceIndex,
27726 decl_name: InternPool.NullTerminatedString,27989 decl_name: InternPool.NullTerminatedString,
27727) CompileError!?InternPool.DeclIndex {27990) CompileError!?InternPool.DeclIndex {
27728 const mod = sema.mod;27991 const pt = sema.pt;
27992 const mod = pt.zcu;
27729 const gpa = sema.gpa;27993 const gpa = sema.gpa;
27730 if (try sema.lookupInNamespace(block, src, opt_namespace, decl_name, true)) |decl_index| {27994 if (try sema.lookupInNamespace(block, src, opt_namespace, decl_name, true)) |decl_index| {
27731 const decl = mod.declPtr(decl_index);27995 const decl = mod.declPtr(decl_index);
...@@ -27780,16 +28044,17 @@ fn structFieldPtr(...@@ -27780,16 +28044,17 @@ fn structFieldPtr(
27780 struct_ty: Type,28044 struct_ty: Type,
27781 initializing: bool,28045 initializing: bool,
27782) CompileError!Air.Inst.Ref {28046) CompileError!Air.Inst.Ref {
27783 const mod = sema.mod;28047 const pt = sema.pt;
28048 const mod = pt.zcu;
27784 const ip = &mod.intern_pool;28049 const ip = &mod.intern_pool;
27785 assert(struct_ty.zigTypeTag(mod) == .Struct);28050 assert(struct_ty.zigTypeTag(mod) == .Struct);
2778628051
27787 try struct_ty.resolveFields(mod);28052 try struct_ty.resolveFields(pt);
27788 try struct_ty.resolveLayout(mod);28053 try struct_ty.resolveLayout(pt);
2778928054
27790 if (struct_ty.isTuple(mod)) {28055 if (struct_ty.isTuple(mod)) {
27791 if (field_name.eqlSlice("len", ip)) {28056 if (field_name.eqlSlice("len", ip)) {
27792 const len_inst = try mod.intRef(Type.usize, struct_ty.structFieldCount(mod));28057 const len_inst = try pt.intRef(Type.usize, struct_ty.structFieldCount(mod));
27793 return sema.analyzeRef(block, src, len_inst);28058 return sema.analyzeRef(block, src, len_inst);
27794 }28059 }
27795 const field_index = try sema.tupleFieldIndex(block, struct_ty, field_name, field_name_src);28060 const field_index = try sema.tupleFieldIndex(block, struct_ty, field_name, field_name_src);
...@@ -27817,14 +28082,15 @@ fn structFieldPtrByIndex(...@@ -27817,14 +28082,15 @@ fn structFieldPtrByIndex(
27817 struct_ty: Type,28082 struct_ty: Type,
27818 initializing: bool,28083 initializing: bool,
27819) CompileError!Air.Inst.Ref {28084) CompileError!Air.Inst.Ref {
27820 const mod = sema.mod;28085 const pt = sema.pt;
28086 const mod = pt.zcu;
27821 const ip = &mod.intern_pool;28087 const ip = &mod.intern_pool;
27822 if (struct_ty.isAnonStruct(mod)) {28088 if (struct_ty.isAnonStruct(mod)) {
27823 return sema.tupleFieldPtr(block, src, struct_ptr, field_src, field_index, initializing);28089 return sema.tupleFieldPtr(block, src, struct_ptr, field_src, field_index, initializing);
27824 }28090 }
2782528091
27826 if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {28092 if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {
27827 const val = try struct_ptr_val.ptrField(field_index, mod);28093 const val = try struct_ptr_val.ptrField(field_index, pt);
27828 return Air.internedToRef(val.toIntern());28094 return Air.internedToRef(val.toIntern());
27829 }28095 }
2783028096
...@@ -27848,7 +28114,7 @@ fn structFieldPtrByIndex(...@@ -27848,7 +28114,7 @@ fn structFieldPtrByIndex(
27848 try sema.typeAbiAlignment(Type.fromInterned(struct_ptr_ty_info.child));28114 try sema.typeAbiAlignment(Type.fromInterned(struct_ptr_ty_info.child));
2784928115
27850 if (struct_type.layout == .@"packed") {28116 if (struct_type.layout == .@"packed") {
27851 switch (struct_ty.packedStructFieldPtrInfo(struct_ptr_ty, field_index, mod)) {28117 switch (struct_ty.packedStructFieldPtrInfo(struct_ptr_ty, field_index, pt)) {
27852 .bit_ptr => |packed_offset| {28118 .bit_ptr => |packed_offset| {
27853 ptr_ty_data.flags.alignment = parent_align;28119 ptr_ty_data.flags.alignment = parent_align;
27854 ptr_ty_data.packed_offset = packed_offset;28120 ptr_ty_data.packed_offset = packed_offset;
...@@ -27861,14 +28127,14 @@ fn structFieldPtrByIndex(...@@ -27861,14 +28127,14 @@ fn structFieldPtrByIndex(
27861 // For extern structs, field alignment might be bigger than type's28127 // For extern structs, field alignment might be bigger than type's
27862 // natural alignment. Eg, in `extern struct { x: u32, y: u16 }` the28128 // natural alignment. Eg, in `extern struct { x: u32, y: u16 }` the
27863 // second field is aligned as u32.28129 // second field is aligned as u32.
27864 const field_offset = struct_ty.structFieldOffset(field_index, mod);28130 const field_offset = struct_ty.structFieldOffset(field_index, pt);
27865 ptr_ty_data.flags.alignment = if (parent_align == .none)28131 ptr_ty_data.flags.alignment = if (parent_align == .none)
27866 .none28132 .none
27867 else28133 else
27868 @enumFromInt(@min(@intFromEnum(parent_align), @ctz(field_offset)));28134 @enumFromInt(@min(@intFromEnum(parent_align), @ctz(field_offset)));
27869 } else {28135 } else {
27870 // Our alignment is capped at the field alignment.28136 // Our alignment is capped at the field alignment.
27871 const field_align = try mod.structFieldAlignmentAdvanced(28137 const field_align = try pt.structFieldAlignmentAdvanced(
27872 struct_type.fieldAlign(ip, field_index),28138 struct_type.fieldAlign(ip, field_index),
27873 Type.fromInterned(field_ty),28139 Type.fromInterned(field_ty),
27874 struct_type.layout,28140 struct_type.layout,
...@@ -27880,11 +28146,11 @@ fn structFieldPtrByIndex(...@@ -27880,11 +28146,11 @@ fn structFieldPtrByIndex(
27880 field_align.min(parent_align);28146 field_align.min(parent_align);
27881 }28147 }
2788228148
27883 const ptr_field_ty = try mod.ptrTypeSema(ptr_ty_data);28149 const ptr_field_ty = try pt.ptrTypeSema(ptr_ty_data);
2788428150
27885 if (struct_type.fieldIsComptime(ip, field_index)) {28151 if (struct_type.fieldIsComptime(ip, field_index)) {
27886 try struct_ty.resolveStructFieldInits(mod);28152 try struct_ty.resolveStructFieldInits(pt);
27887 const val = try mod.intern(.{ .ptr = .{28153 const val = try pt.intern(.{ .ptr = .{
27888 .ty = ptr_field_ty.toIntern(),28154 .ty = ptr_field_ty.toIntern(),
27889 .base_addr = .{ .comptime_field = struct_type.field_inits.get(ip)[field_index] },28155 .base_addr = .{ .comptime_field = struct_type.field_inits.get(ip)[field_index] },
27890 .byte_offset = 0,28156 .byte_offset = 0,
...@@ -27905,11 +28171,12 @@ fn structFieldVal(...@@ -27905,11 +28171,12 @@ fn structFieldVal(
27905 field_name_src: LazySrcLoc,28171 field_name_src: LazySrcLoc,
27906 struct_ty: Type,28172 struct_ty: Type,
27907) CompileError!Air.Inst.Ref {28173) CompileError!Air.Inst.Ref {
27908 const mod = sema.mod;28174 const pt = sema.pt;
28175 const mod = pt.zcu;
27909 const ip = &mod.intern_pool;28176 const ip = &mod.intern_pool;
27910 assert(struct_ty.zigTypeTag(mod) == .Struct);28177 assert(struct_ty.zigTypeTag(mod) == .Struct);
2791128178
27912 try struct_ty.resolveFields(mod);28179 try struct_ty.resolveFields(pt);
2791328180
27914 switch (ip.indexToKey(struct_ty.toIntern())) {28181 switch (ip.indexToKey(struct_ty.toIntern())) {
27915 .struct_type => {28182 .struct_type => {
...@@ -27920,7 +28187,7 @@ fn structFieldVal(...@@ -27920,7 +28187,7 @@ fn structFieldVal(
27920 const field_index = struct_type.nameIndex(ip, field_name) orelse28187 const field_index = struct_type.nameIndex(ip, field_name) orelse
27921 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);28188 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);
27922 if (struct_type.fieldIsComptime(ip, field_index)) {28189 if (struct_type.fieldIsComptime(ip, field_index)) {
27923 try struct_ty.resolveStructFieldInits(mod);28190 try struct_ty.resolveStructFieldInits(pt);
27924 return Air.internedToRef(struct_type.field_inits.get(ip)[field_index]);28191 return Air.internedToRef(struct_type.field_inits.get(ip)[field_index]);
27925 }28192 }
2792628193
...@@ -27929,15 +28196,15 @@ fn structFieldVal(...@@ -27929,15 +28196,15 @@ fn structFieldVal(
27929 return Air.internedToRef(field_val.toIntern());28196 return Air.internedToRef(field_val.toIntern());
2793028197
27931 if (try sema.resolveValue(struct_byval)) |struct_val| {28198 if (try sema.resolveValue(struct_byval)) |struct_val| {
27932 if (struct_val.isUndef(mod)) return mod.undefRef(field_ty);28199 if (struct_val.isUndef(mod)) return pt.undefRef(field_ty);
27933 if ((try sema.typeHasOnePossibleValue(field_ty))) |opv| {28200 if ((try sema.typeHasOnePossibleValue(field_ty))) |opv| {
27934 return Air.internedToRef(opv.toIntern());28201 return Air.internedToRef(opv.toIntern());
27935 }28202 }
27936 return Air.internedToRef((try struct_val.fieldValue(mod, field_index)).toIntern());28203 return Air.internedToRef((try struct_val.fieldValue(pt, field_index)).toIntern());
27937 }28204 }
2793828205
27939 try sema.requireRuntimeBlock(block, src, null);28206 try sema.requireRuntimeBlock(block, src, null);
27940 try field_ty.resolveLayout(mod);28207 try field_ty.resolveLayout(pt);
27941 return block.addStructFieldVal(struct_byval, field_index, field_ty);28208 return block.addStructFieldVal(struct_byval, field_index, field_ty);
27942 },28209 },
27943 .anon_struct_type => |anon_struct| {28210 .anon_struct_type => |anon_struct| {
...@@ -27961,9 +28228,10 @@ fn tupleFieldVal(...@@ -27961,9 +28228,10 @@ fn tupleFieldVal(
27961 field_name_src: LazySrcLoc,28228 field_name_src: LazySrcLoc,
27962 tuple_ty: Type,28229 tuple_ty: Type,
27963) CompileError!Air.Inst.Ref {28230) CompileError!Air.Inst.Ref {
27964 const mod = sema.mod;28231 const pt = sema.pt;
28232 const mod = pt.zcu;
27965 if (field_name.eqlSlice("len", &mod.intern_pool)) {28233 if (field_name.eqlSlice("len", &mod.intern_pool)) {
27966 return mod.intRef(Type.usize, tuple_ty.structFieldCount(mod));28234 return pt.intRef(Type.usize, tuple_ty.structFieldCount(mod));
27967 }28235 }
27968 const field_index = try sema.tupleFieldIndex(block, tuple_ty, field_name, field_name_src);28236 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);28237 return sema.tupleFieldValByIndex(block, src, tuple_byval, field_index, tuple_ty);
...@@ -27977,18 +28245,18 @@ fn tupleFieldIndex(...@@ -27977,18 +28245,18 @@ fn tupleFieldIndex(
27977 field_name: InternPool.NullTerminatedString,28245 field_name: InternPool.NullTerminatedString,
27978 field_name_src: LazySrcLoc,28246 field_name_src: LazySrcLoc,
27979) CompileError!u32 {28247) CompileError!u32 {
27980 const mod = sema.mod;28248 const pt = sema.pt;
27981 const ip = &mod.intern_pool;28249 const ip = &pt.zcu.intern_pool;
27982 assert(!field_name.eqlSlice("len", ip));28250 assert(!field_name.eqlSlice("len", ip));
27983 if (field_name.toUnsigned(ip)) |field_index| {28251 if (field_name.toUnsigned(ip)) |field_index| {
27984 if (field_index < tuple_ty.structFieldCount(mod)) return field_index;28252 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 '{}'", .{28253 return sema.fail(block, field_name_src, "index '{}' out of bounds of tuple '{}'", .{
27986 field_name.fmt(ip), tuple_ty.fmt(mod),28254 field_name.fmt(ip), tuple_ty.fmt(pt),
27987 });28255 });
27988 }28256 }
2798928257
27990 return sema.fail(block, field_name_src, "no field named '{}' in tuple '{}'", .{28258 return sema.fail(block, field_name_src, "no field named '{}' in tuple '{}'", .{
27991 field_name.fmt(ip), tuple_ty.fmt(mod),28259 field_name.fmt(ip), tuple_ty.fmt(pt),
27992 });28260 });
27993}28261}
2799428262
...@@ -28000,12 +28268,13 @@ fn tupleFieldValByIndex(...@@ -28000,12 +28268,13 @@ fn tupleFieldValByIndex(
28000 field_index: u32,28268 field_index: u32,
28001 tuple_ty: Type,28269 tuple_ty: Type,
28002) CompileError!Air.Inst.Ref {28270) CompileError!Air.Inst.Ref {
28003 const mod = sema.mod;28271 const pt = sema.pt;
28272 const mod = pt.zcu;
28004 const field_ty = tuple_ty.structFieldType(field_index, mod);28273 const field_ty = tuple_ty.structFieldType(field_index, mod);
2800528274
28006 if (tuple_ty.structFieldIsComptime(field_index, mod))28275 if (tuple_ty.structFieldIsComptime(field_index, mod))
28007 try tuple_ty.resolveStructFieldInits(mod);28276 try tuple_ty.resolveStructFieldInits(pt);
28008 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| {28277 if (try tuple_ty.structFieldValueComptime(pt, field_index)) |default_value| {
28009 return Air.internedToRef(default_value.toIntern());28278 return Air.internedToRef(default_value.toIntern());
28010 }28279 }
2801128280
...@@ -28014,9 +28283,9 @@ fn tupleFieldValByIndex(...@@ -28014,9 +28283,9 @@ fn tupleFieldValByIndex(
28014 return Air.internedToRef(opv.toIntern());28283 return Air.internedToRef(opv.toIntern());
28015 }28284 }
28016 return switch (mod.intern_pool.indexToKey(tuple_val.toIntern())) {28285 return switch (mod.intern_pool.indexToKey(tuple_val.toIntern())) {
28017 .undef => mod.undefRef(field_ty),28286 .undef => pt.undefRef(field_ty),
28018 .aggregate => |aggregate| Air.internedToRef(switch (aggregate.storage) {28287 .aggregate => |aggregate| Air.internedToRef(switch (aggregate.storage) {
28019 .bytes => |bytes| try mod.intValue(Type.u8, bytes.at(field_index, &mod.intern_pool)),28288 .bytes => |bytes| try pt.intValue(Type.u8, bytes.at(field_index, &mod.intern_pool)),
28020 .elems => |elems| Value.fromInterned(elems[field_index]),28289 .elems => |elems| Value.fromInterned(elems[field_index]),
28021 .repeated_elem => |elem| Value.fromInterned(elem),28290 .repeated_elem => |elem| Value.fromInterned(elem),
28022 }.toIntern()),28291 }.toIntern()),
...@@ -28025,7 +28294,7 @@ fn tupleFieldValByIndex(...@@ -28025,7 +28294,7 @@ fn tupleFieldValByIndex(
28025 }28294 }
2802628295
28027 try sema.requireRuntimeBlock(block, src, null);28296 try sema.requireRuntimeBlock(block, src, null);
28028 try field_ty.resolveLayout(mod);28297 try field_ty.resolveLayout(pt);
28029 return block.addStructFieldVal(tuple_byval, field_index, field_ty);28298 return block.addStructFieldVal(tuple_byval, field_index, field_ty);
28030}28299}
2803128300
...@@ -28039,18 +28308,19 @@ fn unionFieldPtr(...@@ -28039,18 +28308,19 @@ fn unionFieldPtr(
28039 union_ty: Type,28308 union_ty: Type,
28040 initializing: bool,28309 initializing: bool,
28041) CompileError!Air.Inst.Ref {28310) CompileError!Air.Inst.Ref {
28042 const mod = sema.mod;28311 const pt = sema.pt;
28312 const mod = pt.zcu;
28043 const ip = &mod.intern_pool;28313 const ip = &mod.intern_pool;
2804428314
28045 assert(union_ty.zigTypeTag(mod) == .Union);28315 assert(union_ty.zigTypeTag(mod) == .Union);
2804628316
28047 const union_ptr_ty = sema.typeOf(union_ptr);28317 const union_ptr_ty = sema.typeOf(union_ptr);
28048 const union_ptr_info = union_ptr_ty.ptrInfo(mod);28318 const union_ptr_info = union_ptr_ty.ptrInfo(mod);
28049 try union_ty.resolveFields(mod);28319 try union_ty.resolveFields(pt);
28050 const union_obj = mod.typeToUnion(union_ty).?;28320 const union_obj = mod.typeToUnion(union_ty).?;
28051 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);28321 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]);28322 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
28053 const ptr_field_ty = try mod.ptrTypeSema(.{28323 const ptr_field_ty = try pt.ptrTypeSema(.{
28054 .child = field_ty.toIntern(),28324 .child = field_ty.toIntern(),
28055 .flags = .{28325 .flags = .{
28056 .is_const = union_ptr_info.flags.is_const,28326 .is_const = union_ptr_info.flags.is_const,
...@@ -28061,7 +28331,7 @@ fn unionFieldPtr(...@@ -28061,7 +28331,7 @@ fn unionFieldPtr(
28061 union_ptr_info.flags.alignment28331 union_ptr_info.flags.alignment
28062 else28332 else
28063 try sema.typeAbiAlignment(union_ty);28333 try sema.typeAbiAlignment(union_ty);
28064 const field_align = try mod.unionFieldNormalAlignmentAdvanced(union_obj, field_index, .sema);28334 const field_align = try pt.unionFieldNormalAlignmentAdvanced(union_obj, field_index, .sema);
28065 break :blk union_align.min(field_align);28335 break :blk union_align.min(field_align);
28066 } else union_ptr_info.flags.alignment,28336 } else union_ptr_info.flags.alignment,
28067 },28337 },
...@@ -28087,9 +28357,9 @@ fn unionFieldPtr(...@@ -28087,9 +28357,9 @@ fn unionFieldPtr(
28087 switch (union_obj.getLayout(ip)) {28357 switch (union_obj.getLayout(ip)) {
28088 .auto => if (initializing) {28358 .auto => if (initializing) {
28089 // Store to the union to initialize the tag.28359 // 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);28360 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]);28361 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));28362 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);28363 try sema.storePtrVal(block, src, union_ptr_val, new_union_val, union_ty);
28094 } else {28364 } else {
28095 const union_val = (try sema.pointerDeref(block, src, union_ptr_val, union_ptr_ty)) orelse28365 const union_val = (try sema.pointerDeref(block, src, union_ptr_val, union_ptr_ty)) orelse
...@@ -28098,7 +28368,7 @@ fn unionFieldPtr(...@@ -28098,7 +28368,7 @@ fn unionFieldPtr(
28098 return sema.failWithUseOfUndef(block, src);28368 return sema.failWithUseOfUndef(block, src);
28099 }28369 }
28100 const un = ip.indexToKey(union_val.toIntern()).un;28370 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);28371 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();28372 const tag_matches = un.tag == field_tag.toIntern();
28103 if (!tag_matches) {28373 if (!tag_matches) {
28104 const msg = msg: {28374 const msg = msg: {
...@@ -28117,7 +28387,7 @@ fn unionFieldPtr(...@@ -28117,7 +28387,7 @@ fn unionFieldPtr(
28117 },28387 },
28118 .@"packed", .@"extern" => {},28388 .@"packed", .@"extern" => {},
28119 }28389 }
28120 const field_ptr_val = try union_ptr_val.ptrField(field_index, mod);28390 const field_ptr_val = try union_ptr_val.ptrField(field_index, pt);
28121 return Air.internedToRef(field_ptr_val.toIntern());28391 return Air.internedToRef(field_ptr_val.toIntern());
28122 }28392 }
2812328393
...@@ -28125,7 +28395,7 @@ fn unionFieldPtr(...@@ -28125,7 +28395,7 @@ fn unionFieldPtr(
28125 if (!initializing and union_obj.getLayout(ip) == .auto and block.wantSafety() and28395 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)28396 union_ty.unionTagTypeSafety(mod) != null and union_obj.field_types.len > 1)
28127 {28397 {
28128 const wanted_tag_val = try mod.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);28398 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());28399 const wanted_tag = Air.internedToRef(wanted_tag_val.toIntern());
28130 // TODO would it be better if get_union_tag supported pointers to unions?28400 // 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);28401 const union_val = try block.addTyOp(.load, union_ty, union_ptr);
...@@ -28148,21 +28418,22 @@ fn unionFieldVal(...@@ -28148,21 +28418,22 @@ fn unionFieldVal(
28148 field_name_src: LazySrcLoc,28418 field_name_src: LazySrcLoc,
28149 union_ty: Type,28419 union_ty: Type,
28150) CompileError!Air.Inst.Ref {28420) CompileError!Air.Inst.Ref {
28151 const zcu = sema.mod;28421 const pt = sema.pt;
28422 const zcu = pt.zcu;
28152 const ip = &zcu.intern_pool;28423 const ip = &zcu.intern_pool;
28153 assert(union_ty.zigTypeTag(zcu) == .Union);28424 assert(union_ty.zigTypeTag(zcu) == .Union);
2815428425
28155 try union_ty.resolveFields(zcu);28426 try union_ty.resolveFields(pt);
28156 const union_obj = zcu.typeToUnion(union_ty).?;28427 const union_obj = zcu.typeToUnion(union_ty).?;
28157 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);28428 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]);28429 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).?);28430 const enum_field_index: u32 = @intCast(Type.fromInterned(union_obj.enum_tag_ty).enumFieldIndex(field_name, zcu).?);
2816028431
28161 if (try sema.resolveValue(union_byval)) |union_val| {28432 if (try sema.resolveValue(union_byval)) |union_val| {
28162 if (union_val.isUndef(zcu)) return zcu.undefRef(field_ty);28433 if (union_val.isUndef(zcu)) return pt.undefRef(field_ty);
2816328434
28164 const un = ip.indexToKey(union_val.toIntern()).un;28435 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);28436 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();28437 const tag_matches = un.tag == field_tag.toIntern();
28167 switch (union_obj.getLayout(ip)) {28438 switch (union_obj.getLayout(ip)) {
28168 .auto => {28439 .auto => {
...@@ -28191,7 +28462,7 @@ fn unionFieldVal(...@@ -28191,7 +28462,7 @@ fn unionFieldVal(
28191 .@"packed" => if (tag_matches) {28462 .@"packed" => if (tag_matches) {
28192 // Fast path - no need to use bitcast logic.28463 // Fast path - no need to use bitcast logic.
28193 return Air.internedToRef(un.val);28464 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| {28465 } 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());28466 return Air.internedToRef(field_val.toIntern());
28196 },28467 },
28197 }28468 }
...@@ -28201,7 +28472,7 @@ fn unionFieldVal(...@@ -28201,7 +28472,7 @@ fn unionFieldVal(
28201 if (union_obj.getLayout(ip) == .auto and block.wantSafety() and28472 if (union_obj.getLayout(ip) == .auto and block.wantSafety() and
28202 union_ty.unionTagTypeSafety(zcu) != null and union_obj.field_types.len > 1)28473 union_ty.unionTagTypeSafety(zcu) != null and union_obj.field_types.len > 1)
28203 {28474 {
28204 const wanted_tag_val = try zcu.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);28475 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());28476 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);28477 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);28478 try sema.panicInactiveUnionField(block, src, active_tag, wanted_tag);
...@@ -28210,7 +28481,7 @@ fn unionFieldVal(...@@ -28210,7 +28481,7 @@ fn unionFieldVal(
28210 _ = try block.addNoOp(.unreach);28481 _ = try block.addNoOp(.unreach);
28211 return .unreachable_value;28482 return .unreachable_value;
28212 }28483 }
28213 try field_ty.resolveLayout(zcu);28484 try field_ty.resolveLayout(pt);
28214 return block.addStructFieldVal(union_byval, field_index, field_ty);28485 return block.addStructFieldVal(union_byval, field_index, field_ty);
28215}28486}
2821628487
...@@ -28224,13 +28495,14 @@ fn elemPtr(...@@ -28224,13 +28495,14 @@ fn elemPtr(
28224 init: bool,28495 init: bool,
28225 oob_safety: bool,28496 oob_safety: bool,
28226) CompileError!Air.Inst.Ref {28497) CompileError!Air.Inst.Ref {
28227 const mod = sema.mod;28498 const pt = sema.pt;
28499 const mod = pt.zcu;
28228 const indexable_ptr_src = src; // TODO better source location28500 const indexable_ptr_src = src; // TODO better source location
28229 const indexable_ptr_ty = sema.typeOf(indexable_ptr);28501 const indexable_ptr_ty = sema.typeOf(indexable_ptr);
2823028502
28231 const indexable_ty = switch (indexable_ptr_ty.zigTypeTag(mod)) {28503 const indexable_ty = switch (indexable_ptr_ty.zigTypeTag(mod)) {
28232 .Pointer => indexable_ptr_ty.childType(mod),28504 .Pointer => indexable_ptr_ty.childType(mod),
28233 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(mod)}),28505 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(pt)}),
28234 };28506 };
28235 try checkIndexable(sema, block, src, indexable_ty);28507 try checkIndexable(sema, block, src, indexable_ty);
2823628508
...@@ -28241,7 +28513,7 @@ fn elemPtr(...@@ -28241,7 +28513,7 @@ fn elemPtr(
28241 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{28513 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{
28242 .needed_comptime_reason = "tuple field access index must be comptime-known",28514 .needed_comptime_reason = "tuple field access index must be comptime-known",
28243 });28515 });
28244 const index: u32 = @intCast(try index_val.toUnsignedIntSema(mod));28516 const index: u32 = @intCast(try index_val.toUnsignedIntSema(pt));
28245 break :blk try sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index, init);28517 break :blk try sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index, init);
28246 },28518 },
28247 else => {28519 else => {
...@@ -28267,7 +28539,8 @@ fn elemPtrOneLayerOnly(...@@ -28267,7 +28539,8 @@ fn elemPtrOneLayerOnly(
28267) CompileError!Air.Inst.Ref {28539) CompileError!Air.Inst.Ref {
28268 const indexable_src = src; // TODO better source location28540 const indexable_src = src; // TODO better source location
28269 const indexable_ty = sema.typeOf(indexable);28541 const indexable_ty = sema.typeOf(indexable);
28270 const mod = sema.mod;28542 const pt = sema.pt;
28543 const mod = pt.zcu;
2827128544
28272 try checkIndexable(sema, block, src, indexable_ty);28545 try checkIndexable(sema, block, src, indexable_ty);
2827328546
...@@ -28279,11 +28552,11 @@ fn elemPtrOneLayerOnly(...@@ -28279,11 +28552,11 @@ fn elemPtrOneLayerOnly(
28279 const runtime_src = rs: {28552 const runtime_src = rs: {
28280 const ptr_val = maybe_ptr_val orelse break :rs indexable_src;28553 const ptr_val = maybe_ptr_val orelse break :rs indexable_src;
28281 const index_val = maybe_index_val orelse break :rs elem_index_src;28554 const index_val = maybe_index_val orelse break :rs elem_index_src;
28282 const index: usize = @intCast(try index_val.toUnsignedIntSema(mod));28555 const index: usize = @intCast(try index_val.toUnsignedIntSema(pt));
28283 const elem_ptr = try ptr_val.ptrElem(index, mod);28556 const elem_ptr = try ptr_val.ptrElem(index, pt);
28284 return Air.internedToRef(elem_ptr.toIntern());28557 return Air.internedToRef(elem_ptr.toIntern());
28285 };28558 };
28286 const result_ty = try indexable_ty.elemPtrType(null, mod);28559 const result_ty = try indexable_ty.elemPtrType(null, pt);
2828728560
28288 try sema.requireRuntimeBlock(block, src, runtime_src);28561 try sema.requireRuntimeBlock(block, src, runtime_src);
28289 return block.addPtrElemPtr(indexable, elem_index, result_ty);28562 return block.addPtrElemPtr(indexable, elem_index, result_ty);
...@@ -28297,7 +28570,7 @@ fn elemPtrOneLayerOnly(...@@ -28297,7 +28570,7 @@ fn elemPtrOneLayerOnly(
28297 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{28570 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{
28298 .needed_comptime_reason = "tuple field access index must be comptime-known",28571 .needed_comptime_reason = "tuple field access index must be comptime-known",
28299 });28572 });
28300 const index: u32 = @intCast(try index_val.toUnsignedIntSema(mod));28573 const index: u32 = @intCast(try index_val.toUnsignedIntSema(pt));
28301 break :blk try sema.tupleFieldPtr(block, indexable_src, indexable, elem_index_src, index, false);28574 break :blk try sema.tupleFieldPtr(block, indexable_src, indexable, elem_index_src, index, false);
28302 },28575 },
28303 else => unreachable, // Guaranteed by checkIndexable28576 else => unreachable, // Guaranteed by checkIndexable
...@@ -28319,7 +28592,8 @@ fn elemVal(...@@ -28319,7 +28592,8 @@ fn elemVal(
28319) CompileError!Air.Inst.Ref {28592) CompileError!Air.Inst.Ref {
28320 const indexable_src = src; // TODO better source location28593 const indexable_src = src; // TODO better source location
28321 const indexable_ty = sema.typeOf(indexable);28594 const indexable_ty = sema.typeOf(indexable);
28322 const mod = sema.mod;28595 const pt = sema.pt;
28596 const mod = pt.zcu;
2832328597
28324 try checkIndexable(sema, block, src, indexable_ty);28598 try checkIndexable(sema, block, src, indexable_ty);
2832528599
...@@ -28337,14 +28611,14 @@ fn elemVal(...@@ -28337,14 +28611,14 @@ fn elemVal(
28337 const runtime_src = rs: {28611 const runtime_src = rs: {
28338 const indexable_val = maybe_indexable_val orelse break :rs indexable_src;28612 const indexable_val = maybe_indexable_val orelse break :rs indexable_src;
28339 const index_val = maybe_index_val orelse break :rs elem_index_src;28613 const index_val = maybe_index_val orelse break :rs elem_index_src;
28340 const index: usize = @intCast(try index_val.toUnsignedIntSema(mod));28614 const index: usize = @intCast(try index_val.toUnsignedIntSema(pt));
28341 const elem_ty = indexable_ty.elemType2(mod);28615 const elem_ty = indexable_ty.elemType2(mod);
28342 const many_ptr_ty = try mod.manyConstPtrType(elem_ty);28616 const many_ptr_ty = try pt.manyConstPtrType(elem_ty);
28343 const many_ptr_val = try mod.getCoerced(indexable_val, many_ptr_ty);28617 const many_ptr_val = try pt.getCoerced(indexable_val, many_ptr_ty);
28344 const elem_ptr_ty = try mod.singleConstPtrType(elem_ty);28618 const elem_ptr_ty = try pt.singleConstPtrType(elem_ty);
28345 const elem_ptr_val = try many_ptr_val.ptrElem(index, mod);28619 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| {28620 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());28621 return Air.internedToRef((try pt.getCoerced(elem_val, elem_ty)).toIntern());
28348 }28622 }
28349 break :rs indexable_src;28623 break :rs indexable_src;
28350 };28624 };
...@@ -28358,7 +28632,7 @@ fn elemVal(...@@ -28358,7 +28632,7 @@ fn elemVal(
28358 if (inner_ty.zigTypeTag(mod) != .Array) break :arr_sent;28632 if (inner_ty.zigTypeTag(mod) != .Array) break :arr_sent;
28359 const sentinel = inner_ty.sentinel(mod) orelse break :arr_sent;28633 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;28634 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));28635 const index = try sema.usizeCast(block, src, try index_val.toUnsignedIntSema(pt));
28362 if (index != inner_ty.arrayLen(mod)) break :arr_sent;28636 if (index != inner_ty.arrayLen(mod)) break :arr_sent;
28363 return Air.internedToRef(sentinel.toIntern());28637 return Air.internedToRef(sentinel.toIntern());
28364 }28638 }
...@@ -28376,7 +28650,7 @@ fn elemVal(...@@ -28376,7 +28650,7 @@ fn elemVal(
28376 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{28650 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{
28377 .needed_comptime_reason = "tuple field access index must be comptime-known",28651 .needed_comptime_reason = "tuple field access index must be comptime-known",
28378 });28652 });
28379 const index: u32 = @intCast(try index_val.toUnsignedIntSema(mod));28653 const index: u32 = @intCast(try index_val.toUnsignedIntSema(pt));
28380 return sema.tupleField(block, indexable_src, indexable, elem_index_src, index);28654 return sema.tupleField(block, indexable_src, indexable, elem_index_src, index);
28381 },28655 },
28382 else => unreachable,28656 else => unreachable,
...@@ -28391,13 +28665,12 @@ fn validateRuntimeElemAccess(...@@ -28391,13 +28665,12 @@ fn validateRuntimeElemAccess(
28391 parent_ty: Type,28665 parent_ty: Type,
28392 parent_src: LazySrcLoc,28666 parent_src: LazySrcLoc,
28393) CompileError!void {28667) CompileError!void {
28394 const mod = sema.mod;
28395 if (try sema.typeRequiresComptime(elem_ty)) {28668 if (try sema.typeRequiresComptime(elem_ty)) {
28396 const msg = msg: {28669 const msg = msg: {
28397 const msg = try sema.errMsg(28670 const msg = try sema.errMsg(
28398 elem_index_src,28671 elem_index_src,
28399 "values of type '{}' must be comptime-known, but index value is runtime-known",28672 "values of type '{}' must be comptime-known, but index value is runtime-known",
28400 .{parent_ty.fmt(mod)},28673 .{parent_ty.fmt(sema.pt)},
28401 );28674 );
28402 errdefer msg.destroy(sema.gpa);28675 errdefer msg.destroy(sema.gpa);
2840328676
...@@ -28418,10 +28691,11 @@ fn tupleFieldPtr(...@@ -28418,10 +28691,11 @@ fn tupleFieldPtr(
28418 field_index: u32,28691 field_index: u32,
28419 init: bool,28692 init: bool,
28420) CompileError!Air.Inst.Ref {28693) CompileError!Air.Inst.Ref {
28421 const mod = sema.mod;28694 const pt = sema.pt;
28695 const mod = pt.zcu;
28422 const tuple_ptr_ty = sema.typeOf(tuple_ptr);28696 const tuple_ptr_ty = sema.typeOf(tuple_ptr);
28423 const tuple_ty = tuple_ptr_ty.childType(mod);28697 const tuple_ty = tuple_ptr_ty.childType(mod);
28424 try tuple_ty.resolveFields(mod);28698 try tuple_ty.resolveFields(pt);
28425 const field_count = tuple_ty.structFieldCount(mod);28699 const field_count = tuple_ty.structFieldCount(mod);
2842628700
28427 if (field_count == 0) {28701 if (field_count == 0) {
...@@ -28435,7 +28709,7 @@ fn tupleFieldPtr(...@@ -28435,7 +28709,7 @@ fn tupleFieldPtr(
28435 }28709 }
2843628710
28437 const field_ty = tuple_ty.structFieldType(field_index, mod);28711 const field_ty = tuple_ty.structFieldType(field_index, mod);
28438 const ptr_field_ty = try mod.ptrTypeSema(.{28712 const ptr_field_ty = try pt.ptrTypeSema(.{
28439 .child = field_ty.toIntern(),28713 .child = field_ty.toIntern(),
28440 .flags = .{28714 .flags = .{
28441 .is_const = !tuple_ptr_ty.ptrIsMutable(mod),28715 .is_const = !tuple_ptr_ty.ptrIsMutable(mod),
...@@ -28445,10 +28719,10 @@ fn tupleFieldPtr(...@@ -28445,10 +28719,10 @@ fn tupleFieldPtr(
28445 });28719 });
2844628720
28447 if (tuple_ty.structFieldIsComptime(field_index, mod))28721 if (tuple_ty.structFieldIsComptime(field_index, mod))
28448 try tuple_ty.resolveStructFieldInits(mod);28722 try tuple_ty.resolveStructFieldInits(pt);
2844928723
28450 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {28724 if (try tuple_ty.structFieldValueComptime(pt, field_index)) |default_val| {
28451 return Air.internedToRef((try mod.intern(.{ .ptr = .{28725 return Air.internedToRef((try pt.intern(.{ .ptr = .{
28452 .ty = ptr_field_ty.toIntern(),28726 .ty = ptr_field_ty.toIntern(),
28453 .base_addr = .{ .comptime_field = default_val.toIntern() },28727 .base_addr = .{ .comptime_field = default_val.toIntern() },
28454 .byte_offset = 0,28728 .byte_offset = 0,
...@@ -28456,7 +28730,7 @@ fn tupleFieldPtr(...@@ -28456,7 +28730,7 @@ fn tupleFieldPtr(
28456 }28730 }
2845728731
28458 if (try sema.resolveValue(tuple_ptr)) |tuple_ptr_val| {28732 if (try sema.resolveValue(tuple_ptr)) |tuple_ptr_val| {
28459 const field_ptr_val = try tuple_ptr_val.ptrField(field_index, mod);28733 const field_ptr_val = try tuple_ptr_val.ptrField(field_index, pt);
28460 return Air.internedToRef(field_ptr_val.toIntern());28734 return Air.internedToRef(field_ptr_val.toIntern());
28461 }28735 }
2846228736
...@@ -28476,9 +28750,10 @@ fn tupleField(...@@ -28476,9 +28750,10 @@ fn tupleField(
28476 field_index_src: LazySrcLoc,28750 field_index_src: LazySrcLoc,
28477 field_index: u32,28751 field_index: u32,
28478) CompileError!Air.Inst.Ref {28752) CompileError!Air.Inst.Ref {
28479 const mod = sema.mod;28753 const pt = sema.pt;
28754 const mod = pt.zcu;
28480 const tuple_ty = sema.typeOf(tuple);28755 const tuple_ty = sema.typeOf(tuple);
28481 try tuple_ty.resolveFields(mod);28756 try tuple_ty.resolveFields(pt);
28482 const field_count = tuple_ty.structFieldCount(mod);28757 const field_count = tuple_ty.structFieldCount(mod);
2848328758
28484 if (field_count == 0) {28759 if (field_count == 0) {
...@@ -28494,20 +28769,20 @@ fn tupleField(...@@ -28494,20 +28769,20 @@ fn tupleField(
28494 const field_ty = tuple_ty.structFieldType(field_index, mod);28769 const field_ty = tuple_ty.structFieldType(field_index, mod);
2849528770
28496 if (tuple_ty.structFieldIsComptime(field_index, mod))28771 if (tuple_ty.structFieldIsComptime(field_index, mod))
28497 try tuple_ty.resolveStructFieldInits(mod);28772 try tuple_ty.resolveStructFieldInits(pt);
28498 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| {28773 if (try tuple_ty.structFieldValueComptime(pt, field_index)) |default_value| {
28499 return Air.internedToRef(default_value.toIntern()); // comptime field28774 return Air.internedToRef(default_value.toIntern()); // comptime field
28500 }28775 }
2850128776
28502 if (try sema.resolveValue(tuple)) |tuple_val| {28777 if (try sema.resolveValue(tuple)) |tuple_val| {
28503 if (tuple_val.isUndef(mod)) return mod.undefRef(field_ty);28778 if (tuple_val.isUndef(mod)) return pt.undefRef(field_ty);
28504 return Air.internedToRef((try tuple_val.fieldValue(mod, field_index)).toIntern());28779 return Air.internedToRef((try tuple_val.fieldValue(pt, field_index)).toIntern());
28505 }28780 }
2850628781
28507 try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src);28782 try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src);
2850828783
28509 try sema.requireRuntimeBlock(block, tuple_src, null);28784 try sema.requireRuntimeBlock(block, tuple_src, null);
28510 try field_ty.resolveLayout(mod);28785 try field_ty.resolveLayout(pt);
28511 return block.addStructFieldVal(tuple, field_index, field_ty);28786 return block.addStructFieldVal(tuple, field_index, field_ty);
28512}28787}
2851328788
...@@ -28521,7 +28796,8 @@ fn elemValArray(...@@ -28521,7 +28796,8 @@ fn elemValArray(
28521 elem_index: Air.Inst.Ref,28796 elem_index: Air.Inst.Ref,
28522 oob_safety: bool,28797 oob_safety: bool,
28523) CompileError!Air.Inst.Ref {28798) CompileError!Air.Inst.Ref {
28524 const mod = sema.mod;28799 const pt = sema.pt;
28800 const mod = pt.zcu;
28525 const array_ty = sema.typeOf(array);28801 const array_ty = sema.typeOf(array);
28526 const array_sent = array_ty.sentinel(mod);28802 const array_sent = array_ty.sentinel(mod);
28527 const array_len = array_ty.arrayLen(mod);28803 const array_len = array_ty.arrayLen(mod);
...@@ -28537,7 +28813,7 @@ fn elemValArray(...@@ -28537,7 +28813,7 @@ fn elemValArray(
28537 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);28813 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
2853828814
28539 if (maybe_index_val) |index_val| {28815 if (maybe_index_val) |index_val| {
28540 const index: usize = @intCast(try index_val.toUnsignedIntSema(mod));28816 const index: usize = @intCast(try index_val.toUnsignedIntSema(pt));
28541 if (array_sent) |s| {28817 if (array_sent) |s| {
28542 if (index == array_len) {28818 if (index == array_len) {
28543 return Air.internedToRef(s.toIntern());28819 return Air.internedToRef(s.toIntern());
...@@ -28550,11 +28826,11 @@ fn elemValArray(...@@ -28550,11 +28826,11 @@ fn elemValArray(
28550 }28826 }
28551 if (maybe_undef_array_val) |array_val| {28827 if (maybe_undef_array_val) |array_val| {
28552 if (array_val.isUndef(mod)) {28828 if (array_val.isUndef(mod)) {
28553 return mod.undefRef(elem_ty);28829 return pt.undefRef(elem_ty);
28554 }28830 }
28555 if (maybe_index_val) |index_val| {28831 if (maybe_index_val) |index_val| {
28556 const index: usize = @intCast(try index_val.toUnsignedIntSema(mod));28832 const index: usize = @intCast(try index_val.toUnsignedIntSema(pt));
28557 const elem_val = try array_val.elemValue(mod, index);28833 const elem_val = try array_val.elemValue(pt, index);
28558 return Air.internedToRef(elem_val.toIntern());28834 return Air.internedToRef(elem_val.toIntern());
28559 }28835 }
28560 }28836 }
...@@ -28565,7 +28841,7 @@ fn elemValArray(...@@ -28565,7 +28841,7 @@ fn elemValArray(
28565 if (oob_safety and block.wantSafety()) {28841 if (oob_safety and block.wantSafety()) {
28566 // Runtime check is only needed if unable to comptime check28842 // Runtime check is only needed if unable to comptime check
28567 if (maybe_index_val == null) {28843 if (maybe_index_val == null) {
28568 const len_inst = try mod.intRef(Type.usize, array_len);28844 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;28845 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);28846 try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op);
28571 }28847 }
...@@ -28589,7 +28865,8 @@ fn elemPtrArray(...@@ -28589,7 +28865,8 @@ fn elemPtrArray(
28589 init: bool,28865 init: bool,
28590 oob_safety: bool,28866 oob_safety: bool,
28591) CompileError!Air.Inst.Ref {28867) CompileError!Air.Inst.Ref {
28592 const mod = sema.mod;28868 const pt = sema.pt;
28869 const mod = pt.zcu;
28593 const array_ptr_ty = sema.typeOf(array_ptr);28870 const array_ptr_ty = sema.typeOf(array_ptr);
28594 const array_ty = array_ptr_ty.childType(mod);28871 const array_ty = array_ptr_ty.childType(mod);
28595 const array_sent = array_ty.sentinel(mod) != null;28872 const array_sent = array_ty.sentinel(mod) != null;
...@@ -28603,7 +28880,7 @@ fn elemPtrArray(...@@ -28603,7 +28880,7 @@ fn elemPtrArray(
28603 const maybe_undef_array_ptr_val = try sema.resolveValue(array_ptr);28880 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.28881 // 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: {28882 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));28883 const index = try sema.usizeCast(block, elem_index_src, try index_val.toUnsignedIntSema(pt));
28607 if (index >= array_len_s) {28884 if (index >= array_len_s) {
28608 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";28885 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 });28886 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });
...@@ -28611,14 +28888,14 @@ fn elemPtrArray(...@@ -28611,14 +28888,14 @@ fn elemPtrArray(
28611 break :o index;28888 break :o index;
28612 } else null;28889 } else null;
2861328890
28614 const elem_ptr_ty = try array_ptr_ty.elemPtrType(offset, mod);28891 const elem_ptr_ty = try array_ptr_ty.elemPtrType(offset, pt);
2861528892
28616 if (maybe_undef_array_ptr_val) |array_ptr_val| {28893 if (maybe_undef_array_ptr_val) |array_ptr_val| {
28617 if (array_ptr_val.isUndef(mod)) {28894 if (array_ptr_val.isUndef(mod)) {
28618 return mod.undefRef(elem_ptr_ty);28895 return pt.undefRef(elem_ptr_ty);
28619 }28896 }
28620 if (offset) |index| {28897 if (offset) |index| {
28621 const elem_ptr = try array_ptr_val.ptrElem(index, mod);28898 const elem_ptr = try array_ptr_val.ptrElem(index, pt);
28622 return Air.internedToRef(elem_ptr.toIntern());28899 return Air.internedToRef(elem_ptr.toIntern());
28623 }28900 }
28624 }28901 }
...@@ -28632,7 +28909,7 @@ fn elemPtrArray(...@@ -28632,7 +28909,7 @@ fn elemPtrArray(
2863228909
28633 // Runtime check is only needed if unable to comptime check.28910 // Runtime check is only needed if unable to comptime check.
28634 if (oob_safety and block.wantSafety() and offset == null) {28911 if (oob_safety and block.wantSafety() and offset == null) {
28635 const len_inst = try mod.intRef(Type.usize, array_len);28912 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;28913 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);28914 try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op);
28638 }28915 }
...@@ -28650,7 +28927,8 @@ fn elemValSlice(...@@ -28650,7 +28927,8 @@ fn elemValSlice(
28650 elem_index: Air.Inst.Ref,28927 elem_index: Air.Inst.Ref,
28651 oob_safety: bool,28928 oob_safety: bool,
28652) CompileError!Air.Inst.Ref {28929) CompileError!Air.Inst.Ref {
28653 const mod = sema.mod;28930 const pt = sema.pt;
28931 const mod = pt.zcu;
28654 const slice_ty = sema.typeOf(slice);28932 const slice_ty = sema.typeOf(slice);
28655 const slice_sent = slice_ty.sentinel(mod) != null;28933 const slice_sent = slice_ty.sentinel(mod) != null;
28656 const elem_ty = slice_ty.elemType2(mod);28934 const elem_ty = slice_ty.elemType2(mod);
...@@ -28663,19 +28941,19 @@ fn elemValSlice(...@@ -28663,19 +28941,19 @@ fn elemValSlice(
2866328941
28664 if (maybe_slice_val) |slice_val| {28942 if (maybe_slice_val) |slice_val| {
28665 runtime_src = elem_index_src;28943 runtime_src = elem_index_src;
28666 const slice_len = try slice_val.sliceLen(mod);28944 const slice_len = try slice_val.sliceLen(pt);
28667 const slice_len_s = slice_len + @intFromBool(slice_sent);28945 const slice_len_s = slice_len + @intFromBool(slice_sent);
28668 if (slice_len_s == 0) {28946 if (slice_len_s == 0) {
28669 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});28947 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});
28670 }28948 }
28671 if (maybe_index_val) |index_val| {28949 if (maybe_index_val) |index_val| {
28672 const index: usize = @intCast(try index_val.toUnsignedIntSema(mod));28950 const index: usize = @intCast(try index_val.toUnsignedIntSema(pt));
28673 if (index >= slice_len_s) {28951 if (index >= slice_len_s) {
28674 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";28952 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 });28953 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
28676 }28954 }
28677 const elem_ptr_ty = try slice_ty.elemPtrType(index, mod);28955 const elem_ptr_ty = try slice_ty.elemPtrType(index, pt);
28678 const elem_ptr_val = try slice_val.ptrElem(index, mod);28956 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| {28957 if (try sema.pointerDeref(block, slice_src, elem_ptr_val, elem_ptr_ty)) |elem_val| {
28680 return Air.internedToRef(elem_val.toIntern());28958 return Air.internedToRef(elem_val.toIntern());
28681 }28959 }
...@@ -28688,7 +28966,7 @@ fn elemValSlice(...@@ -28688,7 +28966,7 @@ fn elemValSlice(
28688 try sema.requireRuntimeBlock(block, src, runtime_src);28966 try sema.requireRuntimeBlock(block, src, runtime_src);
28689 if (oob_safety and block.wantSafety()) {28967 if (oob_safety and block.wantSafety()) {
28690 const len_inst = if (maybe_slice_val) |slice_val|28968 const len_inst = if (maybe_slice_val) |slice_val|
28691 try mod.intRef(Type.usize, try slice_val.sliceLen(mod))28969 try pt.intRef(Type.usize, try slice_val.sliceLen(pt))
28692 else28970 else
28693 try block.addTyOp(.slice_len, Type.usize, slice);28971 try block.addTyOp(.slice_len, Type.usize, slice);
28694 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;28972 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
...@@ -28707,24 +28985,25 @@ fn elemPtrSlice(...@@ -28707,24 +28985,25 @@ fn elemPtrSlice(
28707 elem_index: Air.Inst.Ref,28985 elem_index: Air.Inst.Ref,
28708 oob_safety: bool,28986 oob_safety: bool,
28709) CompileError!Air.Inst.Ref {28987) CompileError!Air.Inst.Ref {
28710 const mod = sema.mod;28988 const pt = sema.pt;
28989 const mod = pt.zcu;
28711 const slice_ty = sema.typeOf(slice);28990 const slice_ty = sema.typeOf(slice);
28712 const slice_sent = slice_ty.sentinel(mod) != null;28991 const slice_sent = slice_ty.sentinel(mod) != null;
2871328992
28714 const maybe_undef_slice_val = try sema.resolveValue(slice);28993 const maybe_undef_slice_val = try sema.resolveValue(slice);
28715 // The index must not be undefined since it can be out of bounds.28994 // 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: {28995 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));28996 const index = try sema.usizeCast(block, elem_index_src, try index_val.toUnsignedIntSema(pt));
28718 break :o index;28997 break :o index;
28719 } else null;28998 } else null;
2872028999
28721 const elem_ptr_ty = try slice_ty.elemPtrType(offset, mod);29000 const elem_ptr_ty = try slice_ty.elemPtrType(offset, pt);
2872229001
28723 if (maybe_undef_slice_val) |slice_val| {29002 if (maybe_undef_slice_val) |slice_val| {
28724 if (slice_val.isUndef(mod)) {29003 if (slice_val.isUndef(mod)) {
28725 return mod.undefRef(elem_ptr_ty);29004 return pt.undefRef(elem_ptr_ty);
28726 }29005 }
28727 const slice_len = try slice_val.sliceLen(mod);29006 const slice_len = try slice_val.sliceLen(pt);
28728 const slice_len_s = slice_len + @intFromBool(slice_sent);29007 const slice_len_s = slice_len + @intFromBool(slice_sent);
28729 if (slice_len_s == 0) {29008 if (slice_len_s == 0) {
28730 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});29009 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});
...@@ -28734,7 +29013,7 @@ fn elemPtrSlice(...@@ -28734,7 +29013,7 @@ fn elemPtrSlice(
28734 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";29013 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 });29014 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
28736 }29015 }
28737 const elem_ptr_val = try slice_val.ptrElem(index, mod);29016 const elem_ptr_val = try slice_val.ptrElem(index, pt);
28738 return Air.internedToRef(elem_ptr_val.toIntern());29017 return Air.internedToRef(elem_ptr_val.toIntern());
28739 }29018 }
28740 }29019 }
...@@ -28747,7 +29026,7 @@ fn elemPtrSlice(...@@ -28747,7 +29026,7 @@ fn elemPtrSlice(
28747 const len_inst = len: {29026 const len_inst = len: {
28748 if (maybe_undef_slice_val) |slice_val|29027 if (maybe_undef_slice_val) |slice_val|
28749 if (!slice_val.isUndef(mod))29028 if (!slice_val.isUndef(mod))
28750 break :len try mod.intRef(Type.usize, try slice_val.sliceLen(mod));29029 break :len try pt.intRef(Type.usize, try slice_val.sliceLen(pt));
28751 break :len try block.addTyOp(.slice_len, Type.usize, slice);29030 break :len try block.addTyOp(.slice_len, Type.usize, slice);
28752 };29031 };
28753 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;29032 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
...@@ -28810,11 +29089,12 @@ fn coerceExtra(...@@ -28810,11 +29089,12 @@ fn coerceExtra(
28810 opts: CoerceOpts,29089 opts: CoerceOpts,
28811) CoersionError!Air.Inst.Ref {29090) CoersionError!Air.Inst.Ref {
28812 if (dest_ty.isGenericPoison()) return inst;29091 if (dest_ty.isGenericPoison()) return inst;
28813 const zcu = sema.mod;29092 const pt = sema.pt;
29093 const zcu = pt.zcu;
28814 const dest_ty_src = inst_src; // TODO better source location29094 const dest_ty_src = inst_src; // TODO better source location
28815 try dest_ty.resolveFields(zcu);29095 try dest_ty.resolveFields(pt);
28816 const inst_ty = sema.typeOf(inst);29096 const inst_ty = sema.typeOf(inst);
28817 try inst_ty.resolveFields(zcu);29097 try inst_ty.resolveFields(pt);
28818 const target = zcu.getTarget();29098 const target = zcu.getTarget();
28819 // If the types are the same, we can return the operand.29099 // If the types are the same, we can return the operand.
28820 if (dest_ty.eql(inst_ty, zcu))29100 if (dest_ty.eql(inst_ty, zcu))
...@@ -28838,12 +29118,12 @@ fn coerceExtra(...@@ -28838,12 +29118,12 @@ fn coerceExtra(
28838 if (maybe_inst_val) |val| {29118 if (maybe_inst_val) |val| {
28839 // undefined sets the optional bit also to undefined.29119 // undefined sets the optional bit also to undefined.
28840 if (val.toIntern() == .undef) {29120 if (val.toIntern() == .undef) {
28841 return zcu.undefRef(dest_ty);29121 return pt.undefRef(dest_ty);
28842 }29122 }
2884329123
28844 // null to ?T29124 // null to ?T
28845 if (val.toIntern() == .null_value) {29125 if (val.toIntern() == .null_value) {
28846 return Air.internedToRef((try zcu.intern(.{ .opt = .{29126 return Air.internedToRef((try pt.intern(.{ .opt = .{
28847 .ty = dest_ty.toIntern(),29127 .ty = dest_ty.toIntern(),
28848 .val = .none,29128 .val = .none,
28849 } })));29129 } })));
...@@ -29018,7 +29298,7 @@ fn coerceExtra(...@@ -29018,7 +29298,7 @@ fn coerceExtra(
29018 switch (dest_info.flags.size) {29298 switch (dest_info.flags.size) {
29019 // coercion to C pointer29299 // coercion to C pointer
29020 .C => switch (inst_ty.zigTypeTag(zcu)) {29300 .C => switch (inst_ty.zigTypeTag(zcu)) {
29021 .Null => return Air.internedToRef(try zcu.intern(.{ .ptr = .{29301 .Null => return Air.internedToRef(try pt.intern(.{ .ptr = .{
29022 .ty = dest_ty.toIntern(),29302 .ty = dest_ty.toIntern(),
29023 .base_addr = .int,29303 .base_addr = .int,
29024 .byte_offset = 0,29304 .byte_offset = 0,
...@@ -29063,7 +29343,7 @@ fn coerceExtra(...@@ -29063,7 +29343,7 @@ fn coerceExtra(
29063 if (inst_info.flags.size == .Slice) {29343 if (inst_info.flags.size == .Slice) {
29064 assert(dest_info.sentinel == .none);29344 assert(dest_info.sentinel == .none);
29065 if (inst_info.sentinel == .none or29345 if (inst_info.sentinel == .none or
29066 inst_info.sentinel != (try zcu.intValue(Type.fromInterned(inst_info.child), 0)).toIntern())29346 inst_info.sentinel != (try pt.intValue(Type.fromInterned(inst_info.child), 0)).toIntern())
29067 break :p;29347 break :p;
2906829348
29069 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);29349 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
...@@ -29112,7 +29392,7 @@ fn coerceExtra(...@@ -29112,7 +29392,7 @@ fn coerceExtra(
29112 block,29392 block,
29113 inst_src,29393 inst_src,
29114 "array literal requires address-of operator (&) to coerce to slice type '{}'",29394 "array literal requires address-of operator (&) to coerce to slice type '{}'",
29115 .{dest_ty.fmt(zcu)},29395 .{dest_ty.fmt(pt)},
29116 );29396 );
29117 }29397 }
2911829398
...@@ -29123,10 +29403,10 @@ fn coerceExtra(...@@ -29123,10 +29403,10 @@ fn coerceExtra(
29123 // empty tuple to zero-length slice29403 // empty tuple to zero-length slice
29124 // note that this allows coercing to a mutable slice.29404 // note that this allows coercing to a mutable slice.
29125 if (inst_child_ty.structFieldCount(zcu) == 0) {29405 if (inst_child_ty.structFieldCount(zcu) == 0) {
29126 const align_val = try dest_ty.ptrAlignmentAdvanced(zcu, .sema);29406 const align_val = try dest_ty.ptrAlignmentAdvanced(pt, .sema);
29127 return Air.internedToRef(try zcu.intern(.{ .slice = .{29407 return Air.internedToRef(try pt.intern(.{ .slice = .{
29128 .ty = dest_ty.toIntern(),29408 .ty = dest_ty.toIntern(),
29129 .ptr = try zcu.intern(.{ .ptr = .{29409 .ptr = try pt.intern(.{ .ptr = .{
29130 .ty = dest_ty.slicePtrFieldType(zcu).toIntern(),29410 .ty = dest_ty.slicePtrFieldType(zcu).toIntern(),
29131 .base_addr = .int,29411 .base_addr = .int,
29132 .byte_offset = align_val.toByteUnits().?,29412 .byte_offset = align_val.toByteUnits().?,
...@@ -29138,7 +29418,7 @@ fn coerceExtra(...@@ -29138,7 +29418,7 @@ fn coerceExtra(
29138 // pointer to tuple to slice29418 // pointer to tuple to slice
29139 if (!dest_info.flags.is_const) {29419 if (!dest_info.flags.is_const) {
29140 const err_msg = err_msg: {29420 const err_msg = err_msg: {
29141 const err_msg = try sema.errMsg(inst_src, "cannot cast pointer to tuple to '{}'", .{dest_ty.fmt(zcu)});29421 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);29422 errdefer err_msg.destroy(sema.gpa);
29143 try sema.errNote(dest_ty_src, err_msg, "pointers to tuples can only coerce to constant pointers", .{});29423 try sema.errNote(dest_ty_src, err_msg, "pointers to tuples can only coerce to constant pointers", .{});
29144 break :err_msg err_msg;29424 break :err_msg err_msg;
...@@ -29194,12 +29474,12 @@ fn coerceExtra(...@@ -29194,12 +29474,12 @@ fn coerceExtra(
29194 // comptime-known integer to other number29474 // comptime-known integer to other number
29195 if (!(try sema.intFitsInType(val, dest_ty, null))) {29475 if (!(try sema.intFitsInType(val, dest_ty, null))) {
29196 if (!opts.report_err) return error.NotCoercible;29476 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) });29477 return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(pt), val.fmtValue(pt, sema) });
29198 }29478 }
29199 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {29479 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {
29200 .undef => try zcu.undefRef(dest_ty),29480 .undef => try pt.undefRef(dest_ty),
29201 .int => |int| Air.internedToRef(29481 .int => |int| Air.internedToRef(
29202 try zcu.intern_pool.getCoercedInts(zcu.gpa, int, dest_ty.toIntern()),29482 try zcu.intern_pool.getCoercedInts(zcu.gpa, pt.tid, int, dest_ty.toIntern()),
29203 ),29483 ),
29204 else => unreachable,29484 else => unreachable,
29205 };29485 };
...@@ -29228,18 +29508,18 @@ fn coerceExtra(...@@ -29228,18 +29508,18 @@ fn coerceExtra(
29228 .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag(zcu)) {29508 .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag(zcu)) {
29229 .ComptimeFloat => {29509 .ComptimeFloat => {
29230 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);29510 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
29231 const result_val = try val.floatCast(dest_ty, zcu);29511 const result_val = try val.floatCast(dest_ty, pt);
29232 return Air.internedToRef(result_val.toIntern());29512 return Air.internedToRef(result_val.toIntern());
29233 },29513 },
29234 .Float => {29514 .Float => {
29235 if (maybe_inst_val) |val| {29515 if (maybe_inst_val) |val| {
29236 const result_val = try val.floatCast(dest_ty, zcu);29516 const result_val = try val.floatCast(dest_ty, pt);
29237 if (!val.eql(try result_val.floatCast(inst_ty, zcu), inst_ty, zcu)) {29517 if (!val.eql(try result_val.floatCast(inst_ty, pt), inst_ty, zcu)) {
29238 return sema.fail(29518 return sema.fail(
29239 block,29519 block,
29240 inst_src,29520 inst_src,
29241 "type '{}' cannot represent float value '{}'",29521 "type '{}' cannot represent float value '{}'",
29242 .{ dest_ty.fmt(zcu), val.fmtValue(zcu, sema) },29522 .{ dest_ty.fmt(pt), val.fmtValue(pt, sema) },
29243 );29523 );
29244 }29524 }
29245 return Air.internedToRef(result_val.toIntern());29525 return Air.internedToRef(result_val.toIntern());
...@@ -29268,7 +29548,7 @@ fn coerceExtra(...@@ -29268,7 +29548,7 @@ fn coerceExtra(
29268 }29548 }
29269 break :int;29549 break :int;
29270 };29550 };
29271 const result_val = try val.floatFromIntAdvanced(sema.arena, inst_ty, dest_ty, zcu, .sema);29551 const result_val = try val.floatFromIntAdvanced(sema.arena, inst_ty, dest_ty, pt, .sema);
29272 // TODO implement this compile error29552 // TODO implement this compile error
29273 //const int_again_val = try result_val.intFromFloat(sema.arena, inst_ty);29553 //const int_again_val = try result_val.intFromFloat(sema.arena, inst_ty);
29274 //if (!int_again_val.eql(val, inst_ty, zcu)) {29554 //if (!int_again_val.eql(val, inst_ty, zcu)) {
...@@ -29276,7 +29556,7 @@ fn coerceExtra(...@@ -29276,7 +29556,7 @@ fn coerceExtra(
29276 // block,29556 // block,
29277 // inst_src,29557 // inst_src,
29278 // "type '{}' cannot represent integer value '{}'",29558 // "type '{}' cannot represent integer value '{}'",
29279 // .{ dest_ty.fmt(zcu), val },29559 // .{ dest_ty.fmt(pt), val },
29280 // );29560 // );
29281 //}29561 //}
29282 return Air.internedToRef(result_val.toIntern());29562 return Air.internedToRef(result_val.toIntern());
...@@ -29290,10 +29570,10 @@ fn coerceExtra(...@@ -29290,10 +29570,10 @@ fn coerceExtra(
29290 const string = zcu.intern_pool.indexToKey(val.toIntern()).enum_literal;29570 const string = zcu.intern_pool.indexToKey(val.toIntern()).enum_literal;
29291 const field_index = dest_ty.enumFieldIndex(string, zcu) orelse {29571 const field_index = dest_ty.enumFieldIndex(string, zcu) orelse {
29292 return sema.fail(block, inst_src, "no field named '{}' in enum '{}'", .{29572 return sema.fail(block, inst_src, "no field named '{}' in enum '{}'", .{
29293 string.fmt(&zcu.intern_pool), dest_ty.fmt(zcu),29573 string.fmt(&zcu.intern_pool), dest_ty.fmt(pt),
29294 });29574 });
29295 };29575 };
29296 return Air.internedToRef((try zcu.enumValueFieldIndex(dest_ty, @intCast(field_index))).toIntern());29576 return Air.internedToRef((try pt.enumValueFieldIndex(dest_ty, @intCast(field_index))).toIntern());
29297 },29577 },
29298 .Union => blk: {29578 .Union => blk: {
29299 // union to its own tag type29579 // union to its own tag type
...@@ -29308,12 +29588,12 @@ fn coerceExtra(...@@ -29308,12 +29588,12 @@ fn coerceExtra(
29308 .ErrorUnion => eu: {29588 .ErrorUnion => eu: {
29309 if (maybe_inst_val) |inst_val| {29589 if (maybe_inst_val) |inst_val| {
29310 switch (inst_val.toIntern()) {29590 switch (inst_val.toIntern()) {
29311 .undef => return zcu.undefRef(dest_ty),29591 .undef => return pt.undefRef(dest_ty),
29312 else => switch (zcu.intern_pool.indexToKey(inst_val.toIntern())) {29592 else => switch (zcu.intern_pool.indexToKey(inst_val.toIntern())) {
29313 .error_union => |error_union| switch (error_union.val) {29593 .error_union => |error_union| switch (error_union.val) {
29314 .err_name => |err_name| {29594 .err_name => |err_name| {
29315 const error_set_ty = inst_ty.errorUnionSet(zcu);29595 const error_set_ty = inst_ty.errorUnionSet(zcu);
29316 const error_set_val = Air.internedToRef((try zcu.intern(.{ .err = .{29596 const error_set_val = Air.internedToRef((try pt.intern(.{ .err = .{
29317 .ty = error_set_ty.toIntern(),29597 .ty = error_set_ty.toIntern(),
29318 .name = err_name,29598 .name = err_name,
29319 } })));29599 } })));
...@@ -29370,7 +29650,7 @@ fn coerceExtra(...@@ -29370,7 +29650,7 @@ fn coerceExtra(
2937029650
29371 if (dest_ty.sentinel(zcu)) |dest_sent| {29651 if (dest_ty.sentinel(zcu)) |dest_sent| {
29372 const src_sent = inst_ty.sentinel(zcu) orelse break :array_to_array;29652 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()) {29653 if (dest_sent.toIntern() != (try pt.getCoerced(src_sent, dest_ty.childType(zcu))).toIntern()) {
29374 break :array_to_array;29654 break :array_to_array;
29375 }29655 }
29376 }29656 }
...@@ -29414,7 +29694,7 @@ fn coerceExtra(...@@ -29414,7 +29694,7 @@ fn coerceExtra(
29414 // undefined to anything. We do this after the big switch above so that29694 // 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` which29695 // special logic has a chance to run first, such as `*[N]T` to `[]T` which
29416 // should initialize the length field of the slice.29696 // should initialize the length field of the slice.
29417 if (maybe_inst_val) |val| if (val.toIntern() == .undef) return zcu.undefRef(dest_ty);29697 if (maybe_inst_val) |val| if (val.toIntern() == .undef) return pt.undefRef(dest_ty);
2941829698
29419 if (!opts.report_err) return error.NotCoercible;29699 if (!opts.report_err) return error.NotCoercible;
2942029700
...@@ -29434,7 +29714,7 @@ fn coerceExtra(...@@ -29434,7 +29714,7 @@ fn coerceExtra(
29434 }29714 }
2943529715
29436 const msg = msg: {29716 const msg = msg: {
29437 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(zcu), inst_ty.fmt(zcu) });29717 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(pt), inst_ty.fmt(pt) });
29438 errdefer msg.destroy(sema.gpa);29718 errdefer msg.destroy(sema.gpa);
2943929719
29440 // E!T to T29720 // E!T to T
...@@ -29486,7 +29766,7 @@ fn coerceInMemory(...@@ -29486,7 +29766,7 @@ fn coerceInMemory(
29486 val: Value,29766 val: Value,
29487 dst_ty: Type,29767 dst_ty: Type,
29488) CompileError!Air.Inst.Ref {29768) CompileError!Air.Inst.Ref {
29489 return Air.internedToRef((try sema.mod.getCoerced(val, dst_ty)).toIntern());29769 return Air.internedToRef((try sema.pt.getCoerced(val, dst_ty)).toIntern());
29490}29770}
2949129771
29492const InMemoryCoercionResult = union(enum) {29772const InMemoryCoercionResult = union(enum) {
...@@ -29607,7 +29887,7 @@ const InMemoryCoercionResult = union(enum) {...@@ -29607,7 +29887,7 @@ const InMemoryCoercionResult = union(enum) {
29607 }29887 }
2960829888
29609 fn report(res: *const InMemoryCoercionResult, sema: *Sema, src: LazySrcLoc, msg: *Module.ErrorMsg) !void {29889 fn report(res: *const InMemoryCoercionResult, sema: *Sema, src: LazySrcLoc, msg: *Module.ErrorMsg) !void {
29610 const mod = sema.mod;29890 const pt = sema.pt;
29611 var cur = res;29891 var cur = res;
29612 while (true) switch (cur.*) {29892 while (true) switch (cur.*) {
29613 .ok => unreachable,29893 .ok => unreachable,
...@@ -29624,7 +29904,7 @@ const InMemoryCoercionResult = union(enum) {...@@ -29624,7 +29904,7 @@ const InMemoryCoercionResult = union(enum) {
29624 },29904 },
29625 .error_union_payload => |pair| {29905 .error_union_payload => |pair| {
29626 try sema.errNote(src, msg, "error union payload '{}' cannot cast into error union payload '{}'", .{29906 try sema.errNote(src, msg, "error union payload '{}' cannot cast into error union payload '{}'", .{
29627 pair.actual.fmt(mod), pair.wanted.fmt(mod),29907 pair.actual.fmt(pt), pair.wanted.fmt(pt),
29628 });29908 });
29629 cur = pair.child;29909 cur = pair.child;
29630 },29910 },
...@@ -29637,18 +29917,18 @@ const InMemoryCoercionResult = union(enum) {...@@ -29637,18 +29917,18 @@ const InMemoryCoercionResult = union(enum) {
29637 .array_sentinel => |sentinel| {29917 .array_sentinel => |sentinel| {
29638 if (sentinel.actual.toIntern() != .unreachable_value) {29918 if (sentinel.actual.toIntern() != .unreachable_value) {
29639 try sema.errNote(src, msg, "array sentinel '{}' cannot cast into array sentinel '{}'", .{29919 try sema.errNote(src, msg, "array sentinel '{}' cannot cast into array sentinel '{}'", .{
29640 sentinel.actual.fmtValue(mod, sema), sentinel.wanted.fmtValue(mod, sema),29920 sentinel.actual.fmtValue(pt, sema), sentinel.wanted.fmtValue(pt, sema),
29641 });29921 });
29642 } else {29922 } else {
29643 try sema.errNote(src, msg, "destination array requires '{}' sentinel", .{29923 try sema.errNote(src, msg, "destination array requires '{}' sentinel", .{
29644 sentinel.wanted.fmtValue(mod, sema),29924 sentinel.wanted.fmtValue(pt, sema),
29645 });29925 });
29646 }29926 }
29647 break;29927 break;
29648 },29928 },
29649 .array_elem => |pair| {29929 .array_elem => |pair| {
29650 try sema.errNote(src, msg, "array element type '{}' cannot cast into array element type '{}'", .{29930 try sema.errNote(src, msg, "array element type '{}' cannot cast into array element type '{}'", .{
29651 pair.actual.fmt(mod), pair.wanted.fmt(mod),29931 pair.actual.fmt(pt), pair.wanted.fmt(pt),
29652 });29932 });
29653 cur = pair.child;29933 cur = pair.child;
29654 },29934 },
...@@ -29660,19 +29940,19 @@ const InMemoryCoercionResult = union(enum) {...@@ -29660,19 +29940,19 @@ const InMemoryCoercionResult = union(enum) {
29660 },29940 },
29661 .vector_elem => |pair| {29941 .vector_elem => |pair| {
29662 try sema.errNote(src, msg, "vector element type '{}' cannot cast into vector element type '{}'", .{29942 try sema.errNote(src, msg, "vector element type '{}' cannot cast into vector element type '{}'", .{
29663 pair.actual.fmt(mod), pair.wanted.fmt(mod),29943 pair.actual.fmt(pt), pair.wanted.fmt(pt),
29664 });29944 });
29665 cur = pair.child;29945 cur = pair.child;
29666 },29946 },
29667 .optional_shape => |pair| {29947 .optional_shape => |pair| {
29668 try sema.errNote(src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{29948 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),29949 pair.actual.optionalChild(pt.zcu).fmt(pt), pair.wanted.optionalChild(pt.zcu).fmt(pt),
29670 });29950 });
29671 break;29951 break;
29672 },29952 },
29673 .optional_child => |pair| {29953 .optional_child => |pair| {
29674 try sema.errNote(src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{29954 try sema.errNote(src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{
29675 pair.actual.fmt(mod), pair.wanted.fmt(mod),29955 pair.actual.fmt(pt), pair.wanted.fmt(pt),
29676 });29956 });
29677 cur = pair.child;29957 cur = pair.child;
29678 },29958 },
...@@ -29682,7 +29962,7 @@ const InMemoryCoercionResult = union(enum) {...@@ -29682,7 +29962,7 @@ const InMemoryCoercionResult = union(enum) {
29682 },29962 },
29683 .missing_error => |missing_errors| {29963 .missing_error => |missing_errors| {
29684 for (missing_errors) |err| {29964 for (missing_errors) |err| {
29685 try sema.errNote(src, msg, "'error.{}' not a member of destination error set", .{err.fmt(&mod.intern_pool)});29965 try sema.errNote(src, msg, "'error.{}' not a member of destination error set", .{err.fmt(&pt.zcu.intern_pool)});
29686 }29966 }
29687 break;29967 break;
29688 },29968 },
...@@ -29736,7 +30016,7 @@ const InMemoryCoercionResult = union(enum) {...@@ -29736,7 +30016,7 @@ const InMemoryCoercionResult = union(enum) {
29736 },30016 },
29737 .fn_param => |param| {30017 .fn_param => |param| {
29738 try sema.errNote(src, msg, "parameter {d} '{}' cannot cast into '{}'", .{30018 try sema.errNote(src, msg, "parameter {d} '{}' cannot cast into '{}'", .{
29739 param.index, param.actual.fmt(mod), param.wanted.fmt(mod),30019 param.index, param.actual.fmt(pt), param.wanted.fmt(pt),
29740 });30020 });
29741 cur = param.child;30021 cur = param.child;
29742 },30022 },
...@@ -29746,13 +30026,13 @@ const InMemoryCoercionResult = union(enum) {...@@ -29746,13 +30026,13 @@ const InMemoryCoercionResult = union(enum) {
29746 },30026 },
29747 .fn_return_type => |pair| {30027 .fn_return_type => |pair| {
29748 try sema.errNote(src, msg, "return type '{}' cannot cast into return type '{}'", .{30028 try sema.errNote(src, msg, "return type '{}' cannot cast into return type '{}'", .{
29749 pair.actual.fmt(mod), pair.wanted.fmt(mod),30029 pair.actual.fmt(pt), pair.wanted.fmt(pt),
29750 });30030 });
29751 cur = pair.child;30031 cur = pair.child;
29752 },30032 },
29753 .ptr_child => |pair| {30033 .ptr_child => |pair| {
29754 try sema.errNote(src, msg, "pointer type child '{}' cannot cast into pointer type child '{}'", .{30034 try sema.errNote(src, msg, "pointer type child '{}' cannot cast into pointer type child '{}'", .{
29755 pair.actual.fmt(mod), pair.wanted.fmt(mod),30035 pair.actual.fmt(pt), pair.wanted.fmt(pt),
29756 });30036 });
29757 cur = pair.child;30037 cur = pair.child;
29758 },30038 },
...@@ -29763,11 +30043,11 @@ const InMemoryCoercionResult = union(enum) {...@@ -29763,11 +30043,11 @@ const InMemoryCoercionResult = union(enum) {
29763 .ptr_sentinel => |sentinel| {30043 .ptr_sentinel => |sentinel| {
29764 if (sentinel.actual.toIntern() != .unreachable_value) {30044 if (sentinel.actual.toIntern() != .unreachable_value) {
29765 try sema.errNote(src, msg, "pointer sentinel '{}' cannot cast into pointer sentinel '{}'", .{30045 try sema.errNote(src, msg, "pointer sentinel '{}' cannot cast into pointer sentinel '{}'", .{
29766 sentinel.actual.fmtValue(mod, sema), sentinel.wanted.fmtValue(mod, sema),30046 sentinel.actual.fmtValue(pt, sema), sentinel.wanted.fmtValue(pt, sema),
29767 });30047 });
29768 } else {30048 } else {
29769 try sema.errNote(src, msg, "destination pointer requires '{}' sentinel", .{30049 try sema.errNote(src, msg, "destination pointer requires '{}' sentinel", .{
29770 sentinel.wanted.fmtValue(mod, sema),30050 sentinel.wanted.fmtValue(pt, sema),
29771 });30051 });
29772 }30052 }
29773 break;30053 break;
...@@ -29787,15 +30067,15 @@ const InMemoryCoercionResult = union(enum) {...@@ -29787,15 +30067,15 @@ const InMemoryCoercionResult = union(enum) {
29787 break;30067 break;
29788 },30068 },
29789 .ptr_allowzero => |pair| {30069 .ptr_allowzero => |pair| {
29790 const wanted_allow_zero = pair.wanted.ptrAllowsZero(mod);30070 const wanted_allow_zero = pair.wanted.ptrAllowsZero(pt.zcu);
29791 const actual_allow_zero = pair.actual.ptrAllowsZero(mod);30071 const actual_allow_zero = pair.actual.ptrAllowsZero(pt.zcu);
29792 if (actual_allow_zero and !wanted_allow_zero) {30072 if (actual_allow_zero and !wanted_allow_zero) {
29793 try sema.errNote(src, msg, "'{}' could have null values which are illegal in type '{}'", .{30073 try sema.errNote(src, msg, "'{}' could have null values which are illegal in type '{}'", .{
29794 pair.actual.fmt(mod), pair.wanted.fmt(mod),30074 pair.actual.fmt(pt), pair.wanted.fmt(pt),
29795 });30075 });
29796 } else {30076 } else {
29797 try sema.errNote(src, msg, "mutable '{}' allows illegal null values stored to type '{}'", .{30077 try sema.errNote(src, msg, "mutable '{}' allows illegal null values stored to type '{}'", .{
29798 pair.actual.fmt(mod), pair.wanted.fmt(mod),30078 pair.actual.fmt(pt), pair.wanted.fmt(pt),
29799 });30079 });
29800 }30080 }
29801 break;30081 break;
...@@ -29821,13 +30101,13 @@ const InMemoryCoercionResult = union(enum) {...@@ -29821,13 +30101,13 @@ const InMemoryCoercionResult = union(enum) {
29821 },30101 },
29822 .double_ptr_to_anyopaque => |pair| {30102 .double_ptr_to_anyopaque => |pair| {
29823 try sema.errNote(src, msg, "cannot implicitly cast double pointer '{}' to anyopaque pointer '{}'", .{30103 try sema.errNote(src, msg, "cannot implicitly cast double pointer '{}' to anyopaque pointer '{}'", .{
29824 pair.actual.fmt(mod), pair.wanted.fmt(mod),30104 pair.actual.fmt(pt), pair.wanted.fmt(pt),
29825 });30105 });
29826 break;30106 break;
29827 },30107 },
29828 .slice_to_anyopaque => |pair| {30108 .slice_to_anyopaque => |pair| {
29829 try sema.errNote(src, msg, "cannot implicitly cast slice '{}' to anyopaque pointer '{}'", .{30109 try sema.errNote(src, msg, "cannot implicitly cast slice '{}' to anyopaque pointer '{}'", .{
29830 pair.actual.fmt(mod), pair.wanted.fmt(mod),30110 pair.actual.fmt(pt), pair.wanted.fmt(pt),
29831 });30111 });
29832 try sema.errNote(src, msg, "consider using '.ptr'", .{});30112 try sema.errNote(src, msg, "consider using '.ptr'", .{});
29833 break;30113 break;
...@@ -29864,7 +30144,8 @@ pub fn coerceInMemoryAllowed(...@@ -29864,7 +30144,8 @@ pub fn coerceInMemoryAllowed(
29864 dest_src: LazySrcLoc,30144 dest_src: LazySrcLoc,
29865 src_src: LazySrcLoc,30145 src_src: LazySrcLoc,
29866) CompileError!InMemoryCoercionResult {30146) CompileError!InMemoryCoercionResult {
29867 const mod = sema.mod;30147 const pt = sema.pt;
30148 const mod = pt.zcu;
2986830149
29869 if (dest_ty.eql(src_ty, mod))30150 if (dest_ty.eql(src_ty, mod))
29870 return .ok;30151 return .ok;
...@@ -29968,7 +30249,7 @@ pub fn coerceInMemoryAllowed(...@@ -29968,7 +30249,7 @@ pub fn coerceInMemoryAllowed(
29968 (src_info.sentinel != null and30249 (src_info.sentinel != null and
29969 dest_info.sentinel != null and30250 dest_info.sentinel != null and
29970 dest_info.sentinel.?.eql(30251 dest_info.sentinel.?.eql(
29971 try mod.getCoerced(src_info.sentinel.?, dest_info.elem_type),30252 try pt.getCoerced(src_info.sentinel.?, dest_info.elem_type),
29972 dest_info.elem_type,30253 dest_info.elem_type,
29973 mod,30254 mod,
29974 ));30255 ));
...@@ -30045,8 +30326,8 @@ pub fn coerceInMemoryAllowed(...@@ -30045,8 +30326,8 @@ pub fn coerceInMemoryAllowed(
30045 // The memory layout of @Vector(N, iM) is the same as the integer type i(N*M),30326 // 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.30327 // 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.30328 // If there's no padding, the bitcast is possible.
30048 const elem_bit_size = dest_elem_ty.bitSize(mod);30329 const elem_bit_size = dest_elem_ty.bitSize(pt);
30049 const elem_abi_byte_size = dest_elem_ty.abiSize(mod);30330 const elem_abi_byte_size = dest_elem_ty.abiSize(pt);
30050 if (elem_abi_byte_size * 8 == elem_bit_size)30331 if (elem_abi_byte_size * 8 == elem_bit_size)
30051 return .ok;30332 return .ok;
30052 }30333 }
...@@ -30081,7 +30362,7 @@ pub fn coerceInMemoryAllowed(...@@ -30081,7 +30362,7 @@ pub fn coerceInMemoryAllowed(
30081 const field_count = dest_ty.structFieldCount(mod);30362 const field_count = dest_ty.structFieldCount(mod);
30082 for (0..field_count) |field_idx| {30363 for (0..field_count) |field_idx| {
30083 if (dest_ty.structFieldIsComptime(field_idx, mod) != src_ty.structFieldIsComptime(field_idx, mod)) break :tuple;30364 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;30365 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);30366 const dest_field_ty = dest_ty.structFieldType(field_idx, mod);
30086 const src_field_ty = src_ty.structFieldType(field_idx, mod);30367 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);30368 const field = try sema.coerceInMemoryAllowed(block, dest_field_ty, src_field_ty, dest_is_mut, target, dest_src, src_src);
...@@ -30104,7 +30385,8 @@ fn coerceInMemoryAllowedErrorSets(...@@ -30104,7 +30385,8 @@ fn coerceInMemoryAllowedErrorSets(
30104 dest_src: LazySrcLoc,30385 dest_src: LazySrcLoc,
30105 src_src: LazySrcLoc,30386 src_src: LazySrcLoc,
30106) !InMemoryCoercionResult {30387) !InMemoryCoercionResult {
30107 const mod = sema.mod;30388 const pt = sema.pt;
30389 const mod = pt.zcu;
30108 const gpa = sema.gpa;30390 const gpa = sema.gpa;
30109 const ip = &mod.intern_pool;30391 const ip = &mod.intern_pool;
3011030392
...@@ -30202,7 +30484,8 @@ fn coerceInMemoryAllowedFns(...@@ -30202,7 +30484,8 @@ fn coerceInMemoryAllowedFns(
30202 dest_src: LazySrcLoc,30484 dest_src: LazySrcLoc,
30203 src_src: LazySrcLoc,30485 src_src: LazySrcLoc,
30204) !InMemoryCoercionResult {30486) !InMemoryCoercionResult {
30205 const mod = sema.mod;30487 const pt = sema.pt;
30488 const mod = pt.zcu;
30206 const ip = &mod.intern_pool;30489 const ip = &mod.intern_pool;
3020730490
30208 const dest_info = mod.typeToFunc(dest_ty).?;30491 const dest_info = mod.typeToFunc(dest_ty).?;
...@@ -30303,7 +30586,8 @@ fn coerceInMemoryAllowedPtrs(...@@ -30303,7 +30586,8 @@ fn coerceInMemoryAllowedPtrs(
30303 dest_src: LazySrcLoc,30586 dest_src: LazySrcLoc,
30304 src_src: LazySrcLoc,30587 src_src: LazySrcLoc,
30305) !InMemoryCoercionResult {30588) !InMemoryCoercionResult {
30306 const zcu = sema.mod;30589 const pt = sema.pt;
30590 const zcu = pt.zcu;
30307 const dest_info = dest_ptr_ty.ptrInfo(zcu);30591 const dest_info = dest_ptr_ty.ptrInfo(zcu);
30308 const src_info = src_ptr_ty.ptrInfo(zcu);30592 const src_info = src_ptr_ty.ptrInfo(zcu);
3030930593
...@@ -30381,7 +30665,7 @@ fn coerceInMemoryAllowedPtrs(...@@ -30381,7 +30665,7 @@ fn coerceInMemoryAllowedPtrs(
3038130665
30382 const ok_sent = dest_info.sentinel == .none or src_info.flags.size == .C or30666 const ok_sent = dest_info.sentinel == .none or src_info.flags.size == .C or
30383 (src_info.sentinel != .none and30667 (src_info.sentinel != .none and
30384 dest_info.sentinel == try zcu.intern_pool.getCoerced(sema.gpa, src_info.sentinel, dest_info.child));30668 dest_info.sentinel == try zcu.intern_pool.getCoerced(sema.gpa, pt.tid, src_info.sentinel, dest_info.child));
30385 if (!ok_sent) {30669 if (!ok_sent) {
30386 return InMemoryCoercionResult{ .ptr_sentinel = .{30670 return InMemoryCoercionResult{ .ptr_sentinel = .{
30387 .actual = switch (src_info.sentinel) {30671 .actual = switch (src_info.sentinel) {
...@@ -30432,7 +30716,8 @@ fn coerceVarArgParam(...@@ -30432,7 +30716,8 @@ fn coerceVarArgParam(
30432) !Air.Inst.Ref {30716) !Air.Inst.Ref {
30433 if (block.is_typeof) return inst;30717 if (block.is_typeof) return inst;
3043430718
30435 const mod = sema.mod;30719 const pt = sema.pt;
30720 const mod = pt.zcu;
30436 const uncasted_ty = sema.typeOf(inst);30721 const uncasted_ty = sema.typeOf(inst);
30437 const coerced = switch (uncasted_ty.zigTypeTag(mod)) {30722 const coerced = switch (uncasted_ty.zigTypeTag(mod)) {
30438 // TODO consider casting to c_int/f64 if they fit30723 // TODO consider casting to c_int/f64 if they fit
...@@ -30449,9 +30734,9 @@ fn coerceVarArgParam(...@@ -30449,9 +30734,9 @@ fn coerceVarArgParam(
30449 },30734 },
30450 .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}),30735 .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}),
30451 .Float => float: {30736 .Float => float: {
30452 const target = sema.mod.getTarget();30737 const target = mod.getTarget();
30453 const double_bits = target.c_type_bit_size(.double);30738 const double_bits = target.c_type_bit_size(.double);
30454 const inst_bits = uncasted_ty.floatBits(sema.mod.getTarget());30739 const inst_bits = uncasted_ty.floatBits(target);
30455 if (inst_bits >= double_bits) break :float inst;30740 if (inst_bits >= double_bits) break :float inst;
30456 switch (double_bits) {30741 switch (double_bits) {
30457 32 => break :float try sema.coerce(block, Type.f32, inst, inst_src),30742 32 => break :float try sema.coerce(block, Type.f32, inst, inst_src),
...@@ -30461,7 +30746,7 @@ fn coerceVarArgParam(...@@ -30461,7 +30746,7 @@ fn coerceVarArgParam(
30461 },30746 },
30462 else => if (uncasted_ty.isAbiInt(mod)) int: {30747 else => if (uncasted_ty.isAbiInt(mod)) int: {
30463 if (!try sema.validateExternType(uncasted_ty, .param_ty)) break :int inst;30748 if (!try sema.validateExternType(uncasted_ty, .param_ty)) break :int inst;
30464 const target = sema.mod.getTarget();30749 const target = mod.getTarget();
30465 const uncasted_info = uncasted_ty.intInfo(mod);30750 const uncasted_info = uncasted_ty.intInfo(mod);
30466 if (uncasted_info.bits <= target.c_type_bit_size(switch (uncasted_info.signedness) {30751 if (uncasted_info.bits <= target.c_type_bit_size(switch (uncasted_info.signedness) {
30467 .signed => .int,30752 .signed => .int,
...@@ -30491,7 +30776,7 @@ fn coerceVarArgParam(...@@ -30491,7 +30776,7 @@ fn coerceVarArgParam(
30491 const coerced_ty = sema.typeOf(coerced);30776 const coerced_ty = sema.typeOf(coerced);
30492 if (!try sema.validateExternType(coerced_ty, .param_ty)) {30777 if (!try sema.validateExternType(coerced_ty, .param_ty)) {
30493 const msg = msg: {30778 const msg = msg: {
30494 const msg = try sema.errMsg(inst_src, "cannot pass '{}' to variadic function", .{coerced_ty.fmt(sema.mod)});30779 const msg = try sema.errMsg(inst_src, "cannot pass '{}' to variadic function", .{coerced_ty.fmt(pt)});
30495 errdefer msg.destroy(sema.gpa);30780 errdefer msg.destroy(sema.gpa);
3049630781
30497 try sema.explainWhyTypeIsNotExtern(msg, inst_src, coerced_ty, .param_ty);30782 try sema.explainWhyTypeIsNotExtern(msg, inst_src, coerced_ty, .param_ty);
...@@ -30526,7 +30811,8 @@ fn storePtr2(...@@ -30526,7 +30811,8 @@ fn storePtr2(
30526 operand_src: LazySrcLoc,30811 operand_src: LazySrcLoc,
30527 air_tag: Air.Inst.Tag,30812 air_tag: Air.Inst.Tag,
30528) CompileError!void {30813) CompileError!void {
30529 const mod = sema.mod;30814 const pt = sema.pt;
30815 const mod = pt.zcu;
30530 const ptr_ty = sema.typeOf(ptr);30816 const ptr_ty = sema.typeOf(ptr);
30531 if (ptr_ty.isConstPtr(mod))30817 if (ptr_ty.isConstPtr(mod))
30532 return sema.fail(block, ptr_src, "cannot assign to constant", .{});30818 return sema.fail(block, ptr_src, "cannot assign to constant", .{});
...@@ -30548,7 +30834,7 @@ fn storePtr2(...@@ -30548,7 +30834,7 @@ fn storePtr2(
30548 while (i < field_count) : (i += 1) {30834 while (i < field_count) : (i += 1) {
30549 const elem_src = operand_src; // TODO better source location30835 const elem_src = operand_src; // TODO better source location
30550 const elem = try sema.tupleField(block, operand_src, uncasted_operand, elem_src, i);30836 const elem = try sema.tupleField(block, operand_src, uncasted_operand, elem_src, i);
30551 const elem_index = try mod.intRef(Type.usize, i);30837 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);30838 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);30839 try sema.storePtr2(block, src, elem_ptr, elem_src, elem, elem_src, .store);
30554 }30840 }
...@@ -30620,7 +30906,7 @@ fn storePtr2(...@@ -30620,7 +30906,7 @@ fn storePtr2(
30620 return;30906 return;
30621 }30907 }
30622 return sema.fail(block, ptr_src, "unable to determine vector element index of type '{}'", .{30908 return sema.fail(block, ptr_src, "unable to determine vector element index of type '{}'", .{
30623 ptr_ty.fmt(sema.mod),30909 ptr_ty.fmt(pt),
30624 });30910 });
30625 }30911 }
3062630912
...@@ -30734,7 +31020,8 @@ fn markMaybeComptimeAllocRuntime(sema: *Sema, block: *Block, alloc_inst: Air.Ins...@@ -30734,7 +31020,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 the31020/// pointer. Only if the final element type matches the vector element type, and the
30735/// lengths match.31021/// lengths match.
30736fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {31022fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {
30737 const mod = sema.mod;31023 const pt = sema.pt;
31024 const mod = pt.zcu;
30738 const array_ty = sema.typeOf(ptr).childType(mod);31025 const array_ty = sema.typeOf(ptr).childType(mod);
30739 if (array_ty.zigTypeTag(mod) != .Array) return null;31026 if (array_ty.zigTypeTag(mod) != .Array) return null;
30740 var ptr_ref = ptr;31027 var ptr_ref = ptr;
...@@ -30751,7 +31038,7 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {...@@ -30751,7 +31038,7 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {
3075131038
30752 // We have a pointer-to-array and a pointer-to-vector. If the elements and31039 // We have a pointer-to-array and a pointer-to-vector. If the elements and
30753 // lengths match, return the result.31040 // lengths match, return the result.
30754 if (array_ty.childType(mod).eql(vector_ty.childType(mod), sema.mod) and31041 if (array_ty.childType(mod).eql(vector_ty.childType(mod), mod) and
30755 array_ty.arrayLen(mod) == vector_ty.vectorLen(mod))31042 array_ty.arrayLen(mod) == vector_ty.vectorLen(mod))
30756 {31043 {
30757 return ptr_ref;31044 return ptr_ref;
...@@ -30770,17 +31057,18 @@ fn storePtrVal(...@@ -30770,17 +31057,18 @@ fn storePtrVal(
30770 operand_val: Value,31057 operand_val: Value,
30771 operand_ty: Type,31058 operand_ty: Type,
30772) !void {31059) !void {
30773 const zcu = sema.mod;31060 const pt = sema.pt;
31061 const zcu = pt.zcu;
30774 const ip = &zcu.intern_pool;31062 const ip = &zcu.intern_pool;
30775 // TODO: audit use sites to eliminate this coercion31063 // TODO: audit use sites to eliminate this coercion
30776 const coerced_operand_val = try zcu.getCoerced(operand_val, operand_ty);31064 const coerced_operand_val = try pt.getCoerced(operand_val, operand_ty);
30777 // TODO: audit use sites to eliminate this coercion31065 // TODO: audit use sites to eliminate this coercion
30778 const ptr_ty = try zcu.ptrType(info: {31066 const ptr_ty = try pt.ptrType(info: {
30779 var info = ptr_val.typeOf(zcu).ptrInfo(zcu);31067 var info = ptr_val.typeOf(zcu).ptrInfo(zcu);
30780 info.child = operand_ty.toIntern();31068 info.child = operand_ty.toIntern();
30781 break :info info;31069 break :info info;
30782 });31070 });
30783 const coerced_ptr_val = try zcu.getCoerced(ptr_val, ptr_ty);31071 const coerced_ptr_val = try pt.getCoerced(ptr_val, ptr_ty);
3078431072
30785 switch (try sema.storeComptimePtr(block, src, coerced_ptr_val, coerced_operand_val)) {31073 switch (try sema.storeComptimePtr(block, src, coerced_ptr_val, coerced_operand_val)) {
30786 .success => {},31074 .success => {},
...@@ -30800,13 +31088,13 @@ fn storePtrVal(...@@ -30800,13 +31088,13 @@ fn storePtrVal(
30800 block,31088 block,
30801 src,31089 src,
30802 "comptime dereference requires '{}' to have a well-defined layout",31090 "comptime dereference requires '{}' to have a well-defined layout",
30803 .{ty.fmt(zcu)},31091 .{ty.fmt(pt)},
30804 ),31092 ),
30805 .out_of_bounds => |ty| return sema.fail(31093 .out_of_bounds => |ty| return sema.fail(
30806 block,31094 block,
30807 src,31095 src,
30808 "dereference of '{}' exceeds bounds of containing decl of type '{}'",31096 "dereference of '{}' exceeds bounds of containing decl of type '{}'",
30809 .{ ptr_ty.fmt(zcu), ty.fmt(zcu) },31097 .{ ptr_ty.fmt(pt), ty.fmt(pt) },
30810 ),31098 ),
30811 .exceeds_host_size => return sema.fail(block, src, "bit-pointer target exceeds host size", .{}),31099 .exceeds_host_size => return sema.fail(block, src, "bit-pointer target exceeds host size", .{}),
30812 }31100 }
...@@ -30820,31 +31108,32 @@ fn bitCast(...@@ -30820,31 +31108,32 @@ fn bitCast(
30820 inst_src: LazySrcLoc,31108 inst_src: LazySrcLoc,
30821 operand_src: ?LazySrcLoc,31109 operand_src: ?LazySrcLoc,
30822) CompileError!Air.Inst.Ref {31110) CompileError!Air.Inst.Ref {
30823 const zcu = sema.mod;31111 const pt = sema.pt;
30824 try dest_ty.resolveLayout(zcu);31112 const zcu = pt.zcu;
31113 try dest_ty.resolveLayout(pt);
3082531114
30826 const old_ty = sema.typeOf(inst);31115 const old_ty = sema.typeOf(inst);
30827 try old_ty.resolveLayout(zcu);31116 try old_ty.resolveLayout(pt);
3082831117
30829 const dest_bits = dest_ty.bitSize(zcu);31118 const dest_bits = dest_ty.bitSize(pt);
30830 const old_bits = old_ty.bitSize(zcu);31119 const old_bits = old_ty.bitSize(pt);
3083131120
30832 if (old_bits != dest_bits) {31121 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", .{31122 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),31123 dest_ty.fmt(pt),
30835 dest_bits,31124 dest_bits,
30836 old_ty.fmt(zcu),31125 old_ty.fmt(pt),
30837 old_bits,31126 old_bits,
30838 });31127 });
30839 }31128 }
3084031129
30841 if (try sema.resolveValue(inst)) |val| {31130 if (try sema.resolveValue(inst)) |val| {
30842 if (val.isUndef(zcu))31131 if (val.isUndef(zcu))
30843 return zcu.undefRef(dest_ty);31132 return pt.undefRef(dest_ty);
30844 if (old_ty.zigTypeTag(zcu) == .ErrorSet and dest_ty.zigTypeTag(zcu) == .ErrorSet) {31133 if (old_ty.zigTypeTag(zcu) == .ErrorSet and dest_ty.zigTypeTag(zcu) == .ErrorSet) {
30845 // Special case: we sometimes call `bitCast` on error set values, but they31134 // 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.31135 // 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());31136 return Air.internedToRef((try pt.getCoerced(val, dest_ty)).toIntern());
30848 }31137 }
30849 if (try sema.bitCastVal(val, dest_ty, 0, 0, 0)) |result_val| {31138 if (try sema.bitCastVal(val, dest_ty, 0, 0, 0)) |result_val| {
30850 return Air.internedToRef(result_val.toIntern());31139 return Air.internedToRef(result_val.toIntern());
...@@ -30862,16 +31151,17 @@ fn coerceArrayPtrToSlice(...@@ -30862,16 +31151,17 @@ fn coerceArrayPtrToSlice(
30862 inst: Air.Inst.Ref,31151 inst: Air.Inst.Ref,
30863 inst_src: LazySrcLoc,31152 inst_src: LazySrcLoc,
30864) CompileError!Air.Inst.Ref {31153) CompileError!Air.Inst.Ref {
30865 const mod = sema.mod;31154 const pt = sema.pt;
31155 const mod = pt.zcu;
30866 if (try sema.resolveValue(inst)) |val| {31156 if (try sema.resolveValue(inst)) |val| {
30867 const ptr_array_ty = sema.typeOf(inst);31157 const ptr_array_ty = sema.typeOf(inst);
30868 const array_ty = ptr_array_ty.childType(mod);31158 const array_ty = ptr_array_ty.childType(mod);
30869 const slice_ptr_ty = dest_ty.slicePtrFieldType(mod);31159 const slice_ptr_ty = dest_ty.slicePtrFieldType(mod);
30870 const slice_ptr = try mod.getCoerced(val, slice_ptr_ty);31160 const slice_ptr = try pt.getCoerced(val, slice_ptr_ty);
30871 const slice_val = try mod.intern(.{ .slice = .{31161 const slice_val = try pt.intern(.{ .slice = .{
30872 .ty = dest_ty.toIntern(),31162 .ty = dest_ty.toIntern(),
30873 .ptr = slice_ptr.toIntern(),31163 .ptr = slice_ptr.toIntern(),
30874 .len = (try mod.intValue(Type.usize, array_ty.arrayLen(mod))).toIntern(),31164 .len = (try pt.intValue(Type.usize, array_ty.arrayLen(mod))).toIntern(),
30875 } });31165 } });
30876 return Air.internedToRef(slice_val);31166 return Air.internedToRef(slice_val);
30877 }31167 }
...@@ -30880,7 +31170,8 @@ fn coerceArrayPtrToSlice(...@@ -30880,7 +31170,8 @@ fn coerceArrayPtrToSlice(
30880}31170}
3088131171
30882fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_result: *InMemoryCoercionResult) bool {31172fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_result: *InMemoryCoercionResult) bool {
30883 const mod = sema.mod;31173 const pt = sema.pt;
31174 const mod = pt.zcu;
30884 const dest_info = dest_ty.ptrInfo(mod);31175 const dest_info = dest_ty.ptrInfo(mod);
30885 const inst_info = inst_ty.ptrInfo(mod);31176 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 or31177 const len0 = (Type.fromInterned(inst_info.child).zigTypeTag(mod) == .Array and (Type.fromInterned(inst_info.child).arrayLenIncludingSentinel(mod) == 0 or
...@@ -30913,12 +31204,12 @@ fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_resul...@@ -30913,12 +31204,12 @@ fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_resul
30913 const inst_align = if (inst_info.flags.alignment != .none)31204 const inst_align = if (inst_info.flags.alignment != .none)
30914 inst_info.flags.alignment31205 inst_info.flags.alignment
30915 else31206 else
30916 Type.fromInterned(inst_info.child).abiAlignment(mod);31207 Type.fromInterned(inst_info.child).abiAlignment(pt);
3091731208
30918 const dest_align = if (dest_info.flags.alignment != .none)31209 const dest_align = if (dest_info.flags.alignment != .none)
30919 dest_info.flags.alignment31210 dest_info.flags.alignment
30920 else31211 else
30921 Type.fromInterned(dest_info.child).abiAlignment(mod);31212 Type.fromInterned(dest_info.child).abiAlignment(pt);
3092231213
30923 if (dest_align.compare(.gt, inst_align)) {31214 if (dest_align.compare(.gt, inst_align)) {
30924 in_memory_result.* = .{ .ptr_alignment = .{31215 in_memory_result.* = .{ .ptr_alignment = .{
...@@ -30937,15 +31228,16 @@ fn coerceCompatiblePtrs(...@@ -30937,15 +31228,16 @@ fn coerceCompatiblePtrs(
30937 inst: Air.Inst.Ref,31228 inst: Air.Inst.Ref,
30938 inst_src: LazySrcLoc,31229 inst_src: LazySrcLoc,
30939) !Air.Inst.Ref {31230) !Air.Inst.Ref {
30940 const mod = sema.mod;31231 const pt = sema.pt;
31232 const mod = pt.zcu;
30941 const inst_ty = sema.typeOf(inst);31233 const inst_ty = sema.typeOf(inst);
30942 if (try sema.resolveValue(inst)) |val| {31234 if (try sema.resolveValue(inst)) |val| {
30943 if (!val.isUndef(mod) and val.isNull(mod) and !dest_ty.isAllowzeroPtr(mod)) {31235 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)});31236 return sema.fail(block, inst_src, "null pointer casted to type '{}'", .{dest_ty.fmt(pt)});
30945 }31237 }
30946 // The comptime Value representation is compatible with both types.31238 // The comptime Value representation is compatible with both types.
30947 return Air.internedToRef(31239 return Air.internedToRef(
30948 (try mod.getCoerced(val, dest_ty)).toIntern(),31240 (try pt.getCoerced(val, dest_ty)).toIntern(),
30949 );31241 );
30950 }31242 }
30951 try sema.requireRuntimeBlock(block, inst_src, null);31243 try sema.requireRuntimeBlock(block, inst_src, null);
...@@ -30979,14 +31271,15 @@ fn coerceEnumToUnion(...@@ -30979,14 +31271,15 @@ fn coerceEnumToUnion(
30979 inst: Air.Inst.Ref,31271 inst: Air.Inst.Ref,
30980 inst_src: LazySrcLoc,31272 inst_src: LazySrcLoc,
30981) !Air.Inst.Ref {31273) !Air.Inst.Ref {
30982 const mod = sema.mod;31274 const pt = sema.pt;
31275 const mod = pt.zcu;
30983 const ip = &mod.intern_pool;31276 const ip = &mod.intern_pool;
30984 const inst_ty = sema.typeOf(inst);31277 const inst_ty = sema.typeOf(inst);
3098531278
30986 const tag_ty = union_ty.unionTagType(mod) orelse {31279 const tag_ty = union_ty.unionTagType(mod) orelse {
30987 const msg = msg: {31280 const msg = msg: {
30988 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{31281 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{
30989 union_ty.fmt(sema.mod), inst_ty.fmt(sema.mod),31282 union_ty.fmt(pt), inst_ty.fmt(pt),
30990 });31283 });
30991 errdefer msg.destroy(sema.gpa);31284 errdefer msg.destroy(sema.gpa);
30992 try sema.errNote(union_ty_src, msg, "cannot coerce enum to untagged union", .{});31285 try sema.errNote(union_ty_src, msg, "cannot coerce enum to untagged union", .{});
...@@ -30998,15 +31291,15 @@ fn coerceEnumToUnion(...@@ -30998,15 +31291,15 @@ fn coerceEnumToUnion(
3099831291
30999 const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src);31292 const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src);
31000 if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {31293 if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {
31001 const field_index = union_ty.unionTagFieldIndex(val, sema.mod) orelse {31294 const field_index = union_ty.unionTagFieldIndex(val, pt.zcu) orelse {
31002 return sema.fail(block, inst_src, "union '{}' has no tag with value '{}'", .{31295 return sema.fail(block, inst_src, "union '{}' has no tag with value '{}'", .{
31003 union_ty.fmt(sema.mod), val.fmtValue(sema.mod, sema),31296 union_ty.fmt(pt), val.fmtValue(pt, sema),
31004 });31297 });
31005 };31298 };
3100631299
31007 const union_obj = mod.typeToUnion(union_ty).?;31300 const union_obj = mod.typeToUnion(union_ty).?;
31008 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);31301 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
31009 try field_ty.resolveFields(mod);31302 try field_ty.resolveFields(pt);
31010 if (field_ty.zigTypeTag(mod) == .NoReturn) {31303 if (field_ty.zigTypeTag(mod) == .NoReturn) {
31011 const msg = msg: {31304 const msg = msg: {
31012 const msg = try sema.errMsg(inst_src, "cannot initialize 'noreturn' field of union", .{});31305 const msg = try sema.errMsg(inst_src, "cannot initialize 'noreturn' field of union", .{});
...@@ -31025,8 +31318,8 @@ fn coerceEnumToUnion(...@@ -31025,8 +31318,8 @@ fn coerceEnumToUnion(
31025 const msg = msg: {31318 const msg = msg: {
31026 const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index];31319 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 '{}'", .{31320 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),31321 inst_ty.fmt(pt), union_ty.fmt(pt),
31029 field_ty.fmt(sema.mod), field_name.fmt(ip),31322 field_ty.fmt(pt), field_name.fmt(ip),
31030 });31323 });
31031 errdefer msg.destroy(sema.gpa);31324 errdefer msg.destroy(sema.gpa);
3103231325
...@@ -31039,7 +31332,7 @@ fn coerceEnumToUnion(...@@ -31039,7 +31332,7 @@ fn coerceEnumToUnion(
31039 return sema.failWithOwnedErrorMsg(block, msg);31332 return sema.failWithOwnedErrorMsg(block, msg);
31040 };31333 };
3104131334
31042 return Air.internedToRef((try mod.unionValue(union_ty, val, opv)).toIntern());31335 return Air.internedToRef((try pt.unionValue(union_ty, val, opv)).toIntern());
31043 }31336 }
3104431337
31045 try sema.requireRuntimeBlock(block, inst_src, null);31338 try sema.requireRuntimeBlock(block, inst_src, null);
...@@ -31047,7 +31340,7 @@ fn coerceEnumToUnion(...@@ -31047,7 +31340,7 @@ fn coerceEnumToUnion(
31047 if (tag_ty.isNonexhaustiveEnum(mod)) {31340 if (tag_ty.isNonexhaustiveEnum(mod)) {
31048 const msg = msg: {31341 const msg = msg: {
31049 const msg = try sema.errMsg(inst_src, "runtime coercion to union '{}' from non-exhaustive enum", .{31342 const msg = try sema.errMsg(inst_src, "runtime coercion to union '{}' from non-exhaustive enum", .{
31050 union_ty.fmt(sema.mod),31343 union_ty.fmt(pt),
31051 });31344 });
31052 errdefer msg.destroy(sema.gpa);31345 errdefer msg.destroy(sema.gpa);
31053 try sema.addDeclaredHereNote(msg, tag_ty);31346 try sema.addDeclaredHereNote(msg, tag_ty);
...@@ -31066,7 +31359,7 @@ fn coerceEnumToUnion(...@@ -31066,7 +31359,7 @@ fn coerceEnumToUnion(
31066 const err_msg = msg orelse try sema.errMsg(31359 const err_msg = msg orelse try sema.errMsg(
31067 inst_src,31360 inst_src,
31068 "runtime coercion from enum '{}' to union '{}' which has a 'noreturn' field",31361 "runtime coercion from enum '{}' to union '{}' which has a 'noreturn' field",
31069 .{ tag_ty.fmt(sema.mod), union_ty.fmt(sema.mod) },31362 .{ tag_ty.fmt(pt), union_ty.fmt(pt) },
31070 );31363 );
31071 msg = err_msg;31364 msg = err_msg;
3107231365
...@@ -31081,7 +31374,7 @@ fn coerceEnumToUnion(...@@ -31081,7 +31374,7 @@ fn coerceEnumToUnion(
31081 }31374 }
3108231375
31083 // If the union has all fields 0 bits, the union value is just the enum value.31376 // If the union has all fields 0 bits, the union value is just the enum value.
31084 if (union_ty.unionHasAllZeroBitFieldTypes(mod)) {31377 if (union_ty.unionHasAllZeroBitFieldTypes(pt)) {
31085 return block.addBitCast(union_ty, enum_tag);31378 return block.addBitCast(union_ty, enum_tag);
31086 }31379 }
3108731380
...@@ -31089,7 +31382,7 @@ fn coerceEnumToUnion(...@@ -31089,7 +31382,7 @@ fn coerceEnumToUnion(
31089 const msg = try sema.errMsg(31382 const msg = try sema.errMsg(
31090 inst_src,31383 inst_src,
31091 "runtime coercion from enum '{}' to union '{}' which has non-void fields",31384 "runtime coercion from enum '{}' to union '{}' which has non-void fields",
31092 .{ tag_ty.fmt(sema.mod), union_ty.fmt(sema.mod) },31385 .{ tag_ty.fmt(pt), union_ty.fmt(pt) },
31093 );31386 );
31094 errdefer msg.destroy(sema.gpa);31387 errdefer msg.destroy(sema.gpa);
3109531388
...@@ -31099,7 +31392,7 @@ fn coerceEnumToUnion(...@@ -31099,7 +31392,7 @@ fn coerceEnumToUnion(
31099 if (!(try sema.typeHasRuntimeBits(field_ty))) continue;31392 if (!(try sema.typeHasRuntimeBits(field_ty))) continue;
31100 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{}' has type '{}'", .{31393 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{}' has type '{}'", .{
31101 field_name.fmt(ip),31394 field_name.fmt(ip),
31102 field_ty.fmt(sema.mod),31395 field_ty.fmt(pt),
31103 });31396 });
31104 }31397 }
31105 try sema.addDeclaredHereNote(msg, union_ty);31398 try sema.addDeclaredHereNote(msg, union_ty);
...@@ -31116,7 +31409,8 @@ fn coerceAnonStructToUnion(...@@ -31116,7 +31409,8 @@ fn coerceAnonStructToUnion(
31116 inst: Air.Inst.Ref,31409 inst: Air.Inst.Ref,
31117 inst_src: LazySrcLoc,31410 inst_src: LazySrcLoc,
31118) !Air.Inst.Ref {31411) !Air.Inst.Ref {
31119 const mod = sema.mod;31412 const pt = sema.pt;
31413 const mod = pt.zcu;
31120 const ip = &mod.intern_pool;31414 const ip = &mod.intern_pool;
31121 const inst_ty = sema.typeOf(inst);31415 const inst_ty = sema.typeOf(inst);
31122 const field_info: union(enum) {31416 const field_info: union(enum) {
...@@ -31174,7 +31468,8 @@ fn coerceAnonStructToUnionPtrs(...@@ -31174,7 +31468,8 @@ fn coerceAnonStructToUnionPtrs(
31174 ptr_anon_struct: Air.Inst.Ref,31468 ptr_anon_struct: Air.Inst.Ref,
31175 anon_struct_src: LazySrcLoc,31469 anon_struct_src: LazySrcLoc,
31176) !Air.Inst.Ref {31470) !Air.Inst.Ref {
31177 const mod = sema.mod;31471 const pt = sema.pt;
31472 const mod = pt.zcu;
31178 const union_ty = ptr_union_ty.childType(mod);31473 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);31474 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);31475 const union_inst = try sema.coerceAnonStructToUnion(block, union_ty, union_ty_src, anon_struct, anon_struct_src);
...@@ -31189,7 +31484,8 @@ fn coerceAnonStructToStructPtrs(...@@ -31189,7 +31484,8 @@ fn coerceAnonStructToStructPtrs(
31189 ptr_anon_struct: Air.Inst.Ref,31484 ptr_anon_struct: Air.Inst.Ref,
31190 anon_struct_src: LazySrcLoc,31485 anon_struct_src: LazySrcLoc,
31191) !Air.Inst.Ref {31486) !Air.Inst.Ref {
31192 const mod = sema.mod;31487 const pt = sema.pt;
31488 const mod = pt.zcu;
31193 const struct_ty = ptr_struct_ty.childType(mod);31489 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);31490 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);31491 const struct_inst = try sema.coerceTupleToStruct(block, struct_ty, anon_struct, anon_struct_src);
...@@ -31205,7 +31501,8 @@ fn coerceArrayLike(...@@ -31205,7 +31501,8 @@ fn coerceArrayLike(
31205 inst: Air.Inst.Ref,31501 inst: Air.Inst.Ref,
31206 inst_src: LazySrcLoc,31502 inst_src: LazySrcLoc,
31207) !Air.Inst.Ref {31503) !Air.Inst.Ref {
31208 const mod = sema.mod;31504 const pt = sema.pt;
31505 const mod = pt.zcu;
31209 const inst_ty = sema.typeOf(inst);31506 const inst_ty = sema.typeOf(inst);
31210 const target = mod.getTarget();31507 const target = mod.getTarget();
3121131508
...@@ -31226,7 +31523,7 @@ fn coerceArrayLike(...@@ -31226,7 +31523,7 @@ fn coerceArrayLike(
31226 if (dest_len != inst_len) {31523 if (dest_len != inst_len) {
31227 const msg = msg: {31524 const msg = msg: {
31228 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{31525 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{
31229 dest_ty.fmt(mod), inst_ty.fmt(mod),31526 dest_ty.fmt(pt), inst_ty.fmt(pt),
31230 });31527 });
31231 errdefer msg.destroy(sema.gpa);31528 errdefer msg.destroy(sema.gpa);
31232 try sema.errNote(dest_ty_src, msg, "destination has length {d}", .{dest_len});31529 try sema.errNote(dest_ty_src, msg, "destination has length {d}", .{dest_len});
...@@ -31270,7 +31567,7 @@ fn coerceArrayLike(...@@ -31270,7 +31567,7 @@ fn coerceArrayLike(
31270 var runtime_src: ?LazySrcLoc = null;31567 var runtime_src: ?LazySrcLoc = null;
3127131568
31272 for (element_vals, element_refs, 0..) |*val, *ref, i| {31569 for (element_vals, element_refs, 0..) |*val, *ref, i| {
31273 const index_ref = Air.internedToRef((try mod.intValue(Type.usize, i)).toIntern());31570 const index_ref = Air.internedToRef((try pt.intValue(Type.usize, i)).toIntern());
31274 const src = inst_src; // TODO better source location31571 const src = inst_src; // TODO better source location
31275 const elem_src = inst_src; // TODO better source location31572 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);31573 const elem_ref = try sema.elemValArray(block, src, inst_src, inst, elem_src, index_ref, true);
...@@ -31290,7 +31587,7 @@ fn coerceArrayLike(...@@ -31290,7 +31587,7 @@ fn coerceArrayLike(
31290 return block.addAggregateInit(dest_ty, element_refs);31587 return block.addAggregateInit(dest_ty, element_refs);
31291 }31588 }
3129231589
31293 return Air.internedToRef((try mod.intern(.{ .aggregate = .{31590 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
31294 .ty = dest_ty.toIntern(),31591 .ty = dest_ty.toIntern(),
31295 .storage = .{ .elems = element_vals },31592 .storage = .{ .elems = element_vals },
31296 } })));31593 } })));
...@@ -31305,7 +31602,8 @@ fn coerceTupleToArray(...@@ -31305,7 +31602,8 @@ fn coerceTupleToArray(
31305 inst: Air.Inst.Ref,31602 inst: Air.Inst.Ref,
31306 inst_src: LazySrcLoc,31603 inst_src: LazySrcLoc,
31307) !Air.Inst.Ref {31604) !Air.Inst.Ref {
31308 const mod = sema.mod;31605 const pt = sema.pt;
31606 const mod = pt.zcu;
31309 const inst_ty = sema.typeOf(inst);31607 const inst_ty = sema.typeOf(inst);
31310 const inst_len = inst_ty.arrayLen(mod);31608 const inst_len = inst_ty.arrayLen(mod);
31311 const dest_len = dest_ty.arrayLen(mod);31609 const dest_len = dest_ty.arrayLen(mod);
...@@ -31313,7 +31611,7 @@ fn coerceTupleToArray(...@@ -31313,7 +31611,7 @@ fn coerceTupleToArray(
31313 if (dest_len != inst_len) {31611 if (dest_len != inst_len) {
31314 const msg = msg: {31612 const msg = msg: {
31315 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{31613 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{
31316 dest_ty.fmt(sema.mod), inst_ty.fmt(sema.mod),31614 dest_ty.fmt(pt), inst_ty.fmt(pt),
31317 });31615 });
31318 errdefer msg.destroy(sema.gpa);31616 errdefer msg.destroy(sema.gpa);
31319 try sema.errNote(dest_ty_src, msg, "destination has length {d}", .{dest_len});31617 try sema.errNote(dest_ty_src, msg, "destination has length {d}", .{dest_len});
...@@ -31355,7 +31653,7 @@ fn coerceTupleToArray(...@@ -31355,7 +31653,7 @@ fn coerceTupleToArray(
31355 return block.addAggregateInit(dest_ty, element_refs);31653 return block.addAggregateInit(dest_ty, element_refs);
31356 }31654 }
3135731655
31358 return Air.internedToRef((try mod.intern(.{ .aggregate = .{31656 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
31359 .ty = dest_ty.toIntern(),31657 .ty = dest_ty.toIntern(),
31360 .storage = .{ .elems = element_vals },31658 .storage = .{ .elems = element_vals },
31361 } })));31659 } })));
...@@ -31370,11 +31668,12 @@ fn coerceTupleToSlicePtrs(...@@ -31370,11 +31668,12 @@ fn coerceTupleToSlicePtrs(
31370 ptr_tuple: Air.Inst.Ref,31668 ptr_tuple: Air.Inst.Ref,
31371 tuple_src: LazySrcLoc,31669 tuple_src: LazySrcLoc,
31372) !Air.Inst.Ref {31670) !Air.Inst.Ref {
31373 const mod = sema.mod;31671 const pt = sema.pt;
31672 const mod = pt.zcu;
31374 const tuple_ty = sema.typeOf(ptr_tuple).childType(mod);31673 const tuple_ty = sema.typeOf(ptr_tuple).childType(mod);
31375 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);31674 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);
31376 const slice_info = slice_ty.ptrInfo(mod);31675 const slice_info = slice_ty.ptrInfo(mod);
31377 const array_ty = try mod.arrayType(.{31676 const array_ty = try pt.arrayType(.{
31378 .len = tuple_ty.structFieldCount(mod),31677 .len = tuple_ty.structFieldCount(mod),
31379 .sentinel = slice_info.sentinel,31678 .sentinel = slice_info.sentinel,
31380 .child = slice_info.child,31679 .child = slice_info.child,
...@@ -31396,7 +31695,8 @@ fn coerceTupleToArrayPtrs(...@@ -31396,7 +31695,8 @@ fn coerceTupleToArrayPtrs(
31396 ptr_tuple: Air.Inst.Ref,31695 ptr_tuple: Air.Inst.Ref,
31397 tuple_src: LazySrcLoc,31696 tuple_src: LazySrcLoc,
31398) !Air.Inst.Ref {31697) !Air.Inst.Ref {
31399 const mod = sema.mod;31698 const pt = sema.pt;
31699 const mod = pt.zcu;
31400 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);31700 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);
31401 const ptr_info = ptr_array_ty.ptrInfo(mod);31701 const ptr_info = ptr_array_ty.ptrInfo(mod);
31402 const array_ty = Type.fromInterned(ptr_info.child);31702 const array_ty = Type.fromInterned(ptr_info.child);
...@@ -31417,10 +31717,11 @@ fn coerceTupleToStruct(...@@ -31417,10 +31717,11 @@ fn coerceTupleToStruct(
31417 inst: Air.Inst.Ref,31717 inst: Air.Inst.Ref,
31418 inst_src: LazySrcLoc,31718 inst_src: LazySrcLoc,
31419) !Air.Inst.Ref {31719) !Air.Inst.Ref {
31420 const mod = sema.mod;31720 const pt = sema.pt;
31721 const mod = pt.zcu;
31421 const ip = &mod.intern_pool;31722 const ip = &mod.intern_pool;
31422 try struct_ty.resolveFields(mod);31723 try struct_ty.resolveFields(pt);
31423 try struct_ty.resolveStructFieldInits(mod);31724 try struct_ty.resolveStructFieldInits(pt);
3142431725
31425 if (struct_ty.isTupleOrAnonStruct(mod)) {31726 if (struct_ty.isTupleOrAnonStruct(mod)) {
31426 return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src);31727 return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src);
...@@ -31461,7 +31762,7 @@ fn coerceTupleToStruct(...@@ -31461,7 +31762,7 @@ fn coerceTupleToStruct(
31461 };31762 };
3146231763
31463 const field_init = Value.fromInterned(struct_type.field_inits.get(ip)[struct_field_index]);31764 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)) {31765 if (!init_val.eql(field_init, struct_field_ty, pt.zcu)) {
31465 return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, tuple_field_index);31766 return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, tuple_field_index);
31466 }31767 }
31467 }31768 }
...@@ -31512,7 +31813,7 @@ fn coerceTupleToStruct(...@@ -31512,7 +31813,7 @@ fn coerceTupleToStruct(
31512 return block.addAggregateInit(struct_ty, field_refs);31813 return block.addAggregateInit(struct_ty, field_refs);
31513 }31814 }
3151431815
31515 const struct_val = try mod.intern(.{ .aggregate = .{31816 const struct_val = try pt.intern(.{ .aggregate = .{
31516 .ty = struct_ty.toIntern(),31817 .ty = struct_ty.toIntern(),
31517 .storage = .{ .elems = field_vals },31818 .storage = .{ .elems = field_vals },
31518 } });31819 } });
...@@ -31529,7 +31830,8 @@ fn coerceTupleToTuple(...@@ -31529,7 +31830,8 @@ fn coerceTupleToTuple(
31529 inst: Air.Inst.Ref,31830 inst: Air.Inst.Ref,
31530 inst_src: LazySrcLoc,31831 inst_src: LazySrcLoc,
31531) !Air.Inst.Ref {31832) !Air.Inst.Ref {
31532 const mod = sema.mod;31833 const pt = sema.pt;
31834 const mod = pt.zcu;
31533 const ip = &mod.intern_pool;31835 const ip = &mod.intern_pool;
31534 const dest_field_count = switch (ip.indexToKey(tuple_ty.toIntern())) {31836 const dest_field_count = switch (ip.indexToKey(tuple_ty.toIntern())) {
31535 .anon_struct_type => |anon_struct_type| anon_struct_type.types.len,31837 .anon_struct_type => |anon_struct_type| anon_struct_type.types.len,
...@@ -31594,7 +31896,7 @@ fn coerceTupleToTuple(...@@ -31594,7 +31896,7 @@ fn coerceTupleToTuple(
31594 });31896 });
31595 };31897 };
3159631898
31597 if (!init_val.eql(Value.fromInterned(default_val), Type.fromInterned(field_ty), sema.mod)) {31899 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);31900 return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, field_i);
31599 }31901 }
31600 }31902 }
...@@ -31659,7 +31961,7 @@ fn coerceTupleToTuple(...@@ -31659,7 +31961,7 @@ fn coerceTupleToTuple(
31659 return block.addAggregateInit(tuple_ty, field_refs);31961 return block.addAggregateInit(tuple_ty, field_refs);
31660 }31962 }
3166131963
31662 return Air.internedToRef((try mod.intern(.{ .aggregate = .{31964 return Air.internedToRef((try pt.intern(.{ .aggregate = .{
31663 .ty = tuple_ty.toIntern(),31965 .ty = tuple_ty.toIntern(),
31664 .storage = .{ .elems = field_vals },31966 .storage = .{ .elems = field_vals },
31665 } })));31967 } })));
...@@ -31689,17 +31991,19 @@ fn addReferenceEntry(...@@ -31689,17 +31991,19 @@ fn addReferenceEntry(
31689 src: LazySrcLoc,31991 src: LazySrcLoc,
31690 referenced_unit: AnalUnit,31992 referenced_unit: AnalUnit,
31691) !void {31993) !void {
31692 if (sema.mod.comp.reference_trace == 0) return;31994 const zcu = sema.pt.zcu;
31995 if (zcu.comp.reference_trace == 0) return;
31693 const gop = try sema.references.getOrPut(sema.gpa, referenced_unit);31996 const gop = try sema.references.getOrPut(sema.gpa, referenced_unit);
31694 if (gop.found_existing) return;31997 if (gop.found_existing) return;
31695 // TODO: we need to figure out how to model inline calls here.31998 // 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!31999 // 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?32000 // Would representing inline calls in the reference table cause excessive memory usage?
31698 try sema.mod.addUnitReference(sema.ownerUnit(), referenced_unit, src);32001 try zcu.addUnitReference(sema.ownerUnit(), referenced_unit, src);
31699}32002}
3170032003
31701pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) CompileError!void {32004pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) CompileError!void {
31702 const mod = sema.mod;32005 const pt = sema.pt;
32006 const mod = pt.zcu;
31703 const ip = &mod.intern_pool;32007 const ip = &mod.intern_pool;
31704 const decl = mod.declPtr(decl_index);32008 const decl = mod.declPtr(decl_index);
31705 if (decl.analysis == .in_progress) {32009 if (decl.analysis == .in_progress) {
...@@ -31710,7 +32014,7 @@ pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) Compile...@@ -31710,7 +32014,7 @@ pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) Compile
31710 return sema.failWithOwnedErrorMsg(null, msg);32014 return sema.failWithOwnedErrorMsg(null, msg);
31711 }32015 }
3171232016
31713 mod.ensureDeclAnalyzed(decl_index) catch |err| {32017 pt.ensureDeclAnalyzed(decl_index) catch |err| {
31714 if (sema.owner_func_index != .none) {32018 if (sema.owner_func_index != .none) {
31715 ip.funcAnalysis(sema.owner_func_index).state = .dependency_failure;32019 ip.funcAnalysis(sema.owner_func_index).state = .dependency_failure;
31716 } else {32020 } else {
...@@ -31721,9 +32025,10 @@ pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) Compile...@@ -31721,9 +32025,10 @@ pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) Compile
31721}32025}
3172232026
31723fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void {32027fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void {
31724 const mod = sema.mod;32028 const pt = sema.pt;
32029 const mod = pt.zcu;
31725 const ip = &mod.intern_pool;32030 const ip = &mod.intern_pool;
31726 mod.ensureFuncBodyAnalyzed(func) catch |err| {32031 pt.ensureFuncBodyAnalyzed(func) catch |err| {
31727 if (sema.owner_func_index != .none) {32032 if (sema.owner_func_index != .none) {
31728 ip.funcAnalysis(sema.owner_func_index).state = .dependency_failure;32033 ip.funcAnalysis(sema.owner_func_index).state = .dependency_failure;
31729 } else {32034 } else {
...@@ -31734,15 +32039,15 @@ fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void...@@ -31734,15 +32039,15 @@ fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void
31734}32039}
3173532040
31736fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {32041fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {
31737 const mod = sema.mod;32042 const pt = sema.pt;
31738 const ptr_anyopaque_ty = try mod.singleConstPtrType(Type.anyopaque);32043 const ptr_anyopaque_ty = try pt.singleConstPtrType(Type.anyopaque);
31739 return Value.fromInterned((try mod.intern(.{ .opt = .{32044 return Value.fromInterned(try pt.intern(.{ .opt = .{
31740 .ty = (try mod.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(),32045 .ty = (try pt.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(),
31741 .val = if (opt_val) |val| (try mod.getCoerced(32046 .val = if (opt_val) |val| (try pt.getCoerced(
31742 Value.fromInterned(try sema.refValue(val.toIntern())),32047 Value.fromInterned(try sema.refValue(val.toIntern())),
31743 ptr_anyopaque_ty,32048 ptr_anyopaque_ty,
31744 )).toIntern() else .none,32049 )).toIntern() else .none,
31745 } })));32050 } }));
31746}32051}
3174732052
31748fn analyzeDeclRef(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) CompileError!Air.Inst.Ref {32053fn analyzeDeclRef(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) CompileError!Air.Inst.Ref {
...@@ -31754,7 +32059,8 @@ fn analyzeDeclRef(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex...@@ -31754,7 +32059,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` wraps32059/// 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.32060/// 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 {32061fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex, analyze_fn_body: bool) CompileError!Air.Inst.Ref {
31757 const mod = sema.mod;32062 const pt = sema.pt;
32063 const mod = pt.zcu;
31758 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = decl_index }));32064 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = decl_index }));
31759 try sema.ensureDeclAnalyzed(decl_index);32065 try sema.ensureDeclAnalyzed(decl_index);
3176032066
...@@ -31767,7 +32073,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl...@@ -31767,7 +32073,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl
31767 });32073 });
31768 // TODO: if this is a `decl_ref` of a non-variable decl, only depend on decl type32074 // 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 });32075 try sema.declareDependency(.{ .decl_val = decl_index });
31770 const ptr_ty = try mod.ptrTypeSema(.{32076 const ptr_ty = try pt.ptrTypeSema(.{
31771 .child = decl_val.typeOf(mod).toIntern(),32077 .child = decl_val.typeOf(mod).toIntern(),
31772 .flags = .{32078 .flags = .{
31773 .alignment = owner_decl.alignment,32079 .alignment = owner_decl.alignment,
...@@ -31778,7 +32084,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl...@@ -31778,7 +32084,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl
31778 if (analyze_fn_body) {32084 if (analyze_fn_body) {
31779 try sema.maybeQueueFuncBodyAnalysis(src, decl_index);32085 try sema.maybeQueueFuncBodyAnalysis(src, decl_index);
31780 }32086 }
31781 return Air.internedToRef((try mod.intern(.{ .ptr = .{32087 return Air.internedToRef((try pt.intern(.{ .ptr = .{
31782 .ty = ptr_ty.toIntern(),32088 .ty = ptr_ty.toIntern(),
31783 .base_addr = .{ .decl = decl_index },32089 .base_addr = .{ .decl = decl_index },
31784 .byte_offset = 0,32090 .byte_offset = 0,
...@@ -31786,7 +32092,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl...@@ -31786,7 +32092,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl
31786}32092}
3178732093
31788fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) !void {32094fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) !void {
31789 const mod = sema.mod;32095 const mod = sema.pt.zcu;
31790 const decl = mod.declPtr(decl_index);32096 const decl = mod.declPtr(decl_index);
31791 const decl_val = try decl.valueOrFail();32097 const decl_val = try decl.valueOrFail();
31792 if (!mod.intern_pool.isFuncBody(decl_val.toIntern())) return;32098 if (!mod.intern_pool.isFuncBody(decl_val.toIntern())) return;
...@@ -31801,7 +32107,8 @@ fn analyzeRef(...@@ -31801,7 +32107,8 @@ fn analyzeRef(
31801 src: LazySrcLoc,32107 src: LazySrcLoc,
31802 operand: Air.Inst.Ref,32108 operand: Air.Inst.Ref,
31803) CompileError!Air.Inst.Ref {32109) CompileError!Air.Inst.Ref {
31804 const mod = sema.mod;32110 const pt = sema.pt;
32111 const mod = pt.zcu;
31805 const operand_ty = sema.typeOf(operand);32112 const operand_ty = sema.typeOf(operand);
3180632113
31807 if (try sema.resolveValue(operand)) |val| {32114 if (try sema.resolveValue(operand)) |val| {
...@@ -31814,14 +32121,14 @@ fn analyzeRef(...@@ -31814,14 +32121,14 @@ fn analyzeRef(
3181432121
31815 try sema.requireRuntimeBlock(block, src, null);32122 try sema.requireRuntimeBlock(block, src, null);
31816 const address_space = target_util.defaultAddressSpace(mod.getTarget(), .local);32123 const address_space = target_util.defaultAddressSpace(mod.getTarget(), .local);
31817 const ptr_type = try mod.ptrTypeSema(.{32124 const ptr_type = try pt.ptrTypeSema(.{
31818 .child = operand_ty.toIntern(),32125 .child = operand_ty.toIntern(),
31819 .flags = .{32126 .flags = .{
31820 .is_const = true,32127 .is_const = true,
31821 .address_space = address_space,32128 .address_space = address_space,
31822 },32129 },
31823 });32130 });
31824 const mut_ptr_type = try mod.ptrTypeSema(.{32131 const mut_ptr_type = try pt.ptrTypeSema(.{
31825 .child = operand_ty.toIntern(),32132 .child = operand_ty.toIntern(),
31826 .flags = .{ .address_space = address_space },32133 .flags = .{ .address_space = address_space },
31827 });32134 });
...@@ -31839,14 +32146,15 @@ fn analyzeLoad(...@@ -31839,14 +32146,15 @@ fn analyzeLoad(
31839 ptr: Air.Inst.Ref,32146 ptr: Air.Inst.Ref,
31840 ptr_src: LazySrcLoc,32147 ptr_src: LazySrcLoc,
31841) CompileError!Air.Inst.Ref {32148) CompileError!Air.Inst.Ref {
31842 const mod = sema.mod;32149 const pt = sema.pt;
32150 const mod = pt.zcu;
31843 const ptr_ty = sema.typeOf(ptr);32151 const ptr_ty = sema.typeOf(ptr);
31844 const elem_ty = switch (ptr_ty.zigTypeTag(mod)) {32152 const elem_ty = switch (ptr_ty.zigTypeTag(mod)) {
31845 .Pointer => ptr_ty.childType(mod),32153 .Pointer => ptr_ty.childType(mod),
31846 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(sema.mod)}),32154 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(pt)}),
31847 };32155 };
31848 if (elem_ty.zigTypeTag(mod) == .Opaque) {32156 if (elem_ty.zigTypeTag(mod) == .Opaque) {
31849 return sema.fail(block, ptr_src, "cannot load opaque type '{}'", .{elem_ty.fmt(mod)});32157 return sema.fail(block, ptr_src, "cannot load opaque type '{}'", .{elem_ty.fmt(pt)});
31850 }32158 }
3185132159
31852 if (try sema.typeHasOnePossibleValue(elem_ty)) |opv| {32160 if (try sema.typeHasOnePossibleValue(elem_ty)) |opv| {
...@@ -31868,7 +32176,7 @@ fn analyzeLoad(...@@ -31868,7 +32176,7 @@ fn analyzeLoad(
31868 return block.addBinOp(.ptr_elem_val, bin_op.lhs, bin_op.rhs);32176 return block.addBinOp(.ptr_elem_val, bin_op.lhs, bin_op.rhs);
31869 }32177 }
31870 return sema.fail(block, ptr_src, "unable to determine vector element index of type '{}'", .{32178 return sema.fail(block, ptr_src, "unable to determine vector element index of type '{}'", .{
31871 ptr_ty.fmt(sema.mod),32179 ptr_ty.fmt(pt),
31872 });32180 });
31873 }32181 }
3187432182
...@@ -31882,10 +32190,11 @@ fn analyzeSlicePtr(...@@ -31882,10 +32190,11 @@ fn analyzeSlicePtr(
31882 slice: Air.Inst.Ref,32190 slice: Air.Inst.Ref,
31883 slice_ty: Type,32191 slice_ty: Type,
31884) CompileError!Air.Inst.Ref {32192) CompileError!Air.Inst.Ref {
31885 const mod = sema.mod;32193 const pt = sema.pt;
32194 const mod = pt.zcu;
31886 const result_ty = slice_ty.slicePtrFieldType(mod);32195 const result_ty = slice_ty.slicePtrFieldType(mod);
31887 if (try sema.resolveValue(slice)) |val| {32196 if (try sema.resolveValue(slice)) |val| {
31888 if (val.isUndef(mod)) return mod.undefRef(result_ty);32197 if (val.isUndef(mod)) return pt.undefRef(result_ty);
31889 return Air.internedToRef(val.slicePtr(mod).toIntern());32198 return Air.internedToRef(val.slicePtr(mod).toIntern());
31890 }32199 }
31891 try sema.requireRuntimeBlock(block, slice_src, null);32200 try sema.requireRuntimeBlock(block, slice_src, null);
...@@ -31899,11 +32208,12 @@ fn analyzeOptionalSlicePtr(...@@ -31899,11 +32208,12 @@ fn analyzeOptionalSlicePtr(
31899 opt_slice: Air.Inst.Ref,32208 opt_slice: Air.Inst.Ref,
31900 opt_slice_ty: Type,32209 opt_slice_ty: Type,
31901) CompileError!Air.Inst.Ref {32210) CompileError!Air.Inst.Ref {
31902 const mod = sema.mod;32211 const pt = sema.pt;
32212 const mod = pt.zcu;
31903 const result_ty = opt_slice_ty.optionalChild(mod).slicePtrFieldType(mod);32213 const result_ty = opt_slice_ty.optionalChild(mod).slicePtrFieldType(mod);
3190432214
31905 if (try sema.resolveValue(opt_slice)) |opt_val| {32215 if (try sema.resolveValue(opt_slice)) |opt_val| {
31906 if (opt_val.isUndef(mod)) return mod.undefRef(result_ty);32216 if (opt_val.isUndef(mod)) return pt.undefRef(result_ty);
31907 const slice_ptr: InternPool.Index = if (opt_val.optionalValue(mod)) |val|32217 const slice_ptr: InternPool.Index = if (opt_val.optionalValue(mod)) |val|
31908 val.slicePtr(mod).toIntern()32218 val.slicePtr(mod).toIntern()
31909 else32219 else
...@@ -31924,12 +32234,13 @@ fn analyzeSliceLen(...@@ -31924,12 +32234,13 @@ fn analyzeSliceLen(
31924 src: LazySrcLoc,32234 src: LazySrcLoc,
31925 slice_inst: Air.Inst.Ref,32235 slice_inst: Air.Inst.Ref,
31926) CompileError!Air.Inst.Ref {32236) CompileError!Air.Inst.Ref {
31927 const mod = sema.mod;32237 const pt = sema.pt;
32238 const mod = pt.zcu;
31928 if (try sema.resolveValue(slice_inst)) |slice_val| {32239 if (try sema.resolveValue(slice_inst)) |slice_val| {
31929 if (slice_val.isUndef(mod)) {32240 if (slice_val.isUndef(mod)) {
31930 return mod.undefRef(Type.usize);32241 return pt.undefRef(Type.usize);
31931 }32242 }
31932 return mod.intRef(Type.usize, try slice_val.sliceLen(mod));32243 return pt.intRef(Type.usize, try slice_val.sliceLen(pt));
31933 }32244 }
31934 try sema.requireRuntimeBlock(block, src, null);32245 try sema.requireRuntimeBlock(block, src, null);
31935 return block.addTyOp(.slice_len, Type.usize, slice_inst);32246 return block.addTyOp(.slice_len, Type.usize, slice_inst);
...@@ -31942,11 +32253,12 @@ fn analyzeIsNull(...@@ -31942,11 +32253,12 @@ fn analyzeIsNull(
31942 operand: Air.Inst.Ref,32253 operand: Air.Inst.Ref,
31943 invert_logic: bool,32254 invert_logic: bool,
31944) CompileError!Air.Inst.Ref {32255) CompileError!Air.Inst.Ref {
31945 const mod = sema.mod;32256 const pt = sema.pt;
32257 const mod = pt.zcu;
31946 const result_ty = Type.bool;32258 const result_ty = Type.bool;
31947 if (try sema.resolveValue(operand)) |opt_val| {32259 if (try sema.resolveValue(operand)) |opt_val| {
31948 if (opt_val.isUndef(mod)) {32260 if (opt_val.isUndef(mod)) {
31949 return mod.undefRef(result_ty);32261 return pt.undefRef(result_ty);
31950 }32262 }
31951 const is_null = opt_val.isNull(mod);32263 const is_null = opt_val.isNull(mod);
31952 const bool_value = if (invert_logic) !is_null else is_null;32264 const bool_value = if (invert_logic) !is_null else is_null;
...@@ -31972,7 +32284,8 @@ fn analyzePtrIsNonErrComptimeOnly(...@@ -31972,7 +32284,8 @@ fn analyzePtrIsNonErrComptimeOnly(
31972 src: LazySrcLoc,32284 src: LazySrcLoc,
31973 operand: Air.Inst.Ref,32285 operand: Air.Inst.Ref,
31974) CompileError!Air.Inst.Ref {32286) CompileError!Air.Inst.Ref {
31975 const mod = sema.mod;32287 const pt = sema.pt;
32288 const mod = pt.zcu;
31976 const ptr_ty = sema.typeOf(operand);32289 const ptr_ty = sema.typeOf(operand);
31977 assert(ptr_ty.zigTypeTag(mod) == .Pointer);32290 assert(ptr_ty.zigTypeTag(mod) == .Pointer);
31978 const child_ty = ptr_ty.childType(mod);32291 const child_ty = ptr_ty.childType(mod);
...@@ -31994,7 +32307,8 @@ fn analyzeIsNonErrComptimeOnly(...@@ -31994,7 +32307,8 @@ fn analyzeIsNonErrComptimeOnly(
31994 src: LazySrcLoc,32307 src: LazySrcLoc,
31995 operand: Air.Inst.Ref,32308 operand: Air.Inst.Ref,
31996) CompileError!Air.Inst.Ref {32309) CompileError!Air.Inst.Ref {
31997 const mod = sema.mod;32310 const pt = sema.pt;
32311 const mod = pt.zcu;
31998 const ip = &mod.intern_pool;32312 const ip = &mod.intern_pool;
31999 const operand_ty = sema.typeOf(operand);32313 const operand_ty = sema.typeOf(operand);
32000 const ot = operand_ty.zigTypeTag(mod);32314 const ot = operand_ty.zigTypeTag(mod);
...@@ -32014,7 +32328,7 @@ fn analyzeIsNonErrComptimeOnly(...@@ -32014,7 +32328,7 @@ fn analyzeIsNonErrComptimeOnly(
32014 else => {},32328 else => {},
32015 }32329 }
32016 } else if (operand == .undef) {32330 } else if (operand == .undef) {
32017 return mod.undefRef(Type.bool);32331 return pt.undefRef(Type.bool);
32018 } else if (@intFromEnum(operand) < InternPool.static_len) {32332 } else if (@intFromEnum(operand) < InternPool.static_len) {
32019 // None of the ref tags can be errors.32333 // None of the ref tags can be errors.
32020 return .bool_true;32334 return .bool_true;
...@@ -32098,7 +32412,7 @@ fn analyzeIsNonErrComptimeOnly(...@@ -32098,7 +32412,7 @@ fn analyzeIsNonErrComptimeOnly(
3209832412
32099 if (maybe_operand_val) |err_union| {32413 if (maybe_operand_val) |err_union| {
32100 if (err_union.isUndef(mod)) {32414 if (err_union.isUndef(mod)) {
32101 return mod.undefRef(Type.bool);32415 return pt.undefRef(Type.bool);
32102 }32416 }
32103 if (err_union.getErrorName(mod) == .none) {32417 if (err_union.getErrorName(mod) == .none) {
32104 return .bool_true;32418 return .bool_true;
...@@ -32153,13 +32467,14 @@ fn analyzeSlice(...@@ -32153,13 +32467,14 @@ fn analyzeSlice(
32153 end_src: LazySrcLoc,32467 end_src: LazySrcLoc,
32154 by_length: bool,32468 by_length: bool,
32155) CompileError!Air.Inst.Ref {32469) CompileError!Air.Inst.Ref {
32156 const mod = sema.mod;32470 const pt = sema.pt;
32471 const mod = pt.zcu;
32157 // Slice expressions can operate on a variable whose type is an array. This requires32472 // 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.32473 // 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);32474 const ptr_ptr_ty = sema.typeOf(ptr_ptr);
32160 const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag(mod)) {32475 const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag(mod)) {
32161 .Pointer => ptr_ptr_ty.childType(mod),32476 .Pointer => ptr_ptr_ty.childType(mod),
32162 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty.fmt(mod)}),32477 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty.fmt(pt)}),
32163 };32478 };
3216432479
32165 var array_ty = ptr_ptr_child_ty;32480 var array_ty = ptr_ptr_child_ty;
...@@ -32210,8 +32525,8 @@ fn analyzeSlice(...@@ -32210,8 +32525,8 @@ fn analyzeSlice(
32210 msg,32525 msg,
32211 "expected '{}', found '{}'",32526 "expected '{}', found '{}'",
32212 .{32527 .{
32213 Value.zero_comptime_int.fmtValue(mod, sema),32528 Value.zero_comptime_int.fmtValue(pt, sema),
32214 start_value.fmtValue(mod, sema),32529 start_value.fmtValue(pt, sema),
32215 },32530 },
32216 );32531 );
32217 break :msg msg;32532 break :msg msg;
...@@ -32226,8 +32541,8 @@ fn analyzeSlice(...@@ -32226,8 +32541,8 @@ fn analyzeSlice(
32226 msg,32541 msg,
32227 "expected '{}', found '{}'",32542 "expected '{}', found '{}'",
32228 .{32543 .{
32229 Value.one_comptime_int.fmtValue(mod, sema),32544 Value.one_comptime_int.fmtValue(pt, sema),
32230 end_value.fmtValue(mod, sema),32545 end_value.fmtValue(pt, sema),
32231 },32546 },
32232 );32547 );
32233 break :msg msg;32548 break :msg msg;
...@@ -32240,17 +32555,17 @@ fn analyzeSlice(...@@ -32240,17 +32555,17 @@ fn analyzeSlice(
32240 block,32555 block,
32241 end_src,32556 end_src,
32242 "end index {} out of bounds for slice of single-item pointer",32557 "end index {} out of bounds for slice of single-item pointer",
32243 .{end_value.fmtValue(mod, sema)},32558 .{end_value.fmtValue(pt, sema)},
32244 );32559 );
32245 }32560 }
32246 }32561 }
3224732562
32248 array_ty = try mod.arrayType(.{32563 array_ty = try pt.arrayType(.{
32249 .len = 1,32564 .len = 1,
32250 .child = double_child_ty.toIntern(),32565 .child = double_child_ty.toIntern(),
32251 });32566 });
32252 const ptr_info = ptr_ptr_child_ty.ptrInfo(mod);32567 const ptr_info = ptr_ptr_child_ty.ptrInfo(mod);
32253 slice_ty = try mod.ptrType(.{32568 slice_ty = try pt.ptrType(.{
32254 .child = array_ty.toIntern(),32569 .child = array_ty.toIntern(),
32255 .flags = .{32570 .flags = .{
32256 .alignment = ptr_info.flags.alignment,32571 .alignment = ptr_info.flags.alignment,
...@@ -32286,7 +32601,7 @@ fn analyzeSlice(...@@ -32286,7 +32601,7 @@ fn analyzeSlice(
32286 elem_ty = ptr_ptr_child_ty.childType(mod);32601 elem_ty = ptr_ptr_child_ty.childType(mod);
32287 },32602 },
32288 },32603 },
32289 else => return sema.fail(block, src, "slice of non-array type '{}'", .{ptr_ptr_child_ty.fmt(mod)}),32604 else => return sema.fail(block, src, "slice of non-array type '{}'", .{ptr_ptr_child_ty.fmt(pt)}),
32290 }32605 }
3229132606
32292 const ptr = if (slice_ty.isSlice(mod))32607 const ptr = if (slice_ty.isSlice(mod))
...@@ -32297,7 +32612,7 @@ fn analyzeSlice(...@@ -32297,7 +32612,7 @@ fn analyzeSlice(
32297 assert(manyptr_ty_key.flags.size == .One);32612 assert(manyptr_ty_key.flags.size == .One);
32298 manyptr_ty_key.child = elem_ty.toIntern();32613 manyptr_ty_key.child = elem_ty.toIntern();
32299 manyptr_ty_key.flags.size = .Many;32614 manyptr_ty_key.flags.size = .Many;
32300 break :ptr try sema.coerceCompatiblePtrs(block, try mod.ptrTypeSema(manyptr_ty_key), ptr_or_slice, ptr_src);32615 break :ptr try sema.coerceCompatiblePtrs(block, try pt.ptrTypeSema(manyptr_ty_key), ptr_or_slice, ptr_src);
32301 } else ptr_or_slice;32616 } else ptr_or_slice;
3230232617
32303 const start = try sema.coerce(block, Type.usize, uncasted_start, start_src);32618 const start = try sema.coerce(block, Type.usize, uncasted_start, start_src);
...@@ -32311,7 +32626,7 @@ fn analyzeSlice(...@@ -32311,7 +32626,7 @@ fn analyzeSlice(
32311 var end_is_len = uncasted_end_opt == .none;32626 var end_is_len = uncasted_end_opt == .none;
32312 const end = e: {32627 const end = e: {
32313 if (array_ty.zigTypeTag(mod) == .Array) {32628 if (array_ty.zigTypeTag(mod) == .Array) {
32314 const len_val = try mod.intValue(Type.usize, array_ty.arrayLen(mod));32629 const len_val = try pt.intValue(Type.usize, array_ty.arrayLen(mod));
3231532630
32316 if (!end_is_len) {32631 if (!end_is_len) {
32317 const end = if (by_length) end: {32632 const end = if (by_length) end: {
...@@ -32320,7 +32635,7 @@ fn analyzeSlice(...@@ -32320,7 +32635,7 @@ fn analyzeSlice(
32320 break :end try sema.coerce(block, Type.usize, uncasted_end, end_src);32635 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);32636 } else try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
32322 if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| {32637 if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| {
32323 const len_s_val = try mod.intValue(32638 const len_s_val = try pt.intValue(
32324 Type.usize,32639 Type.usize,
32325 array_ty.arrayLenIncludingSentinel(mod),32640 array_ty.arrayLenIncludingSentinel(mod),
32326 );32641 );
...@@ -32335,8 +32650,8 @@ fn analyzeSlice(...@@ -32335,8 +32650,8 @@ fn analyzeSlice(
32335 end_src,32650 end_src,
32336 "end index {} out of bounds for array of length {}{s}",32651 "end index {} out of bounds for array of length {}{s}",
32337 .{32652 .{
32338 end_val.fmtValue(mod, sema),32653 end_val.fmtValue(pt, sema),
32339 len_val.fmtValue(mod, sema),32654 len_val.fmtValue(pt, sema),
32340 sentinel_label,32655 sentinel_label,
32341 },32656 },
32342 );32657 );
...@@ -32366,9 +32681,9 @@ fn analyzeSlice(...@@ -32366,9 +32681,9 @@ fn analyzeSlice(
32366 return sema.fail(block, src, "slice of undefined", .{});32681 return sema.fail(block, src, "slice of undefined", .{});
32367 }32682 }
32368 const has_sentinel = slice_ty.sentinel(mod) != null;32683 const has_sentinel = slice_ty.sentinel(mod) != null;
32369 const slice_len = try slice_val.sliceLen(mod);32684 const slice_len = try slice_val.sliceLen(pt);
32370 const len_plus_sent = slice_len + @intFromBool(has_sentinel);32685 const len_plus_sent = slice_len + @intFromBool(has_sentinel);
32371 const slice_len_val_with_sentinel = try mod.intValue(Type.usize, len_plus_sent);32686 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))) {32687 if (!(try sema.compareAll(end_val, .lte, slice_len_val_with_sentinel, Type.usize))) {
32373 const sentinel_label: []const u8 = if (has_sentinel)32688 const sentinel_label: []const u8 = if (has_sentinel)
32374 " +1 (sentinel)"32689 " +1 (sentinel)"
...@@ -32380,8 +32695,8 @@ fn analyzeSlice(...@@ -32380,8 +32695,8 @@ fn analyzeSlice(
32380 end_src,32695 end_src,
32381 "end index {} out of bounds for slice of length {d}{s}",32696 "end index {} out of bounds for slice of length {d}{s}",
32382 .{32697 .{
32383 end_val.fmtValue(mod, sema),32698 end_val.fmtValue(pt, sema),
32384 try slice_val.sliceLen(mod),32699 try slice_val.sliceLen(pt),
32385 sentinel_label,32700 sentinel_label,
32386 },32701 },
32387 );32702 );
...@@ -32390,7 +32705,7 @@ fn analyzeSlice(...@@ -32390,7 +32705,7 @@ fn analyzeSlice(
32390 // If the slice has a sentinel, we consider end_is_len32705 // If the slice has a sentinel, we consider end_is_len
32391 // is only true if it equals the length WITHOUT the32706 // is only true if it equals the length WITHOUT the
32392 // sentinel, so we don't add a sentinel type.32707 // sentinel, so we don't add a sentinel type.
32393 const slice_len_val = try mod.intValue(Type.usize, slice_len);32708 const slice_len_val = try pt.intValue(Type.usize, slice_len);
32394 if (end_val.eql(slice_len_val, Type.usize, mod)) {32709 if (end_val.eql(slice_len_val, Type.usize, mod)) {
32395 end_is_len = true;32710 end_is_len = true;
32396 }32711 }
...@@ -32440,21 +32755,21 @@ fn analyzeSlice(...@@ -32440,21 +32755,21 @@ fn analyzeSlice(
32440 start_src,32755 start_src,
32441 "start index {} is larger than end index {}",32756 "start index {} is larger than end index {}",
32442 .{32757 .{
32443 start_val.fmtValue(mod, sema),32758 start_val.fmtValue(pt, sema),
32444 end_val.fmtValue(mod, sema),32759 end_val.fmtValue(pt, sema),
32445 },32760 },
32446 );32761 );
32447 }32762 }
32448 checked_start_lte_end = true;32763 checked_start_lte_end = true;
32449 if (try sema.resolveValue(new_ptr)) |ptr_val| sentinel_check: {32764 if (try sema.resolveValue(new_ptr)) |ptr_val| sentinel_check: {
32450 const expected_sentinel = sentinel orelse break :sentinel_check;32765 const expected_sentinel = sentinel orelse break :sentinel_check;
32451 const start_int = start_val.getUnsignedInt(mod).?;32766 const start_int = start_val.getUnsignedInt(pt).?;
32452 const end_int = end_val.getUnsignedInt(mod).?;32767 const end_int = end_val.getUnsignedInt(pt).?;
32453 const sentinel_index = try sema.usizeCast(block, end_src, end_int - start_int);32768 const sentinel_index = try sema.usizeCast(block, end_src, end_int - start_int);
3245432769
32455 const many_ptr_ty = try mod.manyConstPtrType(elem_ty);32770 const many_ptr_ty = try pt.manyConstPtrType(elem_ty);
32456 const many_ptr_val = try mod.getCoerced(ptr_val, many_ptr_ty);32771 const many_ptr_val = try pt.getCoerced(ptr_val, many_ptr_ty);
32457 const elem_ptr = try many_ptr_val.ptrElem(sentinel_index, mod);32772 const elem_ptr = try many_ptr_val.ptrElem(sentinel_index, pt);
32458 const res = try sema.pointerDerefExtra(block, src, elem_ptr);32773 const res = try sema.pointerDerefExtra(block, src, elem_ptr);
32459 const actual_sentinel = switch (res) {32774 const actual_sentinel = switch (res) {
32460 .runtime_load => break :sentinel_check,32775 .runtime_load => break :sentinel_check,
...@@ -32463,13 +32778,13 @@ fn analyzeSlice(...@@ -32463,13 +32778,13 @@ fn analyzeSlice(
32463 block,32778 block,
32464 src,32779 src,
32465 "comptime dereference requires '{}' to have a well-defined layout",32780 "comptime dereference requires '{}' to have a well-defined layout",
32466 .{ty.fmt(mod)},32781 .{ty.fmt(pt)},
32467 ),32782 ),
32468 .out_of_bounds => |ty| return sema.fail(32783 .out_of_bounds => |ty| return sema.fail(
32469 block,32784 block,
32470 end_src,32785 end_src,
32471 "slice end index {d} exceeds bounds of containing decl of type '{}'",32786 "slice end index {d} exceeds bounds of containing decl of type '{}'",
32472 .{ end_int, ty.fmt(mod) },32787 .{ end_int, ty.fmt(pt) },
32473 ),32788 ),
32474 };32789 };
3247532790
...@@ -32478,8 +32793,8 @@ fn analyzeSlice(...@@ -32478,8 +32793,8 @@ fn analyzeSlice(
32478 const msg = try sema.errMsg(src, "value in memory does not match slice sentinel", .{});32793 const msg = try sema.errMsg(src, "value in memory does not match slice sentinel", .{});
32479 errdefer msg.destroy(sema.gpa);32794 errdefer msg.destroy(sema.gpa);
32480 try sema.errNote(src, msg, "expected '{}', found '{}'", .{32795 try sema.errNote(src, msg, "expected '{}', found '{}'", .{
32481 expected_sentinel.fmtValue(mod, sema),32796 expected_sentinel.fmtValue(pt, sema),
32482 actual_sentinel.fmtValue(mod, sema),32797 actual_sentinel.fmtValue(pt, sema),
32483 });32798 });
3248432799
32485 break :msg msg;32800 break :msg msg;
...@@ -32501,7 +32816,7 @@ fn analyzeSlice(...@@ -32501,7 +32816,7 @@ fn analyzeSlice(
32501 assert(!block.is_comptime);32816 assert(!block.is_comptime);
32502 try sema.requireRuntimeBlock(block, src, runtime_src.?);32817 try sema.requireRuntimeBlock(block, src, runtime_src.?);
32503 const ok = try block.addBinOp(.cmp_lte, start, end);32818 const ok = try block.addBinOp(.cmp_lte, start, end);
32504 if (!sema.mod.comp.formatted_panics) {32819 if (!pt.zcu.comp.formatted_panics) {
32505 try sema.addSafetyCheck(block, src, ok, .start_index_greater_than_end);32820 try sema.addSafetyCheck(block, src, ok, .start_index_greater_than_end);
32506 } else {32821 } else {
32507 try sema.safetyCheckFormatted(block, src, ok, "panicStartGreaterThanEnd", &.{ start, end });32822 try sema.safetyCheckFormatted(block, src, ok, "panicStartGreaterThanEnd", &.{ start, end });
...@@ -32517,10 +32832,10 @@ fn analyzeSlice(...@@ -32517,10 +32832,10 @@ fn analyzeSlice(
32517 const new_allowzero = new_ptr_ty_info.flags.is_allowzero and sema.typeOf(ptr).ptrSize(mod) != .C;32832 const new_allowzero = new_ptr_ty_info.flags.is_allowzero and sema.typeOf(ptr).ptrSize(mod) != .C;
3251832833
32519 if (opt_new_len_val) |new_len_val| {32834 if (opt_new_len_val) |new_len_val| {
32520 const new_len_int = try new_len_val.toUnsignedIntSema(mod);32835 const new_len_int = try new_len_val.toUnsignedIntSema(pt);
3252132836
32522 const return_ty = try mod.ptrTypeSema(.{32837 const return_ty = try pt.ptrTypeSema(.{
32523 .child = (try mod.arrayType(.{32838 .child = (try pt.arrayType(.{
32524 .len = new_len_int,32839 .len = new_len_int,
32525 .sentinel = if (sentinel) |s| s.toIntern() else .none,32840 .sentinel = if (sentinel) |s| s.toIntern() else .none,
32526 .child = elem_ty.toIntern(),32841 .child = elem_ty.toIntern(),
...@@ -32546,7 +32861,7 @@ fn analyzeSlice(...@@ -32546,7 +32861,7 @@ fn analyzeSlice(
3254632861
32547 bounds_check: {32862 bounds_check: {
32548 const actual_len = if (array_ty.zigTypeTag(mod) == .Array)32863 const actual_len = if (array_ty.zigTypeTag(mod) == .Array)
32549 try mod.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(mod))32864 try pt.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(mod))
32550 else if (slice_ty.isSlice(mod)) l: {32865 else if (slice_ty.isSlice(mod)) l: {
32551 const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);32866 const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);
32552 break :l if (slice_ty.sentinel(mod) == null)32867 break :l if (slice_ty.sentinel(mod) == null)
...@@ -32570,18 +32885,18 @@ fn analyzeSlice(...@@ -32570,18 +32885,18 @@ fn analyzeSlice(
32570 };32885 };
3257132886
32572 if (!new_ptr_val.isUndef(mod)) {32887 if (!new_ptr_val.isUndef(mod)) {
32573 return Air.internedToRef((try mod.getCoerced(new_ptr_val, return_ty)).toIntern());32888 return Air.internedToRef((try pt.getCoerced(new_ptr_val, return_ty)).toIntern());
32574 }32889 }
3257532890
32576 // Special case: @as([]i32, undefined)[x..x]32891 // Special case: @as([]i32, undefined)[x..x]
32577 if (new_len_int == 0) {32892 if (new_len_int == 0) {
32578 return mod.undefRef(return_ty);32893 return pt.undefRef(return_ty);
32579 }32894 }
3258032895
32581 return sema.fail(block, src, "non-zero length slice of undefined pointer", .{});32896 return sema.fail(block, src, "non-zero length slice of undefined pointer", .{});
32582 }32897 }
3258332898
32584 const return_ty = try mod.ptrTypeSema(.{32899 const return_ty = try pt.ptrTypeSema(.{
32585 .child = elem_ty.toIntern(),32900 .child = elem_ty.toIntern(),
32586 .sentinel = if (sentinel) |s| s.toIntern() else .none,32901 .sentinel = if (sentinel) |s| s.toIntern() else .none,
32587 .flags = .{32902 .flags = .{
...@@ -32604,12 +32919,12 @@ fn analyzeSlice(...@@ -32604,12 +32919,12 @@ fn analyzeSlice(
3260432919
32605 // requirement: end <= len32920 // requirement: end <= len
32606 const opt_len_inst = if (array_ty.zigTypeTag(mod) == .Array)32921 const opt_len_inst = if (array_ty.zigTypeTag(mod) == .Array)
32607 try mod.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(mod))32922 try pt.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(mod))
32608 else if (slice_ty.isSlice(mod)) blk: {32923 else if (slice_ty.isSlice(mod)) blk: {
32609 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {32924 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {
32610 // we don't need to add one for sentinels because the32925 // we don't need to add one for sentinels because the
32611 // underlying value data includes the sentinel32926 // underlying value data includes the sentinel
32612 break :blk try mod.intRef(Type.usize, try slice_val.sliceLen(mod));32927 break :blk try pt.intRef(Type.usize, try slice_val.sliceLen(pt));
32613 }32928 }
3261432929
32615 const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);32930 const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);
...@@ -32657,7 +32972,8 @@ fn cmpNumeric(...@@ -32657,7 +32972,8 @@ fn cmpNumeric(
32657 lhs_src: LazySrcLoc,32972 lhs_src: LazySrcLoc,
32658 rhs_src: LazySrcLoc,32973 rhs_src: LazySrcLoc,
32659) CompileError!Air.Inst.Ref {32974) CompileError!Air.Inst.Ref {
32660 const mod = sema.mod;32975 const pt = sema.pt;
32976 const mod = pt.zcu;
32661 const lhs_ty = sema.typeOf(uncasted_lhs);32977 const lhs_ty = sema.typeOf(uncasted_lhs);
32662 const rhs_ty = sema.typeOf(uncasted_rhs);32978 const rhs_ty = sema.typeOf(uncasted_rhs);
3266332979
...@@ -32696,12 +33012,12 @@ fn cmpNumeric(...@@ -32696,12 +33012,12 @@ fn cmpNumeric(
32696 }33012 }
3269733013
32698 if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) {33014 if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) {
32699 return mod.undefRef(Type.bool);33015 return pt.undefRef(Type.bool);
32700 }33016 }
32701 if (lhs_val.isNan(mod) or rhs_val.isNan(mod)) {33017 if (lhs_val.isNan(mod) or rhs_val.isNan(mod)) {
32702 return if (op == std.math.CompareOperator.neq) .bool_true else .bool_false;33018 return if (op == std.math.CompareOperator.neq) .bool_true else .bool_false;
32703 }33019 }
32704 return if (try Value.compareHeteroAdvanced(lhs_val, op, rhs_val, mod, .sema))33020 return if (try Value.compareHeteroAdvanced(lhs_val, op, rhs_val, pt, .sema))
32705 .bool_true33021 .bool_true
32706 else33022 else
32707 .bool_false;33023 .bool_false;
...@@ -32770,11 +33086,11 @@ fn cmpNumeric(...@@ -32770,11 +33086,11 @@ fn cmpNumeric(
32770 // a signed integer with mantissa bits + 1, and if there was any non-integral part of the float,33086 // a signed integer with mantissa bits + 1, and if there was any non-integral part of the float,
32771 // add/subtract 1.33087 // add/subtract 1.
32772 const lhs_is_signed = if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val|33088 const lhs_is_signed = if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val|
32773 !(try lhs_val.compareAllWithZeroSema(.gte, mod))33089 !(try lhs_val.compareAllWithZeroSema(.gte, pt))
32774 else33090 else
32775 (lhs_ty.isRuntimeFloat() or lhs_ty.isSignedInt(mod));33091 (lhs_ty.isRuntimeFloat() or lhs_ty.isSignedInt(mod));
32776 const rhs_is_signed = if (try sema.resolveDefinedValue(block, rhs_src, rhs)) |rhs_val|33092 const rhs_is_signed = if (try sema.resolveDefinedValue(block, rhs_src, rhs)) |rhs_val|
32777 !(try rhs_val.compareAllWithZeroSema(.gte, mod))33093 !(try rhs_val.compareAllWithZeroSema(.gte, pt))
32778 else33094 else
32779 (rhs_ty.isRuntimeFloat() or rhs_ty.isSignedInt(mod));33095 (rhs_ty.isRuntimeFloat() or rhs_ty.isSignedInt(mod));
32780 const dest_int_is_signed = lhs_is_signed or rhs_is_signed;33096 const dest_int_is_signed = lhs_is_signed or rhs_is_signed;
...@@ -32784,7 +33100,7 @@ fn cmpNumeric(...@@ -32784,7 +33100,7 @@ fn cmpNumeric(
32784 var lhs_bits: usize = undefined;33100 var lhs_bits: usize = undefined;
32785 if (try sema.resolveValueResolveLazy(lhs)) |lhs_val| {33101 if (try sema.resolveValueResolveLazy(lhs)) |lhs_val| {
32786 if (lhs_val.isUndef(mod))33102 if (lhs_val.isUndef(mod))
32787 return mod.undefRef(Type.bool);33103 return pt.undefRef(Type.bool);
32788 if (lhs_val.isNan(mod)) switch (op) {33104 if (lhs_val.isNan(mod)) switch (op) {
32789 .neq => return .bool_true,33105 .neq => return .bool_true,
32790 else => return .bool_false,33106 else => return .bool_false,
...@@ -32796,7 +33112,7 @@ fn cmpNumeric(...@@ -32796,7 +33112,7 @@ fn cmpNumeric(
32796 .lt, .lte => return if (lhs_val.isNegativeInf(mod)) .bool_true else .bool_false,33112 .lt, .lte => return if (lhs_val.isNegativeInf(mod)) .bool_true else .bool_false,
32797 };33113 };
32798 if (!rhs_is_signed) {33114 if (!rhs_is_signed) {
32799 switch (lhs_val.orderAgainstZero(mod)) {33115 switch (lhs_val.orderAgainstZero(pt)) {
32800 .gt => {},33116 .gt => {},
32801 .eq => switch (op) { // LHS = 0, RHS is unsigned33117 .eq => switch (op) { // LHS = 0, RHS is unsigned
32802 .lte => return .bool_true,33118 .lte => return .bool_true,
...@@ -32818,7 +33134,7 @@ fn cmpNumeric(...@@ -32818,7 +33134,7 @@ fn cmpNumeric(
32818 }33134 }
32819 }33135 }
3282033136
32821 var bigint = try float128IntPartToBigInt(sema.gpa, lhs_val.toFloat(f128, mod));33137 var bigint = try float128IntPartToBigInt(sema.gpa, lhs_val.toFloat(f128, pt));
32822 defer bigint.deinit();33138 defer bigint.deinit();
32823 if (lhs_val.floatHasFraction(mod)) {33139 if (lhs_val.floatHasFraction(mod)) {
32824 if (lhs_is_signed) {33140 if (lhs_is_signed) {
...@@ -32829,7 +33145,7 @@ fn cmpNumeric(...@@ -32829,7 +33145,7 @@ fn cmpNumeric(
32829 }33145 }
32830 lhs_bits = bigint.toConst().bitCountTwosComp();33146 lhs_bits = bigint.toConst().bitCountTwosComp();
32831 } else {33147 } else {
32832 lhs_bits = lhs_val.intBitCountTwosComp(mod);33148 lhs_bits = lhs_val.intBitCountTwosComp(pt);
32833 }33149 }
32834 lhs_bits += @intFromBool(!lhs_is_signed and dest_int_is_signed);33150 lhs_bits += @intFromBool(!lhs_is_signed and dest_int_is_signed);
32835 } else if (lhs_is_float) {33151 } else if (lhs_is_float) {
...@@ -32842,7 +33158,7 @@ fn cmpNumeric(...@@ -32842,7 +33158,7 @@ fn cmpNumeric(
32842 var rhs_bits: usize = undefined;33158 var rhs_bits: usize = undefined;
32843 if (try sema.resolveValueResolveLazy(rhs)) |rhs_val| {33159 if (try sema.resolveValueResolveLazy(rhs)) |rhs_val| {
32844 if (rhs_val.isUndef(mod))33160 if (rhs_val.isUndef(mod))
32845 return mod.undefRef(Type.bool);33161 return pt.undefRef(Type.bool);
32846 if (rhs_val.isNan(mod)) switch (op) {33162 if (rhs_val.isNan(mod)) switch (op) {
32847 .neq => return .bool_true,33163 .neq => return .bool_true,
32848 else => return .bool_false,33164 else => return .bool_false,
...@@ -32854,7 +33170,7 @@ fn cmpNumeric(...@@ -32854,7 +33170,7 @@ fn cmpNumeric(
32854 .lt, .lte => return if (rhs_val.isNegativeInf(mod)) .bool_false else .bool_true,33170 .lt, .lte => return if (rhs_val.isNegativeInf(mod)) .bool_false else .bool_true,
32855 };33171 };
32856 if (!lhs_is_signed) {33172 if (!lhs_is_signed) {
32857 switch (rhs_val.orderAgainstZero(mod)) {33173 switch (rhs_val.orderAgainstZero(pt)) {
32858 .gt => {},33174 .gt => {},
32859 .eq => switch (op) { // RHS = 0, LHS is unsigned33175 .eq => switch (op) { // RHS = 0, LHS is unsigned
32860 .gte => return .bool_true,33176 .gte => return .bool_true,
...@@ -32876,7 +33192,7 @@ fn cmpNumeric(...@@ -32876,7 +33192,7 @@ fn cmpNumeric(
32876 }33192 }
32877 }33193 }
3287833194
32879 var bigint = try float128IntPartToBigInt(sema.gpa, rhs_val.toFloat(f128, mod));33195 var bigint = try float128IntPartToBigInt(sema.gpa, rhs_val.toFloat(f128, pt));
32880 defer bigint.deinit();33196 defer bigint.deinit();
32881 if (rhs_val.floatHasFraction(mod)) {33197 if (rhs_val.floatHasFraction(mod)) {
32882 if (rhs_is_signed) {33198 if (rhs_is_signed) {
...@@ -32887,7 +33203,7 @@ fn cmpNumeric(...@@ -32887,7 +33203,7 @@ fn cmpNumeric(
32887 }33203 }
32888 rhs_bits = bigint.toConst().bitCountTwosComp();33204 rhs_bits = bigint.toConst().bitCountTwosComp();
32889 } else {33205 } else {
32890 rhs_bits = rhs_val.intBitCountTwosComp(mod);33206 rhs_bits = rhs_val.intBitCountTwosComp(pt);
32891 }33207 }
32892 rhs_bits += @intFromBool(!rhs_is_signed and dest_int_is_signed);33208 rhs_bits += @intFromBool(!rhs_is_signed and dest_int_is_signed);
32893 } else if (rhs_is_float) {33209 } else if (rhs_is_float) {
...@@ -32901,7 +33217,7 @@ fn cmpNumeric(...@@ -32901,7 +33217,7 @@ fn cmpNumeric(
32901 const max_bits = @max(lhs_bits, rhs_bits);33217 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});33218 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;33219 const signedness: std.builtin.Signedness = if (dest_int_is_signed) .signed else .unsigned;
32904 break :blk try mod.intType(signedness, casted_bits);33220 break :blk try pt.intType(signedness, casted_bits);
32905 };33221 };
32906 const casted_lhs = try sema.coerce(block, dest_ty, lhs, lhs_src);33222 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);33223 const casted_rhs = try sema.coerce(block, dest_ty, rhs, rhs_src);
...@@ -32920,9 +33236,10 @@ fn compareIntsOnlyPossibleResult(...@@ -32920,9 +33236,10 @@ fn compareIntsOnlyPossibleResult(
32920 op: std.math.CompareOperator,33236 op: std.math.CompareOperator,
32921 rhs_ty: Type,33237 rhs_ty: Type,
32922) Allocator.Error!?bool {33238) Allocator.Error!?bool {
32923 const mod = sema.mod;33239 const pt = sema.pt;
33240 const mod = pt.zcu;
32924 const rhs_info = rhs_ty.intInfo(mod);33241 const rhs_info = rhs_ty.intInfo(mod);
32925 const vs_zero = lhs_val.orderAgainstZeroAdvanced(mod, .sema) catch unreachable;33242 const vs_zero = lhs_val.orderAgainstZeroAdvanced(pt, .sema) catch unreachable;
32926 const is_zero = vs_zero == .eq;33243 const is_zero = vs_zero == .eq;
32927 const is_negative = vs_zero == .lt;33244 const is_negative = vs_zero == .lt;
32928 const is_positive = vs_zero == .gt;33245 const is_positive = vs_zero == .gt;
...@@ -32954,7 +33271,7 @@ fn compareIntsOnlyPossibleResult(...@@ -32954,7 +33271,7 @@ fn compareIntsOnlyPossibleResult(
32954 };33271 };
3295533272
32956 const sign_adj = @intFromBool(!is_negative and rhs_info.signedness == .signed);33273 const sign_adj = @intFromBool(!is_negative and rhs_info.signedness == .signed);
32957 const req_bits = lhs_val.intBitCountTwosComp(mod) + sign_adj;33274 const req_bits = lhs_val.intBitCountTwosComp(pt) + sign_adj;
3295833275
32959 // No sized type can have more than 65535 bits.33276 // No sized type can have more than 65535 bits.
32960 // The RHS type operand is either a runtime value or sized (but undefined) constant.33277 // The RHS type operand is either a runtime value or sized (but undefined) constant.
...@@ -32981,11 +33298,11 @@ fn compareIntsOnlyPossibleResult(...@@ -32981,11 +33298,11 @@ fn compareIntsOnlyPossibleResult(
3298133298
32982 if (req_bits != rhs_info.bits) break :edge .{ false, false };33299 if (req_bits != rhs_info.bits) break :edge .{ false, false };
3298333300
32984 const ty = try mod.intType(33301 const ty = try pt.intType(
32985 if (is_negative) .signed else .unsigned,33302 if (is_negative) .signed else .unsigned,
32986 @intCast(req_bits),33303 @intCast(req_bits),
32987 );33304 );
32988 const pop_count = lhs_val.popCount(ty, mod);33305 const pop_count = lhs_val.popCount(ty, pt);
3298933306
32990 if (is_negative) {33307 if (is_negative) {
32991 break :edge .{ pop_count == 1, false };33308 break :edge .{ pop_count == 1, false };
...@@ -33015,7 +33332,8 @@ fn cmpVector(...@@ -33015,7 +33332,8 @@ fn cmpVector(
33015 lhs_src: LazySrcLoc,33332 lhs_src: LazySrcLoc,
33016 rhs_src: LazySrcLoc,33333 rhs_src: LazySrcLoc,
33017) CompileError!Air.Inst.Ref {33334) CompileError!Air.Inst.Ref {
33018 const mod = sema.mod;33335 const pt = sema.pt;
33336 const mod = pt.zcu;
33019 const lhs_ty = sema.typeOf(lhs);33337 const lhs_ty = sema.typeOf(lhs);
33020 const rhs_ty = sema.typeOf(rhs);33338 const rhs_ty = sema.typeOf(rhs);
33021 assert(lhs_ty.zigTypeTag(mod) == .Vector);33339 assert(lhs_ty.zigTypeTag(mod) == .Vector);
...@@ -33026,7 +33344,7 @@ fn cmpVector(...@@ -33026,7 +33344,7 @@ fn cmpVector(
33026 const casted_lhs = try sema.coerce(block, resolved_ty, lhs, lhs_src);33344 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);33345 const casted_rhs = try sema.coerce(block, resolved_ty, rhs, rhs_src);
3302833346
33029 const result_ty = try mod.vectorType(.{33347 const result_ty = try pt.vectorType(.{
33030 .len = lhs_ty.vectorLen(mod),33348 .len = lhs_ty.vectorLen(mod),
33031 .child = .bool_type,33349 .child = .bool_type,
33032 });33350 });
...@@ -33035,7 +33353,7 @@ fn cmpVector(...@@ -33035,7 +33353,7 @@ fn cmpVector(
33035 if (try sema.resolveValue(casted_lhs)) |lhs_val| {33353 if (try sema.resolveValue(casted_lhs)) |lhs_val| {
33036 if (try sema.resolveValue(casted_rhs)) |rhs_val| {33354 if (try sema.resolveValue(casted_rhs)) |rhs_val| {
33037 if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) {33355 if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) {
33038 return mod.undefRef(result_ty);33356 return pt.undefRef(result_ty);
33039 }33357 }
33040 const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_ty);33358 const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_ty);
33041 return Air.internedToRef(cmp_val.toIntern());33359 return Air.internedToRef(cmp_val.toIntern());
...@@ -33059,7 +33377,7 @@ fn wrapOptional(...@@ -33059,7 +33377,7 @@ fn wrapOptional(
33059 inst_src: LazySrcLoc,33377 inst_src: LazySrcLoc,
33060) !Air.Inst.Ref {33378) !Air.Inst.Ref {
33061 if (try sema.resolveValue(inst)) |val| {33379 if (try sema.resolveValue(inst)) |val| {
33062 return Air.internedToRef((try sema.mod.intern(.{ .opt = .{33380 return Air.internedToRef((try sema.pt.intern(.{ .opt = .{
33063 .ty = dest_ty.toIntern(),33381 .ty = dest_ty.toIntern(),
33064 .val = val.toIntern(),33382 .val = val.toIntern(),
33065 } })));33383 } })));
...@@ -33076,11 +33394,12 @@ fn wrapErrorUnionPayload(...@@ -33076,11 +33394,12 @@ fn wrapErrorUnionPayload(
33076 inst: Air.Inst.Ref,33394 inst: Air.Inst.Ref,
33077 inst_src: LazySrcLoc,33395 inst_src: LazySrcLoc,
33078) !Air.Inst.Ref {33396) !Air.Inst.Ref {
33079 const mod = sema.mod;33397 const pt = sema.pt;
33398 const mod = pt.zcu;
33080 const dest_payload_ty = dest_ty.errorUnionPayload(mod);33399 const dest_payload_ty = dest_ty.errorUnionPayload(mod);
33081 const coerced = try sema.coerceExtra(block, dest_payload_ty, inst, inst_src, .{ .report_err = false });33400 const coerced = try sema.coerceExtra(block, dest_payload_ty, inst, inst_src, .{ .report_err = false });
33082 if (try sema.resolveValue(coerced)) |val| {33401 if (try sema.resolveValue(coerced)) |val| {
33083 return Air.internedToRef((try mod.intern(.{ .error_union = .{33402 return Air.internedToRef((try pt.intern(.{ .error_union = .{
33084 .ty = dest_ty.toIntern(),33403 .ty = dest_ty.toIntern(),
33085 .val = .{ .payload = val.toIntern() },33404 .val = .{ .payload = val.toIntern() },
33086 } })));33405 } })));
...@@ -33096,7 +33415,8 @@ fn wrapErrorUnionSet(...@@ -33096,7 +33415,8 @@ fn wrapErrorUnionSet(
33096 inst: Air.Inst.Ref,33415 inst: Air.Inst.Ref,
33097 inst_src: LazySrcLoc,33416 inst_src: LazySrcLoc,
33098) !Air.Inst.Ref {33417) !Air.Inst.Ref {
33099 const mod = sema.mod;33418 const pt = sema.pt;
33419 const mod = pt.zcu;
33100 const ip = &mod.intern_pool;33420 const ip = &mod.intern_pool;
33101 const inst_ty = sema.typeOf(inst);33421 const inst_ty = sema.typeOf(inst);
33102 const dest_err_set_ty = dest_ty.errorUnionSet(mod);33422 const dest_err_set_ty = dest_ty.errorUnionSet(mod);
...@@ -33140,7 +33460,7 @@ fn wrapErrorUnionSet(...@@ -33140,7 +33460,7 @@ fn wrapErrorUnionSet(
33140 else => unreachable,33460 else => unreachable,
33141 },33461 },
33142 }33462 }
33143 return Air.internedToRef((try mod.intern(.{ .error_union = .{33463 return Air.internedToRef((try pt.intern(.{ .error_union = .{
33144 .ty = dest_ty.toIntern(),33464 .ty = dest_ty.toIntern(),
33145 .val = .{ .err_name = expected_name },33465 .val = .{ .err_name = expected_name },
33146 } })));33466 } })));
...@@ -33158,14 +33478,15 @@ fn unionToTag(...@@ -33158,14 +33478,15 @@ fn unionToTag(
33158 un: Air.Inst.Ref,33478 un: Air.Inst.Ref,
33159 un_src: LazySrcLoc,33479 un_src: LazySrcLoc,
33160) !Air.Inst.Ref {33480) !Air.Inst.Ref {
33161 const mod = sema.mod;33481 const pt = sema.pt;
33482 const mod = pt.zcu;
33162 if ((try sema.typeHasOnePossibleValue(enum_ty))) |opv| {33483 if ((try sema.typeHasOnePossibleValue(enum_ty))) |opv| {
33163 return Air.internedToRef(opv.toIntern());33484 return Air.internedToRef(opv.toIntern());
33164 }33485 }
33165 if (try sema.resolveValue(un)) |un_val| {33486 if (try sema.resolveValue(un)) |un_val| {
33166 const tag_val = un_val.unionTag(mod).?;33487 const tag_val = un_val.unionTag(mod).?;
33167 if (tag_val.isUndef(mod))33488 if (tag_val.isUndef(mod))
33168 return try mod.undefRef(enum_ty);33489 return try pt.undefRef(enum_ty);
33169 return Air.internedToRef(tag_val.toIntern());33490 return Air.internedToRef(tag_val.toIntern());
33170 }33491 }
33171 try sema.requireRuntimeBlock(block, un_src, null);33492 try sema.requireRuntimeBlock(block, un_src, null);
...@@ -33399,7 +33720,7 @@ const PeerResolveResult = union(enum) {...@@ -33399,7 +33720,7 @@ const PeerResolveResult = union(enum) {
33399 instructions: []const Air.Inst.Ref,33720 instructions: []const Air.Inst.Ref,
33400 candidate_srcs: PeerTypeCandidateSrc,33721 candidate_srcs: PeerTypeCandidateSrc,
33401 ) !*Module.ErrorMsg {33722 ) !*Module.ErrorMsg {
33402 const mod = sema.mod;33723 const pt = sema.pt;
3340333724
33404 var opt_msg: ?*Module.ErrorMsg = null;33725 var opt_msg: ?*Module.ErrorMsg = null;
33405 errdefer if (opt_msg) |msg| msg.destroy(sema.gpa);33726 errdefer if (opt_msg) |msg| msg.destroy(sema.gpa);
...@@ -33425,7 +33746,7 @@ const PeerResolveResult = union(enum) {...@@ -33425,7 +33746,7 @@ const PeerResolveResult = union(enum) {
33425 },33746 },
33426 .field_error => |field_error| {33747 .field_error => |field_error| {
33427 const fmt = "struct field '{}' has conflicting types";33748 const fmt = "struct field '{}' has conflicting types";
33428 const args = .{field_error.field_name.fmt(&mod.intern_pool)};33749 const args = .{field_error.field_name.fmt(&pt.zcu.intern_pool)};
33429 if (opt_msg) |msg| {33750 if (opt_msg) |msg| {
33430 try sema.errNote(src, msg, fmt, args);33751 try sema.errNote(src, msg, fmt, args);
33431 } else {33752 } else {
...@@ -33457,8 +33778,8 @@ const PeerResolveResult = union(enum) {...@@ -33457,8 +33778,8 @@ const PeerResolveResult = union(enum) {
3345733778
33458 const fmt = "incompatible types: '{}' and '{}'";33779 const fmt = "incompatible types: '{}' and '{}'";
33459 const args = .{33780 const args = .{
33460 conflict_tys[0].fmt(mod),33781 conflict_tys[0].fmt(pt),
33461 conflict_tys[1].fmt(mod),33782 conflict_tys[1].fmt(pt),
33462 };33783 };
33463 const msg = if (opt_msg) |msg| msg: {33784 const msg = if (opt_msg) |msg| msg: {
33464 try sema.errNote(src, msg, fmt, args);33785 try sema.errNote(src, msg, fmt, args);
...@@ -33469,8 +33790,8 @@ const PeerResolveResult = union(enum) {...@@ -33469,8 +33790,8 @@ const PeerResolveResult = union(enum) {
33469 break :msg msg;33790 break :msg msg;
33470 };33791 };
3347133792
33472 if (conflict_srcs[0]) |src_loc| try sema.errNote(src_loc, msg, "type '{}' here", .{conflict_tys[0].fmt(mod)});33793 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)});33794 if (conflict_srcs[1]) |src_loc| try sema.errNote(src_loc, msg, "type '{}' here", .{conflict_tys[1].fmt(pt)});
3347433795
33475 // No child error33796 // No child error
33476 break;33797 break;
...@@ -33517,7 +33838,8 @@ fn resolvePeerTypesInner(...@@ -33517,7 +33838,8 @@ fn resolvePeerTypesInner(
33517 peer_tys: []?Type,33838 peer_tys: []?Type,
33518 peer_vals: []?Value,33839 peer_vals: []?Value,
33519) !PeerResolveResult {33840) !PeerResolveResult {
33520 const mod = sema.mod;33841 const pt = sema.pt;
33842 const mod = pt.zcu;
33521 const ip = &mod.intern_pool;33843 const ip = &mod.intern_pool;
3352233844
33523 var strat_reason: usize = 0;33845 var strat_reason: usize = 0;
...@@ -33581,7 +33903,7 @@ fn resolvePeerTypesInner(...@@ -33581,7 +33903,7 @@ fn resolvePeerTypesInner(
33581 .payload => |payload_ip| val_ptr.* = Value.fromInterned(payload_ip),33903 .payload => |payload_ip| val_ptr.* = Value.fromInterned(payload_ip),
33582 .err_name => val_ptr.* = null,33904 .err_name => val_ptr.* = null,
33583 },33905 },
33584 .undef => val_ptr.* = Value.fromInterned((try sema.mod.intern(.{ .undef = ty_ptr.*.?.toIntern() }))),33906 .undef => val_ptr.* = Value.fromInterned(try pt.intern(.{ .undef = ty_ptr.*.?.toIntern() })),
33585 else => unreachable,33907 else => unreachable,
33586 };33908 };
33587 break :blk set_ty;33909 break :blk set_ty;
...@@ -33604,7 +33926,7 @@ fn resolvePeerTypesInner(...@@ -33604,7 +33926,7 @@ fn resolvePeerTypesInner(
33604 .success => |ty| ty,33926 .success => |ty| ty,
33605 else => |result| return result,33927 else => |result| return result,
33606 };33928 };
33607 return .{ .success = try mod.errorUnionType(final_set.?, final_payload) };33929 return .{ .success = try pt.errorUnionType(final_set.?, final_payload) };
33608 },33930 },
3360933931
33610 .nullable => {33932 .nullable => {
...@@ -33642,7 +33964,7 @@ fn resolvePeerTypesInner(...@@ -33642,7 +33964,7 @@ fn resolvePeerTypesInner(
33642 .success => |ty| ty,33964 .success => |ty| ty,
33643 else => |result| return result,33965 else => |result| return result,
33644 };33966 };
33645 return .{ .success = try mod.optionalType(child_ty.toIntern()) };33967 return .{ .success = try pt.optionalType(child_ty.toIntern()) };
33646 },33968 },
3364733969
33648 .array => {33970 .array => {
...@@ -33730,7 +34052,7 @@ fn resolvePeerTypesInner(...@@ -33730,7 +34052,7 @@ fn resolvePeerTypesInner(
33730 // There should always be at least one array or vector peer34052 // There should always be at least one array or vector peer
33731 assert(opt_first_arr_idx != null);34053 assert(opt_first_arr_idx != null);
3373234054
33733 return .{ .success = try mod.arrayType(.{34055 return .{ .success = try pt.arrayType(.{
33734 .len = len,34056 .len = len,
33735 .child = elem_ty.toIntern(),34057 .child = elem_ty.toIntern(),
33736 .sentinel = if (sentinel) |sent_val| sent_val.toIntern() else .none,34058 .sentinel = if (sentinel) |sent_val| sent_val.toIntern() else .none,
...@@ -33792,7 +34114,7 @@ fn resolvePeerTypesInner(...@@ -33792,7 +34114,7 @@ fn resolvePeerTypesInner(
33792 else => |result| return result,34114 else => |result| return result,
33793 };34115 };
3379434116
33795 return .{ .success = try mod.vectorType(.{34117 return .{ .success = try pt.vectorType(.{
33796 .len = @intCast(len.?),34118 .len = @intCast(len.?),
33797 .child = child_ty.toIntern(),34119 .child = child_ty.toIntern(),
33798 }) };34120 }) };
...@@ -33844,8 +34166,8 @@ fn resolvePeerTypesInner(...@@ -33844,8 +34166,8 @@ fn resolvePeerTypesInner(
33844 }).toIntern();34166 }).toIntern();
3384534167
33846 if (ptr_info.sentinel != .none and peer_info.sentinel != .none) {34168 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);34169 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);34170 const ptr_sent = try ip.getCoerced(sema.gpa, pt.tid, peer_info.sentinel, ptr_info.child);
33849 if (ptr_sent == peer_sent) {34171 if (ptr_sent == peer_sent) {
33850 ptr_info.sentinel = ptr_sent;34172 ptr_info.sentinel = ptr_sent;
33851 } else {34173 } else {
...@@ -33860,12 +34182,12 @@ fn resolvePeerTypesInner(...@@ -33860,12 +34182,12 @@ fn resolvePeerTypesInner(
33860 if (ptr_info.flags.alignment != .none)34182 if (ptr_info.flags.alignment != .none)
33861 ptr_info.flags.alignment34183 ptr_info.flags.alignment
33862 else34184 else
33863 Type.fromInterned(ptr_info.child).abiAlignment(mod),34185 Type.fromInterned(ptr_info.child).abiAlignment(pt),
3386434186
33865 if (peer_info.flags.alignment != .none)34187 if (peer_info.flags.alignment != .none)
33866 peer_info.flags.alignment34188 peer_info.flags.alignment
33867 else34189 else
33868 Type.fromInterned(peer_info.child).abiAlignment(mod),34190 Type.fromInterned(peer_info.child).abiAlignment(pt),
33869 );34191 );
33870 if (ptr_info.flags.address_space != peer_info.flags.address_space) {34192 if (ptr_info.flags.address_space != peer_info.flags.address_space) {
33871 return .{ .conflict = .{34193 return .{ .conflict = .{
...@@ -33888,7 +34210,7 @@ fn resolvePeerTypesInner(...@@ -33888,7 +34210,7 @@ fn resolvePeerTypesInner(
3388834210
33889 opt_ptr_info = ptr_info;34211 opt_ptr_info = ptr_info;
33890 }34212 }
33891 return .{ .success = try mod.ptrTypeSema(opt_ptr_info.?) };34213 return .{ .success = try pt.ptrTypeSema(opt_ptr_info.?) };
33892 },34214 },
3389334215
33894 .ptr => {34216 .ptr => {
...@@ -34004,7 +34326,7 @@ fn resolvePeerTypesInner(...@@ -34004,7 +34326,7 @@ fn resolvePeerTypesInner(
34004 if (try sema.resolvePairInMemoryCoercible(block, src, cur_arr.elem_ty, peer_arr.elem_ty)) |elem_ty| {34326 if (try sema.resolvePairInMemoryCoercible(block, src, cur_arr.elem_ty, peer_arr.elem_ty)) |elem_ty| {
34005 // *[n:x]T + *[n:y]T = *[n]T34327 // *[n:x]T + *[n:y]T = *[n]T
34006 if (cur_arr.len == peer_arr.len) {34328 if (cur_arr.len == peer_arr.len) {
34007 ptr_info.child = (try mod.arrayType(.{34329 ptr_info.child = (try pt.arrayType(.{
34008 .len = cur_arr.len,34330 .len = cur_arr.len,
34009 .child = elem_ty.toIntern(),34331 .child = elem_ty.toIntern(),
34010 })).toIntern();34332 })).toIntern();
...@@ -34148,12 +34470,12 @@ fn resolvePeerTypesInner(...@@ -34148,12 +34470,12 @@ fn resolvePeerTypesInner(
34148 no_sentinel: {34470 no_sentinel: {
34149 if (peer_sentinel == .none) break :no_sentinel;34471 if (peer_sentinel == .none) break :no_sentinel;
34150 if (cur_sentinel == .none) break :no_sentinel;34472 if (cur_sentinel == .none) break :no_sentinel;
34151 const peer_sent_coerced = try ip.getCoerced(sema.gpa, peer_sentinel, sentinel_ty);34473 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);34474 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;34475 if (peer_sent_coerced != cur_sent_coerced) break :no_sentinel;
34154 // Sentinels match34476 // Sentinels match
34155 if (ptr_info.flags.size == .One) switch (ip.indexToKey(ptr_info.child)) {34477 if (ptr_info.flags.size == .One) switch (ip.indexToKey(ptr_info.child)) {
34156 .array_type => |array_type| ptr_info.child = (try mod.arrayType(.{34478 .array_type => |array_type| ptr_info.child = (try pt.arrayType(.{
34157 .len = array_type.len,34479 .len = array_type.len,
34158 .child = array_type.child,34480 .child = array_type.child,
34159 .sentinel = cur_sent_coerced,34481 .sentinel = cur_sent_coerced,
...@@ -34167,7 +34489,7 @@ fn resolvePeerTypesInner(...@@ -34167,7 +34489,7 @@ fn resolvePeerTypesInner(
34167 // Clear existing sentinel34489 // Clear existing sentinel
34168 ptr_info.sentinel = .none;34490 ptr_info.sentinel = .none;
34169 switch (ip.indexToKey(ptr_info.child)) {34491 switch (ip.indexToKey(ptr_info.child)) {
34170 .array_type => |array_type| ptr_info.child = (try mod.arrayType(.{34492 .array_type => |array_type| ptr_info.child = (try pt.arrayType(.{
34171 .len = array_type.len,34493 .len = array_type.len,
34172 .child = array_type.child,34494 .child = array_type.child,
34173 .sentinel = .none,34495 .sentinel = .none,
...@@ -34198,7 +34520,7 @@ fn resolvePeerTypesInner(...@@ -34198,7 +34520,7 @@ fn resolvePeerTypesInner(
34198 },34520 },
34199 }34521 }
3420034522
34201 return .{ .success = try mod.ptrTypeSema(opt_ptr_info.?) };34523 return .{ .success = try pt.ptrTypeSema(opt_ptr_info.?) };
34202 },34524 },
3420334525
34204 .func => {34526 .func => {
...@@ -34517,7 +34839,7 @@ fn resolvePeerTypesInner(...@@ -34517,7 +34839,7 @@ fn resolvePeerTypesInner(
34517 continue;34839 continue;
34518 };34840 };
34519 peer_field_ty.* = ty.structFieldType(field_index, mod);34841 peer_field_ty.* = ty.structFieldType(field_index, mod);
34520 peer_field_val.* = if (opt_val) |val| try val.fieldValue(mod, field_index) else null;34842 peer_field_val.* = if (opt_val) |val| try val.fieldValue(pt, field_index) else null;
34521 }34843 }
3452234844
34523 // Resolve field type recursively34845 // Resolve field type recursively
...@@ -34555,9 +34877,9 @@ fn resolvePeerTypesInner(...@@ -34555,9 +34877,9 @@ fn resolvePeerTypesInner(
34555 var comptime_val: ?Value = null;34877 var comptime_val: ?Value = null;
34556 for (peer_tys) |opt_ty| {34878 for (peer_tys) |opt_ty| {
34557 const struct_ty = opt_ty orelse continue;34879 const struct_ty = opt_ty orelse continue;
34558 try struct_ty.resolveStructFieldInits(mod);34880 try struct_ty.resolveStructFieldInits(pt);
3455934881
34560 const uncoerced_field_val = try struct_ty.structFieldValueComptime(mod, field_index) orelse {34882 const uncoerced_field_val = try struct_ty.structFieldValueComptime(pt, field_index) orelse {
34561 comptime_val = null;34883 comptime_val = null;
34562 break;34884 break;
34563 };34885 };
...@@ -34584,7 +34906,7 @@ fn resolvePeerTypesInner(...@@ -34584,7 +34906,7 @@ fn resolvePeerTypesInner(
34584 field_val.* = if (comptime_val) |v| v.toIntern() else .none;34906 field_val.* = if (comptime_val) |v| v.toIntern() else .none;
34585 }34907 }
3458634908
34587 const final_ty = try ip.getAnonStructType(mod.gpa, .{34909 const final_ty = try ip.getAnonStructType(mod.gpa, pt.tid, .{
34588 .types = field_types,34910 .types = field_types,
34589 .names = if (is_tuple) &.{} else field_names,34911 .names = if (is_tuple) &.{} else field_names,
34590 .values = field_vals,34912 .values = field_vals,
...@@ -34628,13 +34950,15 @@ fn maybeMergeErrorSets(sema: *Sema, block: *Block, src: LazySrcLoc, e0: Type, e1...@@ -34628,13 +34950,15 @@ fn maybeMergeErrorSets(sema: *Sema, block: *Block, src: LazySrcLoc, e0: Type, e1
34628}34950}
3462934951
34630fn resolvePairInMemoryCoercible(sema: *Sema, block: *Block, src: LazySrcLoc, ty_a: Type, ty_b: Type) !?Type {34952fn resolvePairInMemoryCoercible(sema: *Sema, block: *Block, src: LazySrcLoc, ty_a: Type, ty_b: Type) !?Type {
34953 const target = sema.pt.zcu.getTarget();
34954
34631 // ty_b -> ty_a34955 // ty_b -> ty_a
34632 if (.ok == try sema.coerceInMemoryAllowed(block, ty_a, ty_b, true, sema.mod.getTarget(), src, src)) {34956 if (.ok == try sema.coerceInMemoryAllowed(block, ty_a, ty_b, true, target, src, src)) {
34633 return ty_a;34957 return ty_a;
34634 }34958 }
3463534959
34636 // ty_a -> ty_b34960 // ty_a -> ty_b
34637 if (.ok == try sema.coerceInMemoryAllowed(block, ty_b, ty_a, true, sema.mod.getTarget(), src, src)) {34961 if (.ok == try sema.coerceInMemoryAllowed(block, ty_b, ty_a, true, target, src, src)) {
34638 return ty_b;34962 return ty_b;
34639 }34963 }
3464034964
...@@ -34647,7 +34971,8 @@ const ArrayLike = struct {...@@ -34647,7 +34971,8 @@ const ArrayLike = struct {
34647 elem_ty: Type,34971 elem_ty: Type,
34648};34972};
34649fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike {34973fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike {
34650 const mod = sema.mod;34974 const pt = sema.pt;
34975 const mod = pt.zcu;
34651 return switch (ty.zigTypeTag(mod)) {34976 return switch (ty.zigTypeTag(mod)) {
34652 .Array => .{34977 .Array => .{
34653 .len = ty.arrayLen(mod),34978 .len = ty.arrayLen(mod),
...@@ -34676,7 +35001,8 @@ fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike {...@@ -34676,7 +35001,8 @@ fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike {
34676}35001}
3467735002
34678pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void {35003pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void {
34679 const mod = sema.mod;35004 const pt = sema.pt;
35005 const mod = pt.zcu;
34680 const ip = &mod.intern_pool;35006 const ip = &mod.intern_pool;
3468135007
34682 if (sema.fn_ret_ty_ies) |ies| {35008 if (sema.fn_ret_ty_ies) |ies| {
...@@ -34687,26 +35013,27 @@ pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void...@@ -34687,26 +35013,27 @@ pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void
34687}35013}
3468835014
34689pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {35015pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {
34690 const mod = sema.mod;35016 const pt = sema.pt;
35017 const mod = pt.zcu;
34691 const ip = &mod.intern_pool;35018 const ip = &mod.intern_pool;
34692 const fn_ty_info = mod.typeToFunc(fn_ty).?;35019 const fn_ty_info = mod.typeToFunc(fn_ty).?;
3469335020
34694 try Type.fromInterned(fn_ty_info.return_type).resolveFully(mod);35021 try Type.fromInterned(fn_ty_info.return_type).resolveFully(pt);
3469535022
34696 if (mod.comp.config.any_error_tracing and35023 if (mod.comp.config.any_error_tracing and
34697 Type.fromInterned(fn_ty_info.return_type).isError(mod))35024 Type.fromInterned(fn_ty_info.return_type).isError(mod))
34698 {35025 {
34699 // Ensure the type exists so that backends can assume that.35026 // Ensure the type exists so that backends can assume that.
34700 _ = try mod.getBuiltinType("StackTrace");35027 _ = try pt.getBuiltinType("StackTrace");
34701 }35028 }
3470235029
34703 for (0..fn_ty_info.param_types.len) |i| {35030 for (0..fn_ty_info.param_types.len) |i| {
34704 try Type.fromInterned(fn_ty_info.param_types.get(ip)[i]).resolveFully(mod);35031 try Type.fromInterned(fn_ty_info.param_types.get(ip)[i]).resolveFully(pt);
34705 }35032 }
34706}35033}
3470735034
34708fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {35035fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {
34709 return val.resolveLazy(sema.arena, sema.mod);35036 return val.resolveLazy(sema.arena, sema.pt);
34710}35037}
3471135038
34712/// Resolve a struct's alignment only without triggering resolution of its layout.35039/// Resolve a struct's alignment only without triggering resolution of its layout.
...@@ -34716,7 +35043,8 @@ pub fn resolveStructAlignment(...@@ -34716,7 +35043,8 @@ pub fn resolveStructAlignment(
34716 ty: InternPool.Index,35043 ty: InternPool.Index,
34717 struct_type: InternPool.LoadedStructType,35044 struct_type: InternPool.LoadedStructType,
34718) SemaError!void {35045) SemaError!void {
34719 const mod = sema.mod;35046 const pt = sema.pt;
35047 const mod = pt.zcu;
34720 const ip = &mod.intern_pool;35048 const ip = &mod.intern_pool;
34721 const target = mod.getTarget();35049 const target = mod.getTarget();
3472235050
...@@ -34754,7 +35082,7 @@ pub fn resolveStructAlignment(...@@ -34754,7 +35082,7 @@ pub fn resolveStructAlignment(
34754 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);35082 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))35083 if (struct_type.fieldIsComptime(ip, i) or try sema.typeRequiresComptime(field_ty))
34756 continue;35084 continue;
34757 const field_align = try mod.structFieldAlignmentAdvanced(35085 const field_align = try pt.structFieldAlignmentAdvanced(
34758 struct_type.fieldAlign(ip, i),35086 struct_type.fieldAlign(ip, i),
34759 field_ty,35087 field_ty,
34760 struct_type.layout,35088 struct_type.layout,
...@@ -34767,7 +35095,8 @@ pub fn resolveStructAlignment(...@@ -34767,7 +35095,8 @@ pub fn resolveStructAlignment(
34767}35095}
3476835096
34769pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {35097pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
34770 const zcu = sema.mod;35098 const pt = sema.pt;
35099 const zcu = pt.zcu;
34771 const ip = &zcu.intern_pool;35100 const ip = &zcu.intern_pool;
34772 const struct_type = zcu.typeToStruct(ty) orelse return;35101 const struct_type = zcu.typeToStruct(ty) orelse return;
3477335102
...@@ -34776,10 +35105,10 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -34776,10 +35105,10 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
34776 if (struct_type.haveLayout(ip))35105 if (struct_type.haveLayout(ip))
34777 return;35106 return;
3477835107
34779 try ty.resolveFields(zcu);35108 try ty.resolveFields(pt);
3478035109
34781 if (struct_type.layout == .@"packed") {35110 if (struct_type.layout == .@"packed") {
34782 semaBackingIntType(zcu, struct_type) catch |err| switch (err) {35111 semaBackingIntType(pt, struct_type) catch |err| switch (err) {
34783 error.OutOfMemory, error.AnalysisFail => |e| return e,35112 error.OutOfMemory, error.AnalysisFail => |e| return e,
34784 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,35113 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
34785 };35114 };
...@@ -34790,7 +35119,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -34790,7 +35119,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
34790 const msg = try sema.errMsg(35119 const msg = try sema.errMsg(
34791 ty.srcLoc(zcu),35120 ty.srcLoc(zcu),
34792 "struct '{}' depends on itself",35121 "struct '{}' depends on itself",
34793 .{ty.fmt(zcu)},35122 .{ty.fmt(pt)},
34794 );35123 );
34795 return sema.failWithOwnedErrorMsg(null, msg);35124 return sema.failWithOwnedErrorMsg(null, msg);
34796 }35125 }
...@@ -34818,7 +35147,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -34818,7 +35147,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
34818 },35147 },
34819 else => return err,35148 else => return err,
34820 };35149 };
34821 field_align.* = try zcu.structFieldAlignmentAdvanced(35150 field_align.* = try pt.structFieldAlignmentAdvanced(
34822 struct_type.fieldAlign(ip, i),35151 struct_type.fieldAlign(ip, i),
34823 field_ty,35152 field_ty,
34824 struct_type.layout,35153 struct_type.layout,
...@@ -34911,7 +35240,8 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -34911,7 +35240,8 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
34911 _ = try sema.typeRequiresComptime(ty);35240 _ = try sema.typeRequiresComptime(ty);
34912}35241}
3491335242
34914fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) CompileError!void {35243fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructType) CompileError!void {
35244 const zcu = pt.zcu;
34915 const gpa = zcu.gpa;35245 const gpa = zcu.gpa;
34916 const ip = &zcu.intern_pool;35246 const ip = &zcu.intern_pool;
3491735247
...@@ -34927,7 +35257,7 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi...@@ -34927,7 +35257,7 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi
34927 defer comptime_err_ret_trace.deinit();35257 defer comptime_err_ret_trace.deinit();
3492835258
34929 var sema: Sema = .{35259 var sema: Sema = .{
34930 .mod = zcu,35260 .pt = pt,
34931 .gpa = gpa,35261 .gpa = gpa,
34932 .arena = analysis_arena.allocator(),35262 .arena = analysis_arena.allocator(),
34933 .code = zir,35263 .code = zir,
...@@ -34958,7 +35288,7 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi...@@ -34958,7 +35288,7 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi
34958 var accumulator: u64 = 0;35288 var accumulator: u64 = 0;
34959 for (0..struct_type.field_types.len) |i| {35289 for (0..struct_type.field_types.len) |i| {
34960 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);35290 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
34961 accumulator += try field_ty.bitSizeAdvanced(zcu, .sema);35291 accumulator += try field_ty.bitSizeAdvanced(pt, .sema);
34962 }35292 }
34963 break :blk accumulator;35293 break :blk accumulator;
34964 };35294 };
...@@ -35004,7 +35334,7 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi...@@ -35004,7 +35334,7 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi
35004 if (fields_bit_sum > std.math.maxInt(u16)) {35334 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});35335 return sema.fail(&block, block.nodeOffset(0), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum});
35006 }35336 }
35007 const backing_int_ty = try zcu.intType(.unsigned, @intCast(fields_bit_sum));35337 const backing_int_ty = try pt.intType(.unsigned, @intCast(fields_bit_sum));
35008 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();35338 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();
35009 }35339 }
3501035340
...@@ -35012,26 +35342,27 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi...@@ -35012,26 +35342,27 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi
35012}35342}
3501335343
35014fn checkBackingIntType(sema: *Sema, block: *Block, src: LazySrcLoc, backing_int_ty: Type, fields_bit_sum: u64) CompileError!void {35344fn checkBackingIntType(sema: *Sema, block: *Block, src: LazySrcLoc, backing_int_ty: Type, fields_bit_sum: u64) CompileError!void {
35015 const mod = sema.mod;35345 const pt = sema.pt;
35346 const mod = pt.zcu;
3501635347
35017 if (!backing_int_ty.isInt(mod)) {35348 if (!backing_int_ty.isInt(mod)) {
35018 return sema.fail(block, src, "expected backing integer type, found '{}'", .{backing_int_ty.fmt(sema.mod)});35349 return sema.fail(block, src, "expected backing integer type, found '{}'", .{backing_int_ty.fmt(pt)});
35019 }35350 }
35020 if (backing_int_ty.bitSize(mod) != fields_bit_sum) {35351 if (backing_int_ty.bitSize(pt) != fields_bit_sum) {
35021 return sema.fail(35352 return sema.fail(
35022 block,35353 block,
35023 src,35354 src,
35024 "backing integer type '{}' has bit size {} but the struct fields have a total bit size of {}",35355 "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 },35356 .{ backing_int_ty.fmt(pt), backing_int_ty.bitSize(pt), fields_bit_sum },
35026 );35357 );
35027 }35358 }
35028}35359}
3502935360
35030fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {35361fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
35031 const mod = sema.mod;35362 const pt = sema.pt;
35032 if (!ty.isIndexable(mod)) {35363 if (!ty.isIndexable(pt.zcu)) {
35033 const msg = msg: {35364 const msg = msg: {
35034 const msg = try sema.errMsg(src, "type '{}' does not support indexing", .{ty.fmt(sema.mod)});35365 const msg = try sema.errMsg(src, "type '{}' does not support indexing", .{ty.fmt(pt)});
35035 errdefer msg.destroy(sema.gpa);35366 errdefer msg.destroy(sema.gpa);
35036 try sema.errNote(src, msg, "operand must be an array, slice, tuple, or vector", .{});35367 try sema.errNote(src, msg, "operand must be an array, slice, tuple, or vector", .{});
35037 break :msg msg;35368 break :msg msg;
...@@ -35041,7 +35372,8 @@ fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {...@@ -35041,7 +35372,8 @@ fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
35041}35372}
3504235373
35043fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {35374fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
35044 const mod = sema.mod;35375 const pt = sema.pt;
35376 const mod = pt.zcu;
35045 if (ty.zigTypeTag(mod) == .Pointer) {35377 if (ty.zigTypeTag(mod) == .Pointer) {
35046 switch (ty.ptrSize(mod)) {35378 switch (ty.ptrSize(mod)) {
35047 .Slice, .Many, .C => return,35379 .Slice, .Many, .C => return,
...@@ -35054,7 +35386,7 @@ fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void...@@ -35054,7 +35386,7 @@ fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void
35054 }35386 }
35055 }35387 }
35056 const msg = msg: {35388 const msg = msg: {
35057 const msg = try sema.errMsg(src, "type '{}' is not an indexable pointer", .{ty.fmt(sema.mod)});35389 const msg = try sema.errMsg(src, "type '{}' is not an indexable pointer", .{ty.fmt(pt)});
35058 errdefer msg.destroy(sema.gpa);35390 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", .{});35391 try sema.errNote(src, msg, "operand must be a slice, a many pointer or a pointer to an array", .{});
35060 break :msg msg;35392 break :msg msg;
...@@ -35069,9 +35401,9 @@ pub fn resolveUnionAlignment(...@@ -35069,9 +35401,9 @@ pub fn resolveUnionAlignment(
35069 ty: Type,35401 ty: Type,
35070 union_type: InternPool.LoadedUnionType,35402 union_type: InternPool.LoadedUnionType,
35071) SemaError!void {35403) SemaError!void {
35072 const mod = sema.mod;35404 const zcu = sema.pt.zcu;
35073 const ip = &mod.intern_pool;35405 const ip = &zcu.intern_pool;
35074 const target = mod.getTarget();35406 const target = zcu.getTarget();
3507535407
35076 assert(sema.ownerUnit().unwrap().decl == union_type.decl);35408 assert(sema.ownerUnit().unwrap().decl == union_type.decl);
3507735409
...@@ -35108,8 +35440,8 @@ pub fn resolveUnionAlignment(...@@ -35108,8 +35440,8 @@ pub fn resolveUnionAlignment(
3510835440
35109/// This logic must be kept in sync with `Module.getUnionLayout`.35441/// This logic must be kept in sync with `Module.getUnionLayout`.
35110pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {35442pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35111 const zcu = sema.mod;35443 const pt = sema.pt;
35112 const ip = &zcu.intern_pool;35444 const ip = &pt.zcu.intern_pool;
3511335445
35114 try sema.resolveTypeFieldsUnion(ty, ip.loadUnionType(ty.ip_index));35446 try sema.resolveTypeFieldsUnion(ty, ip.loadUnionType(ty.ip_index));
3511535447
...@@ -35122,9 +35454,9 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35122,9 +35454,9 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35122 .none, .have_field_types => {},35454 .none, .have_field_types => {},
35123 .field_types_wip, .layout_wip => {35455 .field_types_wip, .layout_wip => {
35124 const msg = try sema.errMsg(35456 const msg = try sema.errMsg(
35125 ty.srcLoc(zcu),35457 ty.srcLoc(pt.zcu),
35126 "union '{}' depends on itself",35458 "union '{}' depends on itself",
35127 .{ty.fmt(zcu)},35459 .{ty.fmt(pt)},
35128 );35460 );
35129 return sema.failWithOwnedErrorMsg(null, msg);35461 return sema.failWithOwnedErrorMsg(null, msg);
35130 },35462 },
...@@ -35143,7 +35475,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35143,7 +35475,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35143 for (0..union_type.field_types.len) |field_index| {35475 for (0..union_type.field_types.len) |field_index| {
35144 const field_ty = Type.fromInterned(union_type.field_types.get(ip)[field_index]);35476 const field_ty = Type.fromInterned(union_type.field_types.get(ip)[field_index]);
3514535477
35146 if (try sema.typeRequiresComptime(field_ty) or field_ty.zigTypeTag(zcu) == .NoReturn) continue; // TODO: should this affect alignment?35478 if (try sema.typeRequiresComptime(field_ty) or field_ty.zigTypeTag(pt.zcu) == .NoReturn) continue; // TODO: should this affect alignment?
3514735479
35148 max_size = @max(max_size, sema.typeAbiSize(field_ty) catch |err| switch (err) {35480 max_size = @max(max_size, sema.typeAbiSize(field_ty) catch |err| switch (err) {
35149 error.AnalysisFail => {35481 error.AnalysisFail => {
...@@ -35185,7 +35517,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35185,7 +35517,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35185 } else {35517 } else {
35186 // {Payload, Tag}35518 // {Payload, Tag}
35187 size += max_size;35519 size += max_size;
35188 size = switch (zcu.getTarget().ofmt) {35520 size = switch (pt.zcu.getTarget().ofmt) {
35189 .c => max_align,35521 .c => max_align,
35190 else => tag_align,35522 else => tag_align,
35191 }.forward(size);35523 }.forward(size);
...@@ -35205,7 +35537,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35205,7 +35537,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
3520535537
35206 if (union_type.flagsPtr(ip).assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) {35538 if (union_type.flagsPtr(ip).assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) {
35207 const msg = try sema.errMsg(35539 const msg = try sema.errMsg(
35208 ty.srcLoc(zcu),35540 ty.srcLoc(pt.zcu),
35209 "union layout depends on it having runtime bits",35541 "union layout depends on it having runtime bits",
35210 .{},35542 .{},
35211 );35543 );
...@@ -35213,10 +35545,10 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35213,10 +35545,10 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35213 }35545 }
3521435546
35215 if (union_type.flagsPtr(ip).assumed_pointer_aligned and35547 if (union_type.flagsPtr(ip).assumed_pointer_aligned and
35216 alignment.compareStrict(.neq, Alignment.fromByteUnits(@divExact(zcu.getTarget().ptrBitWidth(), 8))))35548 alignment.compareStrict(.neq, Alignment.fromByteUnits(@divExact(pt.zcu.getTarget().ptrBitWidth(), 8))))
35217 {35549 {
35218 const msg = try sema.errMsg(35550 const msg = try sema.errMsg(
35219 ty.srcLoc(zcu),35551 ty.srcLoc(pt.zcu),
35220 "union layout depends on being pointer aligned",35552 "union layout depends on being pointer aligned",
35221 .{},35553 .{},
35222 );35554 );
...@@ -35229,7 +35561,8 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35229,7 +35561,8 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35229pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {35561pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {
35230 try sema.resolveStructLayout(ty);35562 try sema.resolveStructLayout(ty);
3523135563
35232 const mod = sema.mod;35564 const pt = sema.pt;
35565 const mod = pt.zcu;
35233 const ip = &mod.intern_pool;35566 const ip = &mod.intern_pool;
35234 const struct_type = mod.typeToStruct(ty).?;35567 const struct_type = mod.typeToStruct(ty).?;
3523535568
...@@ -35244,14 +35577,15 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {...@@ -35244,14 +35577,15 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {
3524435577
35245 for (0..struct_type.field_types.len) |i| {35578 for (0..struct_type.field_types.len) |i| {
35246 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);35579 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
35247 try field_ty.resolveFully(mod);35580 try field_ty.resolveFully(pt);
35248 }35581 }
35249}35582}
3525035583
35251pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {35584pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {
35252 try sema.resolveUnionLayout(ty);35585 try sema.resolveUnionLayout(ty);
3525335586
35254 const mod = sema.mod;35587 const pt = sema.pt;
35588 const mod = pt.zcu;
35255 const ip = &mod.intern_pool;35589 const ip = &mod.intern_pool;
35256 const union_obj = mod.typeToUnion(ty).?;35590 const union_obj = mod.typeToUnion(ty).?;
3525735591
...@@ -35272,7 +35606,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {...@@ -35272,7 +35606,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {
35272 union_obj.flagsPtr(ip).status = .fully_resolved_wip;35606 union_obj.flagsPtr(ip).status = .fully_resolved_wip;
35273 for (0..union_obj.field_types.len) |field_index| {35607 for (0..union_obj.field_types.len) |field_index| {
35274 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);35608 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
35275 try field_ty.resolveFully(mod);35609 try field_ty.resolveFully(pt);
35276 }35610 }
35277 union_obj.flagsPtr(ip).status = .fully_resolved;35611 union_obj.flagsPtr(ip).status = .fully_resolved;
35278 }35612 }
...@@ -35286,7 +35620,8 @@ pub fn resolveTypeFieldsStruct(...@@ -35286,7 +35620,8 @@ pub fn resolveTypeFieldsStruct(
35286 ty: InternPool.Index,35620 ty: InternPool.Index,
35287 struct_type: InternPool.LoadedStructType,35621 struct_type: InternPool.LoadedStructType,
35288) SemaError!void {35622) SemaError!void {
35289 const zcu = sema.mod;35623 const pt = sema.pt;
35624 const zcu = pt.zcu;
35290 const ip = &zcu.intern_pool;35625 const ip = &zcu.intern_pool;
35291 // If there is no owner decl it means the struct has no fields.35626 // If there is no owner decl it means the struct has no fields.
35292 const owner_decl = struct_type.decl.unwrap() orelse return;35627 const owner_decl = struct_type.decl.unwrap() orelse return;
...@@ -35310,13 +35645,13 @@ pub fn resolveTypeFieldsStruct(...@@ -35310,13 +35645,13 @@ pub fn resolveTypeFieldsStruct(
35310 const msg = try sema.errMsg(35645 const msg = try sema.errMsg(
35311 Type.fromInterned(ty).srcLoc(zcu),35646 Type.fromInterned(ty).srcLoc(zcu),
35312 "struct '{}' depends on itself",35647 "struct '{}' depends on itself",
35313 .{Type.fromInterned(ty).fmt(zcu)},35648 .{Type.fromInterned(ty).fmt(pt)},
35314 );35649 );
35315 return sema.failWithOwnedErrorMsg(null, msg);35650 return sema.failWithOwnedErrorMsg(null, msg);
35316 }35651 }
35317 defer struct_type.clearTypesWip(ip);35652 defer struct_type.clearTypesWip(ip);
3531835653
35319 semaStructFields(zcu, sema.arena, struct_type) catch |err| switch (err) {35654 semaStructFields(pt, sema.arena, struct_type) catch |err| switch (err) {
35320 error.AnalysisFail => {35655 error.AnalysisFail => {
35321 if (zcu.declPtr(owner_decl).analysis == .complete) {35656 if (zcu.declPtr(owner_decl).analysis == .complete) {
35322 zcu.declPtr(owner_decl).analysis = .dependency_failure;35657 zcu.declPtr(owner_decl).analysis = .dependency_failure;
...@@ -35329,7 +35664,8 @@ pub fn resolveTypeFieldsStruct(...@@ -35329,7 +35664,8 @@ pub fn resolveTypeFieldsStruct(
35329}35664}
3533035665
35331pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {35666pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {
35332 const zcu = sema.mod;35667 const pt = sema.pt;
35668 const zcu = pt.zcu;
35333 const ip = &zcu.intern_pool;35669 const ip = &zcu.intern_pool;
35334 const struct_type = zcu.typeToStruct(ty) orelse return;35670 const struct_type = zcu.typeToStruct(ty) orelse return;
35335 const owner_decl = struct_type.decl.unwrap() orelse return;35671 const owner_decl = struct_type.decl.unwrap() orelse return;
...@@ -35345,13 +35681,13 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {...@@ -35345,13 +35681,13 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {
35345 const msg = try sema.errMsg(35681 const msg = try sema.errMsg(
35346 ty.srcLoc(zcu),35682 ty.srcLoc(zcu),
35347 "struct '{}' depends on itself",35683 "struct '{}' depends on itself",
35348 .{ty.fmt(zcu)},35684 .{ty.fmt(pt)},
35349 );35685 );
35350 return sema.failWithOwnedErrorMsg(null, msg);35686 return sema.failWithOwnedErrorMsg(null, msg);
35351 }35687 }
35352 defer struct_type.clearInitsWip(ip);35688 defer struct_type.clearInitsWip(ip);
3535335689
35354 semaStructFieldInits(zcu, sema.arena, struct_type) catch |err| switch (err) {35690 semaStructFieldInits(pt, sema.arena, struct_type) catch |err| switch (err) {
35355 error.AnalysisFail => {35691 error.AnalysisFail => {
35356 if (zcu.declPtr(owner_decl).analysis == .complete) {35692 if (zcu.declPtr(owner_decl).analysis == .complete) {
35357 zcu.declPtr(owner_decl).analysis = .dependency_failure;35693 zcu.declPtr(owner_decl).analysis = .dependency_failure;
...@@ -35365,7 +35701,8 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {...@@ -35365,7 +35701,8 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {
35365}35701}
3536635702
35367pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.LoadedUnionType) SemaError!void {35703pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.LoadedUnionType) SemaError!void {
35368 const zcu = sema.mod;35704 const pt = sema.pt;
35705 const zcu = pt.zcu;
35369 const ip = &zcu.intern_pool;35706 const ip = &zcu.intern_pool;
35370 const owner_decl = zcu.declPtr(union_type.decl);35707 const owner_decl = zcu.declPtr(union_type.decl);
3537135708
...@@ -35387,7 +35724,7 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load...@@ -35387,7 +35724,7 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
35387 const msg = try sema.errMsg(35724 const msg = try sema.errMsg(
35388 ty.srcLoc(zcu),35725 ty.srcLoc(zcu),
35389 "union '{}' depends on itself",35726 "union '{}' depends on itself",
35390 .{ty.fmt(zcu)},35727 .{ty.fmt(pt)},
35391 );35728 );
35392 return sema.failWithOwnedErrorMsg(null, msg);35729 return sema.failWithOwnedErrorMsg(null, msg);
35393 },35730 },
...@@ -35401,7 +35738,7 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load...@@ -35401,7 +35738,7 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
3540135738
35402 union_type.flagsPtr(ip).status = .field_types_wip;35739 union_type.flagsPtr(ip).status = .field_types_wip;
35403 errdefer union_type.flagsPtr(ip).status = .none;35740 errdefer union_type.flagsPtr(ip).status = .none;
35404 semaUnionFields(zcu, sema.arena, union_type) catch |err| switch (err) {35741 semaUnionFields(pt, sema.arena, union_type) catch |err| switch (err) {
35405 error.AnalysisFail => {35742 error.AnalysisFail => {
35406 if (owner_decl.analysis == .complete) {35743 if (owner_decl.analysis == .complete) {
35407 owner_decl.analysis = .dependency_failure;35744 owner_decl.analysis = .dependency_failure;
...@@ -35422,7 +35759,8 @@ fn resolveInferredErrorSet(...@@ -35422,7 +35759,8 @@ fn resolveInferredErrorSet(
35422 src: LazySrcLoc,35759 src: LazySrcLoc,
35423 ies_index: InternPool.Index,35760 ies_index: InternPool.Index,
35424) CompileError!InternPool.Index {35761) CompileError!InternPool.Index {
35425 const mod = sema.mod;35762 const pt = sema.pt;
35763 const mod = pt.zcu;
35426 const ip = &mod.intern_pool;35764 const ip = &mod.intern_pool;
35427 const func_index = ip.iesFuncIndex(ies_index);35765 const func_index = ip.iesFuncIndex(ies_index);
35428 const func = mod.funcInfo(func_index);35766 const func = mod.funcInfo(func_index);
...@@ -35482,8 +35820,8 @@ pub fn resolveInferredErrorSetPtr(...@@ -35482,8 +35820,8 @@ pub fn resolveInferredErrorSetPtr(
35482 src: LazySrcLoc,35820 src: LazySrcLoc,
35483 ies: *InferredErrorSet,35821 ies: *InferredErrorSet,
35484) CompileError!void {35822) CompileError!void {
35485 const mod = sema.mod;35823 const pt = sema.pt;
35486 const ip = &mod.intern_pool;35824 const ip = &pt.zcu.intern_pool;
3548735825
35488 if (ies.resolved != .none) return;35826 if (ies.resolved != .none) return;
3548935827
...@@ -35505,7 +35843,7 @@ pub fn resolveInferredErrorSetPtr(...@@ -35505,7 +35843,7 @@ pub fn resolveInferredErrorSetPtr(
35505 }35843 }
35506 }35844 }
3550735845
35508 const resolved_error_set_ty = try mod.errorSetFromUnsortedNames(ies.errors.keys());35846 const resolved_error_set_ty = try pt.errorSetFromUnsortedNames(ies.errors.keys());
35509 ies.resolved = resolved_error_set_ty.toIntern();35847 ies.resolved = resolved_error_set_ty.toIntern();
35510}35848}
3551135849
...@@ -35515,12 +35853,13 @@ fn resolveAdHocInferredErrorSet(...@@ -35515,12 +35853,13 @@ fn resolveAdHocInferredErrorSet(
35515 src: LazySrcLoc,35853 src: LazySrcLoc,
35516 value: InternPool.Index,35854 value: InternPool.Index,
35517) CompileError!InternPool.Index {35855) CompileError!InternPool.Index {
35518 const mod = sema.mod;35856 const pt = sema.pt;
35857 const mod = pt.zcu;
35519 const gpa = sema.gpa;35858 const gpa = sema.gpa;
35520 const ip = &mod.intern_pool;35859 const ip = &mod.intern_pool;
35521 const new_ty = try resolveAdHocInferredErrorSetTy(sema, block, src, ip.typeOf(value));35860 const new_ty = try resolveAdHocInferredErrorSetTy(sema, block, src, ip.typeOf(value));
35522 if (new_ty == .none) return value;35861 if (new_ty == .none) return value;
35523 return ip.getCoerced(gpa, value, new_ty);35862 return ip.getCoerced(gpa, pt.tid, value, new_ty);
35524}35863}
3552535864
35526fn resolveAdHocInferredErrorSetTy(35865fn resolveAdHocInferredErrorSetTy(
...@@ -35530,8 +35869,8 @@ fn resolveAdHocInferredErrorSetTy(...@@ -35530,8 +35869,8 @@ fn resolveAdHocInferredErrorSetTy(
35530 ty: InternPool.Index,35869 ty: InternPool.Index,
35531) CompileError!InternPool.Index {35870) CompileError!InternPool.Index {
35532 const ies = sema.fn_ret_ty_ies orelse return .none;35871 const ies = sema.fn_ret_ty_ies orelse return .none;
35533 const mod = sema.mod;35872 const pt = sema.pt;
35534 const gpa = sema.gpa;35873 const mod = pt.zcu;
35535 const ip = &mod.intern_pool;35874 const ip = &mod.intern_pool;
35536 const error_union_info = switch (ip.indexToKey(ty)) {35875 const error_union_info = switch (ip.indexToKey(ty)) {
35537 .error_union_type => |x| x,35876 .error_union_type => |x| x,
...@@ -35541,7 +35880,7 @@ fn resolveAdHocInferredErrorSetTy(...@@ -35541,7 +35880,7 @@ fn resolveAdHocInferredErrorSetTy(
35541 return .none;35880 return .none;
3554235881
35543 try sema.resolveInferredErrorSetPtr(block, src, ies);35882 try sema.resolveInferredErrorSetPtr(block, src, ies);
35544 const new_ty = try ip.get(gpa, .{ .error_union_type = .{35883 const new_ty = try pt.intern(.{ .error_union_type = .{
35545 .error_set_type = ies.resolved,35884 .error_set_type = ies.resolved,
35546 .payload_type = error_union_info.payload_type,35885 .payload_type = error_union_info.payload_type,
35547 } });35886 } });
...@@ -35554,7 +35893,8 @@ fn resolveInferredErrorSetTy(...@@ -35554,7 +35893,8 @@ fn resolveInferredErrorSetTy(
35554 src: LazySrcLoc,35893 src: LazySrcLoc,
35555 ty: InternPool.Index,35894 ty: InternPool.Index,
35556) CompileError!InternPool.Index {35895) CompileError!InternPool.Index {
35557 const mod = sema.mod;35896 const pt = sema.pt;
35897 const mod = pt.zcu;
35558 const ip = &mod.intern_pool;35898 const ip = &mod.intern_pool;
35559 if (ty == .anyerror_type) return ty;35899 if (ty == .anyerror_type) return ty;
35560 switch (ip.indexToKey(ty)) {35900 switch (ip.indexToKey(ty)) {
...@@ -35614,10 +35954,11 @@ fn structZirInfo(zir: Zir, zir_index: Zir.Inst.Index) struct {...@@ -35614,10 +35954,11 @@ fn structZirInfo(zir: Zir, zir_index: Zir.Inst.Index) struct {
35614}35954}
3561535955
35616fn semaStructFields(35956fn semaStructFields(
35617 zcu: *Zcu,35957 pt: Zcu.PerThread,
35618 arena: Allocator,35958 arena: Allocator,
35619 struct_type: InternPool.LoadedStructType,35959 struct_type: InternPool.LoadedStructType,
35620) CompileError!void {35960) CompileError!void {
35961 const zcu = pt.zcu;
35621 const gpa = zcu.gpa;35962 const gpa = zcu.gpa;
35622 const ip = &zcu.intern_pool;35963 const ip = &zcu.intern_pool;
35623 const decl_index = struct_type.decl.unwrap() orelse return;35964 const decl_index = struct_type.decl.unwrap() orelse return;
...@@ -35630,7 +35971,7 @@ fn semaStructFields(...@@ -35630,7 +35971,7 @@ fn semaStructFields(
3563035971
35631 if (fields_len == 0) switch (struct_type.layout) {35972 if (fields_len == 0) switch (struct_type.layout) {
35632 .@"packed" => {35973 .@"packed" => {
35633 try semaBackingIntType(zcu, struct_type);35974 try semaBackingIntType(pt, struct_type);
35634 return;35975 return;
35635 },35976 },
35636 .auto, .@"extern" => {35977 .auto, .@"extern" => {
...@@ -35644,7 +35985,7 @@ fn semaStructFields(...@@ -35644,7 +35985,7 @@ fn semaStructFields(
35644 defer comptime_err_ret_trace.deinit();35985 defer comptime_err_ret_trace.deinit();
3564535986
35646 var sema: Sema = .{35987 var sema: Sema = .{
35647 .mod = zcu,35988 .pt = pt,
35648 .gpa = gpa,35989 .gpa = gpa,
35649 .arena = arena,35990 .arena = arena,
35650 .code = zir,35991 .code = zir,
...@@ -35789,7 +36130,7 @@ fn semaStructFields(...@@ -35789,7 +36130,7 @@ fn semaStructFields(
35789 switch (struct_type.layout) {36130 switch (struct_type.layout) {
35790 .@"extern" => if (!try sema.validateExternType(field_ty, .struct_field)) {36131 .@"extern" => if (!try sema.validateExternType(field_ty, .struct_field)) {
35791 const msg = msg: {36132 const msg = msg: {
35792 const msg = try sema.errMsg(ty_src, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(zcu)});36133 const msg = try sema.errMsg(ty_src, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
35793 errdefer msg.destroy(sema.gpa);36134 errdefer msg.destroy(sema.gpa);
3579436135
35795 try sema.explainWhyTypeIsNotExtern(msg, ty_src, field_ty, .struct_field);36136 try sema.explainWhyTypeIsNotExtern(msg, ty_src, field_ty, .struct_field);
...@@ -35801,7 +36142,7 @@ fn semaStructFields(...@@ -35801,7 +36142,7 @@ fn semaStructFields(
35801 },36142 },
35802 .@"packed" => if (!try sema.validatePackedType(field_ty)) {36143 .@"packed" => if (!try sema.validatePackedType(field_ty)) {
35803 const msg = msg: {36144 const msg = msg: {
35804 const msg = try sema.errMsg(ty_src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(zcu)});36145 const msg = try sema.errMsg(ty_src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
35805 errdefer msg.destroy(sema.gpa);36146 errdefer msg.destroy(sema.gpa);
3580636147
35807 try sema.explainWhyTypeIsNotPacked(msg, ty_src, field_ty);36148 try sema.explainWhyTypeIsNotPacked(msg, ty_src, field_ty);
...@@ -35837,10 +36178,11 @@ fn semaStructFields(...@@ -35837,10 +36178,11 @@ fn semaStructFields(
3583736178
35838// This logic must be kept in sync with `semaStructFields`36179// This logic must be kept in sync with `semaStructFields`
35839fn semaStructFieldInits(36180fn semaStructFieldInits(
35840 zcu: *Zcu,36181 pt: Zcu.PerThread,
35841 arena: Allocator,36182 arena: Allocator,
35842 struct_type: InternPool.LoadedStructType,36183 struct_type: InternPool.LoadedStructType,
35843) CompileError!void {36184) CompileError!void {
36185 const zcu = pt.zcu;
35844 const gpa = zcu.gpa;36186 const gpa = zcu.gpa;
35845 const ip = &zcu.intern_pool;36187 const ip = &zcu.intern_pool;
3584636188
...@@ -35857,7 +36199,7 @@ fn semaStructFieldInits(...@@ -35857,7 +36199,7 @@ fn semaStructFieldInits(
35857 defer comptime_err_ret_trace.deinit();36199 defer comptime_err_ret_trace.deinit();
3585836200
35859 var sema: Sema = .{36201 var sema: Sema = .{
35860 .mod = zcu,36202 .pt = pt,
35861 .gpa = gpa,36203 .gpa = gpa,
35862 .arena = arena,36204 .arena = arena,
35863 .code = zir,36205 .code = zir,
...@@ -35977,10 +36319,11 @@ fn semaStructFieldInits(...@@ -35977,10 +36319,11 @@ fn semaStructFieldInits(
35977 try sema.flushExports();36319 try sema.flushExports();
35978}36320}
3597936321
35980fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUnionType) CompileError!void {36322fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.LoadedUnionType) CompileError!void {
35981 const tracy = trace(@src());36323 const tracy = trace(@src());
35982 defer tracy.end();36324 defer tracy.end();
3598336325
36326 const zcu = pt.zcu;
35984 const gpa = zcu.gpa;36327 const gpa = zcu.gpa;
35985 const ip = &zcu.intern_pool;36328 const ip = &zcu.intern_pool;
35986 const decl_index = union_type.decl;36329 const decl_index = union_type.decl;
...@@ -36034,7 +36377,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni...@@ -36034,7 +36377,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni
36034 defer comptime_err_ret_trace.deinit();36377 defer comptime_err_ret_trace.deinit();
3603536378
36036 var sema: Sema = .{36379 var sema: Sema = .{
36037 .mod = zcu,36380 .pt = pt,
36038 .gpa = gpa,36381 .gpa = gpa,
36039 .arena = arena,36382 .arena = arena,
36040 .code = zir,36383 .code = zir,
...@@ -36081,17 +36424,17 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni...@@ -36081,17 +36424,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.36424 // The provided type is an integer type and we must construct the enum tag type here.
36082 int_tag_ty = provided_ty;36425 int_tag_ty = provided_ty;
36083 if (int_tag_ty.zigTypeTag(zcu) != .Int and int_tag_ty.zigTypeTag(zcu) != .ComptimeInt) {36426 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)});36427 return sema.fail(&block_scope, tag_ty_src, "expected integer tag type, found '{}'", .{int_tag_ty.fmt(pt)});
36085 }36428 }
3608636429
36087 if (fields_len > 0) {36430 if (fields_len > 0) {
36088 const field_count_val = try zcu.intValue(Type.comptime_int, fields_len - 1);36431 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))) {36432 if (!(try sema.intFitsInType(field_count_val, int_tag_ty, null))) {
36090 const msg = msg: {36433 const msg = msg: {
36091 const msg = try sema.errMsg(tag_ty_src, "specified integer tag type cannot represent every field", .{});36434 const msg = try sema.errMsg(tag_ty_src, "specified integer tag type cannot represent every field", .{});
36092 errdefer msg.destroy(sema.gpa);36435 errdefer msg.destroy(sema.gpa);
36093 try sema.errNote(tag_ty_src, msg, "type '{}' cannot fit values in range 0...{d}", .{36436 try sema.errNote(tag_ty_src, msg, "type '{}' cannot fit values in range 0...{d}", .{
36094 int_tag_ty.fmt(zcu),36437 int_tag_ty.fmt(pt),
36095 fields_len - 1,36438 fields_len - 1,
36096 });36439 });
36097 break :msg msg;36440 break :msg msg;
...@@ -36106,7 +36449,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni...@@ -36106,7 +36449,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni
36106 union_type.tagTypePtr(ip).* = provided_ty.toIntern();36449 union_type.tagTypePtr(ip).* = provided_ty.toIntern();
36107 const enum_type = switch (ip.indexToKey(provided_ty.toIntern())) {36450 const enum_type = switch (ip.indexToKey(provided_ty.toIntern())) {
36108 .enum_type => ip.loadEnumType(provided_ty.toIntern()),36451 .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)}),36452 else => return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{provided_ty.fmt(pt)}),
36110 };36453 };
36111 // The fields of the union must match the enum exactly.36454 // The fields of the union must match the enum exactly.
36112 // A flag per field is used to check for missing and extraneous fields.36455 // A flag per field is used to check for missing and extraneous fields.
...@@ -36202,7 +36545,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni...@@ -36202,7 +36545,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni
36202 const val = if (last_tag_val) |val|36545 const val = if (last_tag_val) |val|
36203 try sema.intAdd(val, Value.one_comptime_int, int_tag_ty, undefined)36546 try sema.intAdd(val, Value.one_comptime_int, int_tag_ty, undefined)
36204 else36547 else
36205 try zcu.intValue(int_tag_ty, 0);36548 try pt.intValue(int_tag_ty, 0);
36206 last_tag_val = val;36549 last_tag_val = val;
3620736550
36208 break :blk val;36551 break :blk val;
...@@ -36214,7 +36557,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni...@@ -36214,7 +36557,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni
36214 .offset = .{ .container_field_value = @intCast(gop.index) },36557 .offset = .{ .container_field_value = @intCast(gop.index) },
36215 };36558 };
36216 const msg = msg: {36559 const msg = msg: {
36217 const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{enum_tag_val.fmtValue(zcu, &sema)});36560 const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{enum_tag_val.fmtValue(pt, &sema)});
36218 errdefer msg.destroy(gpa);36561 errdefer msg.destroy(gpa);
36219 try sema.errNote(other_value_src, msg, "other occurrence here", .{});36562 try sema.errNote(other_value_src, msg, "other occurrence here", .{});
36220 break :msg msg;36563 break :msg msg;
...@@ -36244,7 +36587,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni...@@ -36244,7 +36587,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni
36244 const tag_info = ip.loadEnumType(union_type.tagTypePtr(ip).*);36587 const tag_info = ip.loadEnumType(union_type.tagTypePtr(ip).*);
36245 const enum_index = tag_info.nameIndex(ip, field_name) orelse {36588 const enum_index = tag_info.nameIndex(ip, field_name) orelse {
36246 return sema.fail(&block_scope, name_src, "no field named '{}' in enum '{}'", .{36589 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),36590 field_name.fmt(ip), Type.fromInterned(union_type.tagTypePtr(ip).*).fmt(pt),
36248 });36591 });
36249 };36592 };
3625036593
...@@ -36286,7 +36629,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni...@@ -36286,7 +36629,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni
36286 !try sema.validateExternType(field_ty, .union_field))36629 !try sema.validateExternType(field_ty, .union_field))
36287 {36630 {
36288 const msg = msg: {36631 const msg = msg: {
36289 const msg = try sema.errMsg(type_src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(zcu)});36632 const msg = try sema.errMsg(type_src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
36290 errdefer msg.destroy(sema.gpa);36633 errdefer msg.destroy(sema.gpa);
3629136634
36292 try sema.explainWhyTypeIsNotExtern(msg, type_src, field_ty, .union_field);36635 try sema.explainWhyTypeIsNotExtern(msg, type_src, field_ty, .union_field);
...@@ -36297,7 +36640,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni...@@ -36297,7 +36640,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni
36297 return sema.failWithOwnedErrorMsg(&block_scope, msg);36640 return sema.failWithOwnedErrorMsg(&block_scope, msg);
36298 } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) {36641 } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) {
36299 const msg = msg: {36642 const msg = msg: {
36300 const msg = try sema.errMsg(type_src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(zcu)});36643 const msg = try sema.errMsg(type_src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
36301 errdefer msg.destroy(sema.gpa);36644 errdefer msg.destroy(sema.gpa);
3630236645
36303 try sema.explainWhyTypeIsNotPacked(msg, type_src, field_ty);36646 try sema.explainWhyTypeIsNotPacked(msg, type_src, field_ty);
...@@ -36366,7 +36709,8 @@ fn generateUnionTagTypeNumbered(...@@ -36366,7 +36709,8 @@ fn generateUnionTagTypeNumbered(
36366 enum_field_vals: []const InternPool.Index,36709 enum_field_vals: []const InternPool.Index,
36367 union_owner_decl: *Module.Decl,36710 union_owner_decl: *Module.Decl,
36368) !InternPool.Index {36711) !InternPool.Index {
36369 const mod = sema.mod;36712 const pt = sema.pt;
36713 const mod = pt.zcu;
36370 const gpa = sema.gpa;36714 const gpa = sema.gpa;
36371 const ip = &mod.intern_pool;36715 const ip = &mod.intern_pool;
3637236716
...@@ -36390,11 +36734,11 @@ fn generateUnionTagTypeNumbered(...@@ -36390,11 +36734,11 @@ fn generateUnionTagTypeNumbered(
36390 new_decl.owns_tv = true;36734 new_decl.owns_tv = true;
36391 new_decl.name_fully_qualified = true;36735 new_decl.name_fully_qualified = true;
3639236736
36393 const enum_ty = try ip.getGeneratedTagEnumType(gpa, .{36737 const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{
36394 .decl = new_decl_index,36738 .decl = new_decl_index,
36395 .owner_union_ty = union_owner_decl.val.toIntern(),36739 .owner_union_ty = union_owner_decl.val.toIntern(),
36396 .tag_ty = if (enum_field_vals.len == 0)36740 .tag_ty = if (enum_field_vals.len == 0)
36397 (try mod.intType(.unsigned, 0)).toIntern()36741 (try pt.intType(.unsigned, 0)).toIntern()
36398 else36742 else
36399 ip.typeOf(enum_field_vals[0]),36743 ip.typeOf(enum_field_vals[0]),
36400 .names = enum_field_names,36744 .names = enum_field_names,
...@@ -36404,7 +36748,7 @@ fn generateUnionTagTypeNumbered(...@@ -36404,7 +36748,7 @@ fn generateUnionTagTypeNumbered(
3640436748
36405 new_decl.val = Value.fromInterned(enum_ty);36749 new_decl.val = Value.fromInterned(enum_ty);
3640636750
36407 try mod.finalizeAnonDecl(new_decl_index);36751 try pt.finalizeAnonDecl(new_decl_index);
36408 return enum_ty;36752 return enum_ty;
36409}36753}
3641036754
...@@ -36414,7 +36758,8 @@ fn generateUnionTagTypeSimple(...@@ -36414,7 +36758,8 @@ fn generateUnionTagTypeSimple(
36414 enum_field_names: []const InternPool.NullTerminatedString,36758 enum_field_names: []const InternPool.NullTerminatedString,
36415 union_owner_decl: *Module.Decl,36759 union_owner_decl: *Module.Decl,
36416) !InternPool.Index {36760) !InternPool.Index {
36417 const mod = sema.mod;36761 const pt = sema.pt;
36762 const mod = pt.zcu;
36418 const ip = &mod.intern_pool;36763 const ip = &mod.intern_pool;
36419 const gpa = sema.gpa;36764 const gpa = sema.gpa;
3642036765
...@@ -36438,13 +36783,13 @@ fn generateUnionTagTypeSimple(...@@ -36438,13 +36783,13 @@ fn generateUnionTagTypeSimple(
36438 };36783 };
36439 errdefer mod.abortAnonDecl(new_decl_index);36784 errdefer mod.abortAnonDecl(new_decl_index);
3644036785
36441 const enum_ty = try ip.getGeneratedTagEnumType(gpa, .{36786 const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{
36442 .decl = new_decl_index,36787 .decl = new_decl_index,
36443 .owner_union_ty = union_owner_decl.val.toIntern(),36788 .owner_union_ty = union_owner_decl.val.toIntern(),
36444 .tag_ty = if (enum_field_names.len == 0)36789 .tag_ty = if (enum_field_names.len == 0)
36445 (try mod.intType(.unsigned, 0)).toIntern()36790 (try pt.intType(.unsigned, 0)).toIntern()
36446 else36791 else
36447 (try mod.smallestUnsignedInt(enum_field_names.len - 1)).toIntern(),36792 (try pt.smallestUnsignedInt(enum_field_names.len - 1)).toIntern(),
36448 .names = enum_field_names,36793 .names = enum_field_names,
36449 .values = &.{},36794 .values = &.{},
36450 .tag_mode = .auto,36795 .tag_mode = .auto,
...@@ -36454,7 +36799,7 @@ fn generateUnionTagTypeSimple(...@@ -36454,7 +36799,7 @@ fn generateUnionTagTypeSimple(
36454 new_decl.owns_tv = true;36799 new_decl.owns_tv = true;
36455 new_decl.val = Value.fromInterned(enum_ty);36800 new_decl.val = Value.fromInterned(enum_ty);
3645636801
36457 try mod.finalizeAnonDecl(new_decl_index);36802 try pt.finalizeAnonDecl(new_decl_index);
36458 return enum_ty;36803 return enum_ty;
36459}36804}
3646036805
...@@ -36464,12 +36809,13 @@ fn generateUnionTagTypeSimple(...@@ -36464,12 +36809,13 @@ fn generateUnionTagTypeSimple(
36464/// that the types are already resolved.36809/// that the types are already resolved.
36465/// TODO assert the return value matches `ty.onePossibleValue`36810/// TODO assert the return value matches `ty.onePossibleValue`
36466pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {36811pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36467 const zcu = sema.mod;36812 const pt = sema.pt;
36813 const zcu = pt.zcu;
36468 const ip = &zcu.intern_pool;36814 const ip = &zcu.intern_pool;
36469 return switch (ty.toIntern()) {36815 return switch (ty.toIntern()) {
36470 .u0_type,36816 .u0_type,
36471 .i0_type,36817 .i0_type,
36472 => try zcu.intValue(ty, 0),36818 => try pt.intValue(ty, 0),
36473 .u1_type,36819 .u1_type,
36474 .u8_type,36820 .u8_type,
36475 .i8_type,36821 .i8_type,
...@@ -36532,7 +36878,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36532,7 +36878,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36532 .anyframe_type => unreachable,36878 .anyframe_type => unreachable,
36533 .null_type => Value.null,36879 .null_type => Value.null,
36534 .undefined_type => Value.undef,36880 .undefined_type => Value.undef,
36535 .optional_noreturn_type => try zcu.nullValue(ty),36881 .optional_noreturn_type => try pt.nullValue(ty),
36536 .generic_poison_type => error.GenericPoison,36882 .generic_poison_type => error.GenericPoison,
36537 .empty_struct_type => Value.empty_struct,36883 .empty_struct_type => Value.empty_struct,
36538 // values, not types36884 // values, not types
...@@ -36646,16 +36992,16 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36646,16 +36992,16 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36646 => switch (ip.indexToKey(ty.toIntern())) {36992 => switch (ip.indexToKey(ty.toIntern())) {
36647 inline .array_type, .vector_type => |seq_type, seq_tag| {36993 inline .array_type, .vector_type => |seq_type, seq_tag| {
36648 const has_sentinel = seq_tag == .array_type and seq_type.sentinel != .none;36994 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 = .{36995 if (seq_type.len + @intFromBool(has_sentinel) == 0) return Value.fromInterned(try pt.intern(.{ .aggregate = .{
36650 .ty = ty.toIntern(),36996 .ty = ty.toIntern(),
36651 .storage = .{ .elems = &.{} },36997 .storage = .{ .elems = &.{} },
36652 } })));36998 } }));
3665336999
36654 if (try sema.typeHasOnePossibleValue(Type.fromInterned(seq_type.child))) |opv| {37000 if (try sema.typeHasOnePossibleValue(Type.fromInterned(seq_type.child))) |opv| {
36655 return Value.fromInterned((try zcu.intern(.{ .aggregate = .{37001 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
36656 .ty = ty.toIntern(),37002 .ty = ty.toIntern(),
36657 .storage = .{ .repeated_elem = opv.toIntern() },37003 .storage = .{ .repeated_elem = opv.toIntern() },
36658 } })));37004 } }));
36659 }37005 }
36660 return null;37006 return null;
36661 },37007 },
...@@ -36663,17 +37009,17 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36663,17 +37009,17 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36663 .struct_type => {37009 .struct_type => {
36664 // Resolving the layout first helps to avoid loops.37010 // Resolving the layout first helps to avoid loops.
36665 // If the type has a coherent layout, we can recurse through fields safely.37011 // If the type has a coherent layout, we can recurse through fields safely.
36666 try ty.resolveLayout(zcu);37012 try ty.resolveLayout(pt);
3666737013
36668 const struct_type = ip.loadStructType(ty.toIntern());37014 const struct_type = ip.loadStructType(ty.toIntern());
3666937015
36670 if (struct_type.field_types.len == 0) {37016 if (struct_type.field_types.len == 0) {
36671 // In this case the struct has no fields at all and37017 // In this case the struct has no fields at all and
36672 // therefore has one possible value.37018 // therefore has one possible value.
36673 return Value.fromInterned((try zcu.intern(.{ .aggregate = .{37019 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
36674 .ty = ty.toIntern(),37020 .ty = ty.toIntern(),
36675 .storage = .{ .elems = &.{} },37021 .storage = .{ .elems = &.{} },
36676 } })));37022 } }));
36677 }37023 }
3667837024
36679 const field_vals = try sema.arena.alloc(37025 const field_vals = try sema.arena.alloc(
...@@ -36682,7 +37028,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36682,7 +37028,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36682 );37028 );
36683 for (field_vals, 0..) |*field_val, i| {37029 for (field_vals, 0..) |*field_val, i| {
36684 if (struct_type.fieldIsComptime(ip, i)) {37030 if (struct_type.fieldIsComptime(ip, i)) {
36685 try ty.resolveStructFieldInits(zcu);37031 try ty.resolveStructFieldInits(pt);
36686 field_val.* = struct_type.field_inits.get(ip)[i];37032 field_val.* = struct_type.field_inits.get(ip)[i];
36687 continue;37033 continue;
36688 }37034 }
...@@ -36694,10 +37040,10 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36694,10 +37040,10 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3669437040
36695 // In this case the struct has no runtime-known fields and37041 // In this case the struct has no runtime-known fields and
36696 // therefore has one possible value.37042 // therefore has one possible value.
36697 return Value.fromInterned((try zcu.intern(.{ .aggregate = .{37043 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
36698 .ty = ty.toIntern(),37044 .ty = ty.toIntern(),
36699 .storage = .{ .elems = field_vals },37045 .storage = .{ .elems = field_vals },
36700 } })));37046 } }));
36701 },37047 },
3670237048
36703 .anon_struct_type => |tuple| {37049 .anon_struct_type => |tuple| {
...@@ -36707,28 +37053,28 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36707,28 +37053,28 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36707 // In this case the struct has all comptime-known fields and37053 // In this case the struct has all comptime-known fields and
36708 // therefore has one possible value.37054 // therefore has one possible value.
36709 // TODO: write something like getCoercedInts to avoid needing to dupe37055 // TODO: write something like getCoercedInts to avoid needing to dupe
36710 return Value.fromInterned((try zcu.intern(.{ .aggregate = .{37056 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
36711 .ty = ty.toIntern(),37057 .ty = ty.toIntern(),
36712 .storage = .{ .elems = try sema.arena.dupe(InternPool.Index, tuple.values.get(ip)) },37058 .storage = .{ .elems = try sema.arena.dupe(InternPool.Index, tuple.values.get(ip)) },
36713 } })));37059 } }));
36714 },37060 },
3671537061
36716 .union_type => {37062 .union_type => {
36717 // Resolving the layout first helps to avoid loops.37063 // Resolving the layout first helps to avoid loops.
36718 // If the type has a coherent layout, we can recurse through fields safely.37064 // If the type has a coherent layout, we can recurse through fields safely.
36719 try ty.resolveLayout(zcu);37065 try ty.resolveLayout(pt);
3672037066
36721 const union_obj = ip.loadUnionType(ty.toIntern());37067 const union_obj = ip.loadUnionType(ty.toIntern());
36722 const tag_val = (try sema.typeHasOnePossibleValue(Type.fromInterned(union_obj.tagTypePtr(ip).*))) orelse37068 const tag_val = (try sema.typeHasOnePossibleValue(Type.fromInterned(union_obj.tagTypePtr(ip).*))) orelse
36723 return null;37069 return null;
36724 if (union_obj.field_types.len == 0) {37070 if (union_obj.field_types.len == 0) {
36725 const only = try zcu.intern(.{ .empty_enum_value = ty.toIntern() });37071 const only = try pt.intern(.{ .empty_enum_value = ty.toIntern() });
36726 return Value.fromInterned(only);37072 return Value.fromInterned(only);
36727 }37073 }
36728 const only_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]);37074 const only_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]);
36729 const val_val = (try sema.typeHasOnePossibleValue(only_field_ty)) orelse37075 const val_val = (try sema.typeHasOnePossibleValue(only_field_ty)) orelse
36730 return null;37076 return null;
36731 const only = try zcu.intern(.{ .un = .{37077 const only = try pt.intern(.{ .un = .{
36732 .ty = ty.toIntern(),37078 .ty = ty.toIntern(),
36733 .tag = tag_val.toIntern(),37079 .tag = tag_val.toIntern(),
36734 .val = val_val.toIntern(),37080 .val = val_val.toIntern(),
...@@ -36743,7 +37089,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36743,7 +37089,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36743 if (enum_type.tag_ty == .comptime_int_type) return null;37089 if (enum_type.tag_ty == .comptime_int_type) return null;
3674437090
36745 if (try sema.typeHasOnePossibleValue(Type.fromInterned(enum_type.tag_ty))) |int_opv| {37091 if (try sema.typeHasOnePossibleValue(Type.fromInterned(enum_type.tag_ty))) |int_opv| {
36746 const only = try zcu.intern(.{ .enum_tag = .{37092 const only = try pt.intern(.{ .enum_tag = .{
36747 .ty = ty.toIntern(),37093 .ty = ty.toIntern(),
36748 .int = int_opv.toIntern(),37094 .int = int_opv.toIntern(),
36749 } });37095 } });
...@@ -36753,18 +37099,19 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36753,18 +37099,19 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36753 return null;37099 return null;
36754 },37100 },
36755 .auto, .explicit => {37101 .auto, .explicit => {
36756 if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(zcu)) return null;37102 if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(pt)) return null;
3675737103
36758 return Value.fromInterned(switch (enum_type.names.len) {37104 return Value.fromInterned(switch (enum_type.names.len) {
36759 0 => try zcu.intern(.{ .empty_enum_value = ty.toIntern() }),37105 0 => try pt.intern(.{ .empty_enum_value = ty.toIntern() }),
36760 1 => try zcu.intern(.{ .enum_tag = .{37106 1 => try pt.intern(.{ .enum_tag = .{
36761 .ty = ty.toIntern(),37107 .ty = ty.toIntern(),
36762 .int = if (enum_type.values.len == 0)37108 .int = if (enum_type.values.len == 0)
36763 (try zcu.intValue(Type.fromInterned(enum_type.tag_ty), 0)).toIntern()37109 (try pt.intValue(Type.fromInterned(enum_type.tag_ty), 0)).toIntern()
36764 else37110 else
36765 try zcu.intern_pool.getCoercedInts(37111 try ip.getCoercedInts(
36766 zcu.gpa,37112 zcu.gpa,
36767 zcu.intern_pool.indexToKey(enum_type.values.get(ip)[0]).int,37113 pt.tid,
37114 ip.indexToKey(enum_type.values.get(ip)[0]).int,
36768 enum_type.tag_ty,37115 enum_type.tag_ty,
36769 ),37116 ),
36770 } }),37117 } }),
...@@ -36782,7 +37129,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36782,7 +37129,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3678237129
36783/// Returns the type of the AIR instruction.37130/// Returns the type of the AIR instruction.
36784fn typeOf(sema: *Sema, inst: Air.Inst.Ref) Type {37131fn typeOf(sema: *Sema, inst: Air.Inst.Ref) Type {
36785 return sema.getTmpAir().typeOf(inst, &sema.mod.intern_pool);37132 return sema.getTmpAir().typeOf(inst, &sema.pt.zcu.intern_pool);
36786}37133}
3678737134
36788pub fn getTmpAir(sema: Sema) Air {37135pub fn getTmpAir(sema: Sema) Air {
...@@ -36838,12 +37185,13 @@ fn analyzeComptimeAlloc(...@@ -36838,12 +37185,13 @@ fn analyzeComptimeAlloc(
36838 var_type: Type,37185 var_type: Type,
36839 alignment: Alignment,37186 alignment: Alignment,
36840) CompileError!Air.Inst.Ref {37187) CompileError!Air.Inst.Ref {
36841 const mod = sema.mod;37188 const pt = sema.pt;
37189 const mod = pt.zcu;
3684237190
36843 // Needed to make an anon decl with type `var_type` (the `finish()` call below).37191 // Needed to make an anon decl with type `var_type` (the `finish()` call below).
36844 _ = try sema.typeHasOnePossibleValue(var_type);37192 _ = try sema.typeHasOnePossibleValue(var_type);
3684537193
36846 const ptr_type = try mod.ptrTypeSema(.{37194 const ptr_type = try pt.ptrTypeSema(.{
36847 .child = var_type.toIntern(),37195 .child = var_type.toIntern(),
36848 .flags = .{37196 .flags = .{
36849 .alignment = alignment,37197 .alignment = alignment,
...@@ -36853,7 +37201,7 @@ fn analyzeComptimeAlloc(...@@ -36853,7 +37201,7 @@ fn analyzeComptimeAlloc(
3685337201
36854 const alloc = try sema.newComptimeAlloc(block, var_type, alignment);37202 const alloc = try sema.newComptimeAlloc(block, var_type, alignment);
3685537203
36856 return Air.internedToRef((try mod.intern(.{ .ptr = .{37204 return Air.internedToRef((try pt.intern(.{ .ptr = .{
36857 .ty = ptr_type.toIntern(),37205 .ty = ptr_type.toIntern(),
36858 .base_addr = .{ .comptime_alloc = alloc },37206 .base_addr = .{ .comptime_alloc = alloc },
36859 .byte_offset = 0,37207 .byte_offset = 0,
...@@ -36896,13 +37244,14 @@ pub fn analyzeAsAddressSpace(...@@ -36896,13 +37244,14 @@ pub fn analyzeAsAddressSpace(
36896 air_ref: Air.Inst.Ref,37244 air_ref: Air.Inst.Ref,
36897 ctx: AddressSpaceContext,37245 ctx: AddressSpaceContext,
36898) !std.builtin.AddressSpace {37246) !std.builtin.AddressSpace {
36899 const mod = sema.mod;37247 const pt = sema.pt;
37248 const mod = pt.zcu;
36900 const coerced = try sema.coerce(block, Type.fromInterned(.address_space_type), air_ref, src);37249 const coerced = try sema.coerce(block, Type.fromInterned(.address_space_type), air_ref, src);
36901 const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{37250 const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{
36902 .needed_comptime_reason = "address space must be comptime-known",37251 .needed_comptime_reason = "address space must be comptime-known",
36903 });37252 });
36904 const address_space = mod.toEnum(std.builtin.AddressSpace, addrspace_val);37253 const address_space = mod.toEnum(std.builtin.AddressSpace, addrspace_val);
36905 const target = sema.mod.getTarget();37254 const target = pt.zcu.getTarget();
36906 const arch = target.cpu.arch;37255 const arch = target.cpu.arch;
3690737256
36908 const is_nv = arch == .nvptx or arch == .nvptx64;37257 const is_nv = arch == .nvptx or arch == .nvptx64;
...@@ -36946,7 +37295,8 @@ pub fn analyzeAsAddressSpace(...@@ -36946,7 +37295,8 @@ pub fn analyzeAsAddressSpace(
36946/// Returns `null` if the pointer contents cannot be loaded at comptime.37295/// 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 {37296fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr_ty: Type) CompileError!?Value {
36948 // TODO: audit use sites to eliminate this coercion37297 // TODO: audit use sites to eliminate this coercion
36949 const coerced_ptr_val = try sema.mod.getCoerced(ptr_val, ptr_ty);37298 const pt = sema.pt;
37299 const coerced_ptr_val = try pt.getCoerced(ptr_val, ptr_ty);
36950 switch (try sema.pointerDerefExtra(block, src, coerced_ptr_val)) {37300 switch (try sema.pointerDerefExtra(block, src, coerced_ptr_val)) {
36951 .runtime_load => return null,37301 .runtime_load => return null,
36952 .val => |v| return v,37302 .val => |v| return v,
...@@ -36954,13 +37304,13 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr...@@ -36954,13 +37304,13 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr
36954 block,37304 block,
36955 src,37305 src,
36956 "comptime dereference requires '{}' to have a well-defined layout",37306 "comptime dereference requires '{}' to have a well-defined layout",
36957 .{ty.fmt(sema.mod)},37307 .{ty.fmt(pt)},
36958 ),37308 ),
36959 .out_of_bounds => |ty| return sema.fail(37309 .out_of_bounds => |ty| return sema.fail(
36960 block,37310 block,
36961 src,37311 src,
36962 "dereference of '{}' exceeds bounds of containing decl of type '{}'",37312 "dereference of '{}' exceeds bounds of containing decl of type '{}'",
36963 .{ ptr_ty.fmt(sema.mod), ty.fmt(sema.mod) },37313 .{ ptr_ty.fmt(pt), ty.fmt(pt) },
36964 ),37314 ),
36965 }37315 }
36966}37316}
...@@ -36973,10 +37323,10 @@ const DerefResult = union(enum) {...@@ -36973,10 +37323,10 @@ const DerefResult = union(enum) {
36973};37323};
3697437324
36975fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value) CompileError!DerefResult {37325fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value) CompileError!DerefResult {
36976 const zcu = sema.mod;37326 const pt = sema.pt;
36977 const ip = &zcu.intern_pool;37327 const ip = &pt.zcu.intern_pool;
36978 switch (try sema.loadComptimePtr(block, src, ptr_val)) {37328 switch (try sema.loadComptimePtr(block, src, ptr_val)) {
36979 .success => |mv| return .{ .val = try mv.intern(zcu, sema.arena) },37329 .success => |mv| return .{ .val = try mv.intern(pt, sema.arena) },
36980 .runtime_load => return .runtime_load,37330 .runtime_load => return .runtime_load,
36981 .undef => return sema.failWithUseOfUndef(block, src),37331 .undef => return sema.failWithUseOfUndef(block, src),
36982 .err_payload => |err_name| return sema.fail(block, src, "attempt to unwrap error: {}", .{err_name.fmt(ip)}),37332 .err_payload => |err_name| return sema.fail(block, src, "attempt to unwrap error: {}", .{err_name.fmt(ip)}),
...@@ -37001,7 +37351,8 @@ fn usizeCast(sema: *Sema, block: *Block, src: LazySrcLoc, int: u64) CompileError...@@ -37001,7 +37351,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.37351/// 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`.37352/// This logic must be kept in sync with `Type.isPtrLikeOptional`.
37003fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {37353fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {
37004 const mod = sema.mod;37354 const pt = sema.pt;
37355 const mod = pt.zcu;
37005 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {37356 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {
37006 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {37357 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
37007 .One, .Many, .C => ty,37358 .One, .Many, .C => ty,
...@@ -37031,27 +37382,28 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {...@@ -37031,27 +37382,28 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {
37031/// `generic_poison` will return false.37382/// `generic_poison` will return false.
37032/// May return false negatives when structs and unions are having their field types resolved.37383/// May return false negatives when structs and unions are having their field types resolved.
37033pub fn typeRequiresComptime(sema: *Sema, ty: Type) SemaError!bool {37384pub fn typeRequiresComptime(sema: *Sema, ty: Type) SemaError!bool {
37034 return ty.comptimeOnlyAdvanced(sema.mod, .sema);37385 return ty.comptimeOnlyAdvanced(sema.pt, .sema);
37035}37386}
3703637387
37037pub fn typeHasRuntimeBits(sema: *Sema, ty: Type) SemaError!bool {37388pub fn typeHasRuntimeBits(sema: *Sema, ty: Type) SemaError!bool {
37038 return ty.hasRuntimeBitsAdvanced(sema.mod, false, .sema) catch |err| switch (err) {37389 return ty.hasRuntimeBitsAdvanced(sema.pt, false, .sema) catch |err| switch (err) {
37039 error.NeedLazy => unreachable,37390 error.NeedLazy => unreachable,
37040 else => |e| return e,37391 else => |e| return e,
37041 };37392 };
37042}37393}
3704337394
37044pub fn typeAbiSize(sema: *Sema, ty: Type) SemaError!u64 {37395pub fn typeAbiSize(sema: *Sema, ty: Type) SemaError!u64 {
37045 try ty.resolveLayout(sema.mod);37396 const pt = sema.pt;
37046 return ty.abiSize(sema.mod);37397 try ty.resolveLayout(pt);
37398 return ty.abiSize(pt);
37047}37399}
3704837400
37049pub fn typeAbiAlignment(sema: *Sema, ty: Type) SemaError!Alignment {37401pub fn typeAbiAlignment(sema: *Sema, ty: Type) SemaError!Alignment {
37050 return (try ty.abiAlignmentAdvanced(sema.mod, .sema)).scalar;37402 return (try ty.abiAlignmentAdvanced(sema.pt, .sema)).scalar;
37051}37403}
3705237404
37053pub fn fnHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool {37405pub fn fnHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool {
37054 return ty.fnHasRuntimeBitsAdvanced(sema.mod, .sema);37406 return ty.fnHasRuntimeBitsAdvanced(sema.pt, .sema);
37055}37407}
3705637408
37057fn unionFieldIndex(37409fn unionFieldIndex(
...@@ -37061,9 +37413,10 @@ fn unionFieldIndex(...@@ -37061,9 +37413,10 @@ fn unionFieldIndex(
37061 field_name: InternPool.NullTerminatedString,37413 field_name: InternPool.NullTerminatedString,
37062 field_src: LazySrcLoc,37414 field_src: LazySrcLoc,
37063) !u32 {37415) !u32 {
37064 const mod = sema.mod;37416 const pt = sema.pt;
37417 const mod = pt.zcu;
37065 const ip = &mod.intern_pool;37418 const ip = &mod.intern_pool;
37066 try union_ty.resolveFields(mod);37419 try union_ty.resolveFields(pt);
37067 const union_obj = mod.typeToUnion(union_ty).?;37420 const union_obj = mod.typeToUnion(union_ty).?;
37068 const field_index = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse37421 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);37422 return sema.failWithBadUnionFieldAccess(block, union_ty, union_obj, field_src, field_name);
...@@ -37077,9 +37430,10 @@ fn structFieldIndex(...@@ -37077,9 +37430,10 @@ fn structFieldIndex(
37077 field_name: InternPool.NullTerminatedString,37430 field_name: InternPool.NullTerminatedString,
37078 field_src: LazySrcLoc,37431 field_src: LazySrcLoc,
37079) !u32 {37432) !u32 {
37080 const mod = sema.mod;37433 const pt = sema.pt;
37434 const mod = pt.zcu;
37081 const ip = &mod.intern_pool;37435 const ip = &mod.intern_pool;
37082 try struct_ty.resolveFields(mod);37436 try struct_ty.resolveFields(pt);
37083 if (struct_ty.isAnonStruct(mod)) {37437 if (struct_ty.isAnonStruct(mod)) {
37084 return sema.anonStructFieldIndex(block, struct_ty, field_name, field_src);37438 return sema.anonStructFieldIndex(block, struct_ty, field_name, field_src);
37085 } else {37439 } else {
...@@ -37096,7 +37450,8 @@ fn anonStructFieldIndex(...@@ -37096,7 +37450,8 @@ fn anonStructFieldIndex(
37096 field_name: InternPool.NullTerminatedString,37450 field_name: InternPool.NullTerminatedString,
37097 field_src: LazySrcLoc,37451 field_src: LazySrcLoc,
37098) !u32 {37452) !u32 {
37099 const mod = sema.mod;37453 const pt = sema.pt;
37454 const mod = pt.zcu;
37100 const ip = &mod.intern_pool;37455 const ip = &mod.intern_pool;
37101 switch (ip.indexToKey(struct_ty.toIntern())) {37456 switch (ip.indexToKey(struct_ty.toIntern())) {
37102 .anon_struct_type => |anon_struct_type| for (anon_struct_type.names.get(ip), 0..) |name, i| {37457 .anon_struct_type => |anon_struct_type| for (anon_struct_type.names.get(ip), 0..) |name, i| {
...@@ -37106,20 +37461,21 @@ fn anonStructFieldIndex(...@@ -37106,20 +37461,21 @@ fn anonStructFieldIndex(
37106 else => unreachable,37461 else => unreachable,
37107 }37462 }
37108 return sema.fail(block, field_src, "no field named '{}' in anonymous struct '{}'", .{37463 return sema.fail(block, field_src, "no field named '{}' in anonymous struct '{}'", .{
37109 field_name.fmt(ip), struct_ty.fmt(sema.mod),37464 field_name.fmt(ip), struct_ty.fmt(pt),
37110 });37465 });
37111}37466}
3711237467
37113/// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting37468/// 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).37469/// 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 {37470fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize) !Value {
37471 const pt = sema.pt;
37116 var overflow: usize = undefined;37472 var overflow: usize = undefined;
37117 return sema.intAddInner(lhs, rhs, ty, &overflow) catch |err| switch (err) {37473 return sema.intAddInner(lhs, rhs, ty, &overflow) catch |err| switch (err) {
37118 error.Overflow => {37474 error.Overflow => {
37119 const is_vec = ty.isVector(sema.mod);37475 const is_vec = ty.isVector(pt.zcu);
37120 overflow_idx.* = if (is_vec) overflow else 0;37476 overflow_idx.* = if (is_vec) overflow else 0;
37121 const safe_ty = if (is_vec) try sema.mod.vectorType(.{37477 const safe_ty = if (is_vec) try pt.vectorType(.{
37122 .len = ty.vectorLen(sema.mod),37478 .len = ty.vectorLen(pt.zcu),
37123 .child = .comptime_int_type,37479 .child = .comptime_int_type,
37124 }) else Type.comptime_int;37480 }) else Type.comptime_int;
37125 return sema.intAddInner(lhs, rhs, safe_ty, undefined) catch |err1| switch (err1) {37481 return sema.intAddInner(lhs, rhs, safe_ty, undefined) catch |err1| switch (err1) {
...@@ -37132,13 +37488,14 @@ fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize)...@@ -37132,13 +37488,14 @@ fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize)
37132}37488}
3713337489
37134fn intAddInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize) !Value {37490fn intAddInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize) !Value {
37135 const mod = sema.mod;37491 const pt = sema.pt;
37492 const mod = pt.zcu;
37136 if (ty.zigTypeTag(mod) == .Vector) {37493 if (ty.zigTypeTag(mod) == .Vector) {
37137 const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod));37494 const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod));
37138 const scalar_ty = ty.scalarType(mod);37495 const scalar_ty = ty.scalarType(mod);
37139 for (result_data, 0..) |*scalar, i| {37496 for (result_data, 0..) |*scalar, i| {
37140 const lhs_elem = try lhs.elemValue(mod, i);37497 const lhs_elem = try lhs.elemValue(pt, i);
37141 const rhs_elem = try rhs.elemValue(mod, i);37498 const rhs_elem = try rhs.elemValue(pt, i);
37142 const val = sema.intAddScalar(lhs_elem, rhs_elem, scalar_ty) catch |err| switch (err) {37499 const val = sema.intAddScalar(lhs_elem, rhs_elem, scalar_ty) catch |err| switch (err) {
37143 error.Overflow => {37500 error.Overflow => {
37144 overflow_idx.* = i;37501 overflow_idx.* = i;
...@@ -37148,34 +37505,34 @@ fn intAddInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi...@@ -37148,34 +37505,34 @@ fn intAddInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi
37148 };37505 };
37149 scalar.* = val.toIntern();37506 scalar.* = val.toIntern();
37150 }37507 }
37151 return Value.fromInterned((try mod.intern(.{ .aggregate = .{37508 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
37152 .ty = ty.toIntern(),37509 .ty = ty.toIntern(),
37153 .storage = .{ .elems = result_data },37510 .storage = .{ .elems = result_data },
37154 } })));37511 } }));
37155 }37512 }
37156 return sema.intAddScalar(lhs, rhs, ty);37513 return sema.intAddScalar(lhs, rhs, ty);
37157}37514}
3715837515
37159fn intAddScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) !Value {37516fn intAddScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) !Value {
37160 const mod = sema.mod;37517 const pt = sema.pt;
37161 if (scalar_ty.toIntern() != .comptime_int_type) {37518 if (scalar_ty.toIntern() != .comptime_int_type) {
37162 const res = try sema.intAddWithOverflowScalar(lhs, rhs, scalar_ty);37519 const res = try sema.intAddWithOverflowScalar(lhs, rhs, scalar_ty);
37163 if (res.overflow_bit.compareAllWithZero(.neq, mod)) return error.Overflow;37520 if (res.overflow_bit.compareAllWithZero(.neq, pt)) return error.Overflow;
37164 return res.wrapped_result;37521 return res.wrapped_result;
37165 }37522 }
37166 // TODO is this a performance issue? maybe we should try the operation without37523 // TODO is this a performance issue? maybe we should try the operation without
37167 // resorting to BigInt first.37524 // resorting to BigInt first.
37168 var lhs_space: Value.BigIntSpace = undefined;37525 var lhs_space: Value.BigIntSpace = undefined;
37169 var rhs_space: Value.BigIntSpace = undefined;37526 var rhs_space: Value.BigIntSpace = undefined;
37170 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema);37527 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, pt, .sema);
37171 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema);37528 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, pt, .sema);
37172 const limbs = try sema.arena.alloc(37529 const limbs = try sema.arena.alloc(
37173 std.math.big.Limb,37530 std.math.big.Limb,
37174 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,37531 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,
37175 );37532 );
37176 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };37533 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
37177 result_bigint.add(lhs_bigint, rhs_bigint);37534 result_bigint.add(lhs_bigint, rhs_bigint);
37178 return mod.intValue_big(scalar_ty, result_bigint.toConst());37535 return pt.intValue_big(scalar_ty, result_bigint.toConst());
37179}37536}
3718037537
37181/// Supports both floats and ints; handles undefined.37538/// Supports both floats and ints; handles undefined.
...@@ -37185,15 +37542,16 @@ fn numberAddWrapScalar(...@@ -37185,15 +37542,16 @@ fn numberAddWrapScalar(
37185 rhs: Value,37542 rhs: Value,
37186 ty: Type,37543 ty: Type,
37187) !Value {37544) !Value {
37188 const mod = sema.mod;37545 const pt = sema.pt;
37189 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return mod.undefValue(ty);37546 const mod = pt.zcu;
37547 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return pt.undefValue(ty);
3719037548
37191 if (ty.zigTypeTag(mod) == .ComptimeInt) {37549 if (ty.zigTypeTag(mod) == .ComptimeInt) {
37192 return sema.intAdd(lhs, rhs, ty, undefined);37550 return sema.intAdd(lhs, rhs, ty, undefined);
37193 }37551 }
3719437552
37195 if (ty.isAnyFloat()) {37553 if (ty.isAnyFloat()) {
37196 return Value.floatAdd(lhs, rhs, ty, sema.arena, mod);37554 return Value.floatAdd(lhs, rhs, ty, sema.arena, pt);
37197 }37555 }
3719837556
37199 const overflow_result = try sema.intAddWithOverflow(lhs, rhs, ty);37557 const overflow_result = try sema.intAddWithOverflow(lhs, rhs, ty);
...@@ -37203,13 +37561,14 @@ fn numberAddWrapScalar(...@@ -37203,13 +37561,14 @@ fn numberAddWrapScalar(
37203/// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting37561/// 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).37562/// 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 {37563fn intSub(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize) !Value {
37564 const pt = sema.pt;
37206 var overflow: usize = undefined;37565 var overflow: usize = undefined;
37207 return sema.intSubInner(lhs, rhs, ty, &overflow) catch |err| switch (err) {37566 return sema.intSubInner(lhs, rhs, ty, &overflow) catch |err| switch (err) {
37208 error.Overflow => {37567 error.Overflow => {
37209 const is_vec = ty.isVector(sema.mod);37568 const is_vec = ty.isVector(pt.zcu);
37210 overflow_idx.* = if (is_vec) overflow else 0;37569 overflow_idx.* = if (is_vec) overflow else 0;
37211 const safe_ty = if (is_vec) try sema.mod.vectorType(.{37570 const safe_ty = if (is_vec) try pt.vectorType(.{
37212 .len = ty.vectorLen(sema.mod),37571 .len = ty.vectorLen(pt.zcu),
37213 .child = .comptime_int_type,37572 .child = .comptime_int_type,
37214 }) else Type.comptime_int;37573 }) else Type.comptime_int;
37215 return sema.intSubInner(lhs, rhs, safe_ty, undefined) catch |err1| switch (err1) {37574 return sema.intSubInner(lhs, rhs, safe_ty, undefined) catch |err1| switch (err1) {
...@@ -37222,13 +37581,13 @@ fn intSub(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize)...@@ -37222,13 +37581,13 @@ fn intSub(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize)
37222}37581}
3722337582
37224fn intSubInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize) !Value {37583fn intSubInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize) !Value {
37225 const mod = sema.mod;37584 const pt = sema.pt;
37226 if (ty.zigTypeTag(mod) == .Vector) {37585 if (ty.zigTypeTag(pt.zcu) == .Vector) {
37227 const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod));37586 const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
37228 const scalar_ty = ty.scalarType(mod);37587 const scalar_ty = ty.scalarType(pt.zcu);
37229 for (result_data, 0..) |*scalar, i| {37588 for (result_data, 0..) |*scalar, i| {
37230 const lhs_elem = try lhs.elemValue(sema.mod, i);37589 const lhs_elem = try lhs.elemValue(pt, i);
37231 const rhs_elem = try rhs.elemValue(sema.mod, i);37590 const rhs_elem = try rhs.elemValue(pt, i);
37232 const val = sema.intSubScalar(lhs_elem, rhs_elem, scalar_ty) catch |err| switch (err) {37591 const val = sema.intSubScalar(lhs_elem, rhs_elem, scalar_ty) catch |err| switch (err) {
37233 error.Overflow => {37592 error.Overflow => {
37234 overflow_idx.* = i;37593 overflow_idx.* = i;
...@@ -37238,34 +37597,34 @@ fn intSubInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi...@@ -37238,34 +37597,34 @@ fn intSubInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi
37238 };37597 };
37239 scalar.* = val.toIntern();37598 scalar.* = val.toIntern();
37240 }37599 }
37241 return Value.fromInterned((try mod.intern(.{ .aggregate = .{37600 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
37242 .ty = ty.toIntern(),37601 .ty = ty.toIntern(),
37243 .storage = .{ .elems = result_data },37602 .storage = .{ .elems = result_data },
37244 } })));37603 } }));
37245 }37604 }
37246 return sema.intSubScalar(lhs, rhs, ty);37605 return sema.intSubScalar(lhs, rhs, ty);
37247}37606}
3724837607
37249fn intSubScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) !Value {37608fn intSubScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) !Value {
37250 const mod = sema.mod;37609 const pt = sema.pt;
37251 if (scalar_ty.toIntern() != .comptime_int_type) {37610 if (scalar_ty.toIntern() != .comptime_int_type) {
37252 const res = try sema.intSubWithOverflowScalar(lhs, rhs, scalar_ty);37611 const res = try sema.intSubWithOverflowScalar(lhs, rhs, scalar_ty);
37253 if (res.overflow_bit.compareAllWithZero(.neq, mod)) return error.Overflow;37612 if (res.overflow_bit.compareAllWithZero(.neq, pt)) return error.Overflow;
37254 return res.wrapped_result;37613 return res.wrapped_result;
37255 }37614 }
37256 // TODO is this a performance issue? maybe we should try the operation without37615 // TODO is this a performance issue? maybe we should try the operation without
37257 // resorting to BigInt first.37616 // resorting to BigInt first.
37258 var lhs_space: Value.BigIntSpace = undefined;37617 var lhs_space: Value.BigIntSpace = undefined;
37259 var rhs_space: Value.BigIntSpace = undefined;37618 var rhs_space: Value.BigIntSpace = undefined;
37260 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema);37619 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, pt, .sema);
37261 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema);37620 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, pt, .sema);
37262 const limbs = try sema.arena.alloc(37621 const limbs = try sema.arena.alloc(
37263 std.math.big.Limb,37622 std.math.big.Limb,
37264 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,37623 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,
37265 );37624 );
37266 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };37625 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
37267 result_bigint.sub(lhs_bigint, rhs_bigint);37626 result_bigint.sub(lhs_bigint, rhs_bigint);
37268 return mod.intValue_big(scalar_ty, result_bigint.toConst());37627 return pt.intValue_big(scalar_ty, result_bigint.toConst());
37269}37628}
3727037629
37271/// Supports both floats and ints; handles undefined.37630/// Supports both floats and ints; handles undefined.
...@@ -37275,15 +37634,16 @@ fn numberSubWrapScalar(...@@ -37275,15 +37634,16 @@ fn numberSubWrapScalar(
37275 rhs: Value,37634 rhs: Value,
37276 ty: Type,37635 ty: Type,
37277) !Value {37636) !Value {
37278 const mod = sema.mod;37637 const pt = sema.pt;
37279 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return mod.undefValue(ty);37638 const mod = pt.zcu;
37639 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return pt.undefValue(ty);
3728037640
37281 if (ty.zigTypeTag(mod) == .ComptimeInt) {37641 if (ty.zigTypeTag(mod) == .ComptimeInt) {
37282 return sema.intSub(lhs, rhs, ty, undefined);37642 return sema.intSub(lhs, rhs, ty, undefined);
37283 }37643 }
3728437644
37285 if (ty.isAnyFloat()) {37645 if (ty.isAnyFloat()) {
37286 return Value.floatSub(lhs, rhs, ty, sema.arena, mod);37646 return Value.floatSub(lhs, rhs, ty, sema.arena, pt);
37287 }37647 }
3728837648
37289 const overflow_result = try sema.intSubWithOverflow(lhs, rhs, ty);37649 const overflow_result = try sema.intSubWithOverflow(lhs, rhs, ty);
...@@ -37296,28 +37656,29 @@ fn intSubWithOverflow(...@@ -37296,28 +37656,29 @@ fn intSubWithOverflow(
37296 rhs: Value,37656 rhs: Value,
37297 ty: Type,37657 ty: Type,
37298) !Value.OverflowArithmeticResult {37658) !Value.OverflowArithmeticResult {
37299 const mod = sema.mod;37659 const pt = sema.pt;
37660 const mod = pt.zcu;
37300 if (ty.zigTypeTag(mod) == .Vector) {37661 if (ty.zigTypeTag(mod) == .Vector) {
37301 const vec_len = ty.vectorLen(mod);37662 const vec_len = ty.vectorLen(mod);
37302 const overflowed_data = try sema.arena.alloc(InternPool.Index, vec_len);37663 const overflowed_data = try sema.arena.alloc(InternPool.Index, vec_len);
37303 const result_data = try sema.arena.alloc(InternPool.Index, vec_len);37664 const result_data = try sema.arena.alloc(InternPool.Index, vec_len);
37304 const scalar_ty = ty.scalarType(mod);37665 const scalar_ty = ty.scalarType(mod);
37305 for (overflowed_data, result_data, 0..) |*of, *scalar, i| {37666 for (overflowed_data, result_data, 0..) |*of, *scalar, i| {
37306 const lhs_elem = try lhs.elemValue(sema.mod, i);37667 const lhs_elem = try lhs.elemValue(pt, i);
37307 const rhs_elem = try rhs.elemValue(sema.mod, i);37668 const rhs_elem = try rhs.elemValue(pt, i);
37308 const of_math_result = try sema.intSubWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty);37669 const of_math_result = try sema.intSubWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty);
37309 of.* = of_math_result.overflow_bit.toIntern();37670 of.* = of_math_result.overflow_bit.toIntern();
37310 scalar.* = of_math_result.wrapped_result.toIntern();37671 scalar.* = of_math_result.wrapped_result.toIntern();
37311 }37672 }
37312 return Value.OverflowArithmeticResult{37673 return Value.OverflowArithmeticResult{
37313 .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{37674 .overflow_bit = Value.fromInterned(try pt.intern(.{ .aggregate = .{
37314 .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),37675 .ty = (try pt.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),
37315 .storage = .{ .elems = overflowed_data },37676 .storage = .{ .elems = overflowed_data },
37316 } }))),37677 } })),
37317 .wrapped_result = Value.fromInterned((try mod.intern(.{ .aggregate = .{37678 .wrapped_result = Value.fromInterned(try pt.intern(.{ .aggregate = .{
37318 .ty = ty.toIntern(),37679 .ty = ty.toIntern(),
37319 .storage = .{ .elems = result_data },37680 .storage = .{ .elems = result_data },
37320 } }))),37681 } })),
37321 };37682 };
37322 }37683 }
37323 return sema.intSubWithOverflowScalar(lhs, rhs, ty);37684 return sema.intSubWithOverflowScalar(lhs, rhs, ty);
...@@ -37329,29 +37690,30 @@ fn intSubWithOverflowScalar(...@@ -37329,29 +37690,30 @@ fn intSubWithOverflowScalar(
37329 rhs: Value,37690 rhs: Value,
37330 ty: Type,37691 ty: Type,
37331) !Value.OverflowArithmeticResult {37692) !Value.OverflowArithmeticResult {
37332 const mod = sema.mod;37693 const pt = sema.pt;
37694 const mod = pt.zcu;
37333 const info = ty.intInfo(mod);37695 const info = ty.intInfo(mod);
3733437696
37335 if (lhs.isUndef(mod) or rhs.isUndef(mod)) {37697 if (lhs.isUndef(mod) or rhs.isUndef(mod)) {
37336 return .{37698 return .{
37337 .overflow_bit = try mod.undefValue(Type.u1),37699 .overflow_bit = try pt.undefValue(Type.u1),
37338 .wrapped_result = try mod.undefValue(ty),37700 .wrapped_result = try pt.undefValue(ty),
37339 };37701 };
37340 }37702 }
3734137703
37342 var lhs_space: Value.BigIntSpace = undefined;37704 var lhs_space: Value.BigIntSpace = undefined;
37343 var rhs_space: Value.BigIntSpace = undefined;37705 var rhs_space: Value.BigIntSpace = undefined;
37344 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema);37706 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, pt, .sema);
37345 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema);37707 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, pt, .sema);
37346 const limbs = try sema.arena.alloc(37708 const limbs = try sema.arena.alloc(
37347 std.math.big.Limb,37709 std.math.big.Limb,
37348 std.math.big.int.calcTwosCompLimbCount(info.bits),37710 std.math.big.int.calcTwosCompLimbCount(info.bits),
37349 );37711 );
37350 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };37712 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);37713 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());37714 const wrapped_result = try pt.intValue_big(ty, result_bigint.toConst());
37353 return Value.OverflowArithmeticResult{37715 return Value.OverflowArithmeticResult{
37354 .overflow_bit = try mod.intValue(Type.u1, @intFromBool(overflowed)),37716 .overflow_bit = try pt.intValue(Type.u1, @intFromBool(overflowed)),
37355 .wrapped_result = wrapped_result,37717 .wrapped_result = wrapped_result,
37356 };37718 };
37357}37719}
...@@ -37367,17 +37729,18 @@ fn intFromFloat(...@@ -37367,17 +37729,18 @@ fn intFromFloat(
37367 int_ty: Type,37729 int_ty: Type,
37368 mode: IntFromFloatMode,37730 mode: IntFromFloatMode,
37369) CompileError!Value {37731) CompileError!Value {
37370 const mod = sema.mod;37732 const pt = sema.pt;
37733 const mod = pt.zcu;
37371 if (float_ty.zigTypeTag(mod) == .Vector) {37734 if (float_ty.zigTypeTag(mod) == .Vector) {
37372 const result_data = try sema.arena.alloc(InternPool.Index, float_ty.vectorLen(mod));37735 const result_data = try sema.arena.alloc(InternPool.Index, float_ty.vectorLen(mod));
37373 for (result_data, 0..) |*scalar, i| {37736 for (result_data, 0..) |*scalar, i| {
37374 const elem_val = try val.elemValue(sema.mod, i);37737 const elem_val = try val.elemValue(pt, i);
37375 scalar.* = (try sema.intFromFloatScalar(block, src, elem_val, int_ty.scalarType(mod), mode)).toIntern();37738 scalar.* = (try sema.intFromFloatScalar(block, src, elem_val, int_ty.scalarType(mod), mode)).toIntern();
37376 }37739 }
37377 return Value.fromInterned((try mod.intern(.{ .aggregate = .{37740 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
37378 .ty = int_ty.toIntern(),37741 .ty = int_ty.toIntern(),
37379 .storage = .{ .elems = result_data },37742 .storage = .{ .elems = result_data },
37380 } })));37743 } }));
37381 }37744 }
37382 return sema.intFromFloatScalar(block, src, val, int_ty, mode);37745 return sema.intFromFloatScalar(block, src, val, int_ty, mode);
37383}37746}
...@@ -37415,7 +37778,8 @@ fn intFromFloatScalar(...@@ -37415,7 +37778,8 @@ fn intFromFloatScalar(
37415 int_ty: Type,37778 int_ty: Type,
37416 mode: IntFromFloatMode,37779 mode: IntFromFloatMode,
37417) CompileError!Value {37780) CompileError!Value {
37418 const mod = sema.mod;37781 const pt = sema.pt;
37782 const mod = pt.zcu;
3741937783
37420 if (val.isUndef(mod)) return sema.failWithUseOfUndef(block, src);37784 if (val.isUndef(mod)) return sema.failWithUseOfUndef(block, src);
3742137785
...@@ -37423,32 +37787,32 @@ fn intFromFloatScalar(...@@ -37423,32 +37787,32 @@ fn intFromFloatScalar(
37423 block,37787 block,
37424 src,37788 src,
37425 "fractional component prevents float value '{}' from coercion to type '{}'",37789 "fractional component prevents float value '{}' from coercion to type '{}'",
37426 .{ val.fmtValue(mod, sema), int_ty.fmt(mod) },37790 .{ val.fmtValue(pt, sema), int_ty.fmt(pt) },
37427 );37791 );
3742837792
37429 const float = val.toFloat(f128, mod);37793 const float = val.toFloat(f128, pt);
37430 if (std.math.isNan(float)) {37794 if (std.math.isNan(float)) {
37431 return sema.fail(block, src, "float value NaN cannot be stored in integer type '{}'", .{37795 return sema.fail(block, src, "float value NaN cannot be stored in integer type '{}'", .{
37432 int_ty.fmt(sema.mod),37796 int_ty.fmt(pt),
37433 });37797 });
37434 }37798 }
37435 if (std.math.isInf(float)) {37799 if (std.math.isInf(float)) {
37436 return sema.fail(block, src, "float value Inf cannot be stored in integer type '{}'", .{37800 return sema.fail(block, src, "float value Inf cannot be stored in integer type '{}'", .{
37437 int_ty.fmt(sema.mod),37801 int_ty.fmt(pt),
37438 });37802 });
37439 }37803 }
3744037804
37441 var big_int = try float128IntPartToBigInt(sema.arena, float);37805 var big_int = try float128IntPartToBigInt(sema.arena, float);
37442 defer big_int.deinit();37806 defer big_int.deinit();
3744337807
37444 const cti_result = try mod.intValue_big(Type.comptime_int, big_int.toConst());37808 const cti_result = try pt.intValue_big(Type.comptime_int, big_int.toConst());
3744537809
37446 if (!(try sema.intFitsInType(cti_result, int_ty, null))) {37810 if (!(try sema.intFitsInType(cti_result, int_ty, null))) {
37447 return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{37811 return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{
37448 val.fmtValue(sema.mod, sema), int_ty.fmt(sema.mod),37812 val.fmtValue(pt, sema), int_ty.fmt(pt),
37449 });37813 });
37450 }37814 }
37451 return mod.getCoerced(cti_result, int_ty);37815 return pt.getCoerced(cti_result, int_ty);
37452}37816}
3745337817
37454/// Asserts the value is an integer, and the destination type is ComptimeInt or Int.37818/// Asserts the value is an integer, and the destination type is ComptimeInt or Int.
...@@ -37461,7 +37825,8 @@ fn intFitsInType(...@@ -37461,7 +37825,8 @@ fn intFitsInType(
37461 ty: Type,37825 ty: Type,
37462 vector_index: ?*usize,37826 vector_index: ?*usize,
37463) CompileError!bool {37827) CompileError!bool {
37464 const mod = sema.mod;37828 const pt = sema.pt;
37829 const mod = pt.zcu;
37465 if (ty.toIntern() == .comptime_int_type) return true;37830 if (ty.toIntern() == .comptime_int_type) return true;
37466 const info = ty.intInfo(mod);37831 const info = ty.intInfo(mod);
37467 switch (val.toIntern()) {37832 switch (val.toIntern()) {
...@@ -37528,22 +37893,23 @@ fn intFitsInType(...@@ -37528,22 +37893,23 @@ fn intFitsInType(
37528}37893}
3752937894
37530fn intInRange(sema: *Sema, tag_ty: Type, int_val: Value, end: usize) !bool {37895fn intInRange(sema: *Sema, tag_ty: Type, int_val: Value, end: usize) !bool {
37531 const mod = sema.mod;37896 const pt = sema.pt;
37532 if (!(try int_val.compareAllWithZeroSema(.gte, mod))) return false;37897 if (!(try int_val.compareAllWithZeroSema(.gte, pt))) return false;
37533 const end_val = try mod.intValue(tag_ty, end);37898 const end_val = try pt.intValue(tag_ty, end);
37534 if (!(try sema.compareAll(int_val, .lt, end_val, tag_ty))) return false;37899 if (!(try sema.compareAll(int_val, .lt, end_val, tag_ty))) return false;
37535 return true;37900 return true;
37536}37901}
3753737902
37538/// Asserts the type is an enum.37903/// Asserts the type is an enum.
37539fn enumHasInt(sema: *Sema, ty: Type, int: Value) CompileError!bool {37904fn enumHasInt(sema: *Sema, ty: Type, int: Value) CompileError!bool {
37540 const mod = sema.mod;37905 const pt = sema.pt;
37906 const mod = pt.zcu;
37541 const enum_type = mod.intern_pool.loadEnumType(ty.toIntern());37907 const enum_type = mod.intern_pool.loadEnumType(ty.toIntern());
37542 assert(enum_type.tag_mode != .nonexhaustive);37908 assert(enum_type.tag_mode != .nonexhaustive);
37543 // The `tagValueIndex` function call below relies on the type being the integer tag type.37909 // The `tagValueIndex` function call below relies on the type being the integer tag type.
37544 // `getCoerced` assumes the value will fit the new type.37910 // `getCoerced` assumes the value will fit the new type.
37545 if (!(try sema.intFitsInType(int, Type.fromInterned(enum_type.tag_ty), null))) return false;37911 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));37912 const int_coerced = try pt.getCoerced(int, Type.fromInterned(enum_type.tag_ty));
3754737913
37548 return enum_type.tagValueIndex(&mod.intern_pool, int_coerced.toIntern()) != null;37914 return enum_type.tagValueIndex(&mod.intern_pool, int_coerced.toIntern()) != null;
37549}37915}
...@@ -37554,28 +37920,29 @@ fn intAddWithOverflow(...@@ -37554,28 +37920,29 @@ fn intAddWithOverflow(
37554 rhs: Value,37920 rhs: Value,
37555 ty: Type,37921 ty: Type,
37556) !Value.OverflowArithmeticResult {37922) !Value.OverflowArithmeticResult {
37557 const mod = sema.mod;37923 const pt = sema.pt;
37924 const mod = pt.zcu;
37558 if (ty.zigTypeTag(mod) == .Vector) {37925 if (ty.zigTypeTag(mod) == .Vector) {
37559 const vec_len = ty.vectorLen(mod);37926 const vec_len = ty.vectorLen(mod);
37560 const overflowed_data = try sema.arena.alloc(InternPool.Index, vec_len);37927 const overflowed_data = try sema.arena.alloc(InternPool.Index, vec_len);
37561 const result_data = try sema.arena.alloc(InternPool.Index, vec_len);37928 const result_data = try sema.arena.alloc(InternPool.Index, vec_len);
37562 const scalar_ty = ty.scalarType(mod);37929 const scalar_ty = ty.scalarType(mod);
37563 for (overflowed_data, result_data, 0..) |*of, *scalar, i| {37930 for (overflowed_data, result_data, 0..) |*of, *scalar, i| {
37564 const lhs_elem = try lhs.elemValue(sema.mod, i);37931 const lhs_elem = try lhs.elemValue(pt, i);
37565 const rhs_elem = try rhs.elemValue(sema.mod, i);37932 const rhs_elem = try rhs.elemValue(pt, i);
37566 const of_math_result = try sema.intAddWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty);37933 const of_math_result = try sema.intAddWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty);
37567 of.* = of_math_result.overflow_bit.toIntern();37934 of.* = of_math_result.overflow_bit.toIntern();
37568 scalar.* = of_math_result.wrapped_result.toIntern();37935 scalar.* = of_math_result.wrapped_result.toIntern();
37569 }37936 }
37570 return Value.OverflowArithmeticResult{37937 return Value.OverflowArithmeticResult{
37571 .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{37938 .overflow_bit = Value.fromInterned(try pt.intern(.{ .aggregate = .{
37572 .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),37939 .ty = (try pt.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),
37573 .storage = .{ .elems = overflowed_data },37940 .storage = .{ .elems = overflowed_data },
37574 } }))),37941 } })),
37575 .wrapped_result = Value.fromInterned((try mod.intern(.{ .aggregate = .{37942 .wrapped_result = Value.fromInterned(try pt.intern(.{ .aggregate = .{
37576 .ty = ty.toIntern(),37943 .ty = ty.toIntern(),
37577 .storage = .{ .elems = result_data },37944 .storage = .{ .elems = result_data },
37578 } }))),37945 } })),
37579 };37946 };
37580 }37947 }
37581 return sema.intAddWithOverflowScalar(lhs, rhs, ty);37948 return sema.intAddWithOverflowScalar(lhs, rhs, ty);
...@@ -37587,29 +37954,30 @@ fn intAddWithOverflowScalar(...@@ -37587,29 +37954,30 @@ fn intAddWithOverflowScalar(
37587 rhs: Value,37954 rhs: Value,
37588 ty: Type,37955 ty: Type,
37589) !Value.OverflowArithmeticResult {37956) !Value.OverflowArithmeticResult {
37590 const mod = sema.mod;37957 const pt = sema.pt;
37958 const mod = pt.zcu;
37591 const info = ty.intInfo(mod);37959 const info = ty.intInfo(mod);
3759237960
37593 if (lhs.isUndef(mod) or rhs.isUndef(mod)) {37961 if (lhs.isUndef(mod) or rhs.isUndef(mod)) {
37594 return .{37962 return .{
37595 .overflow_bit = try mod.undefValue(Type.u1),37963 .overflow_bit = try pt.undefValue(Type.u1),
37596 .wrapped_result = try mod.undefValue(ty),37964 .wrapped_result = try pt.undefValue(ty),
37597 };37965 };
37598 }37966 }
3759937967
37600 var lhs_space: Value.BigIntSpace = undefined;37968 var lhs_space: Value.BigIntSpace = undefined;
37601 var rhs_space: Value.BigIntSpace = undefined;37969 var rhs_space: Value.BigIntSpace = undefined;
37602 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema);37970 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, pt, .sema);
37603 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema);37971 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, pt, .sema);
37604 const limbs = try sema.arena.alloc(37972 const limbs = try sema.arena.alloc(
37605 std.math.big.Limb,37973 std.math.big.Limb,
37606 std.math.big.int.calcTwosCompLimbCount(info.bits),37974 std.math.big.int.calcTwosCompLimbCount(info.bits),
37607 );37975 );
37608 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };37976 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);37977 const overflowed = result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits);
37610 const result = try mod.intValue_big(ty, result_bigint.toConst());37978 const result = try pt.intValue_big(ty, result_bigint.toConst());
37611 return Value.OverflowArithmeticResult{37979 return Value.OverflowArithmeticResult{
37612 .overflow_bit = try mod.intValue(Type.u1, @intFromBool(overflowed)),37980 .overflow_bit = try pt.intValue(Type.u1, @intFromBool(overflowed)),
37613 .wrapped_result = result,37981 .wrapped_result = result,
37614 };37982 };
37615}37983}
...@@ -37625,12 +37993,13 @@ fn compareAll(...@@ -37625,12 +37993,13 @@ fn compareAll(
37625 rhs: Value,37993 rhs: Value,
37626 ty: Type,37994 ty: Type,
37627) CompileError!bool {37995) CompileError!bool {
37628 const mod = sema.mod;37996 const pt = sema.pt;
37997 const mod = pt.zcu;
37629 if (ty.zigTypeTag(mod) == .Vector) {37998 if (ty.zigTypeTag(mod) == .Vector) {
37630 var i: usize = 0;37999 var i: usize = 0;
37631 while (i < ty.vectorLen(mod)) : (i += 1) {38000 while (i < ty.vectorLen(mod)) : (i += 1) {
37632 const lhs_elem = try lhs.elemValue(sema.mod, i);38001 const lhs_elem = try lhs.elemValue(pt, i);
37633 const rhs_elem = try rhs.elemValue(sema.mod, i);38002 const rhs_elem = try rhs.elemValue(pt, i);
37634 if (!(try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod)))) {38003 if (!(try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod)))) {
37635 return false;38004 return false;
37636 }38005 }
...@@ -37648,13 +38017,13 @@ fn compareScalar(...@@ -37648,13 +38017,13 @@ fn compareScalar(
37648 rhs: Value,38017 rhs: Value,
37649 ty: Type,38018 ty: Type,
37650) CompileError!bool {38019) CompileError!bool {
37651 const mod = sema.mod;38020 const pt = sema.pt;
37652 const coerced_lhs = try mod.getCoerced(lhs, ty);38021 const coerced_lhs = try pt.getCoerced(lhs, ty);
37653 const coerced_rhs = try mod.getCoerced(rhs, ty);38022 const coerced_rhs = try pt.getCoerced(rhs, ty);
37654 switch (op) {38023 switch (op) {
37655 .eq => return sema.valuesEqual(coerced_lhs, coerced_rhs, ty),38024 .eq => return sema.valuesEqual(coerced_lhs, coerced_rhs, ty),
37656 .neq => return !(try sema.valuesEqual(coerced_lhs, coerced_rhs, ty)),38025 .neq => return !(try sema.valuesEqual(coerced_lhs, coerced_rhs, ty)),
37657 else => return Value.compareHeteroAdvanced(coerced_lhs, op, coerced_rhs, mod, .sema),38026 else => return Value.compareHeteroAdvanced(coerced_lhs, op, coerced_rhs, pt, .sema),
37658 }38027 }
37659}38028}
3766038029
...@@ -37664,7 +38033,7 @@ fn valuesEqual(...@@ -37664,7 +38033,7 @@ fn valuesEqual(
37664 rhs: Value,38033 rhs: Value,
37665 ty: Type,38034 ty: Type,
37666) CompileError!bool {38035) CompileError!bool {
37667 return lhs.eql(rhs, ty, sema.mod);38036 return lhs.eql(rhs, ty, sema.pt.zcu);
37668}38037}
3766938038
37670/// Asserts the values are comparable vectors of type `ty`.38039/// Asserts the values are comparable vectors of type `ty`.
...@@ -37675,29 +38044,30 @@ fn compareVector(...@@ -37675,29 +38044,30 @@ fn compareVector(
37675 rhs: Value,38044 rhs: Value,
37676 ty: Type,38045 ty: Type,
37677) !Value {38046) !Value {
37678 const mod = sema.mod;38047 const pt = sema.pt;
38048 const mod = pt.zcu;
37679 assert(ty.zigTypeTag(mod) == .Vector);38049 assert(ty.zigTypeTag(mod) == .Vector);
37680 const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod));38050 const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod));
37681 for (result_data, 0..) |*scalar, i| {38051 for (result_data, 0..) |*scalar, i| {
37682 const lhs_elem = try lhs.elemValue(sema.mod, i);38052 const lhs_elem = try lhs.elemValue(pt, i);
37683 const rhs_elem = try rhs.elemValue(sema.mod, i);38053 const rhs_elem = try rhs.elemValue(pt, i);
37684 const res_bool = try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod));38054 const res_bool = try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod));
37685 scalar.* = Value.makeBool(res_bool).toIntern();38055 scalar.* = Value.makeBool(res_bool).toIntern();
37686 }38056 }
37687 return Value.fromInterned((try mod.intern(.{ .aggregate = .{38057 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
37688 .ty = (try mod.vectorType(.{ .len = ty.vectorLen(mod), .child = .bool_type })).toIntern(),38058 .ty = (try pt.vectorType(.{ .len = ty.vectorLen(mod), .child = .bool_type })).toIntern(),
37689 .storage = .{ .elems = result_data },38059 .storage = .{ .elems = result_data },
37690 } })));38060 } }));
37691}38061}
3769238062
37693/// Merge lhs with rhs.38063/// Merge lhs with rhs.
37694/// Asserts that lhs and rhs are both error sets and are resolved.38064/// Asserts that lhs and rhs are both error sets and are resolved.
37695fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type {38065fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type {
37696 const mod = sema.mod;38066 const pt = sema.pt;
37697 const ip = &mod.intern_pool;38067 const ip = &pt.zcu.intern_pool;
37698 const arena = sema.arena;38068 const arena = sema.arena;
37699 const lhs_names = lhs.errorSetNames(mod);38069 const lhs_names = lhs.errorSetNames(pt.zcu);
37700 const rhs_names = rhs.errorSetNames(mod);38070 const rhs_names = rhs.errorSetNames(pt.zcu);
37701 var names: InferredErrorSet.NameMap = .{};38071 var names: InferredErrorSet.NameMap = .{};
37702 try names.ensureUnusedCapacity(arena, lhs_names.len);38072 try names.ensureUnusedCapacity(arena, lhs_names.len);
3770338073
...@@ -37708,7 +38078,7 @@ fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type {...@@ -37708,7 +38078,7 @@ fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type {
37708 try names.put(arena, rhs_names.get(ip)[rhs_index], {});38078 try names.put(arena, rhs_names.get(ip)[rhs_index], {});
37709 }38079 }
3771038080
37711 return mod.errorSetFromUnsortedNames(names.keys());38081 return pt.errorSetFromUnsortedNames(names.keys());
37712}38082}
3771338083
37714/// Avoids crashing the compiler when asking if inferred allocations are noreturn.38084/// Avoids crashing the compiler when asking if inferred allocations are noreturn.
...@@ -37718,7 +38088,7 @@ fn isNoReturn(sema: *Sema, ref: Air.Inst.Ref) bool {...@@ -37718,7 +38088,7 @@ fn isNoReturn(sema: *Sema, ref: Air.Inst.Ref) bool {
37718 .inferred_alloc, .inferred_alloc_comptime => return false,38088 .inferred_alloc, .inferred_alloc_comptime => return false,
37719 else => {},38089 else => {},
37720 };38090 };
37721 return sema.typeOf(ref).isNoReturn(sema.mod);38091 return sema.typeOf(ref).isNoReturn(sema.pt.zcu);
37722}38092}
3772338093
37724/// Avoids crashing the compiler when asking if inferred allocations are known to be a certain zig type.38094/// Avoids crashing the compiler when asking if inferred allocations are known to be a certain zig type.
...@@ -37727,11 +38097,12 @@ fn isKnownZigType(sema: *Sema, ref: Air.Inst.Ref, tag: std.builtin.TypeId) bool...@@ -37727,11 +38097,12 @@ fn isKnownZigType(sema: *Sema, ref: Air.Inst.Ref, tag: std.builtin.TypeId) bool
37727 .inferred_alloc, .inferred_alloc_comptime => return false,38097 .inferred_alloc, .inferred_alloc_comptime => return false,
37728 else => {},38098 else => {},
37729 };38099 };
37730 return sema.typeOf(ref).zigTypeTag(sema.mod) == tag;38100 return sema.typeOf(ref).zigTypeTag(sema.pt.zcu) == tag;
37731}38101}
3773238102
37733pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {38103pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {
37734 if (!sema.mod.comp.debug_incremental) return;38104 const zcu = sema.pt.zcu;
38105 if (!zcu.comp.debug_incremental) return;
3773538106
37736 // Avoid creating dependencies on ourselves. This situation can arise when we analyze the fields38107 // 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 would38108 // of a type and they use `@This()`. This dependency would be unnecessary, and in fact would
...@@ -37747,11 +38118,11 @@ pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {...@@ -37747,11 +38118,11 @@ pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {
37747 else38118 else
37748 .{ .decl = sema.owner_decl_index },38119 .{ .decl = sema.owner_decl_index },
37749 );38120 );
37750 try sema.mod.intern_pool.addDependency(sema.gpa, depender, dependee);38121 try zcu.intern_pool.addDependency(sema.gpa, depender, dependee);
37751}38122}
3775238123
37753fn isComptimeMutablePtr(sema: *Sema, val: Value) bool {38124fn isComptimeMutablePtr(sema: *Sema, val: Value) bool {
37754 return switch (sema.mod.intern_pool.indexToKey(val.toIntern())) {38125 return switch (sema.pt.zcu.intern_pool.indexToKey(val.toIntern())) {
37755 .slice => |slice| sema.isComptimeMutablePtr(Value.fromInterned(slice.ptr)),38126 .slice => |slice| sema.isComptimeMutablePtr(Value.fromInterned(slice.ptr)),
37756 .ptr => |ptr| switch (ptr.base_addr) {38127 .ptr => |ptr| switch (ptr.base_addr) {
37757 .anon_decl, .decl, .int => false,38128 .anon_decl, .decl, .int => false,
...@@ -37766,7 +38137,7 @@ fn isComptimeMutablePtr(sema: *Sema, val: Value) bool {...@@ -37766,7 +38137,7 @@ fn isComptimeMutablePtr(sema: *Sema, val: Value) bool {
3776638137
37767fn checkRuntimeValue(sema: *Sema, ptr: Air.Inst.Ref) bool {38138fn checkRuntimeValue(sema: *Sema, ptr: Air.Inst.Ref) bool {
37768 const val = ptr.toInterned() orelse return true;38139 const val = ptr.toInterned() orelse return true;
37769 return !Value.fromInterned(val).canMutateComptimeVarState(sema.mod);38140 return !Value.fromInterned(val).canMutateComptimeVarState(sema.pt.zcu);
37770}38141}
3777138142
37772fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Air.Inst.Ref) CompileError!void {38143fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Air.Inst.Ref) CompileError!void {
...@@ -37781,7 +38152,8 @@ fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Ai...@@ -37781,7 +38152,8 @@ fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Ai
3778138152
37782/// Returns true if any value contained in `val` is undefined.38153/// Returns true if any value contained in `val` is undefined.
37783fn anyUndef(sema: *Sema, block: *Block, src: LazySrcLoc, val: Value) !bool {38154fn anyUndef(sema: *Sema, block: *Block, src: LazySrcLoc, val: Value) !bool {
37784 const mod = sema.mod;38155 const pt = sema.pt;
38156 const mod = pt.zcu;
37785 return switch (mod.intern_pool.indexToKey(val.toIntern())) {38157 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
37786 .undef => true,38158 .undef => true,
37787 .simple_value => |v| v == .undefined,38159 .simple_value => |v| v == .undefined,
...@@ -37807,13 +38179,14 @@ fn sliceToIpString(...@@ -37807,13 +38179,14 @@ fn sliceToIpString(
37807 slice_val: Value,38179 slice_val: Value,
37808 reason: NeededComptimeReason,38180 reason: NeededComptimeReason,
37809) CompileError!InternPool.NullTerminatedString {38181) CompileError!InternPool.NullTerminatedString {
37810 const zcu = sema.mod;38182 const pt = sema.pt;
38183 const zcu = pt.zcu;
37811 const slice_ty = slice_val.typeOf(zcu);38184 const slice_ty = slice_val.typeOf(zcu);
37812 assert(slice_ty.isSlice(zcu));38185 assert(slice_ty.isSlice(zcu));
37813 assert(slice_ty.childType(zcu).toIntern() == .u8_type);38186 assert(slice_ty.childType(zcu).toIntern() == .u8_type);
37814 const array_val = try sema.derefSliceAsArray(block, src, slice_val, reason);38187 const array_val = try sema.derefSliceAsArray(block, src, slice_val, reason);
37815 const array_ty = array_val.typeOf(zcu);38188 const array_ty = array_val.typeOf(zcu);
37816 return array_val.toIpString(array_ty, zcu);38189 return array_val.toIpString(array_ty, pt);
37817}38190}
3781838191
37819/// Given a slice value, attempts to dereference it into a comptime-known array.38192/// Given a slice value, attempts to dereference it into a comptime-known array.
...@@ -37840,7 +38213,8 @@ fn maybeDerefSliceAsArray(...@@ -37840,7 +38213,8 @@ fn maybeDerefSliceAsArray(
37840 src: LazySrcLoc,38213 src: LazySrcLoc,
37841 slice_val: Value,38214 slice_val: Value,
37842) CompileError!?Value {38215) CompileError!?Value {
37843 const zcu = sema.mod;38216 const pt = sema.pt;
38217 const zcu = pt.zcu;
37844 const ip = &zcu.intern_pool;38218 const ip = &zcu.intern_pool;
37845 assert(slice_val.typeOf(zcu).isSlice(zcu));38219 assert(slice_val.typeOf(zcu).isSlice(zcu));
37846 const slice = switch (ip.indexToKey(slice_val.toIntern())) {38220 const slice = switch (ip.indexToKey(slice_val.toIntern())) {
...@@ -37849,19 +38223,19 @@ fn maybeDerefSliceAsArray(...@@ -37849,19 +38223,19 @@ fn maybeDerefSliceAsArray(
37849 else => unreachable,38223 else => unreachable,
37850 };38224 };
37851 const elem_ty = Type.fromInterned(slice.ty).childType(zcu);38225 const elem_ty = Type.fromInterned(slice.ty).childType(zcu);
37852 const len = try Value.fromInterned(slice.len).toUnsignedIntSema(zcu);38226 const len = try Value.fromInterned(slice.len).toUnsignedIntSema(pt);
37853 const array_ty = try zcu.arrayType(.{38227 const array_ty = try pt.arrayType(.{
37854 .child = elem_ty.toIntern(),38228 .child = elem_ty.toIntern(),
37855 .len = len,38229 .len = len,
37856 });38230 });
37857 const ptr_ty = try zcu.ptrTypeSema(p: {38231 const ptr_ty = try pt.ptrTypeSema(p: {
37858 var p = Type.fromInterned(slice.ty).ptrInfo(zcu);38232 var p = Type.fromInterned(slice.ty).ptrInfo(zcu);
37859 p.flags.size = .One;38233 p.flags.size = .One;
37860 p.child = array_ty.toIntern();38234 p.child = array_ty.toIntern();
37861 p.sentinel = .none;38235 p.sentinel = .none;
37862 break :p p;38236 break :p p;
37863 });38237 });
37864 const casted_ptr = try zcu.getCoerced(Value.fromInterned(slice.ptr), ptr_ty);38238 const casted_ptr = try pt.getCoerced(Value.fromInterned(slice.ptr), ptr_ty);
37865 return sema.pointerDeref(block, src, casted_ptr, ptr_ty);38239 return sema.pointerDeref(block, src, casted_ptr, ptr_ty);
37866}38240}
3786738241
...@@ -37879,7 +38253,7 @@ fn analyzeUnreachable(sema: *Sema, block: *Block, src: LazySrcLoc, safety_check:...@@ -37879,7 +38253,7 @@ fn analyzeUnreachable(sema: *Sema, block: *Block, src: LazySrcLoc, safety_check:
37879pub fn flushExports(sema: *Sema) !void {38253pub fn flushExports(sema: *Sema) !void {
37880 if (sema.exports.items.len == 0) return;38254 if (sema.exports.items.len == 0) return;
3788138255
37882 const zcu = sema.mod;38256 const zcu = sema.pt.zcu;
37883 const gpa = zcu.gpa;38257 const gpa = zcu.gpa;
3788438258
37885 const unit = sema.ownerUnit();38259 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+376-361
...@@ -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) {
...@@ -3680,22 +3690,23 @@ pub fn resolveFields(ty: Type, zcu: *Zcu) SemaError!void {...@@ -3680,22 +3690,23 @@ pub fn resolveFields(ty: Type, zcu: *Zcu) SemaError!void {
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+1163-1084
...@@ -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,15 +55,16 @@ pub fn fmtValueFull(ctx: print_value.FormatContext) std.fmt.Formatter(print_valu...@@ -55,15 +55,16 @@ 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: usize = @intCast(ty.arrayLen(mod));
68 try ip.string_bytes.appendNTimes(mod.gpa, byte, len);69 try ip.string_bytes.appendNTimes(mod.gpa, byte, len);
69 return ip.getOrPutTrailingString(mod.gpa, len, .no_embedded_nulls);70 return ip.getOrPutTrailingString(mod.gpa, len, .no_embedded_nulls);
...@@ -73,16 +74,17 @@ pub fn toIpString(val: Value, ty: Type, mod: *Module) !InternPool.NullTerminated...@@ -73,16 +74,17 @@ pub fn toIpString(val: Value, ty: Type, mod: *Module) !InternPool.NullTerminated
7374
74/// Asserts that the value is representable as an array of bytes.75/// 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.76/// 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 {77pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) ![]u8 {
78 const mod = pt.zcu;
77 const ip = &mod.intern_pool;79 const ip = &mod.intern_pool;
78 return switch (ip.indexToKey(val.toIntern())) {80 return switch (ip.indexToKey(val.toIntern())) {
79 .enum_literal => |enum_literal| allocator.dupe(u8, enum_literal.toSlice(ip)),81 .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),82 .slice => |slice| try arrayToAllocatedBytes(val, Value.fromInterned(slice.len).toUnsignedInt(pt), allocator, pt),
81 .aggregate => |aggregate| switch (aggregate.storage) {83 .aggregate => |aggregate| switch (aggregate.storage) {
82 .bytes => |bytes| try allocator.dupe(u8, bytes.toSlice(ty.arrayLenIncludingSentinel(mod), ip)),84 .bytes => |bytes| try allocator.dupe(u8, bytes.toSlice(ty.arrayLenIncludingSentinel(mod), ip)),
83 .elems => try arrayToAllocatedBytes(val, ty.arrayLen(mod), allocator, mod),85 .elems => try arrayToAllocatedBytes(val, ty.arrayLen(mod), allocator, pt),
84 .repeated_elem => |elem| {86 .repeated_elem => |elem| {
85 const byte: u8 = @intCast(Value.fromInterned(elem).toUnsignedInt(mod));87 const byte: u8 = @intCast(Value.fromInterned(elem).toUnsignedInt(pt));
86 const result = try allocator.alloc(u8, @intCast(ty.arrayLen(mod)));88 const result = try allocator.alloc(u8, @intCast(ty.arrayLen(mod)));
87 @memset(result, byte);89 @memset(result, byte);
88 return result;90 return result;
...@@ -92,16 +94,17 @@ pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module...@@ -92,16 +94,17 @@ pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module
92 };94 };
93}95}
9496
95fn arrayToAllocatedBytes(val: Value, len: u64, allocator: Allocator, mod: *Module) ![]u8 {97fn arrayToAllocatedBytes(val: Value, len: u64, allocator: Allocator, pt: Zcu.PerThread) ![]u8 {
96 const result = try allocator.alloc(u8, @intCast(len));98 const result = try allocator.alloc(u8, @intCast(len));
97 for (result, 0..) |*elem, i| {99 for (result, 0..) |*elem, i| {
98 const elem_val = try val.elemValue(mod, i);100 const elem_val = try val.elemValue(pt, i);
99 elem.* = @intCast(elem_val.toUnsignedInt(mod));101 elem.* = @intCast(elem_val.toUnsignedInt(pt));
100 }102 }
101 return result;103 return result;
102}104}
103105
104fn arrayToIpString(val: Value, len_u64: u64, mod: *Module) !InternPool.NullTerminatedString {106fn arrayToIpString(val: Value, len_u64: u64, pt: Zcu.PerThread) !InternPool.NullTerminatedString {
107 const mod = pt.zcu;
105 const gpa = mod.gpa;108 const gpa = mod.gpa;
106 const ip = &mod.intern_pool;109 const ip = &mod.intern_pool;
107 const len: usize = @intCast(len_u64);110 const len: usize = @intCast(len_u64);
...@@ -110,9 +113,9 @@ fn arrayToIpString(val: Value, len_u64: u64, mod: *Module) !InternPool.NullTermi...@@ -110,9 +113,9 @@ fn arrayToIpString(val: Value, len_u64: u64, mod: *Module) !InternPool.NullTermi
110 // I don't think elemValue has the possibility to affect ip.string_bytes. Let's113 // I don't think elemValue has the possibility to affect ip.string_bytes. Let's
111 // assert just to be sure.114 // assert just to be sure.
112 const prev = ip.string_bytes.items.len;115 const prev = ip.string_bytes.items.len;
113 const elem_val = try val.elemValue(mod, i);116 const elem_val = try val.elemValue(pt, i);
114 assert(ip.string_bytes.items.len == prev);117 assert(ip.string_bytes.items.len == prev);
115 const byte: u8 = @intCast(elem_val.toUnsignedInt(mod));118 const byte: u8 = @intCast(elem_val.toUnsignedInt(pt));
116 ip.string_bytes.appendAssumeCapacity(byte);119 ip.string_bytes.appendAssumeCapacity(byte);
117 }120 }
118 return ip.getOrPutTrailingString(gpa, len, .no_embedded_nulls);121 return ip.getOrPutTrailingString(gpa, len, .no_embedded_nulls);
...@@ -133,14 +136,14 @@ pub fn toType(self: Value) Type {...@@ -133,14 +136,14 @@ pub fn toType(self: Value) Type {
133 return Type.fromInterned(self.toIntern());136 return Type.fromInterned(self.toIntern());
134}137}
135138
136pub fn intFromEnum(val: Value, ty: Type, mod: *Module) Allocator.Error!Value {139pub fn intFromEnum(val: Value, ty: Type, pt: Zcu.PerThread) Allocator.Error!Value {
137 const ip = &mod.intern_pool;140 const ip = &pt.zcu.intern_pool;
138 const enum_ty = ip.typeOf(val.toIntern());141 const enum_ty = ip.typeOf(val.toIntern());
139 return switch (ip.indexToKey(enum_ty)) {142 return switch (ip.indexToKey(enum_ty)) {
140 // Assume it is already an integer and return it directly.143 // Assume it is already an integer and return it directly.
141 .simple_type, .int_type => val,144 .simple_type, .int_type => val,
142 .enum_literal => |enum_literal| {145 .enum_literal => |enum_literal| {
143 const field_index = ty.enumFieldIndex(enum_literal, mod).?;146 const field_index = ty.enumFieldIndex(enum_literal, pt.zcu).?;
144 switch (ip.indexToKey(ty.toIntern())) {147 switch (ip.indexToKey(ty.toIntern())) {
145 // Assume it is already an integer and return it directly.148 // Assume it is already an integer and return it directly.
146 .simple_type, .int_type => return val,149 .simple_type, .int_type => return val,
...@@ -150,13 +153,13 @@ pub fn intFromEnum(val: Value, ty: Type, mod: *Module) Allocator.Error!Value {...@@ -150,13 +153,13 @@ pub fn intFromEnum(val: Value, ty: Type, mod: *Module) Allocator.Error!Value {
150 return Value.fromInterned(enum_type.values.get(ip)[field_index]);153 return Value.fromInterned(enum_type.values.get(ip)[field_index]);
151 } else {154 } else {
152 // Field index and integer values are the same.155 // Field index and integer values are the same.
153 return mod.intValue(Type.fromInterned(enum_type.tag_ty), field_index);156 return pt.intValue(Type.fromInterned(enum_type.tag_ty), field_index);
154 }157 }
155 },158 },
156 else => unreachable,159 else => unreachable,
157 }160 }
158 },161 },
159 .enum_type => try mod.getCoerced(val, Type.fromInterned(ip.loadEnumType(enum_ty).tag_ty)),162 .enum_type => try pt.getCoerced(val, Type.fromInterned(ip.loadEnumType(enum_ty).tag_ty)),
160 else => unreachable,163 else => unreachable,
161 };164 };
162}165}
...@@ -164,38 +167,38 @@ pub fn intFromEnum(val: Value, ty: Type, mod: *Module) Allocator.Error!Value {...@@ -164,38 +167,38 @@ pub fn intFromEnum(val: Value, ty: Type, mod: *Module) Allocator.Error!Value {
164pub const ResolveStrat = Type.ResolveStrat;167pub const ResolveStrat = Type.ResolveStrat;
165168
166/// Asserts the value is an integer.169/// Asserts the value is an integer.
167pub fn toBigInt(val: Value, space: *BigIntSpace, mod: *Module) BigIntConst {170pub fn toBigInt(val: Value, space: *BigIntSpace, pt: Zcu.PerThread) BigIntConst {
168 return val.toBigIntAdvanced(space, mod, .normal) catch unreachable;171 return val.toBigIntAdvanced(space, pt, .normal) catch unreachable;
169}172}
170173
171/// Asserts the value is an integer.174/// Asserts the value is an integer.
172pub fn toBigIntAdvanced(175pub fn toBigIntAdvanced(
173 val: Value,176 val: Value,
174 space: *BigIntSpace,177 space: *BigIntSpace,
175 mod: *Module,178 pt: Zcu.PerThread,
176 strat: ResolveStrat,179 strat: ResolveStrat,
177) Module.CompileError!BigIntConst {180) Module.CompileError!BigIntConst {
178 return switch (val.toIntern()) {181 return switch (val.toIntern()) {
179 .bool_false => BigIntMutable.init(&space.limbs, 0).toConst(),182 .bool_false => BigIntMutable.init(&space.limbs, 0).toConst(),
180 .bool_true => BigIntMutable.init(&space.limbs, 1).toConst(),183 .bool_true => BigIntMutable.init(&space.limbs, 1).toConst(),
181 .null_value => BigIntMutable.init(&space.limbs, 0).toConst(),184 .null_value => BigIntMutable.init(&space.limbs, 0).toConst(),
182 else => switch (mod.intern_pool.indexToKey(val.toIntern())) {185 else => switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) {
183 .int => |int| switch (int.storage) {186 .int => |int| switch (int.storage) {
184 .u64, .i64, .big_int => int.storage.toBigInt(space),187 .u64, .i64, .big_int => int.storage.toBigInt(space),
185 .lazy_align, .lazy_size => |ty| {188 .lazy_align, .lazy_size => |ty| {
186 if (strat == .sema) try Type.fromInterned(ty).resolveLayout(mod);189 if (strat == .sema) try Type.fromInterned(ty).resolveLayout(pt);
187 const x = switch (int.storage) {190 const x = switch (int.storage) {
188 else => unreachable,191 else => unreachable,
189 .lazy_align => Type.fromInterned(ty).abiAlignment(mod).toByteUnits() orelse 0,192 .lazy_align => Type.fromInterned(ty).abiAlignment(pt).toByteUnits() orelse 0,
190 .lazy_size => Type.fromInterned(ty).abiSize(mod),193 .lazy_size => Type.fromInterned(ty).abiSize(pt),
191 };194 };
192 return BigIntMutable.init(&space.limbs, x).toConst();195 return BigIntMutable.init(&space.limbs, x).toConst();
193 },196 },
194 },197 },
195 .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).toBigIntAdvanced(space, mod, strat),198 .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).toBigIntAdvanced(space, pt, strat),
196 .opt, .ptr => BigIntMutable.init(199 .opt, .ptr => BigIntMutable.init(
197 &space.limbs,200 &space.limbs,
198 (try val.getUnsignedIntAdvanced(mod, strat)).?,201 (try val.getUnsignedIntAdvanced(pt, strat)).?,
199 ).toConst(),202 ).toConst(),
200 else => unreachable,203 else => unreachable,
201 },204 },
...@@ -229,13 +232,14 @@ pub fn getVariable(val: Value, mod: *Module) ?InternPool.Key.Variable {...@@ -229,13 +232,14 @@ pub fn getVariable(val: Value, mod: *Module) ?InternPool.Key.Variable {
229232
230/// If the value fits in a u64, return it, otherwise null.233/// If the value fits in a u64, return it, otherwise null.
231/// Asserts not undefined.234/// Asserts not undefined.
232pub fn getUnsignedInt(val: Value, mod: *Module) ?u64 {235pub fn getUnsignedInt(val: Value, pt: Zcu.PerThread) ?u64 {
233 return getUnsignedIntAdvanced(val, mod, .normal) catch unreachable;236 return getUnsignedIntAdvanced(val, pt, .normal) catch unreachable;
234}237}
235238
236/// If the value fits in a u64, return it, otherwise null.239/// If the value fits in a u64, return it, otherwise null.
237/// Asserts not undefined.240/// Asserts not undefined.
238pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, strat: ResolveStrat) !?u64 {241pub fn getUnsignedIntAdvanced(val: Value, pt: Zcu.PerThread, strat: ResolveStrat) !?u64 {
242 const mod = pt.zcu;
239 return switch (val.toIntern()) {243 return switch (val.toIntern()) {
240 .undef => unreachable,244 .undef => unreachable,
241 .bool_false => 0,245 .bool_false => 0,
...@@ -246,22 +250,22 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, strat: ResolveStrat) !?u...@@ -246,22 +250,22 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, strat: ResolveStrat) !?u
246 .big_int => |big_int| big_int.to(u64) catch null,250 .big_int => |big_int| big_int.to(u64) catch null,
247 .u64 => |x| x,251 .u64 => |x| x,
248 .i64 => |x| std.math.cast(u64, x),252 .i64 => |x| std.math.cast(u64, x),
249 .lazy_align => |ty| (try Type.fromInterned(ty).abiAlignmentAdvanced(mod, strat.toLazy())).scalar.toByteUnits() orelse 0,253 .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,254 .lazy_size => |ty| (try Type.fromInterned(ty).abiSizeAdvanced(pt, strat.toLazy())).scalar,
251 },255 },
252 .ptr => |ptr| switch (ptr.base_addr) {256 .ptr => |ptr| switch (ptr.base_addr) {
253 .int => ptr.byte_offset,257 .int => ptr.byte_offset,
254 .field => |field| {258 .field => |field| {
255 const base_addr = (try Value.fromInterned(field.base).getUnsignedIntAdvanced(mod, strat)) orelse return null;259 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);260 const struct_ty = Value.fromInterned(field.base).typeOf(mod).childType(mod);
257 if (strat == .sema) try struct_ty.resolveLayout(mod);261 if (strat == .sema) try struct_ty.resolveLayout(pt);
258 return base_addr + struct_ty.structFieldOffset(@intCast(field.index), mod) + ptr.byte_offset;262 return base_addr + struct_ty.structFieldOffset(@intCast(field.index), pt) + ptr.byte_offset;
259 },263 },
260 else => null,264 else => null,
261 },265 },
262 .opt => |opt| switch (opt.val) {266 .opt => |opt| switch (opt.val) {
263 .none => 0,267 .none => 0,
264 else => |payload| Value.fromInterned(payload).getUnsignedIntAdvanced(mod, strat),268 else => |payload| Value.fromInterned(payload).getUnsignedIntAdvanced(pt, strat),
265 },269 },
266 else => null,270 else => null,
267 },271 },
...@@ -269,27 +273,27 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, strat: ResolveStrat) !?u...@@ -269,27 +273,27 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, strat: ResolveStrat) !?u
269}273}
270274
271/// Asserts the value is an integer and it fits in a u64275/// Asserts the value is an integer and it fits in a u64
272pub fn toUnsignedInt(val: Value, zcu: *Zcu) u64 {276pub fn toUnsignedInt(val: Value, pt: Zcu.PerThread) u64 {
273 return getUnsignedInt(val, zcu).?;277 return getUnsignedInt(val, pt).?;
274}278}
275279
276/// Asserts the value is an integer and it fits in a u64280/// Asserts the value is an integer and it fits in a u64
277pub fn toUnsignedIntSema(val: Value, zcu: *Zcu) !u64 {281pub fn toUnsignedIntSema(val: Value, pt: Zcu.PerThread) !u64 {
278 return (try getUnsignedIntAdvanced(val, zcu, .sema)).?;282 return (try getUnsignedIntAdvanced(val, pt, .sema)).?;
279}283}
280284
281/// Asserts the value is an integer and it fits in a i64285/// Asserts the value is an integer and it fits in a i64
282pub fn toSignedInt(val: Value, mod: *Module) i64 {286pub fn toSignedInt(val: Value, pt: Zcu.PerThread) i64 {
283 return switch (val.toIntern()) {287 return switch (val.toIntern()) {
284 .bool_false => 0,288 .bool_false => 0,
285 .bool_true => 1,289 .bool_true => 1,
286 else => switch (mod.intern_pool.indexToKey(val.toIntern())) {290 else => switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) {
287 .int => |int| switch (int.storage) {291 .int => |int| switch (int.storage) {
288 .big_int => |big_int| big_int.to(i64) catch unreachable,292 .big_int => |big_int| big_int.to(i64) catch unreachable,
289 .i64 => |x| x,293 .i64 => |x| x,
290 .u64 => |x| @intCast(x),294 .u64 => |x| @intCast(x),
291 .lazy_align => |ty| @intCast(Type.fromInterned(ty).abiAlignment(mod).toByteUnits() orelse 0),295 .lazy_align => |ty| @intCast(Type.fromInterned(ty).abiAlignment(pt).toByteUnits() orelse 0),
292 .lazy_size => |ty| @intCast(Type.fromInterned(ty).abiSize(mod)),296 .lazy_size => |ty| @intCast(Type.fromInterned(ty).abiSize(pt)),
293 },297 },
294 else => unreachable,298 else => unreachable,
295 },299 },
...@@ -321,16 +325,17 @@ fn ptrHasIntAddr(val: Value, mod: *Module) bool {...@@ -321,16 +325,17 @@ fn ptrHasIntAddr(val: Value, mod: *Module) bool {
321///325///
322/// Asserts that buffer.len >= ty.abiSize(). The buffer is allowed to extend past326/// Asserts that buffer.len >= ty.abiSize(). The buffer is allowed to extend past
323/// the end of the value in memory.327/// the end of the value in memory.
324pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{328pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) error{
325 ReinterpretDeclRef,329 ReinterpretDeclRef,
326 IllDefinedMemoryLayout,330 IllDefinedMemoryLayout,
327 Unimplemented,331 Unimplemented,
328 OutOfMemory,332 OutOfMemory,
329}!void {333}!void {
334 const mod = pt.zcu;
330 const target = mod.getTarget();335 const target = mod.getTarget();
331 const endian = target.cpu.arch.endian();336 const endian = target.cpu.arch.endian();
332 if (val.isUndef(mod)) {337 if (val.isUndef(mod)) {
333 const size: usize = @intCast(ty.abiSize(mod));338 const size: usize = @intCast(ty.abiSize(pt));
334 @memset(buffer[0..size], 0xaa);339 @memset(buffer[0..size], 0xaa);
335 return;340 return;
336 }341 }
...@@ -346,41 +351,41 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{...@@ -346,41 +351,41 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{
346 const byte_count: u16 = @intCast((@as(u17, bits) + 7) / 8);351 const byte_count: u16 = @intCast((@as(u17, bits) + 7) / 8);
347352
348 var bigint_buffer: BigIntSpace = undefined;353 var bigint_buffer: BigIntSpace = undefined;
349 const bigint = val.toBigInt(&bigint_buffer, mod);354 const bigint = val.toBigInt(&bigint_buffer, pt);
350 bigint.writeTwosComplement(buffer[0..byte_count], endian);355 bigint.writeTwosComplement(buffer[0..byte_count], endian);
351 },356 },
352 .Float => switch (ty.floatBits(target)) {357 .Float => switch (ty.floatBits(target)) {
353 16 => std.mem.writeInt(u16, buffer[0..2], @bitCast(val.toFloat(f16, mod)), endian),358 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),359 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),360 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),361 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),362 128 => std.mem.writeInt(u128, buffer[0..16], @bitCast(val.toFloat(f128, pt)), endian),
358 else => unreachable,363 else => unreachable,
359 },364 },
360 .Array => {365 .Array => {
361 const len = ty.arrayLen(mod);366 const len = ty.arrayLen(mod);
362 const elem_ty = ty.childType(mod);367 const elem_ty = ty.childType(mod);
363 const elem_size: usize = @intCast(elem_ty.abiSize(mod));368 const elem_size: usize = @intCast(elem_ty.abiSize(pt));
364 var elem_i: usize = 0;369 var elem_i: usize = 0;
365 var buf_off: usize = 0;370 var buf_off: usize = 0;
366 while (elem_i < len) : (elem_i += 1) {371 while (elem_i < len) : (elem_i += 1) {
367 const elem_val = try val.elemValue(mod, elem_i);372 const elem_val = try val.elemValue(pt, elem_i);
368 try elem_val.writeToMemory(elem_ty, mod, buffer[buf_off..]);373 try elem_val.writeToMemory(elem_ty, pt, buffer[buf_off..]);
369 buf_off += elem_size;374 buf_off += elem_size;
370 }375 }
371 },376 },
372 .Vector => {377 .Vector => {
373 // We use byte_count instead of abi_size here, so that any padding bytes378 // 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.379 // follow the data bytes, on both big- and little-endian systems.
375 const byte_count = (@as(usize, @intCast(ty.bitSize(mod))) + 7) / 8;380 const byte_count = (@as(usize, @intCast(ty.bitSize(pt))) + 7) / 8;
376 return writeToPackedMemory(val, ty, mod, buffer[0..byte_count], 0);381 return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0);
377 },382 },
378 .Struct => {383 .Struct => {
379 const struct_type = mod.typeToStruct(ty) orelse return error.IllDefinedMemoryLayout;384 const struct_type = mod.typeToStruct(ty) orelse return error.IllDefinedMemoryLayout;
380 switch (struct_type.layout) {385 switch (struct_type.layout) {
381 .auto => return error.IllDefinedMemoryLayout,386 .auto => return error.IllDefinedMemoryLayout,
382 .@"extern" => for (0..struct_type.field_types.len) |field_index| {387 .@"extern" => for (0..struct_type.field_types.len) |field_index| {
383 const off: usize = @intCast(ty.structFieldOffset(field_index, mod));388 const off: usize = @intCast(ty.structFieldOffset(field_index, pt));
384 const field_val = Value.fromInterned(switch (ip.indexToKey(val.toIntern()).aggregate.storage) {389 const field_val = Value.fromInterned(switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
385 .bytes => |bytes| {390 .bytes => |bytes| {
386 buffer[off] = bytes.at(field_index, ip);391 buffer[off] = bytes.at(field_index, ip);
...@@ -390,11 +395,11 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{...@@ -390,11 +395,11 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{
390 .repeated_elem => |elem| elem,395 .repeated_elem => |elem| elem,
391 });396 });
392 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);397 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
393 try writeToMemory(field_val, field_ty, mod, buffer[off..]);398 try writeToMemory(field_val, field_ty, pt, buffer[off..]);
394 },399 },
395 .@"packed" => {400 .@"packed" => {
396 const byte_count = (@as(usize, @intCast(ty.bitSize(mod))) + 7) / 8;401 const byte_count = (@as(usize, @intCast(ty.bitSize(pt))) + 7) / 8;
397 return writeToPackedMemory(val, ty, mod, buffer[0..byte_count], 0);402 return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0);
398 },403 },
399 }404 }
400 },405 },
...@@ -421,34 +426,34 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{...@@ -421,34 +426,34 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{
421 const union_obj = mod.typeToUnion(ty).?;426 const union_obj = mod.typeToUnion(ty).?;
422 const field_index = mod.unionTagFieldIndex(union_obj, union_tag).?;427 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]);428 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);429 const field_val = try val.fieldValue(pt, field_index);
425 const byte_count: usize = @intCast(field_type.abiSize(mod));430 const byte_count: usize = @intCast(field_type.abiSize(pt));
426 return writeToMemory(field_val, field_type, mod, buffer[0..byte_count]);431 return writeToMemory(field_val, field_type, pt, buffer[0..byte_count]);
427 } else {432 } else {
428 const backing_ty = try ty.unionBackingType(mod);433 const backing_ty = try ty.unionBackingType(pt);
429 const byte_count: usize = @intCast(backing_ty.abiSize(mod));434 const byte_count: usize = @intCast(backing_ty.abiSize(pt));
430 return writeToMemory(val.unionValue(mod), backing_ty, mod, buffer[0..byte_count]);435 return writeToMemory(val.unionValue(mod), backing_ty, pt, buffer[0..byte_count]);
431 }436 }
432 },437 },
433 .@"packed" => {438 .@"packed" => {
434 const backing_ty = try ty.unionBackingType(mod);439 const backing_ty = try ty.unionBackingType(pt);
435 const byte_count: usize = @intCast(backing_ty.abiSize(mod));440 const byte_count: usize = @intCast(backing_ty.abiSize(pt));
436 return writeToPackedMemory(val, ty, mod, buffer[0..byte_count], 0);441 return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0);
437 },442 },
438 },443 },
439 .Pointer => {444 .Pointer => {
440 if (ty.isSlice(mod)) return error.IllDefinedMemoryLayout;445 if (ty.isSlice(mod)) return error.IllDefinedMemoryLayout;
441 if (!val.ptrHasIntAddr(mod)) return error.ReinterpretDeclRef;446 if (!val.ptrHasIntAddr(mod)) return error.ReinterpretDeclRef;
442 return val.writeToMemory(Type.usize, mod, buffer);447 return val.writeToMemory(Type.usize, pt, buffer);
443 },448 },
444 .Optional => {449 .Optional => {
445 if (!ty.isPtrLikeOptional(mod)) return error.IllDefinedMemoryLayout;450 if (!ty.isPtrLikeOptional(mod)) return error.IllDefinedMemoryLayout;
446 const child = ty.optionalChild(mod);451 const child = ty.optionalChild(mod);
447 const opt_val = val.optionalValue(mod);452 const opt_val = val.optionalValue(mod);
448 if (opt_val) |some| {453 if (opt_val) |some| {
449 return some.writeToMemory(child, mod, buffer);454 return some.writeToMemory(child, pt, buffer);
450 } else {455 } else {
451 return writeToMemory(try mod.intValue(Type.usize, 0), Type.usize, mod, buffer);456 return writeToMemory(try pt.intValue(Type.usize, 0), Type.usize, pt, buffer);
452 }457 }
453 },458 },
454 else => return error.Unimplemented,459 else => return error.Unimplemented,
...@@ -462,15 +467,16 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{...@@ -462,15 +467,16 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{
462pub fn writeToPackedMemory(467pub fn writeToPackedMemory(
463 val: Value,468 val: Value,
464 ty: Type,469 ty: Type,
465 mod: *Module,470 pt: Zcu.PerThread,
466 buffer: []u8,471 buffer: []u8,
467 bit_offset: usize,472 bit_offset: usize,
468) error{ ReinterpretDeclRef, OutOfMemory }!void {473) error{ ReinterpretDeclRef, OutOfMemory }!void {
474 const mod = pt.zcu;
469 const ip = &mod.intern_pool;475 const ip = &mod.intern_pool;
470 const target = mod.getTarget();476 const target = mod.getTarget();
471 const endian = target.cpu.arch.endian();477 const endian = target.cpu.arch.endian();
472 if (val.isUndef(mod)) {478 if (val.isUndef(mod)) {
473 const bit_size: usize = @intCast(ty.bitSize(mod));479 const bit_size: usize = @intCast(ty.bitSize(pt));
474 if (bit_size != 0) {480 if (bit_size != 0) {
475 std.mem.writeVarPackedInt(buffer, bit_offset, bit_size, @as(u1, 0), endian);481 std.mem.writeVarPackedInt(buffer, bit_offset, bit_size, @as(u1, 0), endian);
476 }482 }
...@@ -494,30 +500,30 @@ pub fn writeToPackedMemory(...@@ -494,30 +500,30 @@ pub fn writeToPackedMemory(
494 const bits = ty.intInfo(mod).bits;500 const bits = ty.intInfo(mod).bits;
495 if (bits == 0) return;501 if (bits == 0) return;
496502
497 switch (ip.indexToKey((try val.intFromEnum(ty, mod)).toIntern()).int.storage) {503 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),504 inline .u64, .i64 => |int| std.mem.writeVarPackedInt(buffer, bit_offset, bits, int, endian),
499 .big_int => |bigint| bigint.writePackedTwosComplement(buffer, bit_offset, bits, endian),505 .big_int => |bigint| bigint.writePackedTwosComplement(buffer, bit_offset, bits, endian),
500 .lazy_align => |lazy_align| {506 .lazy_align => |lazy_align| {
501 const num = Type.fromInterned(lazy_align).abiAlignment(mod).toByteUnits() orelse 0;507 const num = Type.fromInterned(lazy_align).abiAlignment(pt).toByteUnits() orelse 0;
502 std.mem.writeVarPackedInt(buffer, bit_offset, bits, num, endian);508 std.mem.writeVarPackedInt(buffer, bit_offset, bits, num, endian);
503 },509 },
504 .lazy_size => |lazy_size| {510 .lazy_size => |lazy_size| {
505 const num = Type.fromInterned(lazy_size).abiSize(mod);511 const num = Type.fromInterned(lazy_size).abiSize(pt);
506 std.mem.writeVarPackedInt(buffer, bit_offset, bits, num, endian);512 std.mem.writeVarPackedInt(buffer, bit_offset, bits, num, endian);
507 },513 },
508 }514 }
509 },515 },
510 .Float => switch (ty.floatBits(target)) {516 .Float => switch (ty.floatBits(target)) {
511 16 => std.mem.writePackedInt(u16, buffer, bit_offset, @bitCast(val.toFloat(f16, mod)), endian),517 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),518 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),519 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),520 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),521 128 => std.mem.writePackedInt(u128, buffer, bit_offset, @bitCast(val.toFloat(f128, pt)), endian),
516 else => unreachable,522 else => unreachable,
517 },523 },
518 .Vector => {524 .Vector => {
519 const elem_ty = ty.childType(mod);525 const elem_ty = ty.childType(mod);
520 const elem_bit_size: u16 = @intCast(elem_ty.bitSize(mod));526 const elem_bit_size: u16 = @intCast(elem_ty.bitSize(pt));
521 const len: usize = @intCast(ty.arrayLen(mod));527 const len: usize = @intCast(ty.arrayLen(mod));
522528
523 var bits: u16 = 0;529 var bits: u16 = 0;
...@@ -525,8 +531,8 @@ pub fn writeToPackedMemory(...@@ -525,8 +531,8 @@ pub fn writeToPackedMemory(
525 while (elem_i < len) : (elem_i += 1) {531 while (elem_i < len) : (elem_i += 1) {
526 // On big-endian systems, LLVM reverses the element order of vectors by default532 // 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;533 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);534 const elem_val = try val.elemValue(pt, tgt_elem_i);
529 try elem_val.writeToPackedMemory(elem_ty, mod, buffer, bit_offset + bits);535 try elem_val.writeToPackedMemory(elem_ty, pt, buffer, bit_offset + bits);
530 bits += elem_bit_size;536 bits += elem_bit_size;
531 }537 }
532 },538 },
...@@ -543,8 +549,8 @@ pub fn writeToPackedMemory(...@@ -543,8 +549,8 @@ pub fn writeToPackedMemory(
543 .repeated_elem => |elem| elem,549 .repeated_elem => |elem| elem,
544 });550 });
545 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);551 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
546 const field_bits: u16 = @intCast(field_ty.bitSize(mod));552 const field_bits: u16 = @intCast(field_ty.bitSize(pt));
547 try field_val.writeToPackedMemory(field_ty, mod, buffer, bit_offset + bits);553 try field_val.writeToPackedMemory(field_ty, pt, buffer, bit_offset + bits);
548 bits += field_bits;554 bits += field_bits;
549 }555 }
550 },556 },
...@@ -556,11 +562,11 @@ pub fn writeToPackedMemory(...@@ -556,11 +562,11 @@ pub fn writeToPackedMemory(
556 if (val.unionTag(mod)) |union_tag| {562 if (val.unionTag(mod)) |union_tag| {
557 const field_index = mod.unionTagFieldIndex(union_obj, union_tag).?;563 const field_index = mod.unionTagFieldIndex(union_obj, union_tag).?;
558 const field_type = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);564 const field_type = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
559 const field_val = try val.fieldValue(mod, field_index);565 const field_val = try val.fieldValue(pt, field_index);
560 return field_val.writeToPackedMemory(field_type, mod, buffer, bit_offset);566 return field_val.writeToPackedMemory(field_type, pt, buffer, bit_offset);
561 } else {567 } else {
562 const backing_ty = try ty.unionBackingType(mod);568 const backing_ty = try ty.unionBackingType(pt);
563 return val.unionValue(mod).writeToPackedMemory(backing_ty, mod, buffer, bit_offset);569 return val.unionValue(mod).writeToPackedMemory(backing_ty, pt, buffer, bit_offset);
564 }570 }
565 },571 },
566 }572 }
...@@ -568,16 +574,16 @@ pub fn writeToPackedMemory(...@@ -568,16 +574,16 @@ pub fn writeToPackedMemory(
568 .Pointer => {574 .Pointer => {
569 assert(!ty.isSlice(mod)); // No well defined layout.575 assert(!ty.isSlice(mod)); // No well defined layout.
570 if (!val.ptrHasIntAddr(mod)) return error.ReinterpretDeclRef;576 if (!val.ptrHasIntAddr(mod)) return error.ReinterpretDeclRef;
571 return val.writeToPackedMemory(Type.usize, mod, buffer, bit_offset);577 return val.writeToPackedMemory(Type.usize, pt, buffer, bit_offset);
572 },578 },
573 .Optional => {579 .Optional => {
574 assert(ty.isPtrLikeOptional(mod));580 assert(ty.isPtrLikeOptional(mod));
575 const child = ty.optionalChild(mod);581 const child = ty.optionalChild(mod);
576 const opt_val = val.optionalValue(mod);582 const opt_val = val.optionalValue(mod);
577 if (opt_val) |some| {583 if (opt_val) |some| {
578 return some.writeToPackedMemory(child, mod, buffer, bit_offset);584 return some.writeToPackedMemory(child, pt, buffer, bit_offset);
579 } else {585 } else {
580 return writeToPackedMemory(try mod.intValue(Type.usize, 0), Type.usize, mod, buffer, bit_offset);586 return writeToPackedMemory(try pt.intValue(Type.usize, 0), Type.usize, pt, buffer, bit_offset);
581 }587 }
582 },588 },
583 else => @panic("TODO implement writeToPackedMemory for more types"),589 else => @panic("TODO implement writeToPackedMemory for more types"),
...@@ -590,7 +596,7 @@ pub fn writeToPackedMemory(...@@ -590,7 +596,7 @@ pub fn writeToPackedMemory(
590/// the end of the value in memory.596/// the end of the value in memory.
591pub fn readFromMemory(597pub fn readFromMemory(
592 ty: Type,598 ty: Type,
593 mod: *Module,599 pt: Zcu.PerThread,
594 buffer: []const u8,600 buffer: []const u8,
595 arena: Allocator,601 arena: Allocator,
596) error{602) error{
...@@ -598,6 +604,7 @@ pub fn readFromMemory(...@@ -598,6 +604,7 @@ pub fn readFromMemory(
598 Unimplemented,604 Unimplemented,
599 OutOfMemory,605 OutOfMemory,
600}!Value {606}!Value {
607 const mod = pt.zcu;
601 const ip = &mod.intern_pool;608 const ip = &mod.intern_pool;
602 const target = mod.getTarget();609 const target = mod.getTarget();
603 const endian = target.cpu.arch.endian();610 const endian = target.cpu.arch.endian();
...@@ -642,7 +649,7 @@ pub fn readFromMemory(...@@ -642,7 +649,7 @@ pub fn readFromMemory(
642 return mod.getCoerced(try mod.intValue_big(int_ty, bigint.toConst()), ty);649 return mod.getCoerced(try mod.intValue_big(int_ty, bigint.toConst()), ty);
643 }650 }
644 },651 },
645 .Float => return Value.fromInterned((try mod.intern(.{ .float = .{652 .Float => return Value.fromInterned(try pt.intern(.{ .float = .{
646 .ty = ty.toIntern(),653 .ty = ty.toIntern(),
647 .storage = switch (ty.floatBits(target)) {654 .storage = switch (ty.floatBits(target)) {
648 16 => .{ .f16 = @bitCast(std.mem.readInt(u16, buffer[0..2], endian)) },655 16 => .{ .f16 = @bitCast(std.mem.readInt(u16, buffer[0..2], endian)) },
...@@ -652,25 +659,25 @@ pub fn readFromMemory(...@@ -652,25 +659,25 @@ pub fn readFromMemory(
652 128 => .{ .f128 = @bitCast(std.mem.readInt(u128, buffer[0..16], endian)) },659 128 => .{ .f128 = @bitCast(std.mem.readInt(u128, buffer[0..16], endian)) },
653 else => unreachable,660 else => unreachable,
654 },661 },
655 } }))),662 } })),
656 .Array => {663 .Array => {
657 const elem_ty = ty.childType(mod);664 const elem_ty = ty.childType(mod);
658 const elem_size = elem_ty.abiSize(mod);665 const elem_size = elem_ty.abiSize(pt);
659 const elems = try arena.alloc(InternPool.Index, @intCast(ty.arrayLen(mod)));666 const elems = try arena.alloc(InternPool.Index, @intCast(ty.arrayLen(mod)));
660 var offset: usize = 0;667 var offset: usize = 0;
661 for (elems) |*elem| {668 for (elems) |*elem| {
662 elem.* = (try readFromMemory(elem_ty, mod, buffer[offset..], arena)).toIntern();669 elem.* = (try readFromMemory(elem_ty, mod, buffer[offset..], arena)).toIntern();
663 offset += @intCast(elem_size);670 offset += @intCast(elem_size);
664 }671 }
665 return Value.fromInterned((try mod.intern(.{ .aggregate = .{672 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
666 .ty = ty.toIntern(),673 .ty = ty.toIntern(),
667 .storage = .{ .elems = elems },674 .storage = .{ .elems = elems },
668 } })));675 } }));
669 },676 },
670 .Vector => {677 .Vector => {
671 // We use byte_count instead of abi_size here, so that any padding bytes678 // 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.679 // follow the data bytes, on both big- and little-endian systems.
673 const byte_count = (@as(usize, @intCast(ty.bitSize(mod))) + 7) / 8;680 const byte_count = (@as(usize, @intCast(ty.bitSize(pt))) + 7) / 8;
674 return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena);681 return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena);
675 },682 },
676 .Struct => {683 .Struct => {
...@@ -683,16 +690,16 @@ pub fn readFromMemory(...@@ -683,16 +690,16 @@ pub fn readFromMemory(
683 for (field_vals, 0..) |*field_val, i| {690 for (field_vals, 0..) |*field_val, i| {
684 const field_ty = Type.fromInterned(field_types.get(ip)[i]);691 const field_ty = Type.fromInterned(field_types.get(ip)[i]);
685 const off: usize = @intCast(ty.structFieldOffset(i, mod));692 const off: usize = @intCast(ty.structFieldOffset(i, mod));
686 const sz: usize = @intCast(field_ty.abiSize(mod));693 const sz: usize = @intCast(field_ty.abiSize(pt));
687 field_val.* = (try readFromMemory(field_ty, mod, buffer[off..(off + sz)], arena)).toIntern();694 field_val.* = (try readFromMemory(field_ty, mod, buffer[off..(off + sz)], arena)).toIntern();
688 }695 }
689 return Value.fromInterned((try mod.intern(.{ .aggregate = .{696 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
690 .ty = ty.toIntern(),697 .ty = ty.toIntern(),
691 .storage = .{ .elems = field_vals },698 .storage = .{ .elems = field_vals },
692 } })));699 } }));
693 },700 },
694 .@"packed" => {701 .@"packed" => {
695 const byte_count = (@as(usize, @intCast(ty.bitSize(mod))) + 7) / 8;702 const byte_count = (@as(usize, @intCast(ty.bitSize(pt))) + 7) / 8;
696 return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena);703 return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena);
697 },704 },
698 }705 }
...@@ -704,49 +711,49 @@ pub fn readFromMemory(...@@ -704,49 +711,49 @@ pub fn readFromMemory(
704 const index = (int << @as(u6, @intCast(64 - bits))) >> @as(u6, @intCast(64 - bits));711 const index = (int << @as(u6, @intCast(64 - bits))) >> @as(u6, @intCast(64 - bits));
705 const name = mod.global_error_set.keys()[@intCast(index)];712 const name = mod.global_error_set.keys()[@intCast(index)];
706713
707 return Value.fromInterned((try mod.intern(.{ .err = .{714 return Value.fromInterned(try pt.intern(.{ .err = .{
708 .ty = ty.toIntern(),715 .ty = ty.toIntern(),
709 .name = name,716 .name = name,
710 } })));717 } }));
711 },718 },
712 .Union => switch (ty.containerLayout(mod)) {719 .Union => switch (ty.containerLayout(mod)) {
713 .auto => return error.IllDefinedMemoryLayout,720 .auto => return error.IllDefinedMemoryLayout,
714 .@"extern" => {721 .@"extern" => {
715 const union_size = ty.abiSize(mod);722 const union_size = ty.abiSize(pt);
716 const array_ty = try mod.arrayType(.{ .len = union_size, .child = .u8_type });723 const array_ty = try mod.arrayType(.{ .len = union_size, .child = .u8_type });
717 const val = (try readFromMemory(array_ty, mod, buffer, arena)).toIntern();724 const val = (try readFromMemory(array_ty, mod, buffer, arena)).toIntern();
718 return Value.fromInterned((try mod.intern(.{ .un = .{725 return Value.fromInterned(try pt.intern(.{ .un = .{
719 .ty = ty.toIntern(),726 .ty = ty.toIntern(),
720 .tag = .none,727 .tag = .none,
721 .val = val,728 .val = val,
722 } })));729 } }));
723 },730 },
724 .@"packed" => {731 .@"packed" => {
725 const byte_count = (@as(usize, @intCast(ty.bitSize(mod))) + 7) / 8;732 const byte_count = (@as(usize, @intCast(ty.bitSize(pt))) + 7) / 8;
726 return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena);733 return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena);
727 },734 },
728 },735 },
729 .Pointer => {736 .Pointer => {
730 assert(!ty.isSlice(mod)); // No well defined layout.737 assert(!ty.isSlice(mod)); // No well defined layout.
731 const int_val = try readFromMemory(Type.usize, mod, buffer, arena);738 const int_val = try readFromMemory(Type.usize, mod, buffer, arena);
732 return Value.fromInterned((try mod.intern(.{ .ptr = .{739 return Value.fromInterned(try pt.intern(.{ .ptr = .{
733 .ty = ty.toIntern(),740 .ty = ty.toIntern(),
734 .base_addr = .int,741 .base_addr = .int,
735 .byte_offset = int_val.toUnsignedInt(mod),742 .byte_offset = int_val.toUnsignedInt(pt),
736 } })));743 } }));
737 },744 },
738 .Optional => {745 .Optional => {
739 assert(ty.isPtrLikeOptional(mod));746 assert(ty.isPtrLikeOptional(mod));
740 const child_ty = ty.optionalChild(mod);747 const child_ty = ty.optionalChild(mod);
741 const child_val = try readFromMemory(child_ty, mod, buffer, arena);748 const child_val = try readFromMemory(child_ty, mod, buffer, arena);
742 return Value.fromInterned((try mod.intern(.{ .opt = .{749 return Value.fromInterned(try pt.intern(.{ .opt = .{
743 .ty = ty.toIntern(),750 .ty = ty.toIntern(),
744 .val = switch (child_val.orderAgainstZero(mod)) {751 .val = switch (child_val.orderAgainstZero(pt)) {
745 .lt => unreachable,752 .lt => unreachable,
746 .eq => .none,753 .eq => .none,
747 .gt => child_val.toIntern(),754 .gt => child_val.toIntern(),
748 },755 },
749 } })));756 } }));
750 },757 },
751 else => return error.Unimplemented,758 else => return error.Unimplemented,
752 }759 }
...@@ -758,7 +765,7 @@ pub fn readFromMemory(...@@ -758,7 +765,7 @@ pub fn readFromMemory(
758/// big-endian packed memory layouts start at the end of the buffer.765/// big-endian packed memory layouts start at the end of the buffer.
759pub fn readFromPackedMemory(766pub fn readFromPackedMemory(
760 ty: Type,767 ty: Type,
761 mod: *Module,768 pt: Zcu.PerThread,
762 buffer: []const u8,769 buffer: []const u8,
763 bit_offset: usize,770 bit_offset: usize,
764 arena: Allocator,771 arena: Allocator,
...@@ -766,6 +773,7 @@ pub fn readFromPackedMemory(...@@ -766,6 +773,7 @@ pub fn readFromPackedMemory(
766 IllDefinedMemoryLayout,773 IllDefinedMemoryLayout,
767 OutOfMemory,774 OutOfMemory,
768}!Value {775}!Value {
776 const mod = pt.zcu;
769 const ip = &mod.intern_pool;777 const ip = &mod.intern_pool;
770 const target = mod.getTarget();778 const target = mod.getTarget();
771 const endian = target.cpu.arch.endian();779 const endian = target.cpu.arch.endian();
...@@ -783,35 +791,35 @@ pub fn readFromPackedMemory(...@@ -783,35 +791,35 @@ pub fn readFromPackedMemory(
783 }791 }
784 },792 },
785 .Int => {793 .Int => {
786 if (buffer.len == 0) return mod.intValue(ty, 0);794 if (buffer.len == 0) return pt.intValue(ty, 0);
787 const int_info = ty.intInfo(mod);795 const int_info = ty.intInfo(mod);
788 const bits = int_info.bits;796 const bits = int_info.bits;
789 if (bits == 0) return mod.intValue(ty, 0);797 if (bits == 0) return pt.intValue(ty, 0);
790798
791 // Fast path for integers <= u64799 // Fast path for integers <= u64
792 if (bits <= 64) switch (int_info.signedness) {800 if (bits <= 64) switch (int_info.signedness) {
793 // Use different backing types for unsigned vs signed to avoid the need to go via801 // Use different backing types for unsigned vs signed to avoid the need to go via
794 // a larger type like `i128`.802 // a larger type like `i128`.
795 .unsigned => return mod.intValue(ty, std.mem.readVarPackedInt(u64, buffer, bit_offset, bits, endian, .unsigned)),803 .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)),804 .signed => return pt.intValue(ty, std.mem.readVarPackedInt(i64, buffer, bit_offset, bits, endian, .signed)),
797 };805 };
798806
799 // Slow path, we have to construct a big-int807 // Slow path, we have to construct a big-int
800 const abi_size: usize = @intCast(ty.abiSize(mod));808 const abi_size: usize = @intCast(ty.abiSize(pt));
801 const Limb = std.math.big.Limb;809 const Limb = std.math.big.Limb;
802 const limb_count = (abi_size + @sizeOf(Limb) - 1) / @sizeOf(Limb);810 const limb_count = (abi_size + @sizeOf(Limb) - 1) / @sizeOf(Limb);
803 const limbs_buffer = try arena.alloc(Limb, limb_count);811 const limbs_buffer = try arena.alloc(Limb, limb_count);
804812
805 var bigint = BigIntMutable.init(limbs_buffer, 0);813 var bigint = BigIntMutable.init(limbs_buffer, 0);
806 bigint.readPackedTwosComplement(buffer, bit_offset, bits, endian, int_info.signedness);814 bigint.readPackedTwosComplement(buffer, bit_offset, bits, endian, int_info.signedness);
807 return mod.intValue_big(ty, bigint.toConst());815 return pt.intValue_big(ty, bigint.toConst());
808 },816 },
809 .Enum => {817 .Enum => {
810 const int_ty = ty.intTagType(mod);818 const int_ty = ty.intTagType(mod);
811 const int_val = try Value.readFromPackedMemory(int_ty, mod, buffer, bit_offset, arena);819 const int_val = try Value.readFromPackedMemory(int_ty, pt, buffer, bit_offset, arena);
812 return mod.getCoerced(int_val, ty);820 return pt.getCoerced(int_val, ty);
813 },821 },
814 .Float => return Value.fromInterned((try mod.intern(.{ .float = .{822 .Float => return Value.fromInterned(try pt.intern(.{ .float = .{
815 .ty = ty.toIntern(),823 .ty = ty.toIntern(),
816 .storage = switch (ty.floatBits(target)) {824 .storage = switch (ty.floatBits(target)) {
817 16 => .{ .f16 = @bitCast(std.mem.readPackedInt(u16, buffer, bit_offset, endian)) },825 16 => .{ .f16 = @bitCast(std.mem.readPackedInt(u16, buffer, bit_offset, endian)) },
...@@ -821,23 +829,23 @@ pub fn readFromPackedMemory(...@@ -821,23 +829,23 @@ pub fn readFromPackedMemory(
821 128 => .{ .f128 = @bitCast(std.mem.readPackedInt(u128, buffer, bit_offset, endian)) },829 128 => .{ .f128 = @bitCast(std.mem.readPackedInt(u128, buffer, bit_offset, endian)) },
822 else => unreachable,830 else => unreachable,
823 },831 },
824 } }))),832 } })),
825 .Vector => {833 .Vector => {
826 const elem_ty = ty.childType(mod);834 const elem_ty = ty.childType(mod);
827 const elems = try arena.alloc(InternPool.Index, @intCast(ty.arrayLen(mod)));835 const elems = try arena.alloc(InternPool.Index, @intCast(ty.arrayLen(mod)));
828836
829 var bits: u16 = 0;837 var bits: u16 = 0;
830 const elem_bit_size: u16 = @intCast(elem_ty.bitSize(mod));838 const elem_bit_size: u16 = @intCast(elem_ty.bitSize(pt));
831 for (elems, 0..) |_, i| {839 for (elems, 0..) |_, i| {
832 // On big-endian systems, LLVM reverses the element order of vectors by default840 // 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;841 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();842 elems[tgt_elem_i] = (try readFromPackedMemory(elem_ty, pt, buffer, bit_offset + bits, arena)).toIntern();
835 bits += elem_bit_size;843 bits += elem_bit_size;
836 }844 }
837 return Value.fromInterned((try mod.intern(.{ .aggregate = .{845 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
838 .ty = ty.toIntern(),846 .ty = ty.toIntern(),
839 .storage = .{ .elems = elems },847 .storage = .{ .elems = elems },
840 } })));848 } }));
841 },849 },
842 .Struct => {850 .Struct => {
843 // Sema is supposed to have emitted a compile error already for Auto layout structs,851 // Sema is supposed to have emitted a compile error already for Auto layout structs,
...@@ -847,43 +855,43 @@ pub fn readFromPackedMemory(...@@ -847,43 +855,43 @@ pub fn readFromPackedMemory(
847 const field_vals = try arena.alloc(InternPool.Index, struct_type.field_types.len);855 const field_vals = try arena.alloc(InternPool.Index, struct_type.field_types.len);
848 for (field_vals, 0..) |*field_val, i| {856 for (field_vals, 0..) |*field_val, i| {
849 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);857 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
850 const field_bits: u16 = @intCast(field_ty.bitSize(mod));858 const field_bits: u16 = @intCast(field_ty.bitSize(pt));
851 field_val.* = (try readFromPackedMemory(field_ty, mod, buffer, bit_offset + bits, arena)).toIntern();859 field_val.* = (try readFromPackedMemory(field_ty, pt, buffer, bit_offset + bits, arena)).toIntern();
852 bits += field_bits;860 bits += field_bits;
853 }861 }
854 return Value.fromInterned((try mod.intern(.{ .aggregate = .{862 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
855 .ty = ty.toIntern(),863 .ty = ty.toIntern(),
856 .storage = .{ .elems = field_vals },864 .storage = .{ .elems = field_vals },
857 } })));865 } }));
858 },866 },
859 .Union => switch (ty.containerLayout(mod)) {867 .Union => switch (ty.containerLayout(mod)) {
860 .auto, .@"extern" => unreachable, // Handled by non-packed readFromMemory868 .auto, .@"extern" => unreachable, // Handled by non-packed readFromMemory
861 .@"packed" => {869 .@"packed" => {
862 const backing_ty = try ty.unionBackingType(mod);870 const backing_ty = try ty.unionBackingType(pt);
863 const val = (try readFromPackedMemory(backing_ty, mod, buffer, bit_offset, arena)).toIntern();871 const val = (try readFromPackedMemory(backing_ty, pt, buffer, bit_offset, arena)).toIntern();
864 return Value.fromInterned((try mod.intern(.{ .un = .{872 return Value.fromInterned(try pt.intern(.{ .un = .{
865 .ty = ty.toIntern(),873 .ty = ty.toIntern(),
866 .tag = .none,874 .tag = .none,
867 .val = val,875 .val = val,
868 } })));876 } }));
869 },877 },
870 },878 },
871 .Pointer => {879 .Pointer => {
872 assert(!ty.isSlice(mod)); // No well defined layout.880 assert(!ty.isSlice(mod)); // No well defined layout.
873 const int_val = try readFromPackedMemory(Type.usize, mod, buffer, bit_offset, arena);881 const int_val = try readFromPackedMemory(Type.usize, pt, buffer, bit_offset, arena);
874 return Value.fromInterned(try mod.intern(.{ .ptr = .{882 return Value.fromInterned(try pt.intern(.{ .ptr = .{
875 .ty = ty.toIntern(),883 .ty = ty.toIntern(),
876 .base_addr = .int,884 .base_addr = .int,
877 .byte_offset = int_val.toUnsignedInt(mod),885 .byte_offset = int_val.toUnsignedInt(pt),
878 } }));886 } }));
879 },887 },
880 .Optional => {888 .Optional => {
881 assert(ty.isPtrLikeOptional(mod));889 assert(ty.isPtrLikeOptional(mod));
882 const child_ty = ty.optionalChild(mod);890 const child_ty = ty.optionalChild(mod);
883 const child_val = try readFromPackedMemory(child_ty, mod, buffer, bit_offset, arena);891 const child_val = try readFromPackedMemory(child_ty, pt, buffer, bit_offset, arena);
884 return Value.fromInterned(try mod.intern(.{ .opt = .{892 return Value.fromInterned(try pt.intern(.{ .opt = .{
885 .ty = ty.toIntern(),893 .ty = ty.toIntern(),
886 .val = switch (child_val.orderAgainstZero(mod)) {894 .val = switch (child_val.orderAgainstZero(pt)) {
887 .lt => unreachable,895 .lt => unreachable,
888 .eq => .none,896 .eq => .none,
889 .gt => child_val.toIntern(),897 .gt => child_val.toIntern(),
...@@ -895,8 +903,8 @@ pub fn readFromPackedMemory(...@@ -895,8 +903,8 @@ pub fn readFromPackedMemory(
895}903}
896904
897/// Asserts that the value is a float or an integer.905/// Asserts that the value is a float or an integer.
898pub fn toFloat(val: Value, comptime T: type, mod: *Module) T {906pub fn toFloat(val: Value, comptime T: type, pt: Zcu.PerThread) T {
899 return switch (mod.intern_pool.indexToKey(val.toIntern())) {907 return switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) {
900 .int => |int| switch (int.storage) {908 .int => |int| switch (int.storage) {
901 .big_int => |big_int| @floatCast(bigIntToFloat(big_int.limbs, big_int.positive)),909 .big_int => |big_int| @floatCast(bigIntToFloat(big_int.limbs, big_int.positive)),
902 inline .u64, .i64 => |x| {910 inline .u64, .i64 => |x| {
...@@ -905,8 +913,8 @@ pub fn toFloat(val: Value, comptime T: type, mod: *Module) T {...@@ -905,8 +913,8 @@ pub fn toFloat(val: Value, comptime T: type, mod: *Module) T {
905 }913 }
906 return @floatFromInt(x);914 return @floatFromInt(x);
907 },915 },
908 .lazy_align => |ty| @floatFromInt(Type.fromInterned(ty).abiAlignment(mod).toByteUnits() orelse 0),916 .lazy_align => |ty| @floatFromInt(Type.fromInterned(ty).abiAlignment(pt).toByteUnits() orelse 0),
909 .lazy_size => |ty| @floatFromInt(Type.fromInterned(ty).abiSize(mod)),917 .lazy_size => |ty| @floatFromInt(Type.fromInterned(ty).abiSize(pt)),
910 },918 },
911 .float => |float| switch (float.storage) {919 .float => |float| switch (float.storage) {
912 inline else => |x| @floatCast(x),920 inline else => |x| @floatCast(x),
...@@ -934,29 +942,30 @@ fn bigIntToFloat(limbs: []const std.math.big.Limb, positive: bool) f128 {...@@ -934,29 +942,30 @@ fn bigIntToFloat(limbs: []const std.math.big.Limb, positive: bool) f128 {
934 }942 }
935}943}
936944
937pub fn clz(val: Value, ty: Type, mod: *Module) u64 {945pub fn clz(val: Value, ty: Type, pt: Zcu.PerThread) u64 {
938 var bigint_buf: BigIntSpace = undefined;946 var bigint_buf: BigIntSpace = undefined;
939 const bigint = val.toBigInt(&bigint_buf, mod);947 const bigint = val.toBigInt(&bigint_buf, pt);
940 return bigint.clz(ty.intInfo(mod).bits);948 return bigint.clz(ty.intInfo(pt.zcu).bits);
941}949}
942950
943pub fn ctz(val: Value, ty: Type, mod: *Module) u64 {951pub fn ctz(val: Value, ty: Type, pt: Zcu.PerThread) u64 {
944 var bigint_buf: BigIntSpace = undefined;952 var bigint_buf: BigIntSpace = undefined;
945 const bigint = val.toBigInt(&bigint_buf, mod);953 const bigint = val.toBigInt(&bigint_buf, pt);
946 return bigint.ctz(ty.intInfo(mod).bits);954 return bigint.ctz(ty.intInfo(pt.zcu).bits);
947}955}
948956
949pub fn popCount(val: Value, ty: Type, mod: *Module) u64 {957pub fn popCount(val: Value, ty: Type, pt: Zcu.PerThread) u64 {
950 var bigint_buf: BigIntSpace = undefined;958 var bigint_buf: BigIntSpace = undefined;
951 const bigint = val.toBigInt(&bigint_buf, mod);959 const bigint = val.toBigInt(&bigint_buf, pt);
952 return @intCast(bigint.popCount(ty.intInfo(mod).bits));960 return @intCast(bigint.popCount(ty.intInfo(pt.zcu).bits));
953}961}
954962
955pub fn bitReverse(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value {963pub fn bitReverse(val: Value, ty: Type, pt: Zcu.PerThread, arena: Allocator) !Value {
964 const mod = pt.zcu;
956 const info = ty.intInfo(mod);965 const info = ty.intInfo(mod);
957966
958 var buffer: Value.BigIntSpace = undefined;967 var buffer: Value.BigIntSpace = undefined;
959 const operand_bigint = val.toBigInt(&buffer, mod);968 const operand_bigint = val.toBigInt(&buffer, pt);
960969
961 const limbs = try arena.alloc(970 const limbs = try arena.alloc(
962 std.math.big.Limb,971 std.math.big.Limb,
...@@ -965,17 +974,18 @@ pub fn bitReverse(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value {...@@ -965,17 +974,18 @@ pub fn bitReverse(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value {
965 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };974 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
966 result_bigint.bitReverse(operand_bigint, info.signedness, info.bits);975 result_bigint.bitReverse(operand_bigint, info.signedness, info.bits);
967976
968 return mod.intValue_big(ty, result_bigint.toConst());977 return pt.intValue_big(ty, result_bigint.toConst());
969}978}
970979
971pub fn byteSwap(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value {980pub fn byteSwap(val: Value, ty: Type, pt: Zcu.PerThread, arena: Allocator) !Value {
981 const mod = pt.zcu;
972 const info = ty.intInfo(mod);982 const info = ty.intInfo(mod);
973983
974 // Bit count must be evenly divisible by 8984 // Bit count must be evenly divisible by 8
975 assert(info.bits % 8 == 0);985 assert(info.bits % 8 == 0);
976986
977 var buffer: Value.BigIntSpace = undefined;987 var buffer: Value.BigIntSpace = undefined;
978 const operand_bigint = val.toBigInt(&buffer, mod);988 const operand_bigint = val.toBigInt(&buffer, pt);
979989
980 const limbs = try arena.alloc(990 const limbs = try arena.alloc(
981 std.math.big.Limb,991 std.math.big.Limb,
...@@ -984,33 +994,33 @@ pub fn byteSwap(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value {...@@ -984,33 +994,33 @@ pub fn byteSwap(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value {
984 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };994 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
985 result_bigint.byteSwap(operand_bigint, info.signedness, info.bits / 8);995 result_bigint.byteSwap(operand_bigint, info.signedness, info.bits / 8);
986996
987 return mod.intValue_big(ty, result_bigint.toConst());997 return pt.intValue_big(ty, result_bigint.toConst());
988}998}
989999
990/// Asserts the value is an integer and not undefined.1000/// 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.1001/// Returns the number of bits the value requires to represent stored in twos complement form.
992pub fn intBitCountTwosComp(self: Value, mod: *Module) usize {1002pub fn intBitCountTwosComp(self: Value, pt: Zcu.PerThread) usize {
993 var buffer: BigIntSpace = undefined;1003 var buffer: BigIntSpace = undefined;
994 const big_int = self.toBigInt(&buffer, mod);1004 const big_int = self.toBigInt(&buffer, pt);
995 return big_int.bitCountTwosComp();1005 return big_int.bitCountTwosComp();
996}1006}
9971007
998/// Converts an integer or a float to a float. May result in a loss of information.1008/// 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.1009/// Caller can find out by equality checking the result against the operand.
1000pub fn floatCast(val: Value, dest_ty: Type, zcu: *Zcu) !Value {1010pub fn floatCast(val: Value, dest_ty: Type, pt: Zcu.PerThread) !Value {
1001 const target = zcu.getTarget();1011 const target = pt.zcu.getTarget();
1002 if (val.isUndef(zcu)) return zcu.undefValue(dest_ty);1012 if (val.isUndef(pt.zcu)) return pt.undefValue(dest_ty);
1003 return Value.fromInterned((try zcu.intern(.{ .float = .{1013 return Value.fromInterned(try pt.intern(.{ .float = .{
1004 .ty = dest_ty.toIntern(),1014 .ty = dest_ty.toIntern(),
1005 .storage = switch (dest_ty.floatBits(target)) {1015 .storage = switch (dest_ty.floatBits(target)) {
1006 16 => .{ .f16 = val.toFloat(f16, zcu) },1016 16 => .{ .f16 = val.toFloat(f16, pt) },
1007 32 => .{ .f32 = val.toFloat(f32, zcu) },1017 32 => .{ .f32 = val.toFloat(f32, pt) },
1008 64 => .{ .f64 = val.toFloat(f64, zcu) },1018 64 => .{ .f64 = val.toFloat(f64, pt) },
1009 80 => .{ .f80 = val.toFloat(f80, zcu) },1019 80 => .{ .f80 = val.toFloat(f80, pt) },
1010 128 => .{ .f128 = val.toFloat(f128, zcu) },1020 128 => .{ .f128 = val.toFloat(f128, pt) },
1011 else => unreachable,1021 else => unreachable,
1012 },1022 },
1013 } })));1023 } }));
1014}1024}
10151025
1016/// Asserts the value is a float1026/// Asserts the value is a float
...@@ -1023,19 +1033,19 @@ pub fn floatHasFraction(self: Value, mod: *const Module) bool {...@@ -1023,19 +1033,19 @@ pub fn floatHasFraction(self: Value, mod: *const Module) bool {
1023 };1033 };
1024}1034}
10251035
1026pub fn orderAgainstZero(lhs: Value, mod: *Module) std.math.Order {1036pub fn orderAgainstZero(lhs: Value, pt: Zcu.PerThread) std.math.Order {
1027 return orderAgainstZeroAdvanced(lhs, mod, .normal) catch unreachable;1037 return orderAgainstZeroAdvanced(lhs, pt, .normal) catch unreachable;
1028}1038}
10291039
1030pub fn orderAgainstZeroAdvanced(1040pub fn orderAgainstZeroAdvanced(
1031 lhs: Value,1041 lhs: Value,
1032 mod: *Module,1042 pt: Zcu.PerThread,
1033 strat: ResolveStrat,1043 strat: ResolveStrat,
1034) Module.CompileError!std.math.Order {1044) Module.CompileError!std.math.Order {
1035 return switch (lhs.toIntern()) {1045 return switch (lhs.toIntern()) {
1036 .bool_false => .eq,1046 .bool_false => .eq,
1037 .bool_true => .gt,1047 .bool_true => .gt,
1038 else => switch (mod.intern_pool.indexToKey(lhs.toIntern())) {1048 else => switch (pt.zcu.intern_pool.indexToKey(lhs.toIntern())) {
1039 .ptr => |ptr| if (ptr.byte_offset > 0) .gt else switch (ptr.base_addr) {1049 .ptr => |ptr| if (ptr.byte_offset > 0) .gt else switch (ptr.base_addr) {
1040 .decl, .comptime_alloc, .comptime_field => .gt,1050 .decl, .comptime_alloc, .comptime_field => .gt,
1041 .int => .eq,1051 .int => .eq,
...@@ -1046,7 +1056,7 @@ pub fn orderAgainstZeroAdvanced(...@@ -1046,7 +1056,7 @@ pub fn orderAgainstZeroAdvanced(
1046 inline .u64, .i64 => |x| std.math.order(x, 0),1056 inline .u64, .i64 => |x| std.math.order(x, 0),
1047 .lazy_align => .gt, // alignment is never 01057 .lazy_align => .gt, // alignment is never 0
1048 .lazy_size => |ty| return if (Type.fromInterned(ty).hasRuntimeBitsAdvanced(1058 .lazy_size => |ty| return if (Type.fromInterned(ty).hasRuntimeBitsAdvanced(
1049 mod,1059 pt,
1050 false,1060 false,
1051 strat.toLazy(),1061 strat.toLazy(),
1052 ) catch |err| switch (err) {1062 ) catch |err| switch (err) {
...@@ -1054,7 +1064,7 @@ pub fn orderAgainstZeroAdvanced(...@@ -1054,7 +1064,7 @@ pub fn orderAgainstZeroAdvanced(
1054 else => |e| return e,1064 else => |e| return e,
1055 }) .gt else .eq,1065 }) .gt else .eq,
1056 },1066 },
1057 .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).orderAgainstZeroAdvanced(mod, strat),1067 .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).orderAgainstZeroAdvanced(pt, strat),
1058 .float => |float| switch (float.storage) {1068 .float => |float| switch (float.storage) {
1059 inline else => |x| std.math.order(x, 0),1069 inline else => |x| std.math.order(x, 0),
1060 },1070 },
...@@ -1064,14 +1074,14 @@ pub fn orderAgainstZeroAdvanced(...@@ -1064,14 +1074,14 @@ pub fn orderAgainstZeroAdvanced(
1064}1074}
10651075
1066/// Asserts the value is comparable.1076/// Asserts the value is comparable.
1067pub fn order(lhs: Value, rhs: Value, mod: *Module) std.math.Order {1077pub fn order(lhs: Value, rhs: Value, pt: Zcu.PerThread) std.math.Order {
1068 return orderAdvanced(lhs, rhs, mod, .normal) catch unreachable;1078 return orderAdvanced(lhs, rhs, pt, .normal) catch unreachable;
1069}1079}
10701080
1071/// Asserts the value is comparable.1081/// Asserts the value is comparable.
1072pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *Module, strat: ResolveStrat) !std.math.Order {1082pub fn orderAdvanced(lhs: Value, rhs: Value, pt: Zcu.PerThread, strat: ResolveStrat) !std.math.Order {
1073 const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(mod, strat);1083 const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(pt, strat);
1074 const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(mod, strat);1084 const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(pt, strat);
1075 switch (lhs_against_zero) {1085 switch (lhs_against_zero) {
1076 .lt => if (rhs_against_zero != .lt) return .lt,1086 .lt => if (rhs_against_zero != .lt) return .lt,
1077 .eq => return rhs_against_zero.invert(),1087 .eq => return rhs_against_zero.invert(),
...@@ -1083,34 +1093,34 @@ pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *Module, strat: ResolveStrat)...@@ -1083,34 +1093,34 @@ pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *Module, strat: ResolveStrat)
1083 .gt => {},1093 .gt => {},
1084 }1094 }
10851095
1086 if (lhs.isFloat(mod) or rhs.isFloat(mod)) {1096 if (lhs.isFloat(pt.zcu) or rhs.isFloat(pt.zcu)) {
1087 const lhs_f128 = lhs.toFloat(f128, mod);1097 const lhs_f128 = lhs.toFloat(f128, pt);
1088 const rhs_f128 = rhs.toFloat(f128, mod);1098 const rhs_f128 = rhs.toFloat(f128, pt);
1089 return std.math.order(lhs_f128, rhs_f128);1099 return std.math.order(lhs_f128, rhs_f128);
1090 }1100 }
10911101
1092 var lhs_bigint_space: BigIntSpace = undefined;1102 var lhs_bigint_space: BigIntSpace = undefined;
1093 var rhs_bigint_space: BigIntSpace = undefined;1103 var rhs_bigint_space: BigIntSpace = undefined;
1094 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, mod, strat);1104 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, pt, strat);
1095 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, mod, strat);1105 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, pt, strat);
1096 return lhs_bigint.order(rhs_bigint);1106 return lhs_bigint.order(rhs_bigint);
1097}1107}
10981108
1099/// Asserts the value is comparable. Does not take a type parameter because it supports1109/// Asserts the value is comparable. Does not take a type parameter because it supports
1100/// comparisons between heterogeneous types.1110/// comparisons between heterogeneous types.
1101pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, mod: *Module) bool {1111pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, pt: Zcu.PerThread) bool {
1102 return compareHeteroAdvanced(lhs, op, rhs, mod, .normal) catch unreachable;1112 return compareHeteroAdvanced(lhs, op, rhs, pt, .normal) catch unreachable;
1103}1113}
11041114
1105pub fn compareHeteroAdvanced(1115pub fn compareHeteroAdvanced(
1106 lhs: Value,1116 lhs: Value,
1107 op: std.math.CompareOperator,1117 op: std.math.CompareOperator,
1108 rhs: Value,1118 rhs: Value,
1109 mod: *Module,1119 pt: Zcu.PerThread,
1110 strat: ResolveStrat,1120 strat: ResolveStrat,
1111) !bool {1121) !bool {
1112 if (lhs.pointerDecl(mod)) |lhs_decl| {1122 if (lhs.pointerDecl(pt.zcu)) |lhs_decl| {
1113 if (rhs.pointerDecl(mod)) |rhs_decl| {1123 if (rhs.pointerDecl(pt.zcu)) |rhs_decl| {
1114 switch (op) {1124 switch (op) {
1115 .eq => return lhs_decl == rhs_decl,1125 .eq => return lhs_decl == rhs_decl,
1116 .neq => return lhs_decl != rhs_decl,1126 .neq => return lhs_decl != rhs_decl,
...@@ -1123,31 +1133,32 @@ pub fn compareHeteroAdvanced(...@@ -1123,31 +1133,32 @@ pub fn compareHeteroAdvanced(
1123 else => {},1133 else => {},
1124 }1134 }
1125 }1135 }
1126 } else if (rhs.pointerDecl(mod)) |_| {1136 } else if (rhs.pointerDecl(pt.zcu)) |_| {
1127 switch (op) {1137 switch (op) {
1128 .eq => return false,1138 .eq => return false,
1129 .neq => return true,1139 .neq => return true,
1130 else => {},1140 else => {},
1131 }1141 }
1132 }1142 }
1133 return (try orderAdvanced(lhs, rhs, mod, strat)).compare(op);1143 return (try orderAdvanced(lhs, rhs, pt, strat)).compare(op);
1134}1144}
11351145
1136/// Asserts the values are comparable. Both operands have type `ty`.1146/// Asserts the values are comparable. Both operands have type `ty`.
1137/// For vectors, returns true if comparison is true for ALL elements.1147/// 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 {1148pub fn compareAll(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, pt: Zcu.PerThread) !bool {
1149 const mod = pt.zcu;
1139 if (ty.zigTypeTag(mod) == .Vector) {1150 if (ty.zigTypeTag(mod) == .Vector) {
1140 const scalar_ty = ty.scalarType(mod);1151 const scalar_ty = ty.scalarType(mod);
1141 for (0..ty.vectorLen(mod)) |i| {1152 for (0..ty.vectorLen(mod)) |i| {
1142 const lhs_elem = try lhs.elemValue(mod, i);1153 const lhs_elem = try lhs.elemValue(pt, i);
1143 const rhs_elem = try rhs.elemValue(mod, i);1154 const rhs_elem = try rhs.elemValue(pt, i);
1144 if (!compareScalar(lhs_elem, op, rhs_elem, scalar_ty, mod)) {1155 if (!compareScalar(lhs_elem, op, rhs_elem, scalar_ty, pt)) {
1145 return false;1156 return false;
1146 }1157 }
1147 }1158 }
1148 return true;1159 return true;
1149 }1160 }
1150 return compareScalar(lhs, op, rhs, ty, mod);1161 return compareScalar(lhs, op, rhs, ty, pt);
1151}1162}
11521163
1153/// Asserts the values are comparable. Both operands have type `ty`.1164/// Asserts the values are comparable. Both operands have type `ty`.
...@@ -1156,12 +1167,12 @@ pub fn compareScalar(...@@ -1156,12 +1167,12 @@ pub fn compareScalar(
1156 op: std.math.CompareOperator,1167 op: std.math.CompareOperator,
1157 rhs: Value,1168 rhs: Value,
1158 ty: Type,1169 ty: Type,
1159 mod: *Module,1170 pt: Zcu.PerThread,
1160) bool {1171) bool {
1161 return switch (op) {1172 return switch (op) {
1162 .eq => lhs.eql(rhs, ty, mod),1173 .eq => lhs.eql(rhs, ty, pt.zcu),
1163 .neq => !lhs.eql(rhs, ty, mod),1174 .neq => !lhs.eql(rhs, ty, pt.zcu),
1164 else => compareHetero(lhs, op, rhs, mod),1175 else => compareHetero(lhs, op, rhs, pt),
1165 };1176 };
1166}1177}
11671178
...@@ -1170,24 +1181,25 @@ pub fn compareScalar(...@@ -1170,24 +1181,25 @@ pub fn compareScalar(
1170/// Returns `false` if the value or any vector element is undefined.1181/// Returns `false` if the value or any vector element is undefined.
1171///1182///
1172/// Note that `!compareAllWithZero(.eq, ...) != compareAllWithZero(.neq, ...)`1183/// Note that `!compareAllWithZero(.eq, ...) != compareAllWithZero(.neq, ...)`
1173pub fn compareAllWithZero(lhs: Value, op: std.math.CompareOperator, mod: *Module) bool {1184pub fn compareAllWithZero(lhs: Value, op: std.math.CompareOperator, pt: Zcu.PerThread) bool {
1174 return compareAllWithZeroAdvancedExtra(lhs, op, mod, .normal) catch unreachable;1185 return compareAllWithZeroAdvancedExtra(lhs, op, pt, .normal) catch unreachable;
1175}1186}
11761187
1177pub fn compareAllWithZeroSema(1188pub fn compareAllWithZeroSema(
1178 lhs: Value,1189 lhs: Value,
1179 op: std.math.CompareOperator,1190 op: std.math.CompareOperator,
1180 zcu: *Zcu,1191 pt: Zcu.PerThread,
1181) Module.CompileError!bool {1192) Module.CompileError!bool {
1182 return compareAllWithZeroAdvancedExtra(lhs, op, zcu, .sema);1193 return compareAllWithZeroAdvancedExtra(lhs, op, pt, .sema);
1183}1194}
11841195
1185pub fn compareAllWithZeroAdvancedExtra(1196pub fn compareAllWithZeroAdvancedExtra(
1186 lhs: Value,1197 lhs: Value,
1187 op: std.math.CompareOperator,1198 op: std.math.CompareOperator,
1188 mod: *Module,1199 pt: Zcu.PerThread,
1189 strat: ResolveStrat,1200 strat: ResolveStrat,
1190) Module.CompileError!bool {1201) Module.CompileError!bool {
1202 const mod = pt.zcu;
1191 if (lhs.isInf(mod)) {1203 if (lhs.isInf(mod)) {
1192 switch (op) {1204 switch (op) {
1193 .neq => return true,1205 .neq => return true,
...@@ -1206,14 +1218,14 @@ pub fn compareAllWithZeroAdvancedExtra(...@@ -1206,14 +1218,14 @@ pub fn compareAllWithZeroAdvancedExtra(
1206 if (!std.math.order(byte, 0).compare(op)) break false;1218 if (!std.math.order(byte, 0).compare(op)) break false;
1207 } else true,1219 } else true,
1208 .elems => |elems| for (elems) |elem| {1220 .elems => |elems| for (elems) |elem| {
1209 if (!try Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, mod, strat)) break false;1221 if (!try Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, pt, strat)) break false;
1210 } else true,1222 } else true,
1211 .repeated_elem => |elem| Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, mod, strat),1223 .repeated_elem => |elem| Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, pt, strat),
1212 },1224 },
1213 .undef => return false,1225 .undef => return false,
1214 else => {},1226 else => {},
1215 }1227 }
1216 return (try orderAgainstZeroAdvanced(lhs, mod, strat)).compare(op);1228 return (try orderAgainstZeroAdvanced(lhs, pt, strat)).compare(op);
1217}1229}
12181230
1219pub fn eql(a: Value, b: Value, ty: Type, mod: *Module) bool {1231pub fn eql(a: Value, b: Value, ty: Type, mod: *Module) bool {
...@@ -1275,21 +1287,22 @@ pub fn slicePtr(val: Value, mod: *Module) Value {...@@ -1275,21 +1287,22 @@ pub fn slicePtr(val: Value, mod: *Module) Value {
12751287
1276/// Gets the `len` field of a slice value as a `u64`.1288/// Gets the `len` field of a slice value as a `u64`.
1277/// Resolves the length using `Sema` if necessary.1289/// Resolves the length using `Sema` if necessary.
1278pub fn sliceLen(val: Value, zcu: *Zcu) !u64 {1290pub fn sliceLen(val: Value, pt: Zcu.PerThread) !u64 {
1279 return Value.fromInterned(zcu.intern_pool.sliceLen(val.toIntern())).toUnsignedIntSema(zcu);1291 return Value.fromInterned(pt.zcu.intern_pool.sliceLen(val.toIntern())).toUnsignedIntSema(pt);
1280}1292}
12811293
1282/// Asserts the value is an aggregate, and returns the element value at the given index.1294/// 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 {1295pub fn elemValue(val: Value, pt: Zcu.PerThread, index: usize) Allocator.Error!Value {
1296 const zcu = pt.zcu;
1284 const ip = &zcu.intern_pool;1297 const ip = &zcu.intern_pool;
1285 switch (zcu.intern_pool.indexToKey(val.toIntern())) {1298 switch (zcu.intern_pool.indexToKey(val.toIntern())) {
1286 .undef => |ty| {1299 .undef => |ty| {
1287 return Value.fromInterned(try zcu.intern(.{ .undef = Type.fromInterned(ty).childType(zcu).toIntern() }));1300 return Value.fromInterned(try pt.intern(.{ .undef = Type.fromInterned(ty).childType(zcu).toIntern() }));
1288 },1301 },
1289 .aggregate => |aggregate| {1302 .aggregate => |aggregate| {
1290 const len = ip.aggregateTypeLen(aggregate.ty);1303 const len = ip.aggregateTypeLen(aggregate.ty);
1291 if (index < len) return Value.fromInterned(switch (aggregate.storage) {1304 if (index < len) return Value.fromInterned(switch (aggregate.storage) {
1292 .bytes => |bytes| try zcu.intern(.{ .int = .{1305 .bytes => |bytes| try pt.intern(.{ .int = .{
1293 .ty = .u8_type,1306 .ty = .u8_type,
1294 .storage = .{ .u64 = bytes.at(index, ip) },1307 .storage = .{ .u64 = bytes.at(index, ip) },
1295 } }),1308 } }),
...@@ -1330,17 +1343,17 @@ pub fn sliceArray(...@@ -1330,17 +1343,17 @@ pub fn sliceArray(
1330 start: usize,1343 start: usize,
1331 end: usize,1344 end: usize,
1332) error{OutOfMemory}!Value {1345) error{OutOfMemory}!Value {
1333 const mod = sema.mod;1346 const pt = sema.pt;
1334 const ip = &mod.intern_pool;1347 const ip = &pt.zcu.intern_pool;
1335 return Value.fromInterned(try mod.intern(.{1348 return Value.fromInterned(try pt.intern(.{
1336 .aggregate = .{1349 .aggregate = .{
1337 .ty = switch (mod.intern_pool.indexToKey(mod.intern_pool.typeOf(val.toIntern()))) {1350 .ty = switch (pt.zcu.intern_pool.indexToKey(pt.zcu.intern_pool.typeOf(val.toIntern()))) {
1338 .array_type => |array_type| try mod.arrayType(.{1351 .array_type => |array_type| try pt.arrayType(.{
1339 .len = @intCast(end - start),1352 .len = @intCast(end - start),
1340 .child = array_type.child,1353 .child = array_type.child,
1341 .sentinel = if (end == array_type.len) array_type.sentinel else .none,1354 .sentinel = if (end == array_type.len) array_type.sentinel else .none,
1342 }),1355 }),
1343 .vector_type => |vector_type| try mod.vectorType(.{1356 .vector_type => |vector_type| try pt.vectorType(.{
1344 .len = @intCast(end - start),1357 .len = @intCast(end - start),
1345 .child = vector_type.child,1358 .child = vector_type.child,
1346 }),1359 }),
...@@ -1363,13 +1376,14 @@ pub fn sliceArray(...@@ -1363,13 +1376,14 @@ pub fn sliceArray(
1363 }));1376 }));
1364}1377}
13651378
1366pub fn fieldValue(val: Value, mod: *Module, index: usize) !Value {1379pub fn fieldValue(val: Value, pt: Zcu.PerThread, index: usize) !Value {
1380 const mod = pt.zcu;
1367 return switch (mod.intern_pool.indexToKey(val.toIntern())) {1381 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
1368 .undef => |ty| Value.fromInterned((try mod.intern(.{1382 .undef => |ty| Value.fromInterned(try pt.intern(.{
1369 .undef = Type.fromInterned(ty).structFieldType(index, mod).toIntern(),1383 .undef = Type.fromInterned(ty).structFieldType(index, mod).toIntern(),
1370 }))),1384 })),
1371 .aggregate => |aggregate| Value.fromInterned(switch (aggregate.storage) {1385 .aggregate => |aggregate| Value.fromInterned(switch (aggregate.storage) {
1372 .bytes => |bytes| try mod.intern(.{ .int = .{1386 .bytes => |bytes| try pt.intern(.{ .int = .{
1373 .ty = .u8_type,1387 .ty = .u8_type,
1374 .storage = .{ .u64 = bytes.at(index, &mod.intern_pool) },1388 .storage = .{ .u64 = bytes.at(index, &mod.intern_pool) },
1375 } }),1389 } }),
...@@ -1483,40 +1497,49 @@ pub fn floatFromInt(val: Value, arena: Allocator, int_ty: Type, float_ty: Type,...@@ -1483,40 +1497,49 @@ pub fn floatFromInt(val: Value, arena: Allocator, int_ty: Type, float_ty: Type,
1483 };1497 };
1484}1498}
14851499
1486pub fn floatFromIntAdvanced(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, mod: *Module, strat: ResolveStrat) !Value {1500pub fn floatFromIntAdvanced(
1501 val: Value,
1502 arena: Allocator,
1503 int_ty: Type,
1504 float_ty: Type,
1505 pt: Zcu.PerThread,
1506 strat: ResolveStrat,
1507) !Value {
1508 const mod = pt.zcu;
1487 if (int_ty.zigTypeTag(mod) == .Vector) {1509 if (int_ty.zigTypeTag(mod) == .Vector) {
1488 const result_data = try arena.alloc(InternPool.Index, int_ty.vectorLen(mod));1510 const result_data = try arena.alloc(InternPool.Index, int_ty.vectorLen(mod));
1489 const scalar_ty = float_ty.scalarType(mod);1511 const scalar_ty = float_ty.scalarType(mod);
1490 for (result_data, 0..) |*scalar, i| {1512 for (result_data, 0..) |*scalar, i| {
1491 const elem_val = try val.elemValue(mod, i);1513 const elem_val = try val.elemValue(pt, i);
1492 scalar.* = (try floatFromIntScalar(elem_val, scalar_ty, mod, strat)).toIntern();1514 scalar.* = (try floatFromIntScalar(elem_val, scalar_ty, pt, strat)).toIntern();
1493 }1515 }
1494 return Value.fromInterned((try mod.intern(.{ .aggregate = .{1516 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
1495 .ty = float_ty.toIntern(),1517 .ty = float_ty.toIntern(),
1496 .storage = .{ .elems = result_data },1518 .storage = .{ .elems = result_data },
1497 } })));1519 } }));
1498 }1520 }
1499 return floatFromIntScalar(val, float_ty, mod, strat);1521 return floatFromIntScalar(val, float_ty, pt, strat);
1500}1522}
15011523
1502pub fn floatFromIntScalar(val: Value, float_ty: Type, mod: *Module, strat: ResolveStrat) !Value {1524pub fn floatFromIntScalar(val: Value, float_ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) !Value {
1525 const mod = pt.zcu;
1503 return switch (mod.intern_pool.indexToKey(val.toIntern())) {1526 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
1504 .undef => try mod.undefValue(float_ty),1527 .undef => try pt.undefValue(float_ty),
1505 .int => |int| switch (int.storage) {1528 .int => |int| switch (int.storage) {
1506 .big_int => |big_int| {1529 .big_int => |big_int| {
1507 const float = bigIntToFloat(big_int.limbs, big_int.positive);1530 const float = bigIntToFloat(big_int.limbs, big_int.positive);
1508 return mod.floatValue(float_ty, float);1531 return pt.floatValue(float_ty, float);
1509 },1532 },
1510 inline .u64, .i64 => |x| floatFromIntInner(x, float_ty, mod),1533 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),1534 .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),1535 .lazy_size => |ty| return floatFromIntInner((try Type.fromInterned(ty).abiSizeAdvanced(pt, strat.toLazy())).scalar, float_ty, pt),
1513 },1536 },
1514 else => unreachable,1537 else => unreachable,
1515 };1538 };
1516}1539}
15171540
1518fn floatFromIntInner(x: anytype, dest_ty: Type, mod: *Module) !Value {1541fn floatFromIntInner(x: anytype, dest_ty: Type, pt: Zcu.PerThread) !Value {
1519 const target = mod.getTarget();1542 const target = pt.zcu.getTarget();
1520 const storage: InternPool.Key.Float.Storage = switch (dest_ty.floatBits(target)) {1543 const storage: InternPool.Key.Float.Storage = switch (dest_ty.floatBits(target)) {
1521 16 => .{ .f16 = @floatFromInt(x) },1544 16 => .{ .f16 = @floatFromInt(x) },
1522 32 => .{ .f32 = @floatFromInt(x) },1545 32 => .{ .f32 = @floatFromInt(x) },
...@@ -1525,10 +1548,10 @@ fn floatFromIntInner(x: anytype, dest_ty: Type, mod: *Module) !Value {...@@ -1525,10 +1548,10 @@ fn floatFromIntInner(x: anytype, dest_ty: Type, mod: *Module) !Value {
1525 128 => .{ .f128 = @floatFromInt(x) },1548 128 => .{ .f128 = @floatFromInt(x) },
1526 else => unreachable,1549 else => unreachable,
1527 };1550 };
1528 return Value.fromInterned((try mod.intern(.{ .float = .{1551 return Value.fromInterned(try pt.intern(.{ .float = .{
1529 .ty = dest_ty.toIntern(),1552 .ty = dest_ty.toIntern(),
1530 .storage = storage,1553 .storage = storage,
1531 } })));1554 } }));
1532}1555}
15331556
1534fn calcLimbLenFloat(scalar: anytype) usize {1557fn calcLimbLenFloat(scalar: anytype) usize {
...@@ -1551,22 +1574,22 @@ pub fn intAddSat(...@@ -1551,22 +1574,22 @@ pub fn intAddSat(
1551 rhs: Value,1574 rhs: Value,
1552 ty: Type,1575 ty: Type,
1553 arena: Allocator,1576 arena: Allocator,
1554 mod: *Module,1577 pt: Zcu.PerThread,
1555) !Value {1578) !Value {
1556 if (ty.zigTypeTag(mod) == .Vector) {1579 if (ty.zigTypeTag(pt.zcu) == .Vector) {
1557 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));1580 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
1558 const scalar_ty = ty.scalarType(mod);1581 const scalar_ty = ty.scalarType(pt.zcu);
1559 for (result_data, 0..) |*scalar, i| {1582 for (result_data, 0..) |*scalar, i| {
1560 const lhs_elem = try lhs.elemValue(mod, i);1583 const lhs_elem = try lhs.elemValue(pt, i);
1561 const rhs_elem = try rhs.elemValue(mod, i);1584 const rhs_elem = try rhs.elemValue(pt, i);
1562 scalar.* = (try intAddSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();1585 scalar.* = (try intAddSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern();
1563 }1586 }
1564 return Value.fromInterned((try mod.intern(.{ .aggregate = .{1587 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
1565 .ty = ty.toIntern(),1588 .ty = ty.toIntern(),
1566 .storage = .{ .elems = result_data },1589 .storage = .{ .elems = result_data },
1567 } })));1590 } }));
1568 }1591 }
1569 return intAddSatScalar(lhs, rhs, ty, arena, mod);1592 return intAddSatScalar(lhs, rhs, ty, arena, pt);
1570}1593}
15711594
1572/// Supports integers only; asserts neither operand is undefined.1595/// Supports integers only; asserts neither operand is undefined.
...@@ -1575,24 +1598,24 @@ pub fn intAddSatScalar(...@@ -1575,24 +1598,24 @@ pub fn intAddSatScalar(
1575 rhs: Value,1598 rhs: Value,
1576 ty: Type,1599 ty: Type,
1577 arena: Allocator,1600 arena: Allocator,
1578 mod: *Module,1601 pt: Zcu.PerThread,
1579) !Value {1602) !Value {
1580 assert(!lhs.isUndef(mod));1603 assert(!lhs.isUndef(pt.zcu));
1581 assert(!rhs.isUndef(mod));1604 assert(!rhs.isUndef(pt.zcu));
15821605
1583 const info = ty.intInfo(mod);1606 const info = ty.intInfo(pt.zcu);
15841607
1585 var lhs_space: Value.BigIntSpace = undefined;1608 var lhs_space: Value.BigIntSpace = undefined;
1586 var rhs_space: Value.BigIntSpace = undefined;1609 var rhs_space: Value.BigIntSpace = undefined;
1587 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);1610 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
1588 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);1611 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
1589 const limbs = try arena.alloc(1612 const limbs = try arena.alloc(
1590 std.math.big.Limb,1613 std.math.big.Limb,
1591 std.math.big.int.calcTwosCompLimbCount(info.bits),1614 std.math.big.int.calcTwosCompLimbCount(info.bits),
1592 );1615 );
1593 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };1616 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
1594 result_bigint.addSat(lhs_bigint, rhs_bigint, info.signedness, info.bits);1617 result_bigint.addSat(lhs_bigint, rhs_bigint, info.signedness, info.bits);
1595 return mod.intValue_big(ty, result_bigint.toConst());1618 return pt.intValue_big(ty, result_bigint.toConst());
1596}1619}
15971620
1598/// Supports (vectors of) integers only; asserts neither operand is undefined.1621/// Supports (vectors of) integers only; asserts neither operand is undefined.
...@@ -1601,22 +1624,22 @@ pub fn intSubSat(...@@ -1601,22 +1624,22 @@ pub fn intSubSat(
1601 rhs: Value,1624 rhs: Value,
1602 ty: Type,1625 ty: Type,
1603 arena: Allocator,1626 arena: Allocator,
1604 mod: *Module,1627 pt: Zcu.PerThread,
1605) !Value {1628) !Value {
1606 if (ty.zigTypeTag(mod) == .Vector) {1629 if (ty.zigTypeTag(pt.zcu) == .Vector) {
1607 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));1630 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
1608 const scalar_ty = ty.scalarType(mod);1631 const scalar_ty = ty.scalarType(pt.zcu);
1609 for (result_data, 0..) |*scalar, i| {1632 for (result_data, 0..) |*scalar, i| {
1610 const lhs_elem = try lhs.elemValue(mod, i);1633 const lhs_elem = try lhs.elemValue(pt, i);
1611 const rhs_elem = try rhs.elemValue(mod, i);1634 const rhs_elem = try rhs.elemValue(pt, i);
1612 scalar.* = (try intSubSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();1635 scalar.* = (try intSubSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern();
1613 }1636 }
1614 return Value.fromInterned((try mod.intern(.{ .aggregate = .{1637 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
1615 .ty = ty.toIntern(),1638 .ty = ty.toIntern(),
1616 .storage = .{ .elems = result_data },1639 .storage = .{ .elems = result_data },
1617 } })));1640 } }));
1618 }1641 }
1619 return intSubSatScalar(lhs, rhs, ty, arena, mod);1642 return intSubSatScalar(lhs, rhs, ty, arena, pt);
1620}1643}
16211644
1622/// Supports integers only; asserts neither operand is undefined.1645/// Supports integers only; asserts neither operand is undefined.
...@@ -1625,24 +1648,24 @@ pub fn intSubSatScalar(...@@ -1625,24 +1648,24 @@ pub fn intSubSatScalar(
1625 rhs: Value,1648 rhs: Value,
1626 ty: Type,1649 ty: Type,
1627 arena: Allocator,1650 arena: Allocator,
1628 mod: *Module,1651 pt: Zcu.PerThread,
1629) !Value {1652) !Value {
1630 assert(!lhs.isUndef(mod));1653 assert(!lhs.isUndef(pt.zcu));
1631 assert(!rhs.isUndef(mod));1654 assert(!rhs.isUndef(pt.zcu));
16321655
1633 const info = ty.intInfo(mod);1656 const info = ty.intInfo(pt.zcu);
16341657
1635 var lhs_space: Value.BigIntSpace = undefined;1658 var lhs_space: Value.BigIntSpace = undefined;
1636 var rhs_space: Value.BigIntSpace = undefined;1659 var rhs_space: Value.BigIntSpace = undefined;
1637 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);1660 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
1638 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);1661 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
1639 const limbs = try arena.alloc(1662 const limbs = try arena.alloc(
1640 std.math.big.Limb,1663 std.math.big.Limb,
1641 std.math.big.int.calcTwosCompLimbCount(info.bits),1664 std.math.big.int.calcTwosCompLimbCount(info.bits),
1642 );1665 );
1643 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };1666 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
1644 result_bigint.subSat(lhs_bigint, rhs_bigint, info.signedness, info.bits);1667 result_bigint.subSat(lhs_bigint, rhs_bigint, info.signedness, info.bits);
1645 return mod.intValue_big(ty, result_bigint.toConst());1668 return pt.intValue_big(ty, result_bigint.toConst());
1646}1669}
16471670
1648pub fn intMulWithOverflow(1671pub fn intMulWithOverflow(
...@@ -1650,32 +1673,33 @@ pub fn intMulWithOverflow(...@@ -1650,32 +1673,33 @@ pub fn intMulWithOverflow(
1650 rhs: Value,1673 rhs: Value,
1651 ty: Type,1674 ty: Type,
1652 arena: Allocator,1675 arena: Allocator,
1653 mod: *Module,1676 pt: Zcu.PerThread,
1654) !OverflowArithmeticResult {1677) !OverflowArithmeticResult {
1678 const mod = pt.zcu;
1655 if (ty.zigTypeTag(mod) == .Vector) {1679 if (ty.zigTypeTag(mod) == .Vector) {
1656 const vec_len = ty.vectorLen(mod);1680 const vec_len = ty.vectorLen(mod);
1657 const overflowed_data = try arena.alloc(InternPool.Index, vec_len);1681 const overflowed_data = try arena.alloc(InternPool.Index, vec_len);
1658 const result_data = try arena.alloc(InternPool.Index, vec_len);1682 const result_data = try arena.alloc(InternPool.Index, vec_len);
1659 const scalar_ty = ty.scalarType(mod);1683 const scalar_ty = ty.scalarType(mod);
1660 for (overflowed_data, result_data, 0..) |*of, *scalar, i| {1684 for (overflowed_data, result_data, 0..) |*of, *scalar, i| {
1661 const lhs_elem = try lhs.elemValue(mod, i);1685 const lhs_elem = try lhs.elemValue(pt, i);
1662 const rhs_elem = try rhs.elemValue(mod, i);1686 const rhs_elem = try rhs.elemValue(pt, i);
1663 const of_math_result = try intMulWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod);1687 const of_math_result = try intMulWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt);
1664 of.* = of_math_result.overflow_bit.toIntern();1688 of.* = of_math_result.overflow_bit.toIntern();
1665 scalar.* = of_math_result.wrapped_result.toIntern();1689 scalar.* = of_math_result.wrapped_result.toIntern();
1666 }1690 }
1667 return OverflowArithmeticResult{1691 return OverflowArithmeticResult{
1668 .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{1692 .overflow_bit = Value.fromInterned(try pt.intern(.{ .aggregate = .{
1669 .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),1693 .ty = (try pt.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),
1670 .storage = .{ .elems = overflowed_data },1694 .storage = .{ .elems = overflowed_data },
1671 } }))),1695 } })),
1672 .wrapped_result = Value.fromInterned((try mod.intern(.{ .aggregate = .{1696 .wrapped_result = Value.fromInterned(try pt.intern(.{ .aggregate = .{
1673 .ty = ty.toIntern(),1697 .ty = ty.toIntern(),
1674 .storage = .{ .elems = result_data },1698 .storage = .{ .elems = result_data },
1675 } }))),1699 } })),
1676 };1700 };
1677 }1701 }
1678 return intMulWithOverflowScalar(lhs, rhs, ty, arena, mod);1702 return intMulWithOverflowScalar(lhs, rhs, ty, arena, pt);
1679}1703}
16801704
1681pub fn intMulWithOverflowScalar(1705pub fn intMulWithOverflowScalar(
...@@ -1683,21 +1707,22 @@ pub fn intMulWithOverflowScalar(...@@ -1683,21 +1707,22 @@ pub fn intMulWithOverflowScalar(
1683 rhs: Value,1707 rhs: Value,
1684 ty: Type,1708 ty: Type,
1685 arena: Allocator,1709 arena: Allocator,
1686 mod: *Module,1710 pt: Zcu.PerThread,
1687) !OverflowArithmeticResult {1711) !OverflowArithmeticResult {
1712 const mod = pt.zcu;
1688 const info = ty.intInfo(mod);1713 const info = ty.intInfo(mod);
16891714
1690 if (lhs.isUndef(mod) or rhs.isUndef(mod)) {1715 if (lhs.isUndef(mod) or rhs.isUndef(mod)) {
1691 return .{1716 return .{
1692 .overflow_bit = try mod.undefValue(Type.u1),1717 .overflow_bit = try pt.undefValue(Type.u1),
1693 .wrapped_result = try mod.undefValue(ty),1718 .wrapped_result = try pt.undefValue(ty),
1694 };1719 };
1695 }1720 }
16961721
1697 var lhs_space: Value.BigIntSpace = undefined;1722 var lhs_space: Value.BigIntSpace = undefined;
1698 var rhs_space: Value.BigIntSpace = undefined;1723 var rhs_space: Value.BigIntSpace = undefined;
1699 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);1724 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
1700 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);1725 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
1701 const limbs = try arena.alloc(1726 const limbs = try arena.alloc(
1702 std.math.big.Limb,1727 std.math.big.Limb,
1703 lhs_bigint.limbs.len + rhs_bigint.limbs.len,1728 lhs_bigint.limbs.len + rhs_bigint.limbs.len,
...@@ -1715,8 +1740,8 @@ pub fn intMulWithOverflowScalar(...@@ -1715,8 +1740,8 @@ pub fn intMulWithOverflowScalar(
1715 }1740 }
17161741
1717 return OverflowArithmeticResult{1742 return OverflowArithmeticResult{
1718 .overflow_bit = try mod.intValue(Type.u1, @intFromBool(overflowed)),1743 .overflow_bit = try pt.intValue(Type.u1, @intFromBool(overflowed)),
1719 .wrapped_result = try mod.intValue_big(ty, result_bigint.toConst()),1744 .wrapped_result = try pt.intValue_big(ty, result_bigint.toConst()),
1720 };1745 };
1721}1746}
17221747
...@@ -1726,22 +1751,23 @@ pub fn numberMulWrap(...@@ -1726,22 +1751,23 @@ pub fn numberMulWrap(
1726 rhs: Value,1751 rhs: Value,
1727 ty: Type,1752 ty: Type,
1728 arena: Allocator,1753 arena: Allocator,
1729 mod: *Module,1754 pt: Zcu.PerThread,
1730) !Value {1755) !Value {
1756 const mod = pt.zcu;
1731 if (ty.zigTypeTag(mod) == .Vector) {1757 if (ty.zigTypeTag(mod) == .Vector) {
1732 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));1758 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));
1733 const scalar_ty = ty.scalarType(mod);1759 const scalar_ty = ty.scalarType(mod);
1734 for (result_data, 0..) |*scalar, i| {1760 for (result_data, 0..) |*scalar, i| {
1735 const lhs_elem = try lhs.elemValue(mod, i);1761 const lhs_elem = try lhs.elemValue(pt, i);
1736 const rhs_elem = try rhs.elemValue(mod, i);1762 const rhs_elem = try rhs.elemValue(pt, i);
1737 scalar.* = (try numberMulWrapScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();1763 scalar.* = (try numberMulWrapScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern();
1738 }1764 }
1739 return Value.fromInterned((try mod.intern(.{ .aggregate = .{1765 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
1740 .ty = ty.toIntern(),1766 .ty = ty.toIntern(),
1741 .storage = .{ .elems = result_data },1767 .storage = .{ .elems = result_data },
1742 } })));1768 } }));
1743 }1769 }
1744 return numberMulWrapScalar(lhs, rhs, ty, arena, mod);1770 return numberMulWrapScalar(lhs, rhs, ty, arena, pt);
1745}1771}
17461772
1747/// Supports both floats and ints; handles undefined.1773/// Supports both floats and ints; handles undefined.
...@@ -1750,19 +1776,20 @@ pub fn numberMulWrapScalar(...@@ -1750,19 +1776,20 @@ pub fn numberMulWrapScalar(
1750 rhs: Value,1776 rhs: Value,
1751 ty: Type,1777 ty: Type,
1752 arena: Allocator,1778 arena: Allocator,
1753 mod: *Module,1779 pt: Zcu.PerThread,
1754) !Value {1780) !Value {
1781 const mod = pt.zcu;
1755 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.undef;1782 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.undef;
17561783
1757 if (ty.zigTypeTag(mod) == .ComptimeInt) {1784 if (ty.zigTypeTag(mod) == .ComptimeInt) {
1758 return intMul(lhs, rhs, ty, undefined, arena, mod);1785 return intMul(lhs, rhs, ty, undefined, arena, pt);
1759 }1786 }
17601787
1761 if (ty.isAnyFloat()) {1788 if (ty.isAnyFloat()) {
1762 return floatMul(lhs, rhs, ty, arena, mod);1789 return floatMul(lhs, rhs, ty, arena, pt);
1763 }1790 }
17641791
1765 const overflow_result = try intMulWithOverflow(lhs, rhs, ty, arena, mod);1792 const overflow_result = try intMulWithOverflow(lhs, rhs, ty, arena, pt);
1766 return overflow_result.wrapped_result;1793 return overflow_result.wrapped_result;
1767}1794}
17681795
...@@ -1772,22 +1799,22 @@ pub fn intMulSat(...@@ -1772,22 +1799,22 @@ pub fn intMulSat(
1772 rhs: Value,1799 rhs: Value,
1773 ty: Type,1800 ty: Type,
1774 arena: Allocator,1801 arena: Allocator,
1775 mod: *Module,1802 pt: Zcu.PerThread,
1776) !Value {1803) !Value {
1777 if (ty.zigTypeTag(mod) == .Vector) {1804 if (ty.zigTypeTag(pt.zcu) == .Vector) {
1778 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));1805 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
1779 const scalar_ty = ty.scalarType(mod);1806 const scalar_ty = ty.scalarType(pt.zcu);
1780 for (result_data, 0..) |*scalar, i| {1807 for (result_data, 0..) |*scalar, i| {
1781 const lhs_elem = try lhs.elemValue(mod, i);1808 const lhs_elem = try lhs.elemValue(pt, i);
1782 const rhs_elem = try rhs.elemValue(mod, i);1809 const rhs_elem = try rhs.elemValue(pt, i);
1783 scalar.* = (try intMulSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();1810 scalar.* = (try intMulSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern();
1784 }1811 }
1785 return Value.fromInterned((try mod.intern(.{ .aggregate = .{1812 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
1786 .ty = ty.toIntern(),1813 .ty = ty.toIntern(),
1787 .storage = .{ .elems = result_data },1814 .storage = .{ .elems = result_data },
1788 } })));1815 } }));
1789 }1816 }
1790 return intMulSatScalar(lhs, rhs, ty, arena, mod);1817 return intMulSatScalar(lhs, rhs, ty, arena, pt);
1791}1818}
17921819
1793/// Supports (vectors of) integers only; asserts neither operand is undefined.1820/// Supports (vectors of) integers only; asserts neither operand is undefined.
...@@ -1796,17 +1823,17 @@ pub fn intMulSatScalar(...@@ -1796,17 +1823,17 @@ pub fn intMulSatScalar(
1796 rhs: Value,1823 rhs: Value,
1797 ty: Type,1824 ty: Type,
1798 arena: Allocator,1825 arena: Allocator,
1799 mod: *Module,1826 pt: Zcu.PerThread,
1800) !Value {1827) !Value {
1801 assert(!lhs.isUndef(mod));1828 assert(!lhs.isUndef(pt.zcu));
1802 assert(!rhs.isUndef(mod));1829 assert(!rhs.isUndef(pt.zcu));
18031830
1804 const info = ty.intInfo(mod);1831 const info = ty.intInfo(pt.zcu);
18051832
1806 var lhs_space: Value.BigIntSpace = undefined;1833 var lhs_space: Value.BigIntSpace = undefined;
1807 var rhs_space: Value.BigIntSpace = undefined;1834 var rhs_space: Value.BigIntSpace = undefined;
1808 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);1835 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
1809 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);1836 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
1810 const limbs = try arena.alloc(1837 const limbs = try arena.alloc(
1811 std.math.big.Limb,1838 std.math.big.Limb,
1812 @max(1839 @max(
...@@ -1822,53 +1849,55 @@ pub fn intMulSatScalar(...@@ -1822,53 +1849,55 @@ pub fn intMulSatScalar(
1822 );1849 );
1823 result_bigint.mul(lhs_bigint, rhs_bigint, limbs_buffer, arena);1850 result_bigint.mul(lhs_bigint, rhs_bigint, limbs_buffer, arena);
1824 result_bigint.saturate(result_bigint.toConst(), info.signedness, info.bits);1851 result_bigint.saturate(result_bigint.toConst(), info.signedness, info.bits);
1825 return mod.intValue_big(ty, result_bigint.toConst());1852 return pt.intValue_big(ty, result_bigint.toConst());
1826}1853}
18271854
1828/// Supports both floats and ints; handles undefined.1855/// Supports both floats and ints; handles undefined.
1829pub fn numberMax(lhs: Value, rhs: Value, mod: *Module) Value {1856pub fn numberMax(lhs: Value, rhs: Value, pt: Zcu.PerThread) Value {
1830 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return undef;1857 if (lhs.isUndef(pt.zcu) or rhs.isUndef(pt.zcu)) return undef;
1831 if (lhs.isNan(mod)) return rhs;1858 if (lhs.isNan(pt.zcu)) return rhs;
1832 if (rhs.isNan(mod)) return lhs;1859 if (rhs.isNan(pt.zcu)) return lhs;
18331860
1834 return switch (order(lhs, rhs, mod)) {1861 return switch (order(lhs, rhs, pt)) {
1835 .lt => rhs,1862 .lt => rhs,
1836 .gt, .eq => lhs,1863 .gt, .eq => lhs,
1837 };1864 };
1838}1865}
18391866
1840/// Supports both floats and ints; handles undefined.1867/// Supports both floats and ints; handles undefined.
1841pub fn numberMin(lhs: Value, rhs: Value, mod: *Module) Value {1868pub fn numberMin(lhs: Value, rhs: Value, pt: Zcu.PerThread) Value {
1842 if (lhs.isUndef(mod) or rhs.isUndef(mod)) return undef;1869 if (lhs.isUndef(pt.zcu) or rhs.isUndef(pt.zcu)) return undef;
1843 if (lhs.isNan(mod)) return rhs;1870 if (lhs.isNan(pt.zcu)) return rhs;
1844 if (rhs.isNan(mod)) return lhs;1871 if (rhs.isNan(pt.zcu)) return lhs;
18451872
1846 return switch (order(lhs, rhs, mod)) {1873 return switch (order(lhs, rhs, pt)) {
1847 .lt => lhs,1874 .lt => lhs,
1848 .gt, .eq => rhs,1875 .gt, .eq => rhs,
1849 };1876 };
1850}1877}
18511878
1852/// operands must be (vectors of) integers; handles undefined scalars.1879/// operands must be (vectors of) integers; handles undefined scalars.
1853pub fn bitwiseNot(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value {1880pub fn bitwiseNot(val: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
1881 const mod = pt.zcu;
1854 if (ty.zigTypeTag(mod) == .Vector) {1882 if (ty.zigTypeTag(mod) == .Vector) {
1855 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));1883 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));
1856 const scalar_ty = ty.scalarType(mod);1884 const scalar_ty = ty.scalarType(mod);
1857 for (result_data, 0..) |*scalar, i| {1885 for (result_data, 0..) |*scalar, i| {
1858 const elem_val = try val.elemValue(mod, i);1886 const elem_val = try val.elemValue(pt, i);
1859 scalar.* = (try bitwiseNotScalar(elem_val, scalar_ty, arena, mod)).toIntern();1887 scalar.* = (try bitwiseNotScalar(elem_val, scalar_ty, arena, pt)).toIntern();
1860 }1888 }
1861 return Value.fromInterned((try mod.intern(.{ .aggregate = .{1889 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
1862 .ty = ty.toIntern(),1890 .ty = ty.toIntern(),
1863 .storage = .{ .elems = result_data },1891 .storage = .{ .elems = result_data },
1864 } })));1892 } }));
1865 }1893 }
1866 return bitwiseNotScalar(val, ty, arena, mod);1894 return bitwiseNotScalar(val, ty, arena, pt);
1867}1895}
18681896
1869/// operands must be integers; handles undefined.1897/// operands must be integers; handles undefined.
1870pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value {1898pub 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() })));1899 const mod = pt.zcu;
1900 if (val.isUndef(mod)) return Value.fromInterned(try pt.intern(.{ .undef = ty.toIntern() }));
1872 if (ty.toIntern() == .bool_type) return makeBool(!val.toBool());1901 if (ty.toIntern() == .bool_type) return makeBool(!val.toBool());
18731902
1874 const info = ty.intInfo(mod);1903 const info = ty.intInfo(mod);
...@@ -1880,7 +1909,7 @@ pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, mod: *Module) !V...@@ -1880,7 +1909,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 without1909 // TODO is this a performance issue? maybe we should try the operation without
1881 // resorting to BigInt first.1910 // resorting to BigInt first.
1882 var val_space: Value.BigIntSpace = undefined;1911 var val_space: Value.BigIntSpace = undefined;
1883 const val_bigint = val.toBigInt(&val_space, mod);1912 const val_bigint = val.toBigInt(&val_space, pt);
1884 const limbs = try arena.alloc(1913 const limbs = try arena.alloc(
1885 std.math.big.Limb,1914 std.math.big.Limb,
1886 std.math.big.int.calcTwosCompLimbCount(info.bits),1915 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -1888,29 +1917,31 @@ pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, mod: *Module) !V...@@ -1888,29 +1917,31 @@ pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, mod: *Module) !V
18881917
1889 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };1918 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
1890 result_bigint.bitNotWrap(val_bigint, info.signedness, info.bits);1919 result_bigint.bitNotWrap(val_bigint, info.signedness, info.bits);
1891 return mod.intValue_big(ty, result_bigint.toConst());1920 return pt.intValue_big(ty, result_bigint.toConst());
1892}1921}
18931922
1894/// operands must be (vectors of) integers; handles undefined scalars.1923/// operands must be (vectors of) integers; handles undefined scalars.
1895pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {1924pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
1925 const mod = pt.zcu;
1896 if (ty.zigTypeTag(mod) == .Vector) {1926 if (ty.zigTypeTag(mod) == .Vector) {
1897 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));1927 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));
1898 const scalar_ty = ty.scalarType(mod);1928 const scalar_ty = ty.scalarType(mod);
1899 for (result_data, 0..) |*scalar, i| {1929 for (result_data, 0..) |*scalar, i| {
1900 const lhs_elem = try lhs.elemValue(mod, i);1930 const lhs_elem = try lhs.elemValue(pt, i);
1901 const rhs_elem = try rhs.elemValue(mod, i);1931 const rhs_elem = try rhs.elemValue(pt, i);
1902 scalar.* = (try bitwiseAndScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();1932 scalar.* = (try bitwiseAndScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern();
1903 }1933 }
1904 return Value.fromInterned((try mod.intern(.{ .aggregate = .{1934 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
1905 .ty = ty.toIntern(),1935 .ty = ty.toIntern(),
1906 .storage = .{ .elems = result_data },1936 .storage = .{ .elems = result_data },
1907 } })));1937 } }));
1908 }1938 }
1909 return bitwiseAndScalar(lhs, rhs, ty, allocator, mod);1939 return bitwiseAndScalar(lhs, rhs, ty, allocator, pt);
1910}1940}
19111941
1912/// operands must be integers; handles undefined.1942/// operands must be integers; handles undefined.
1913pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Allocator, zcu: *Zcu) !Value {1943pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
1944 const zcu = pt.zcu;
1914 // If one operand is defined, we turn the other into `0xAA` so the bitwise AND can1945 // If one operand is defined, we turn the other into `0xAA` so the bitwise AND can
1915 // still zero out some bits.1946 // still zero out some bits.
1916 // TODO: ideally we'd still like tracking for the undef bits. Related: #19634.1947 // TODO: ideally we'd still like tracking for the undef bits. Related: #19634.
...@@ -1919,9 +1950,9 @@ pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloc...@@ -1919,9 +1950,9 @@ pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloc
1919 const rhs_undef = orig_rhs.isUndef(zcu);1950 const rhs_undef = orig_rhs.isUndef(zcu);
1920 break :make_defined switch ((@as(u2, @intFromBool(lhs_undef)) << 1) | @intFromBool(rhs_undef)) {1951 break :make_defined switch ((@as(u2, @intFromBool(lhs_undef)) << 1) | @intFromBool(rhs_undef)) {
1921 0b00 => .{ orig_lhs, orig_rhs },1952 0b00 => .{ orig_lhs, orig_rhs },
1922 0b01 => .{ orig_lhs, try intValueAa(ty, arena, zcu) },1953 0b01 => .{ orig_lhs, try intValueAa(ty, arena, pt) },
1923 0b10 => .{ try intValueAa(ty, arena, zcu), orig_rhs },1954 0b10 => .{ try intValueAa(ty, arena, pt), orig_rhs },
1924 0b11 => return zcu.undefValue(ty),1955 0b11 => return pt.undefValue(ty),
1925 };1956 };
1926 };1957 };
19271958
...@@ -1931,8 +1962,8 @@ pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloc...@@ -1931,8 +1962,8 @@ pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloc
1931 // resorting to BigInt first.1962 // resorting to BigInt first.
1932 var lhs_space: Value.BigIntSpace = undefined;1963 var lhs_space: Value.BigIntSpace = undefined;
1933 var rhs_space: Value.BigIntSpace = undefined;1964 var rhs_space: Value.BigIntSpace = undefined;
1934 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);1965 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
1935 const rhs_bigint = rhs.toBigInt(&rhs_space, zcu);1966 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
1936 const limbs = try arena.alloc(1967 const limbs = try arena.alloc(
1937 std.math.big.Limb,1968 std.math.big.Limb,
1938 // + 1 for negatives1969 // + 1 for negatives
...@@ -1940,12 +1971,13 @@ pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloc...@@ -1940,12 +1971,13 @@ pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloc
1940 );1971 );
1941 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };1972 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
1942 result_bigint.bitAnd(lhs_bigint, rhs_bigint);1973 result_bigint.bitAnd(lhs_bigint, rhs_bigint);
1943 return zcu.intValue_big(ty, result_bigint.toConst());1974 return pt.intValue_big(ty, result_bigint.toConst());
1944}1975}
19451976
1946/// Given an integer or boolean type, creates an value of that with the bit pattern 0xAA.1977/// 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.1978/// This is used to convert undef values into 0xAA when performing e.g. bitwise operations.
1948fn intValueAa(ty: Type, arena: Allocator, zcu: *Zcu) !Value {1979fn intValueAa(ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
1980 const zcu = pt.zcu;
1949 if (ty.toIntern() == .bool_type) return Value.true;1981 if (ty.toIntern() == .bool_type) return Value.true;
1950 const info = ty.intInfo(zcu);1982 const info = ty.intInfo(zcu);
19511983
...@@ -1958,68 +1990,71 @@ fn intValueAa(ty: Type, arena: Allocator, zcu: *Zcu) !Value {...@@ -1958,68 +1990,71 @@ fn intValueAa(ty: Type, arena: Allocator, zcu: *Zcu) !Value {
1958 );1990 );
1959 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };1991 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
1960 result_bigint.readTwosComplement(buf, info.bits, zcu.getTarget().cpu.arch.endian(), info.signedness);1992 result_bigint.readTwosComplement(buf, info.bits, zcu.getTarget().cpu.arch.endian(), info.signedness);
1961 return zcu.intValue_big(ty, result_bigint.toConst());1993 return pt.intValue_big(ty, result_bigint.toConst());
1962}1994}
19631995
1964/// operands must be (vectors of) integers; handles undefined scalars.1996/// operands must be (vectors of) integers; handles undefined scalars.
1965pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value {1997pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
1998 const mod = pt.zcu;
1966 if (ty.zigTypeTag(mod) == .Vector) {1999 if (ty.zigTypeTag(mod) == .Vector) {
1967 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));2000 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));
1968 const scalar_ty = ty.scalarType(mod);2001 const scalar_ty = ty.scalarType(mod);
1969 for (result_data, 0..) |*scalar, i| {2002 for (result_data, 0..) |*scalar, i| {
1970 const lhs_elem = try lhs.elemValue(mod, i);2003 const lhs_elem = try lhs.elemValue(pt, i);
1971 const rhs_elem = try rhs.elemValue(mod, i);2004 const rhs_elem = try rhs.elemValue(pt, i);
1972 scalar.* = (try bitwiseNandScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();2005 scalar.* = (try bitwiseNandScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern();
1973 }2006 }
1974 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2007 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
1975 .ty = ty.toIntern(),2008 .ty = ty.toIntern(),
1976 .storage = .{ .elems = result_data },2009 .storage = .{ .elems = result_data },
1977 } })));2010 } }));
1978 }2011 }
1979 return bitwiseNandScalar(lhs, rhs, ty, arena, mod);2012 return bitwiseNandScalar(lhs, rhs, ty, arena, pt);
1980}2013}
19812014
1982/// operands must be integers; handles undefined.2015/// operands must be integers; handles undefined.
1983pub fn bitwiseNandScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value {2016pub 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() })));2017 const mod = pt.zcu;
2018 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()));2019 if (ty.toIntern() == .bool_type) return makeBool(!(lhs.toBool() and rhs.toBool()));
19862020
1987 const anded = try bitwiseAnd(lhs, rhs, ty, arena, mod);2021 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);2022 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);2023 return bitwiseXor(anded, all_ones, ty, arena, pt);
1990}2024}
19912025
1992/// operands must be (vectors of) integers; handles undefined scalars.2026/// operands must be (vectors of) integers; handles undefined scalars.
1993pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2027pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
2028 const mod = pt.zcu;
1994 if (ty.zigTypeTag(mod) == .Vector) {2029 if (ty.zigTypeTag(mod) == .Vector) {
1995 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));2030 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));
1996 const scalar_ty = ty.scalarType(mod);2031 const scalar_ty = ty.scalarType(mod);
1997 for (result_data, 0..) |*scalar, i| {2032 for (result_data, 0..) |*scalar, i| {
1998 const lhs_elem = try lhs.elemValue(mod, i);2033 const lhs_elem = try lhs.elemValue(pt, i);
1999 const rhs_elem = try rhs.elemValue(mod, i);2034 const rhs_elem = try rhs.elemValue(pt, i);
2000 scalar.* = (try bitwiseOrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();2035 scalar.* = (try bitwiseOrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern();
2001 }2036 }
2002 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2037 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2003 .ty = ty.toIntern(),2038 .ty = ty.toIntern(),
2004 .storage = .{ .elems = result_data },2039 .storage = .{ .elems = result_data },
2005 } })));2040 } }));
2006 }2041 }
2007 return bitwiseOrScalar(lhs, rhs, ty, allocator, mod);2042 return bitwiseOrScalar(lhs, rhs, ty, allocator, pt);
2008}2043}
20092044
2010/// operands must be integers; handles undefined.2045/// operands must be integers; handles undefined.
2011pub fn bitwiseOrScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Allocator, zcu: *Zcu) !Value {2046pub 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 can2047 // If one operand is defined, we turn the other into `0xAA` so the bitwise AND can
2013 // still zero out some bits.2048 // still zero out some bits.
2014 // TODO: ideally we'd still like tracking for the undef bits. Related: #19634.2049 // TODO: ideally we'd still like tracking for the undef bits. Related: #19634.
2015 const lhs: Value, const rhs: Value = make_defined: {2050 const lhs: Value, const rhs: Value = make_defined: {
2016 const lhs_undef = orig_lhs.isUndef(zcu);2051 const lhs_undef = orig_lhs.isUndef(pt.zcu);
2017 const rhs_undef = orig_rhs.isUndef(zcu);2052 const rhs_undef = orig_rhs.isUndef(pt.zcu);
2018 break :make_defined switch ((@as(u2, @intFromBool(lhs_undef)) << 1) | @intFromBool(rhs_undef)) {2053 break :make_defined switch ((@as(u2, @intFromBool(lhs_undef)) << 1) | @intFromBool(rhs_undef)) {
2019 0b00 => .{ orig_lhs, orig_rhs },2054 0b00 => .{ orig_lhs, orig_rhs },
2020 0b01 => .{ orig_lhs, try intValueAa(ty, arena, zcu) },2055 0b01 => .{ orig_lhs, try intValueAa(ty, arena, pt) },
2021 0b10 => .{ try intValueAa(ty, arena, zcu), orig_rhs },2056 0b10 => .{ try intValueAa(ty, arena, pt), orig_rhs },
2022 0b11 => return zcu.undefValue(ty),2057 0b11 => return pt.undefValue(ty),
2023 };2058 };
2024 };2059 };
20252060
...@@ -2029,46 +2064,48 @@ pub fn bitwiseOrScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloca...@@ -2029,46 +2064,48 @@ pub fn bitwiseOrScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloca
2029 // resorting to BigInt first.2064 // resorting to BigInt first.
2030 var lhs_space: Value.BigIntSpace = undefined;2065 var lhs_space: Value.BigIntSpace = undefined;
2031 var rhs_space: Value.BigIntSpace = undefined;2066 var rhs_space: Value.BigIntSpace = undefined;
2032 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);2067 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
2033 const rhs_bigint = rhs.toBigInt(&rhs_space, zcu);2068 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
2034 const limbs = try arena.alloc(2069 const limbs = try arena.alloc(
2035 std.math.big.Limb,2070 std.math.big.Limb,
2036 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),2071 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
2037 );2072 );
2038 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };2073 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
2039 result_bigint.bitOr(lhs_bigint, rhs_bigint);2074 result_bigint.bitOr(lhs_bigint, rhs_bigint);
2040 return zcu.intValue_big(ty, result_bigint.toConst());2075 return pt.intValue_big(ty, result_bigint.toConst());
2041}2076}
20422077
2043/// operands must be (vectors of) integers; handles undefined scalars.2078/// operands must be (vectors of) integers; handles undefined scalars.
2044pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2079pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
2080 const mod = pt.zcu;
2045 if (ty.zigTypeTag(mod) == .Vector) {2081 if (ty.zigTypeTag(mod) == .Vector) {
2046 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));2082 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));
2047 const scalar_ty = ty.scalarType(mod);2083 const scalar_ty = ty.scalarType(mod);
2048 for (result_data, 0..) |*scalar, i| {2084 for (result_data, 0..) |*scalar, i| {
2049 const lhs_elem = try lhs.elemValue(mod, i);2085 const lhs_elem = try lhs.elemValue(pt, i);
2050 const rhs_elem = try rhs.elemValue(mod, i);2086 const rhs_elem = try rhs.elemValue(pt, i);
2051 scalar.* = (try bitwiseXorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();2087 scalar.* = (try bitwiseXorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern();
2052 }2088 }
2053 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2089 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2054 .ty = ty.toIntern(),2090 .ty = ty.toIntern(),
2055 .storage = .{ .elems = result_data },2091 .storage = .{ .elems = result_data },
2056 } })));2092 } }));
2057 }2093 }
2058 return bitwiseXorScalar(lhs, rhs, ty, allocator, mod);2094 return bitwiseXorScalar(lhs, rhs, ty, allocator, pt);
2059}2095}
20602096
2061/// operands must be integers; handles undefined.2097/// operands must be integers; handles undefined.
2062pub fn bitwiseXorScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value {2098pub 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() })));2099 const mod = pt.zcu;
2100 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());2101 if (ty.toIntern() == .bool_type) return makeBool(lhs.toBool() != rhs.toBool());
20652102
2066 // TODO is this a performance issue? maybe we should try the operation without2103 // TODO is this a performance issue? maybe we should try the operation without
2067 // resorting to BigInt first.2104 // resorting to BigInt first.
2068 var lhs_space: Value.BigIntSpace = undefined;2105 var lhs_space: Value.BigIntSpace = undefined;
2069 var rhs_space: Value.BigIntSpace = undefined;2106 var rhs_space: Value.BigIntSpace = undefined;
2070 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);2107 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
2071 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);2108 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
2072 const limbs = try arena.alloc(2109 const limbs = try arena.alloc(
2073 std.math.big.Limb,2110 std.math.big.Limb,
2074 // + 1 for negatives2111 // + 1 for negatives
...@@ -2076,22 +2113,22 @@ pub fn bitwiseXorScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod:...@@ -2076,22 +2113,22 @@ pub fn bitwiseXorScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod:
2076 );2113 );
2077 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };2114 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
2078 result_bigint.bitXor(lhs_bigint, rhs_bigint);2115 result_bigint.bitXor(lhs_bigint, rhs_bigint);
2079 return mod.intValue_big(ty, result_bigint.toConst());2116 return pt.intValue_big(ty, result_bigint.toConst());
2080}2117}
20812118
2082/// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting2119/// 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).2120/// 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 {2121pub fn intDiv(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator: Allocator, pt: Zcu.PerThread) !Value {
2085 var overflow: usize = undefined;2122 var overflow: usize = undefined;
2086 return intDivInner(lhs, rhs, ty, &overflow, allocator, mod) catch |err| switch (err) {2123 return intDivInner(lhs, rhs, ty, &overflow, allocator, pt) catch |err| switch (err) {
2087 error.Overflow => {2124 error.Overflow => {
2088 const is_vec = ty.isVector(mod);2125 const is_vec = ty.isVector(pt.zcu);
2089 overflow_idx.* = if (is_vec) overflow else 0;2126 overflow_idx.* = if (is_vec) overflow else 0;
2090 const safe_ty = if (is_vec) try mod.vectorType(.{2127 const safe_ty = if (is_vec) try pt.vectorType(.{
2091 .len = ty.vectorLen(mod),2128 .len = ty.vectorLen(pt.zcu),
2092 .child = .comptime_int_type,2129 .child = .comptime_int_type,
2093 }) else Type.comptime_int;2130 }) else Type.comptime_int;
2094 return intDivInner(lhs, rhs, safe_ty, undefined, allocator, mod) catch |err1| switch (err1) {2131 return intDivInner(lhs, rhs, safe_ty, undefined, allocator, pt) catch |err1| switch (err1) {
2095 error.Overflow => unreachable,2132 error.Overflow => unreachable,
2096 else => |e| return e,2133 else => |e| return e,
2097 };2134 };
...@@ -2100,14 +2137,14 @@ pub fn intDiv(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator...@@ -2100,14 +2137,14 @@ pub fn intDiv(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator
2100 };2137 };
2101}2138}
21022139
2103fn intDivInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator: Allocator, mod: *Module) !Value {2140fn intDivInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator: Allocator, pt: Zcu.PerThread) !Value {
2104 if (ty.zigTypeTag(mod) == .Vector) {2141 if (ty.zigTypeTag(pt.zcu) == .Vector) {
2105 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));2142 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
2106 const scalar_ty = ty.scalarType(mod);2143 const scalar_ty = ty.scalarType(pt.zcu);
2107 for (result_data, 0..) |*scalar, i| {2144 for (result_data, 0..) |*scalar, i| {
2108 const lhs_elem = try lhs.elemValue(mod, i);2145 const lhs_elem = try lhs.elemValue(pt, i);
2109 const rhs_elem = try rhs.elemValue(mod, i);2146 const rhs_elem = try rhs.elemValue(pt, i);
2110 const val = intDivScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod) catch |err| switch (err) {2147 const val = intDivScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt) catch |err| switch (err) {
2111 error.Overflow => {2148 error.Overflow => {
2112 overflow_idx.* = i;2149 overflow_idx.* = i;
2113 return error.Overflow;2150 return error.Overflow;
...@@ -2116,21 +2153,21 @@ fn intDivInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator...@@ -2116,21 +2153,21 @@ fn intDivInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator
2116 };2153 };
2117 scalar.* = val.toIntern();2154 scalar.* = val.toIntern();
2118 }2155 }
2119 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2156 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2120 .ty = ty.toIntern(),2157 .ty = ty.toIntern(),
2121 .storage = .{ .elems = result_data },2158 .storage = .{ .elems = result_data },
2122 } })));2159 } }));
2123 }2160 }
2124 return intDivScalar(lhs, rhs, ty, allocator, mod);2161 return intDivScalar(lhs, rhs, ty, allocator, pt);
2125}2162}
21262163
2127pub fn intDivScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2164pub 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 without2165 // TODO is this a performance issue? maybe we should try the operation without
2129 // resorting to BigInt first.2166 // resorting to BigInt first.
2130 var lhs_space: Value.BigIntSpace = undefined;2167 var lhs_space: Value.BigIntSpace = undefined;
2131 var rhs_space: Value.BigIntSpace = undefined;2168 var rhs_space: Value.BigIntSpace = undefined;
2132 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);2169 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
2133 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);2170 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
2134 const limbs_q = try allocator.alloc(2171 const limbs_q = try allocator.alloc(
2135 std.math.big.Limb,2172 std.math.big.Limb,
2136 lhs_bigint.limbs.len,2173 lhs_bigint.limbs.len,
...@@ -2147,38 +2184,38 @@ pub fn intDivScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod:...@@ -2147,38 +2184,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 };2184 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };
2148 result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);2185 result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);
2149 if (ty.toIntern() != .comptime_int_type) {2186 if (ty.toIntern() != .comptime_int_type) {
2150 const info = ty.intInfo(mod);2187 const info = ty.intInfo(pt.zcu);
2151 if (!result_q.toConst().fitsInTwosComp(info.signedness, info.bits)) {2188 if (!result_q.toConst().fitsInTwosComp(info.signedness, info.bits)) {
2152 return error.Overflow;2189 return error.Overflow;
2153 }2190 }
2154 }2191 }
2155 return mod.intValue_big(ty, result_q.toConst());2192 return pt.intValue_big(ty, result_q.toConst());
2156}2193}
21572194
2158pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2195pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
2159 if (ty.zigTypeTag(mod) == .Vector) {2196 if (ty.zigTypeTag(pt.zcu) == .Vector) {
2160 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));2197 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
2161 const scalar_ty = ty.scalarType(mod);2198 const scalar_ty = ty.scalarType(pt.zcu);
2162 for (result_data, 0..) |*scalar, i| {2199 for (result_data, 0..) |*scalar, i| {
2163 const lhs_elem = try lhs.elemValue(mod, i);2200 const lhs_elem = try lhs.elemValue(pt, i);
2164 const rhs_elem = try rhs.elemValue(mod, i);2201 const rhs_elem = try rhs.elemValue(pt, i);
2165 scalar.* = (try intDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();2202 scalar.* = (try intDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern();
2166 }2203 }
2167 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2204 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2168 .ty = ty.toIntern(),2205 .ty = ty.toIntern(),
2169 .storage = .{ .elems = result_data },2206 .storage = .{ .elems = result_data },
2170 } })));2207 } }));
2171 }2208 }
2172 return intDivFloorScalar(lhs, rhs, ty, allocator, mod);2209 return intDivFloorScalar(lhs, rhs, ty, allocator, pt);
2173}2210}
21742211
2175pub fn intDivFloorScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2212pub 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 without2213 // TODO is this a performance issue? maybe we should try the operation without
2177 // resorting to BigInt first.2214 // resorting to BigInt first.
2178 var lhs_space: Value.BigIntSpace = undefined;2215 var lhs_space: Value.BigIntSpace = undefined;
2179 var rhs_space: Value.BigIntSpace = undefined;2216 var rhs_space: Value.BigIntSpace = undefined;
2180 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);2217 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
2181 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);2218 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
2182 const limbs_q = try allocator.alloc(2219 const limbs_q = try allocator.alloc(
2183 std.math.big.Limb,2220 std.math.big.Limb,
2184 lhs_bigint.limbs.len,2221 lhs_bigint.limbs.len,
...@@ -2194,33 +2231,33 @@ pub fn intDivFloorScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator,...@@ -2194,33 +2231,33 @@ pub fn intDivFloorScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator,
2194 var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };2231 var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };
2195 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };2232 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };
2196 result_q.divFloor(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);2233 result_q.divFloor(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);
2197 return mod.intValue_big(ty, result_q.toConst());2234 return pt.intValue_big(ty, result_q.toConst());
2198}2235}
21992236
2200pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2237pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
2201 if (ty.zigTypeTag(mod) == .Vector) {2238 if (ty.zigTypeTag(pt.zcu) == .Vector) {
2202 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));2239 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
2203 const scalar_ty = ty.scalarType(mod);2240 const scalar_ty = ty.scalarType(pt.zcu);
2204 for (result_data, 0..) |*scalar, i| {2241 for (result_data, 0..) |*scalar, i| {
2205 const lhs_elem = try lhs.elemValue(mod, i);2242 const lhs_elem = try lhs.elemValue(pt, i);
2206 const rhs_elem = try rhs.elemValue(mod, i);2243 const rhs_elem = try rhs.elemValue(pt, i);
2207 scalar.* = (try intModScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();2244 scalar.* = (try intModScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern();
2208 }2245 }
2209 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2246 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2210 .ty = ty.toIntern(),2247 .ty = ty.toIntern(),
2211 .storage = .{ .elems = result_data },2248 .storage = .{ .elems = result_data },
2212 } })));2249 } }));
2213 }2250 }
2214 return intModScalar(lhs, rhs, ty, allocator, mod);2251 return intModScalar(lhs, rhs, ty, allocator, pt);
2215}2252}
22162253
2217pub fn intModScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2254pub 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 without2255 // TODO is this a performance issue? maybe we should try the operation without
2219 // resorting to BigInt first.2256 // resorting to BigInt first.
2220 var lhs_space: Value.BigIntSpace = undefined;2257 var lhs_space: Value.BigIntSpace = undefined;
2221 var rhs_space: Value.BigIntSpace = undefined;2258 var rhs_space: Value.BigIntSpace = undefined;
2222 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);2259 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
2223 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);2260 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
2224 const limbs_q = try allocator.alloc(2261 const limbs_q = try allocator.alloc(
2225 std.math.big.Limb,2262 std.math.big.Limb,
2226 lhs_bigint.limbs.len,2263 lhs_bigint.limbs.len,
...@@ -2236,7 +2273,7 @@ pub fn intModScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod:...@@ -2236,7 +2273,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 };2273 var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };
2237 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };2274 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };
2238 result_q.divFloor(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);2275 result_q.divFloor(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);
2239 return mod.intValue_big(ty, result_r.toConst());2276 return pt.intValue_big(ty, result_r.toConst());
2240}2277}
22412278
2242/// Returns true if the value is a floating point type and is NaN. Returns false otherwise.2279/// Returns true if the value is a floating point type and is NaN. Returns false otherwise.
...@@ -2268,85 +2305,86 @@ pub fn isNegativeInf(val: Value, mod: *const Module) bool {...@@ -2268,85 +2305,86 @@ pub fn isNegativeInf(val: Value, mod: *const Module) bool {
2268 };2305 };
2269}2306}
22702307
2271pub fn floatRem(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {2308pub fn floatRem(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
2272 if (float_type.zigTypeTag(mod) == .Vector) {2309 if (float_type.zigTypeTag(pt.zcu) == .Vector) {
2273 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));2310 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(pt.zcu));
2274 const scalar_ty = float_type.scalarType(mod);2311 const scalar_ty = float_type.scalarType(pt.zcu);
2275 for (result_data, 0..) |*scalar, i| {2312 for (result_data, 0..) |*scalar, i| {
2276 const lhs_elem = try lhs.elemValue(mod, i);2313 const lhs_elem = try lhs.elemValue(pt, i);
2277 const rhs_elem = try rhs.elemValue(mod, i);2314 const rhs_elem = try rhs.elemValue(pt, i);
2278 scalar.* = (try floatRemScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();2315 scalar.* = (try floatRemScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern();
2279 }2316 }
2280 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2317 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2281 .ty = float_type.toIntern(),2318 .ty = float_type.toIntern(),
2282 .storage = .{ .elems = result_data },2319 .storage = .{ .elems = result_data },
2283 } })));2320 } }));
2284 }2321 }
2285 return floatRemScalar(lhs, rhs, float_type, mod);2322 return floatRemScalar(lhs, rhs, float_type, pt);
2286}2323}
22872324
2288pub fn floatRemScalar(lhs: Value, rhs: Value, float_type: Type, mod: *Module) !Value {2325pub fn floatRemScalar(lhs: Value, rhs: Value, float_type: Type, pt: Zcu.PerThread) !Value {
2289 const target = mod.getTarget();2326 const target = pt.zcu.getTarget();
2290 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {2327 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
2291 16 => .{ .f16 = @rem(lhs.toFloat(f16, mod), rhs.toFloat(f16, mod)) },2328 16 => .{ .f16 = @rem(lhs.toFloat(f16, pt), rhs.toFloat(f16, pt)) },
2292 32 => .{ .f32 = @rem(lhs.toFloat(f32, mod), rhs.toFloat(f32, mod)) },2329 32 => .{ .f32 = @rem(lhs.toFloat(f32, pt), rhs.toFloat(f32, pt)) },
2293 64 => .{ .f64 = @rem(lhs.toFloat(f64, mod), rhs.toFloat(f64, mod)) },2330 64 => .{ .f64 = @rem(lhs.toFloat(f64, pt), rhs.toFloat(f64, pt)) },
2294 80 => .{ .f80 = @rem(lhs.toFloat(f80, mod), rhs.toFloat(f80, mod)) },2331 80 => .{ .f80 = @rem(lhs.toFloat(f80, pt), rhs.toFloat(f80, pt)) },
2295 128 => .{ .f128 = @rem(lhs.toFloat(f128, mod), rhs.toFloat(f128, mod)) },2332 128 => .{ .f128 = @rem(lhs.toFloat(f128, pt), rhs.toFloat(f128, pt)) },
2296 else => unreachable,2333 else => unreachable,
2297 };2334 };
2298 return Value.fromInterned((try mod.intern(.{ .float = .{2335 return Value.fromInterned(try pt.intern(.{ .float = .{
2299 .ty = float_type.toIntern(),2336 .ty = float_type.toIntern(),
2300 .storage = storage,2337 .storage = storage,
2301 } })));2338 } }));
2302}2339}
23032340
2304pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {2341pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
2305 if (float_type.zigTypeTag(mod) == .Vector) {2342 if (float_type.zigTypeTag(pt.zcu) == .Vector) {
2306 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));2343 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(pt.zcu));
2307 const scalar_ty = float_type.scalarType(mod);2344 const scalar_ty = float_type.scalarType(pt.zcu);
2308 for (result_data, 0..) |*scalar, i| {2345 for (result_data, 0..) |*scalar, i| {
2309 const lhs_elem = try lhs.elemValue(mod, i);2346 const lhs_elem = try lhs.elemValue(pt, i);
2310 const rhs_elem = try rhs.elemValue(mod, i);2347 const rhs_elem = try rhs.elemValue(pt, i);
2311 scalar.* = (try floatModScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();2348 scalar.* = (try floatModScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern();
2312 }2349 }
2313 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2350 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2314 .ty = float_type.toIntern(),2351 .ty = float_type.toIntern(),
2315 .storage = .{ .elems = result_data },2352 .storage = .{ .elems = result_data },
2316 } })));2353 } }));
2317 }2354 }
2318 return floatModScalar(lhs, rhs, float_type, mod);2355 return floatModScalar(lhs, rhs, float_type, pt);
2319}2356}
23202357
2321pub fn floatModScalar(lhs: Value, rhs: Value, float_type: Type, mod: *Module) !Value {2358pub fn floatModScalar(lhs: Value, rhs: Value, float_type: Type, pt: Zcu.PerThread) !Value {
2322 const target = mod.getTarget();2359 const target = pt.zcu.getTarget();
2323 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {2360 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
2324 16 => .{ .f16 = @mod(lhs.toFloat(f16, mod), rhs.toFloat(f16, mod)) },2361 16 => .{ .f16 = @mod(lhs.toFloat(f16, pt), rhs.toFloat(f16, pt)) },
2325 32 => .{ .f32 = @mod(lhs.toFloat(f32, mod), rhs.toFloat(f32, mod)) },2362 32 => .{ .f32 = @mod(lhs.toFloat(f32, pt), rhs.toFloat(f32, pt)) },
2326 64 => .{ .f64 = @mod(lhs.toFloat(f64, mod), rhs.toFloat(f64, mod)) },2363 64 => .{ .f64 = @mod(lhs.toFloat(f64, pt), rhs.toFloat(f64, pt)) },
2327 80 => .{ .f80 = @mod(lhs.toFloat(f80, mod), rhs.toFloat(f80, mod)) },2364 80 => .{ .f80 = @mod(lhs.toFloat(f80, pt), rhs.toFloat(f80, pt)) },
2328 128 => .{ .f128 = @mod(lhs.toFloat(f128, mod), rhs.toFloat(f128, mod)) },2365 128 => .{ .f128 = @mod(lhs.toFloat(f128, pt), rhs.toFloat(f128, pt)) },
2329 else => unreachable,2366 else => unreachable,
2330 };2367 };
2331 return Value.fromInterned((try mod.intern(.{ .float = .{2368 return Value.fromInterned(try pt.intern(.{ .float = .{
2332 .ty = float_type.toIntern(),2369 .ty = float_type.toIntern(),
2333 .storage = storage,2370 .storage = storage,
2334 } })));2371 } }));
2335}2372}
23362373
2337/// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting2374/// 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).2375/// 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 {2376pub fn intMul(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator: Allocator, pt: Zcu.PerThread) !Value {
2377 const mod = pt.zcu;
2340 var overflow: usize = undefined;2378 var overflow: usize = undefined;
2341 return intMulInner(lhs, rhs, ty, &overflow, allocator, mod) catch |err| switch (err) {2379 return intMulInner(lhs, rhs, ty, &overflow, allocator, pt) catch |err| switch (err) {
2342 error.Overflow => {2380 error.Overflow => {
2343 const is_vec = ty.isVector(mod);2381 const is_vec = ty.isVector(mod);
2344 overflow_idx.* = if (is_vec) overflow else 0;2382 overflow_idx.* = if (is_vec) overflow else 0;
2345 const safe_ty = if (is_vec) try mod.vectorType(.{2383 const safe_ty = if (is_vec) try pt.vectorType(.{
2346 .len = ty.vectorLen(mod),2384 .len = ty.vectorLen(mod),
2347 .child = .comptime_int_type,2385 .child = .comptime_int_type,
2348 }) else Type.comptime_int;2386 }) else Type.comptime_int;
2349 return intMulInner(lhs, rhs, safe_ty, undefined, allocator, mod) catch |err1| switch (err1) {2387 return intMulInner(lhs, rhs, safe_ty, undefined, allocator, pt) catch |err1| switch (err1) {
2350 error.Overflow => unreachable,2388 error.Overflow => unreachable,
2351 else => |e| return e,2389 else => |e| return e,
2352 };2390 };
...@@ -2355,14 +2393,15 @@ pub fn intMul(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator...@@ -2355,14 +2393,15 @@ pub fn intMul(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator
2355 };2393 };
2356}2394}
23572395
2358fn intMulInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator: Allocator, mod: *Module) !Value {2396fn intMulInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator: Allocator, pt: Zcu.PerThread) !Value {
2397 const mod = pt.zcu;
2359 if (ty.zigTypeTag(mod) == .Vector) {2398 if (ty.zigTypeTag(mod) == .Vector) {
2360 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));2399 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));
2361 const scalar_ty = ty.scalarType(mod);2400 const scalar_ty = ty.scalarType(mod);
2362 for (result_data, 0..) |*scalar, i| {2401 for (result_data, 0..) |*scalar, i| {
2363 const lhs_elem = try lhs.elemValue(mod, i);2402 const lhs_elem = try lhs.elemValue(pt, i);
2364 const rhs_elem = try rhs.elemValue(mod, i);2403 const rhs_elem = try rhs.elemValue(pt, i);
2365 const val = intMulScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod) catch |err| switch (err) {2404 const val = intMulScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt) catch |err| switch (err) {
2366 error.Overflow => {2405 error.Overflow => {
2367 overflow_idx.* = i;2406 overflow_idx.* = i;
2368 return error.Overflow;2407 return error.Overflow;
...@@ -2371,26 +2410,26 @@ fn intMulInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator...@@ -2371,26 +2410,26 @@ fn intMulInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator
2371 };2410 };
2372 scalar.* = val.toIntern();2411 scalar.* = val.toIntern();
2373 }2412 }
2374 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2413 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2375 .ty = ty.toIntern(),2414 .ty = ty.toIntern(),
2376 .storage = .{ .elems = result_data },2415 .storage = .{ .elems = result_data },
2377 } })));2416 } }));
2378 }2417 }
2379 return intMulScalar(lhs, rhs, ty, allocator, mod);2418 return intMulScalar(lhs, rhs, ty, allocator, pt);
2380}2419}
23812420
2382pub fn intMulScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2421pub fn intMulScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
2383 if (ty.toIntern() != .comptime_int_type) {2422 if (ty.toIntern() != .comptime_int_type) {
2384 const res = try intMulWithOverflowScalar(lhs, rhs, ty, allocator, mod);2423 const res = try intMulWithOverflowScalar(lhs, rhs, ty, allocator, pt);
2385 if (res.overflow_bit.compareAllWithZero(.neq, mod)) return error.Overflow;2424 if (res.overflow_bit.compareAllWithZero(.neq, pt)) return error.Overflow;
2386 return res.wrapped_result;2425 return res.wrapped_result;
2387 }2426 }
2388 // TODO is this a performance issue? maybe we should try the operation without2427 // TODO is this a performance issue? maybe we should try the operation without
2389 // resorting to BigInt first.2428 // resorting to BigInt first.
2390 var lhs_space: Value.BigIntSpace = undefined;2429 var lhs_space: Value.BigIntSpace = undefined;
2391 var rhs_space: Value.BigIntSpace = undefined;2430 var rhs_space: Value.BigIntSpace = undefined;
2392 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);2431 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
2393 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);2432 const rhs_bigint = rhs.toBigInt(&rhs_space, pt);
2394 const limbs = try allocator.alloc(2433 const limbs = try allocator.alloc(
2395 std.math.big.Limb,2434 std.math.big.Limb,
2396 lhs_bigint.limbs.len + rhs_bigint.limbs.len,2435 lhs_bigint.limbs.len + rhs_bigint.limbs.len,
...@@ -2402,23 +2441,24 @@ pub fn intMulScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod:...@@ -2402,23 +2441,24 @@ pub fn intMulScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod:
2402 );2441 );
2403 defer allocator.free(limbs_buffer);2442 defer allocator.free(limbs_buffer);
2404 result_bigint.mul(lhs_bigint, rhs_bigint, limbs_buffer, allocator);2443 result_bigint.mul(lhs_bigint, rhs_bigint, limbs_buffer, allocator);
2405 return mod.intValue_big(ty, result_bigint.toConst());2444 return pt.intValue_big(ty, result_bigint.toConst());
2406}2445}
24072446
2408pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, mod: *Module) !Value {2447pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, pt: Zcu.PerThread) !Value {
2448 const mod = pt.zcu;
2409 if (ty.zigTypeTag(mod) == .Vector) {2449 if (ty.zigTypeTag(mod) == .Vector) {
2410 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));2450 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));
2411 const scalar_ty = ty.scalarType(mod);2451 const scalar_ty = ty.scalarType(mod);
2412 for (result_data, 0..) |*scalar, i| {2452 for (result_data, 0..) |*scalar, i| {
2413 const elem_val = try val.elemValue(mod, i);2453 const elem_val = try val.elemValue(pt, i);
2414 scalar.* = (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, bits, mod)).toIntern();2454 scalar.* = (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, bits, pt)).toIntern();
2415 }2455 }
2416 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2456 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2417 .ty = ty.toIntern(),2457 .ty = ty.toIntern(),
2418 .storage = .{ .elems = result_data },2458 .storage = .{ .elems = result_data },
2419 } })));2459 } }));
2420 }2460 }
2421 return intTruncScalar(val, ty, allocator, signedness, bits, mod);2461 return intTruncScalar(val, ty, allocator, signedness, bits, pt);
2422}2462}
24232463
2424/// This variant may vectorize on `bits`. Asserts that `bits` is a (vector of) `u16`.2464/// This variant may vectorize on `bits`. Asserts that `bits` is a (vector of) `u16`.
...@@ -2428,22 +2468,22 @@ pub fn intTruncBitsAsValue(...@@ -2428,22 +2468,22 @@ pub fn intTruncBitsAsValue(
2428 allocator: Allocator,2468 allocator: Allocator,
2429 signedness: std.builtin.Signedness,2469 signedness: std.builtin.Signedness,
2430 bits: Value,2470 bits: Value,
2431 mod: *Module,2471 pt: Zcu.PerThread,
2432) !Value {2472) !Value {
2433 if (ty.zigTypeTag(mod) == .Vector) {2473 if (ty.zigTypeTag(pt.zcu) == .Vector) {
2434 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));2474 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
2435 const scalar_ty = ty.scalarType(mod);2475 const scalar_ty = ty.scalarType(pt.zcu);
2436 for (result_data, 0..) |*scalar, i| {2476 for (result_data, 0..) |*scalar, i| {
2437 const elem_val = try val.elemValue(mod, i);2477 const elem_val = try val.elemValue(pt, i);
2438 const bits_elem = try bits.elemValue(mod, i);2478 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();2479 scalar.* = (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, @intCast(bits_elem.toUnsignedInt(pt)), pt)).toIntern();
2440 }2480 }
2441 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2481 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2442 .ty = ty.toIntern(),2482 .ty = ty.toIntern(),
2443 .storage = .{ .elems = result_data },2483 .storage = .{ .elems = result_data },
2444 } })));2484 } }));
2445 }2485 }
2446 return intTruncScalar(val, ty, allocator, signedness, @intCast(bits.toUnsignedInt(mod)), mod);2486 return intTruncScalar(val, ty, allocator, signedness, @intCast(bits.toUnsignedInt(pt)), pt);
2447}2487}
24482488
2449pub fn intTruncScalar(2489pub fn intTruncScalar(
...@@ -2452,14 +2492,15 @@ pub fn intTruncScalar(...@@ -2452,14 +2492,15 @@ pub fn intTruncScalar(
2452 allocator: Allocator,2492 allocator: Allocator,
2453 signedness: std.builtin.Signedness,2493 signedness: std.builtin.Signedness,
2454 bits: u16,2494 bits: u16,
2455 zcu: *Zcu,2495 pt: Zcu.PerThread,
2456) !Value {2496) !Value {
2457 if (bits == 0) return zcu.intValue(ty, 0);2497 const zcu = pt.zcu;
2498 if (bits == 0) return pt.intValue(ty, 0);
24582499
2459 if (val.isUndef(zcu)) return zcu.undefValue(ty);2500 if (val.isUndef(zcu)) return pt.undefValue(ty);
24602501
2461 var val_space: Value.BigIntSpace = undefined;2502 var val_space: Value.BigIntSpace = undefined;
2462 const val_bigint = val.toBigInt(&val_space, zcu);2503 const val_bigint = val.toBigInt(&val_space, pt);
24632504
2464 const limbs = try allocator.alloc(2505 const limbs = try allocator.alloc(
2465 std.math.big.Limb,2506 std.math.big.Limb,
...@@ -2468,32 +2509,33 @@ pub fn intTruncScalar(...@@ -2468,32 +2509,33 @@ pub fn intTruncScalar(
2468 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };2509 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
24692510
2470 result_bigint.truncate(val_bigint, signedness, bits);2511 result_bigint.truncate(val_bigint, signedness, bits);
2471 return zcu.intValue_big(ty, result_bigint.toConst());2512 return pt.intValue_big(ty, result_bigint.toConst());
2472}2513}
24732514
2474pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2515pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
2516 const mod = pt.zcu;
2475 if (ty.zigTypeTag(mod) == .Vector) {2517 if (ty.zigTypeTag(mod) == .Vector) {
2476 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));2518 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));
2477 const scalar_ty = ty.scalarType(mod);2519 const scalar_ty = ty.scalarType(mod);
2478 for (result_data, 0..) |*scalar, i| {2520 for (result_data, 0..) |*scalar, i| {
2479 const lhs_elem = try lhs.elemValue(mod, i);2521 const lhs_elem = try lhs.elemValue(pt, i);
2480 const rhs_elem = try rhs.elemValue(mod, i);2522 const rhs_elem = try rhs.elemValue(pt, i);
2481 scalar.* = (try shlScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();2523 scalar.* = (try shlScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern();
2482 }2524 }
2483 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2525 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2484 .ty = ty.toIntern(),2526 .ty = ty.toIntern(),
2485 .storage = .{ .elems = result_data },2527 .storage = .{ .elems = result_data },
2486 } })));2528 } }));
2487 }2529 }
2488 return shlScalar(lhs, rhs, ty, allocator, mod);2530 return shlScalar(lhs, rhs, ty, allocator, pt);
2489}2531}
24902532
2491pub fn shlScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2533pub 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 without2534 // TODO is this a performance issue? maybe we should try the operation without
2493 // resorting to BigInt first.2535 // resorting to BigInt first.
2494 var lhs_space: Value.BigIntSpace = undefined;2536 var lhs_space: Value.BigIntSpace = undefined;
2495 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);2537 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
2496 const shift: usize = @intCast(rhs.toUnsignedInt(mod));2538 const shift: usize = @intCast(rhs.toUnsignedInt(pt));
2497 const limbs = try allocator.alloc(2539 const limbs = try allocator.alloc(
2498 std.math.big.Limb,2540 std.math.big.Limb,
2499 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,2541 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,
...@@ -2505,11 +2547,11 @@ pub fn shlScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *M...@@ -2505,11 +2547,11 @@ pub fn shlScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *M
2505 };2547 };
2506 result_bigint.shiftLeft(lhs_bigint, shift);2548 result_bigint.shiftLeft(lhs_bigint, shift);
2507 if (ty.toIntern() != .comptime_int_type) {2549 if (ty.toIntern() != .comptime_int_type) {
2508 const int_info = ty.intInfo(mod);2550 const int_info = ty.intInfo(pt.zcu);
2509 result_bigint.truncate(result_bigint.toConst(), int_info.signedness, int_info.bits);2551 result_bigint.truncate(result_bigint.toConst(), int_info.signedness, int_info.bits);
2510 }2552 }
25112553
2512 return mod.intValue_big(ty, result_bigint.toConst());2554 return pt.intValue_big(ty, result_bigint.toConst());
2513}2555}
25142556
2515pub fn shlWithOverflow(2557pub fn shlWithOverflow(
...@@ -2517,32 +2559,32 @@ pub fn shlWithOverflow(...@@ -2517,32 +2559,32 @@ pub fn shlWithOverflow(
2517 rhs: Value,2559 rhs: Value,
2518 ty: Type,2560 ty: Type,
2519 allocator: Allocator,2561 allocator: Allocator,
2520 mod: *Module,2562 pt: Zcu.PerThread,
2521) !OverflowArithmeticResult {2563) !OverflowArithmeticResult {
2522 if (ty.zigTypeTag(mod) == .Vector) {2564 if (ty.zigTypeTag(pt.zcu) == .Vector) {
2523 const vec_len = ty.vectorLen(mod);2565 const vec_len = ty.vectorLen(pt.zcu);
2524 const overflowed_data = try allocator.alloc(InternPool.Index, vec_len);2566 const overflowed_data = try allocator.alloc(InternPool.Index, vec_len);
2525 const result_data = try allocator.alloc(InternPool.Index, vec_len);2567 const result_data = try allocator.alloc(InternPool.Index, vec_len);
2526 const scalar_ty = ty.scalarType(mod);2568 const scalar_ty = ty.scalarType(pt.zcu);
2527 for (overflowed_data, result_data, 0..) |*of, *scalar, i| {2569 for (overflowed_data, result_data, 0..) |*of, *scalar, i| {
2528 const lhs_elem = try lhs.elemValue(mod, i);2570 const lhs_elem = try lhs.elemValue(pt, i);
2529 const rhs_elem = try rhs.elemValue(mod, i);2571 const rhs_elem = try rhs.elemValue(pt, i);
2530 const of_math_result = try shlWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod);2572 const of_math_result = try shlWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt);
2531 of.* = of_math_result.overflow_bit.toIntern();2573 of.* = of_math_result.overflow_bit.toIntern();
2532 scalar.* = of_math_result.wrapped_result.toIntern();2574 scalar.* = of_math_result.wrapped_result.toIntern();
2533 }2575 }
2534 return OverflowArithmeticResult{2576 return OverflowArithmeticResult{
2535 .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{2577 .overflow_bit = Value.fromInterned(try pt.intern(.{ .aggregate = .{
2536 .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),2578 .ty = (try pt.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),
2537 .storage = .{ .elems = overflowed_data },2579 .storage = .{ .elems = overflowed_data },
2538 } }))),2580 } })),
2539 .wrapped_result = Value.fromInterned((try mod.intern(.{ .aggregate = .{2581 .wrapped_result = Value.fromInterned(try pt.intern(.{ .aggregate = .{
2540 .ty = ty.toIntern(),2582 .ty = ty.toIntern(),
2541 .storage = .{ .elems = result_data },2583 .storage = .{ .elems = result_data },
2542 } }))),2584 } })),
2543 };2585 };
2544 }2586 }
2545 return shlWithOverflowScalar(lhs, rhs, ty, allocator, mod);2587 return shlWithOverflowScalar(lhs, rhs, ty, allocator, pt);
2546}2588}
25472589
2548pub fn shlWithOverflowScalar(2590pub fn shlWithOverflowScalar(
...@@ -2550,12 +2592,12 @@ pub fn shlWithOverflowScalar(...@@ -2550,12 +2592,12 @@ pub fn shlWithOverflowScalar(
2550 rhs: Value,2592 rhs: Value,
2551 ty: Type,2593 ty: Type,
2552 allocator: Allocator,2594 allocator: Allocator,
2553 mod: *Module,2595 pt: Zcu.PerThread,
2554) !OverflowArithmeticResult {2596) !OverflowArithmeticResult {
2555 const info = ty.intInfo(mod);2597 const info = ty.intInfo(pt.zcu);
2556 var lhs_space: Value.BigIntSpace = undefined;2598 var lhs_space: Value.BigIntSpace = undefined;
2557 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);2599 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
2558 const shift: usize = @intCast(rhs.toUnsignedInt(mod));2600 const shift: usize = @intCast(rhs.toUnsignedInt(pt));
2559 const limbs = try allocator.alloc(2601 const limbs = try allocator.alloc(
2560 std.math.big.Limb,2602 std.math.big.Limb,
2561 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,2603 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,
...@@ -2571,8 +2613,8 @@ pub fn shlWithOverflowScalar(...@@ -2571,8 +2613,8 @@ pub fn shlWithOverflowScalar(
2571 result_bigint.truncate(result_bigint.toConst(), info.signedness, info.bits);2613 result_bigint.truncate(result_bigint.toConst(), info.signedness, info.bits);
2572 }2614 }
2573 return OverflowArithmeticResult{2615 return OverflowArithmeticResult{
2574 .overflow_bit = try mod.intValue(Type.u1, @intFromBool(overflowed)),2616 .overflow_bit = try pt.intValue(Type.u1, @intFromBool(overflowed)),
2575 .wrapped_result = try mod.intValue_big(ty, result_bigint.toConst()),2617 .wrapped_result = try pt.intValue_big(ty, result_bigint.toConst()),
2576 };2618 };
2577}2619}
25782620
...@@ -2581,22 +2623,22 @@ pub fn shlSat(...@@ -2581,22 +2623,22 @@ pub fn shlSat(
2581 rhs: Value,2623 rhs: Value,
2582 ty: Type,2624 ty: Type,
2583 arena: Allocator,2625 arena: Allocator,
2584 mod: *Module,2626 pt: Zcu.PerThread,
2585) !Value {2627) !Value {
2586 if (ty.zigTypeTag(mod) == .Vector) {2628 if (ty.zigTypeTag(pt.zcu) == .Vector) {
2587 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));2629 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
2588 const scalar_ty = ty.scalarType(mod);2630 const scalar_ty = ty.scalarType(pt.zcu);
2589 for (result_data, 0..) |*scalar, i| {2631 for (result_data, 0..) |*scalar, i| {
2590 const lhs_elem = try lhs.elemValue(mod, i);2632 const lhs_elem = try lhs.elemValue(pt, i);
2591 const rhs_elem = try rhs.elemValue(mod, i);2633 const rhs_elem = try rhs.elemValue(pt, i);
2592 scalar.* = (try shlSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();2634 scalar.* = (try shlSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern();
2593 }2635 }
2594 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2636 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2595 .ty = ty.toIntern(),2637 .ty = ty.toIntern(),
2596 .storage = .{ .elems = result_data },2638 .storage = .{ .elems = result_data },
2597 } })));2639 } }));
2598 }2640 }
2599 return shlSatScalar(lhs, rhs, ty, arena, mod);2641 return shlSatScalar(lhs, rhs, ty, arena, pt);
2600}2642}
26012643
2602pub fn shlSatScalar(2644pub fn shlSatScalar(
...@@ -2604,15 +2646,15 @@ pub fn shlSatScalar(...@@ -2604,15 +2646,15 @@ pub fn shlSatScalar(
2604 rhs: Value,2646 rhs: Value,
2605 ty: Type,2647 ty: Type,
2606 arena: Allocator,2648 arena: Allocator,
2607 mod: *Module,2649 pt: Zcu.PerThread,
2608) !Value {2650) !Value {
2609 // TODO is this a performance issue? maybe we should try the operation without2651 // TODO is this a performance issue? maybe we should try the operation without
2610 // resorting to BigInt first.2652 // resorting to BigInt first.
2611 const info = ty.intInfo(mod);2653 const info = ty.intInfo(pt.zcu);
26122654
2613 var lhs_space: Value.BigIntSpace = undefined;2655 var lhs_space: Value.BigIntSpace = undefined;
2614 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);2656 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
2615 const shift: usize = @intCast(rhs.toUnsignedInt(mod));2657 const shift: usize = @intCast(rhs.toUnsignedInt(pt));
2616 const limbs = try arena.alloc(2658 const limbs = try arena.alloc(
2617 std.math.big.Limb,2659 std.math.big.Limb,
2618 std.math.big.int.calcTwosCompLimbCount(info.bits) + 1,2660 std.math.big.int.calcTwosCompLimbCount(info.bits) + 1,
...@@ -2623,7 +2665,7 @@ pub fn shlSatScalar(...@@ -2623,7 +2665,7 @@ pub fn shlSatScalar(
2623 .len = undefined,2665 .len = undefined,
2624 };2666 };
2625 result_bigint.shiftLeftSat(lhs_bigint, shift, info.signedness, info.bits);2667 result_bigint.shiftLeftSat(lhs_bigint, shift, info.signedness, info.bits);
2626 return mod.intValue_big(ty, result_bigint.toConst());2668 return pt.intValue_big(ty, result_bigint.toConst());
2627}2669}
26282670
2629pub fn shlTrunc(2671pub fn shlTrunc(
...@@ -2631,22 +2673,22 @@ pub fn shlTrunc(...@@ -2631,22 +2673,22 @@ pub fn shlTrunc(
2631 rhs: Value,2673 rhs: Value,
2632 ty: Type,2674 ty: Type,
2633 arena: Allocator,2675 arena: Allocator,
2634 mod: *Module,2676 pt: Zcu.PerThread,
2635) !Value {2677) !Value {
2636 if (ty.zigTypeTag(mod) == .Vector) {2678 if (ty.zigTypeTag(pt.zcu) == .Vector) {
2637 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));2679 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
2638 const scalar_ty = ty.scalarType(mod);2680 const scalar_ty = ty.scalarType(pt.zcu);
2639 for (result_data, 0..) |*scalar, i| {2681 for (result_data, 0..) |*scalar, i| {
2640 const lhs_elem = try lhs.elemValue(mod, i);2682 const lhs_elem = try lhs.elemValue(pt, i);
2641 const rhs_elem = try rhs.elemValue(mod, i);2683 const rhs_elem = try rhs.elemValue(pt, i);
2642 scalar.* = (try shlTruncScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();2684 scalar.* = (try shlTruncScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern();
2643 }2685 }
2644 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2686 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2645 .ty = ty.toIntern(),2687 .ty = ty.toIntern(),
2646 .storage = .{ .elems = result_data },2688 .storage = .{ .elems = result_data },
2647 } })));2689 } }));
2648 }2690 }
2649 return shlTruncScalar(lhs, rhs, ty, arena, mod);2691 return shlTruncScalar(lhs, rhs, ty, arena, pt);
2650}2692}
26512693
2652pub fn shlTruncScalar(2694pub fn shlTruncScalar(
...@@ -2654,46 +2696,46 @@ pub fn shlTruncScalar(...@@ -2654,46 +2696,46 @@ pub fn shlTruncScalar(
2654 rhs: Value,2696 rhs: Value,
2655 ty: Type,2697 ty: Type,
2656 arena: Allocator,2698 arena: Allocator,
2657 mod: *Module,2699 pt: Zcu.PerThread,
2658) !Value {2700) !Value {
2659 const shifted = try lhs.shl(rhs, ty, arena, mod);2701 const shifted = try lhs.shl(rhs, ty, arena, pt);
2660 const int_info = ty.intInfo(mod);2702 const int_info = ty.intInfo(pt.zcu);
2661 const truncated = try shifted.intTrunc(ty, arena, int_info.signedness, int_info.bits, mod);2703 const truncated = try shifted.intTrunc(ty, arena, int_info.signedness, int_info.bits, pt);
2662 return truncated;2704 return truncated;
2663}2705}
26642706
2665pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2707pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value {
2666 if (ty.zigTypeTag(mod) == .Vector) {2708 if (ty.zigTypeTag(pt.zcu) == .Vector) {
2667 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod));2709 const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(pt.zcu));
2668 const scalar_ty = ty.scalarType(mod);2710 const scalar_ty = ty.scalarType(pt.zcu);
2669 for (result_data, 0..) |*scalar, i| {2711 for (result_data, 0..) |*scalar, i| {
2670 const lhs_elem = try lhs.elemValue(mod, i);2712 const lhs_elem = try lhs.elemValue(pt, i);
2671 const rhs_elem = try rhs.elemValue(mod, i);2713 const rhs_elem = try rhs.elemValue(pt, i);
2672 scalar.* = (try shrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();2714 scalar.* = (try shrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern();
2673 }2715 }
2674 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2716 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2675 .ty = ty.toIntern(),2717 .ty = ty.toIntern(),
2676 .storage = .{ .elems = result_data },2718 .storage = .{ .elems = result_data },
2677 } })));2719 } }));
2678 }2720 }
2679 return shrScalar(lhs, rhs, ty, allocator, mod);2721 return shrScalar(lhs, rhs, ty, allocator, pt);
2680}2722}
26812723
2682pub fn shrScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {2724pub 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 without2725 // TODO is this a performance issue? maybe we should try the operation without
2684 // resorting to BigInt first.2726 // resorting to BigInt first.
2685 var lhs_space: Value.BigIntSpace = undefined;2727 var lhs_space: Value.BigIntSpace = undefined;
2686 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);2728 const lhs_bigint = lhs.toBigInt(&lhs_space, pt);
2687 const shift: usize = @intCast(rhs.toUnsignedInt(mod));2729 const shift: usize = @intCast(rhs.toUnsignedInt(pt));
26882730
2689 const result_limbs = lhs_bigint.limbs.len -| (shift / (@sizeOf(std.math.big.Limb) * 8));2731 const result_limbs = lhs_bigint.limbs.len -| (shift / (@sizeOf(std.math.big.Limb) * 8));
2690 if (result_limbs == 0) {2732 if (result_limbs == 0) {
2691 // The shift is enough to remove all the bits from the number, which means the2733 // 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.2734 // result is 0 or -1 depending on the sign.
2693 if (lhs_bigint.positive) {2735 if (lhs_bigint.positive) {
2694 return mod.intValue(ty, 0);2736 return pt.intValue(ty, 0);
2695 } else {2737 } else {
2696 return mod.intValue(ty, -1);2738 return pt.intValue(ty, -1);
2697 }2739 }
2698 }2740 }
26992741
...@@ -2707,48 +2749,45 @@ pub fn shrScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *M...@@ -2707,48 +2749,45 @@ pub fn shrScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *M
2707 .len = undefined,2749 .len = undefined,
2708 };2750 };
2709 result_bigint.shiftRight(lhs_bigint, shift);2751 result_bigint.shiftRight(lhs_bigint, shift);
2710 return mod.intValue_big(ty, result_bigint.toConst());2752 return pt.intValue_big(ty, result_bigint.toConst());
2711}2753}
27122754
2713pub fn floatNeg(2755pub fn floatNeg(
2714 val: Value,2756 val: Value,
2715 float_type: Type,2757 float_type: Type,
2716 arena: Allocator,2758 arena: Allocator,
2717 mod: *Module,2759 pt: Zcu.PerThread,
2718) !Value {2760) !Value {
2761 const mod = pt.zcu;
2719 if (float_type.zigTypeTag(mod) == .Vector) {2762 if (float_type.zigTypeTag(mod) == .Vector) {
2720 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));2763 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
2721 const scalar_ty = float_type.scalarType(mod);2764 const scalar_ty = float_type.scalarType(mod);
2722 for (result_data, 0..) |*scalar, i| {2765 for (result_data, 0..) |*scalar, i| {
2723 const elem_val = try val.elemValue(mod, i);2766 const elem_val = try val.elemValue(pt, i);
2724 scalar.* = (try floatNegScalar(elem_val, scalar_ty, mod)).toIntern();2767 scalar.* = (try floatNegScalar(elem_val, scalar_ty, pt)).toIntern();
2725 }2768 }
2726 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2769 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2727 .ty = float_type.toIntern(),2770 .ty = float_type.toIntern(),
2728 .storage = .{ .elems = result_data },2771 .storage = .{ .elems = result_data },
2729 } })));2772 } }));
2730 }2773 }
2731 return floatNegScalar(val, float_type, mod);2774 return floatNegScalar(val, float_type, pt);
2732}2775}
27332776
2734pub fn floatNegScalar(2777pub fn floatNegScalar(val: Value, float_type: Type, pt: Zcu.PerThread) !Value {
2735 val: Value,2778 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)) {2779 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
2741 16 => .{ .f16 = -val.toFloat(f16, mod) },2780 16 => .{ .f16 = -val.toFloat(f16, pt) },
2742 32 => .{ .f32 = -val.toFloat(f32, mod) },2781 32 => .{ .f32 = -val.toFloat(f32, pt) },
2743 64 => .{ .f64 = -val.toFloat(f64, mod) },2782 64 => .{ .f64 = -val.toFloat(f64, pt) },
2744 80 => .{ .f80 = -val.toFloat(f80, mod) },2783 80 => .{ .f80 = -val.toFloat(f80, pt) },
2745 128 => .{ .f128 = -val.toFloat(f128, mod) },2784 128 => .{ .f128 = -val.toFloat(f128, pt) },
2746 else => unreachable,2785 else => unreachable,
2747 };2786 };
2748 return Value.fromInterned((try mod.intern(.{ .float = .{2787 return Value.fromInterned(try pt.intern(.{ .float = .{
2749 .ty = float_type.toIntern(),2788 .ty = float_type.toIntern(),
2750 .storage = storage,2789 .storage = storage,
2751 } })));2790 } }));
2752}2791}
27532792
2754pub fn floatAdd(2793pub fn floatAdd(
...@@ -2756,43 +2795,45 @@ pub fn floatAdd(...@@ -2756,43 +2795,45 @@ pub fn floatAdd(
2756 rhs: Value,2795 rhs: Value,
2757 float_type: Type,2796 float_type: Type,
2758 arena: Allocator,2797 arena: Allocator,
2759 mod: *Module,2798 pt: Zcu.PerThread,
2760) !Value {2799) !Value {
2800 const mod = pt.zcu;
2761 if (float_type.zigTypeTag(mod) == .Vector) {2801 if (float_type.zigTypeTag(mod) == .Vector) {
2762 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));2802 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
2763 const scalar_ty = float_type.scalarType(mod);2803 const scalar_ty = float_type.scalarType(mod);
2764 for (result_data, 0..) |*scalar, i| {2804 for (result_data, 0..) |*scalar, i| {
2765 const lhs_elem = try lhs.elemValue(mod, i);2805 const lhs_elem = try lhs.elemValue(pt, i);
2766 const rhs_elem = try rhs.elemValue(mod, i);2806 const rhs_elem = try rhs.elemValue(pt, i);
2767 scalar.* = (try floatAddScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();2807 scalar.* = (try floatAddScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern();
2768 }2808 }
2769 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2809 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2770 .ty = float_type.toIntern(),2810 .ty = float_type.toIntern(),
2771 .storage = .{ .elems = result_data },2811 .storage = .{ .elems = result_data },
2772 } })));2812 } }));
2773 }2813 }
2774 return floatAddScalar(lhs, rhs, float_type, mod);2814 return floatAddScalar(lhs, rhs, float_type, pt);
2775}2815}
27762816
2777pub fn floatAddScalar(2817pub fn floatAddScalar(
2778 lhs: Value,2818 lhs: Value,
2779 rhs: Value,2819 rhs: Value,
2780 float_type: Type,2820 float_type: Type,
2781 mod: *Module,2821 pt: Zcu.PerThread,
2782) !Value {2822) !Value {
2823 const mod = pt.zcu;
2783 const target = mod.getTarget();2824 const target = mod.getTarget();
2784 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {2825 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
2785 16 => .{ .f16 = lhs.toFloat(f16, mod) + rhs.toFloat(f16, mod) },2826 16 => .{ .f16 = lhs.toFloat(f16, pt) + rhs.toFloat(f16, pt) },
2786 32 => .{ .f32 = lhs.toFloat(f32, mod) + rhs.toFloat(f32, mod) },2827 32 => .{ .f32 = lhs.toFloat(f32, pt) + rhs.toFloat(f32, pt) },
2787 64 => .{ .f64 = lhs.toFloat(f64, mod) + rhs.toFloat(f64, mod) },2828 64 => .{ .f64 = lhs.toFloat(f64, pt) + rhs.toFloat(f64, pt) },
2788 80 => .{ .f80 = lhs.toFloat(f80, mod) + rhs.toFloat(f80, mod) },2829 80 => .{ .f80 = lhs.toFloat(f80, pt) + rhs.toFloat(f80, pt) },
2789 128 => .{ .f128 = lhs.toFloat(f128, mod) + rhs.toFloat(f128, mod) },2830 128 => .{ .f128 = lhs.toFloat(f128, pt) + rhs.toFloat(f128, pt) },
2790 else => unreachable,2831 else => unreachable,
2791 };2832 };
2792 return Value.fromInterned((try mod.intern(.{ .float = .{2833 return Value.fromInterned(try pt.intern(.{ .float = .{
2793 .ty = float_type.toIntern(),2834 .ty = float_type.toIntern(),
2794 .storage = storage,2835 .storage = storage,
2795 } })));2836 } }));
2796}2837}
27972838
2798pub fn floatSub(2839pub fn floatSub(
...@@ -2800,43 +2841,45 @@ pub fn floatSub(...@@ -2800,43 +2841,45 @@ pub fn floatSub(
2800 rhs: Value,2841 rhs: Value,
2801 float_type: Type,2842 float_type: Type,
2802 arena: Allocator,2843 arena: Allocator,
2803 mod: *Module,2844 pt: Zcu.PerThread,
2804) !Value {2845) !Value {
2846 const mod = pt.zcu;
2805 if (float_type.zigTypeTag(mod) == .Vector) {2847 if (float_type.zigTypeTag(mod) == .Vector) {
2806 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));2848 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
2807 const scalar_ty = float_type.scalarType(mod);2849 const scalar_ty = float_type.scalarType(mod);
2808 for (result_data, 0..) |*scalar, i| {2850 for (result_data, 0..) |*scalar, i| {
2809 const lhs_elem = try lhs.elemValue(mod, i);2851 const lhs_elem = try lhs.elemValue(pt, i);
2810 const rhs_elem = try rhs.elemValue(mod, i);2852 const rhs_elem = try rhs.elemValue(pt, i);
2811 scalar.* = (try floatSubScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();2853 scalar.* = (try floatSubScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern();
2812 }2854 }
2813 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2855 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2814 .ty = float_type.toIntern(),2856 .ty = float_type.toIntern(),
2815 .storage = .{ .elems = result_data },2857 .storage = .{ .elems = result_data },
2816 } })));2858 } }));
2817 }2859 }
2818 return floatSubScalar(lhs, rhs, float_type, mod);2860 return floatSubScalar(lhs, rhs, float_type, pt);
2819}2861}
28202862
2821pub fn floatSubScalar(2863pub fn floatSubScalar(
2822 lhs: Value,2864 lhs: Value,
2823 rhs: Value,2865 rhs: Value,
2824 float_type: Type,2866 float_type: Type,
2825 mod: *Module,2867 pt: Zcu.PerThread,
2826) !Value {2868) !Value {
2869 const mod = pt.zcu;
2827 const target = mod.getTarget();2870 const target = mod.getTarget();
2828 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {2871 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
2829 16 => .{ .f16 = lhs.toFloat(f16, mod) - rhs.toFloat(f16, mod) },2872 16 => .{ .f16 = lhs.toFloat(f16, pt) - rhs.toFloat(f16, pt) },
2830 32 => .{ .f32 = lhs.toFloat(f32, mod) - rhs.toFloat(f32, mod) },2873 32 => .{ .f32 = lhs.toFloat(f32, pt) - rhs.toFloat(f32, pt) },
2831 64 => .{ .f64 = lhs.toFloat(f64, mod) - rhs.toFloat(f64, mod) },2874 64 => .{ .f64 = lhs.toFloat(f64, pt) - rhs.toFloat(f64, pt) },
2832 80 => .{ .f80 = lhs.toFloat(f80, mod) - rhs.toFloat(f80, mod) },2875 80 => .{ .f80 = lhs.toFloat(f80, pt) - rhs.toFloat(f80, pt) },
2833 128 => .{ .f128 = lhs.toFloat(f128, mod) - rhs.toFloat(f128, mod) },2876 128 => .{ .f128 = lhs.toFloat(f128, pt) - rhs.toFloat(f128, pt) },
2834 else => unreachable,2877 else => unreachable,
2835 };2878 };
2836 return Value.fromInterned((try mod.intern(.{ .float = .{2879 return Value.fromInterned(try pt.intern(.{ .float = .{
2837 .ty = float_type.toIntern(),2880 .ty = float_type.toIntern(),
2838 .storage = storage,2881 .storage = storage,
2839 } })));2882 } }));
2840}2883}
28412884
2842pub fn floatDiv(2885pub fn floatDiv(
...@@ -2844,43 +2887,43 @@ pub fn floatDiv(...@@ -2844,43 +2887,43 @@ pub fn floatDiv(
2844 rhs: Value,2887 rhs: Value,
2845 float_type: Type,2888 float_type: Type,
2846 arena: Allocator,2889 arena: Allocator,
2847 mod: *Module,2890 pt: Zcu.PerThread,
2848) !Value {2891) !Value {
2849 if (float_type.zigTypeTag(mod) == .Vector) {2892 if (float_type.zigTypeTag(pt.zcu) == .Vector) {
2850 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));2893 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(pt.zcu));
2851 const scalar_ty = float_type.scalarType(mod);2894 const scalar_ty = float_type.scalarType(pt.zcu);
2852 for (result_data, 0..) |*scalar, i| {2895 for (result_data, 0..) |*scalar, i| {
2853 const lhs_elem = try lhs.elemValue(mod, i);2896 const lhs_elem = try lhs.elemValue(pt, i);
2854 const rhs_elem = try rhs.elemValue(mod, i);2897 const rhs_elem = try rhs.elemValue(pt, i);
2855 scalar.* = (try floatDivScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();2898 scalar.* = (try floatDivScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern();
2856 }2899 }
2857 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2900 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2858 .ty = float_type.toIntern(),2901 .ty = float_type.toIntern(),
2859 .storage = .{ .elems = result_data },2902 .storage = .{ .elems = result_data },
2860 } })));2903 } }));
2861 }2904 }
2862 return floatDivScalar(lhs, rhs, float_type, mod);2905 return floatDivScalar(lhs, rhs, float_type, pt);
2863}2906}
28642907
2865pub fn floatDivScalar(2908pub fn floatDivScalar(
2866 lhs: Value,2909 lhs: Value,
2867 rhs: Value,2910 rhs: Value,
2868 float_type: Type,2911 float_type: Type,
2869 mod: *Module,2912 pt: Zcu.PerThread,
2870) !Value {2913) !Value {
2871 const target = mod.getTarget();2914 const target = pt.zcu.getTarget();
2872 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {2915 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
2873 16 => .{ .f16 = lhs.toFloat(f16, mod) / rhs.toFloat(f16, mod) },2916 16 => .{ .f16 = lhs.toFloat(f16, pt) / rhs.toFloat(f16, pt) },
2874 32 => .{ .f32 = lhs.toFloat(f32, mod) / rhs.toFloat(f32, mod) },2917 32 => .{ .f32 = lhs.toFloat(f32, pt) / rhs.toFloat(f32, pt) },
2875 64 => .{ .f64 = lhs.toFloat(f64, mod) / rhs.toFloat(f64, mod) },2918 64 => .{ .f64 = lhs.toFloat(f64, pt) / rhs.toFloat(f64, pt) },
2876 80 => .{ .f80 = lhs.toFloat(f80, mod) / rhs.toFloat(f80, mod) },2919 80 => .{ .f80 = lhs.toFloat(f80, pt) / rhs.toFloat(f80, pt) },
2877 128 => .{ .f128 = lhs.toFloat(f128, mod) / rhs.toFloat(f128, mod) },2920 128 => .{ .f128 = lhs.toFloat(f128, pt) / rhs.toFloat(f128, pt) },
2878 else => unreachable,2921 else => unreachable,
2879 };2922 };
2880 return Value.fromInterned((try mod.intern(.{ .float = .{2923 return Value.fromInterned(try pt.intern(.{ .float = .{
2881 .ty = float_type.toIntern(),2924 .ty = float_type.toIntern(),
2882 .storage = storage,2925 .storage = storage,
2883 } })));2926 } }));
2884}2927}
28852928
2886pub fn floatDivFloor(2929pub fn floatDivFloor(
...@@ -2888,43 +2931,43 @@ pub fn floatDivFloor(...@@ -2888,43 +2931,43 @@ pub fn floatDivFloor(
2888 rhs: Value,2931 rhs: Value,
2889 float_type: Type,2932 float_type: Type,
2890 arena: Allocator,2933 arena: Allocator,
2891 mod: *Module,2934 pt: Zcu.PerThread,
2892) !Value {2935) !Value {
2893 if (float_type.zigTypeTag(mod) == .Vector) {2936 if (float_type.zigTypeTag(pt.zcu) == .Vector) {
2894 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));2937 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(pt.zcu));
2895 const scalar_ty = float_type.scalarType(mod);2938 const scalar_ty = float_type.scalarType(pt.zcu);
2896 for (result_data, 0..) |*scalar, i| {2939 for (result_data, 0..) |*scalar, i| {
2897 const lhs_elem = try lhs.elemValue(mod, i);2940 const lhs_elem = try lhs.elemValue(pt, i);
2898 const rhs_elem = try rhs.elemValue(mod, i);2941 const rhs_elem = try rhs.elemValue(pt, i);
2899 scalar.* = (try floatDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();2942 scalar.* = (try floatDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern();
2900 }2943 }
2901 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2944 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2902 .ty = float_type.toIntern(),2945 .ty = float_type.toIntern(),
2903 .storage = .{ .elems = result_data },2946 .storage = .{ .elems = result_data },
2904 } })));2947 } }));
2905 }2948 }
2906 return floatDivFloorScalar(lhs, rhs, float_type, mod);2949 return floatDivFloorScalar(lhs, rhs, float_type, pt);
2907}2950}
29082951
2909pub fn floatDivFloorScalar(2952pub fn floatDivFloorScalar(
2910 lhs: Value,2953 lhs: Value,
2911 rhs: Value,2954 rhs: Value,
2912 float_type: Type,2955 float_type: Type,
2913 mod: *Module,2956 pt: Zcu.PerThread,
2914) !Value {2957) !Value {
2915 const target = mod.getTarget();2958 const target = pt.zcu.getTarget();
2916 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {2959 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
2917 16 => .{ .f16 = @divFloor(lhs.toFloat(f16, mod), rhs.toFloat(f16, mod)) },2960 16 => .{ .f16 = @divFloor(lhs.toFloat(f16, pt), rhs.toFloat(f16, pt)) },
2918 32 => .{ .f32 = @divFloor(lhs.toFloat(f32, mod), rhs.toFloat(f32, mod)) },2961 32 => .{ .f32 = @divFloor(lhs.toFloat(f32, pt), rhs.toFloat(f32, pt)) },
2919 64 => .{ .f64 = @divFloor(lhs.toFloat(f64, mod), rhs.toFloat(f64, mod)) },2962 64 => .{ .f64 = @divFloor(lhs.toFloat(f64, pt), rhs.toFloat(f64, pt)) },
2920 80 => .{ .f80 = @divFloor(lhs.toFloat(f80, mod), rhs.toFloat(f80, mod)) },2963 80 => .{ .f80 = @divFloor(lhs.toFloat(f80, pt), rhs.toFloat(f80, pt)) },
2921 128 => .{ .f128 = @divFloor(lhs.toFloat(f128, mod), rhs.toFloat(f128, mod)) },2964 128 => .{ .f128 = @divFloor(lhs.toFloat(f128, pt), rhs.toFloat(f128, pt)) },
2922 else => unreachable,2965 else => unreachable,
2923 };2966 };
2924 return Value.fromInterned((try mod.intern(.{ .float = .{2967 return Value.fromInterned(try pt.intern(.{ .float = .{
2925 .ty = float_type.toIntern(),2968 .ty = float_type.toIntern(),
2926 .storage = storage,2969 .storage = storage,
2927 } })));2970 } }));
2928}2971}
29292972
2930pub fn floatDivTrunc(2973pub fn floatDivTrunc(
...@@ -2932,43 +2975,43 @@ pub fn floatDivTrunc(...@@ -2932,43 +2975,43 @@ pub fn floatDivTrunc(
2932 rhs: Value,2975 rhs: Value,
2933 float_type: Type,2976 float_type: Type,
2934 arena: Allocator,2977 arena: Allocator,
2935 mod: *Module,2978 pt: Zcu.PerThread,
2936) !Value {2979) !Value {
2937 if (float_type.zigTypeTag(mod) == .Vector) {2980 if (float_type.zigTypeTag(pt.zcu) == .Vector) {
2938 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));2981 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(pt.zcu));
2939 const scalar_ty = float_type.scalarType(mod);2982 const scalar_ty = float_type.scalarType(pt.zcu);
2940 for (result_data, 0..) |*scalar, i| {2983 for (result_data, 0..) |*scalar, i| {
2941 const lhs_elem = try lhs.elemValue(mod, i);2984 const lhs_elem = try lhs.elemValue(pt, i);
2942 const rhs_elem = try rhs.elemValue(mod, i);2985 const rhs_elem = try rhs.elemValue(pt, i);
2943 scalar.* = (try floatDivTruncScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();2986 scalar.* = (try floatDivTruncScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern();
2944 }2987 }
2945 return Value.fromInterned((try mod.intern(.{ .aggregate = .{2988 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2946 .ty = float_type.toIntern(),2989 .ty = float_type.toIntern(),
2947 .storage = .{ .elems = result_data },2990 .storage = .{ .elems = result_data },
2948 } })));2991 } }));
2949 }2992 }
2950 return floatDivTruncScalar(lhs, rhs, float_type, mod);2993 return floatDivTruncScalar(lhs, rhs, float_type, pt);
2951}2994}
29522995
2953pub fn floatDivTruncScalar(2996pub fn floatDivTruncScalar(
2954 lhs: Value,2997 lhs: Value,
2955 rhs: Value,2998 rhs: Value,
2956 float_type: Type,2999 float_type: Type,
2957 mod: *Module,3000 pt: Zcu.PerThread,
2958) !Value {3001) !Value {
2959 const target = mod.getTarget();3002 const target = pt.zcu.getTarget();
2960 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3003 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
2961 16 => .{ .f16 = @divTrunc(lhs.toFloat(f16, mod), rhs.toFloat(f16, mod)) },3004 16 => .{ .f16 = @divTrunc(lhs.toFloat(f16, pt), rhs.toFloat(f16, pt)) },
2962 32 => .{ .f32 = @divTrunc(lhs.toFloat(f32, mod), rhs.toFloat(f32, mod)) },3005 32 => .{ .f32 = @divTrunc(lhs.toFloat(f32, pt), rhs.toFloat(f32, pt)) },
2963 64 => .{ .f64 = @divTrunc(lhs.toFloat(f64, mod), rhs.toFloat(f64, mod)) },3006 64 => .{ .f64 = @divTrunc(lhs.toFloat(f64, pt), rhs.toFloat(f64, pt)) },
2964 80 => .{ .f80 = @divTrunc(lhs.toFloat(f80, mod), rhs.toFloat(f80, mod)) },3007 80 => .{ .f80 = @divTrunc(lhs.toFloat(f80, pt), rhs.toFloat(f80, pt)) },
2965 128 => .{ .f128 = @divTrunc(lhs.toFloat(f128, mod), rhs.toFloat(f128, mod)) },3008 128 => .{ .f128 = @divTrunc(lhs.toFloat(f128, pt), rhs.toFloat(f128, pt)) },
2966 else => unreachable,3009 else => unreachable,
2967 };3010 };
2968 return Value.fromInterned((try mod.intern(.{ .float = .{3011 return Value.fromInterned(try pt.intern(.{ .float = .{
2969 .ty = float_type.toIntern(),3012 .ty = float_type.toIntern(),
2970 .storage = storage,3013 .storage = storage,
2971 } })));3014 } }));
2972}3015}
29733016
2974pub fn floatMul(3017pub fn floatMul(
...@@ -2976,510 +3019,539 @@ pub fn floatMul(...@@ -2976,510 +3019,539 @@ pub fn floatMul(
2976 rhs: Value,3019 rhs: Value,
2977 float_type: Type,3020 float_type: Type,
2978 arena: Allocator,3021 arena: Allocator,
2979 mod: *Module,3022 pt: Zcu.PerThread,
2980) !Value {3023) !Value {
3024 const mod = pt.zcu;
2981 if (float_type.zigTypeTag(mod) == .Vector) {3025 if (float_type.zigTypeTag(mod) == .Vector) {
2982 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3026 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
2983 const scalar_ty = float_type.scalarType(mod);3027 const scalar_ty = float_type.scalarType(mod);
2984 for (result_data, 0..) |*scalar, i| {3028 for (result_data, 0..) |*scalar, i| {
2985 const lhs_elem = try lhs.elemValue(mod, i);3029 const lhs_elem = try lhs.elemValue(pt, i);
2986 const rhs_elem = try rhs.elemValue(mod, i);3030 const rhs_elem = try rhs.elemValue(pt, i);
2987 scalar.* = (try floatMulScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();3031 scalar.* = (try floatMulScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern();
2988 }3032 }
2989 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3033 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
2990 .ty = float_type.toIntern(),3034 .ty = float_type.toIntern(),
2991 .storage = .{ .elems = result_data },3035 .storage = .{ .elems = result_data },
2992 } })));3036 } }));
2993 }3037 }
2994 return floatMulScalar(lhs, rhs, float_type, mod);3038 return floatMulScalar(lhs, rhs, float_type, pt);
2995}3039}
29963040
2997pub fn floatMulScalar(3041pub fn floatMulScalar(
2998 lhs: Value,3042 lhs: Value,
2999 rhs: Value,3043 rhs: Value,
3000 float_type: Type,3044 float_type: Type,
3001 mod: *Module,3045 pt: Zcu.PerThread,
3002) !Value {3046) !Value {
3047 const mod = pt.zcu;
3003 const target = mod.getTarget();3048 const target = mod.getTarget();
3004 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3049 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3005 16 => .{ .f16 = lhs.toFloat(f16, mod) * rhs.toFloat(f16, mod) },3050 16 => .{ .f16 = lhs.toFloat(f16, pt) * rhs.toFloat(f16, pt) },
3006 32 => .{ .f32 = lhs.toFloat(f32, mod) * rhs.toFloat(f32, mod) },3051 32 => .{ .f32 = lhs.toFloat(f32, pt) * rhs.toFloat(f32, pt) },
3007 64 => .{ .f64 = lhs.toFloat(f64, mod) * rhs.toFloat(f64, mod) },3052 64 => .{ .f64 = lhs.toFloat(f64, pt) * rhs.toFloat(f64, pt) },
3008 80 => .{ .f80 = lhs.toFloat(f80, mod) * rhs.toFloat(f80, mod) },3053 80 => .{ .f80 = lhs.toFloat(f80, pt) * rhs.toFloat(f80, pt) },
3009 128 => .{ .f128 = lhs.toFloat(f128, mod) * rhs.toFloat(f128, mod) },3054 128 => .{ .f128 = lhs.toFloat(f128, pt) * rhs.toFloat(f128, pt) },
3010 else => unreachable,3055 else => unreachable,
3011 };3056 };
3012 return Value.fromInterned((try mod.intern(.{ .float = .{3057 return Value.fromInterned(try pt.intern(.{ .float = .{
3013 .ty = float_type.toIntern(),3058 .ty = float_type.toIntern(),
3014 .storage = storage,3059 .storage = storage,
3015 } })));3060 } }));
3016}3061}
30173062
3018pub fn sqrt(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3063pub fn sqrt(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3019 if (float_type.zigTypeTag(mod) == .Vector) {3064 if (float_type.zigTypeTag(pt.zcu) == .Vector) {
3020 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3065 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(pt.zcu));
3021 const scalar_ty = float_type.scalarType(mod);3066 const scalar_ty = float_type.scalarType(pt.zcu);
3022 for (result_data, 0..) |*scalar, i| {3067 for (result_data, 0..) |*scalar, i| {
3023 const elem_val = try val.elemValue(mod, i);3068 const elem_val = try val.elemValue(pt, i);
3024 scalar.* = (try sqrtScalar(elem_val, scalar_ty, mod)).toIntern();3069 scalar.* = (try sqrtScalar(elem_val, scalar_ty, pt)).toIntern();
3025 }3070 }
3026 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3071 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3027 .ty = float_type.toIntern(),3072 .ty = float_type.toIntern(),
3028 .storage = .{ .elems = result_data },3073 .storage = .{ .elems = result_data },
3029 } })));3074 } }));
3030 }3075 }
3031 return sqrtScalar(val, float_type, mod);3076 return sqrtScalar(val, float_type, pt);
3032}3077}
30333078
3034pub fn sqrtScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3079pub fn sqrtScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3080 const mod = pt.zcu;
3035 const target = mod.getTarget();3081 const target = mod.getTarget();
3036 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3082 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3037 16 => .{ .f16 = @sqrt(val.toFloat(f16, mod)) },3083 16 => .{ .f16 = @sqrt(val.toFloat(f16, pt)) },
3038 32 => .{ .f32 = @sqrt(val.toFloat(f32, mod)) },3084 32 => .{ .f32 = @sqrt(val.toFloat(f32, pt)) },
3039 64 => .{ .f64 = @sqrt(val.toFloat(f64, mod)) },3085 64 => .{ .f64 = @sqrt(val.toFloat(f64, pt)) },
3040 80 => .{ .f80 = @sqrt(val.toFloat(f80, mod)) },3086 80 => .{ .f80 = @sqrt(val.toFloat(f80, pt)) },
3041 128 => .{ .f128 = @sqrt(val.toFloat(f128, mod)) },3087 128 => .{ .f128 = @sqrt(val.toFloat(f128, pt)) },
3042 else => unreachable,3088 else => unreachable,
3043 };3089 };
3044 return Value.fromInterned((try mod.intern(.{ .float = .{3090 return Value.fromInterned(try pt.intern(.{ .float = .{
3045 .ty = float_type.toIntern(),3091 .ty = float_type.toIntern(),
3046 .storage = storage,3092 .storage = storage,
3047 } })));3093 } }));
3048}3094}
30493095
3050pub fn sin(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3096pub fn sin(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3097 const mod = pt.zcu;
3051 if (float_type.zigTypeTag(mod) == .Vector) {3098 if (float_type.zigTypeTag(mod) == .Vector) {
3052 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3099 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3053 const scalar_ty = float_type.scalarType(mod);3100 const scalar_ty = float_type.scalarType(mod);
3054 for (result_data, 0..) |*scalar, i| {3101 for (result_data, 0..) |*scalar, i| {
3055 const elem_val = try val.elemValue(mod, i);3102 const elem_val = try val.elemValue(pt, i);
3056 scalar.* = (try sinScalar(elem_val, scalar_ty, mod)).toIntern();3103 scalar.* = (try sinScalar(elem_val, scalar_ty, pt)).toIntern();
3057 }3104 }
3058 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3105 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3059 .ty = float_type.toIntern(),3106 .ty = float_type.toIntern(),
3060 .storage = .{ .elems = result_data },3107 .storage = .{ .elems = result_data },
3061 } })));3108 } }));
3062 }3109 }
3063 return sinScalar(val, float_type, mod);3110 return sinScalar(val, float_type, pt);
3064}3111}
30653112
3066pub fn sinScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3113pub fn sinScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3114 const mod = pt.zcu;
3067 const target = mod.getTarget();3115 const target = mod.getTarget();
3068 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3116 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3069 16 => .{ .f16 = @sin(val.toFloat(f16, mod)) },3117 16 => .{ .f16 = @sin(val.toFloat(f16, pt)) },
3070 32 => .{ .f32 = @sin(val.toFloat(f32, mod)) },3118 32 => .{ .f32 = @sin(val.toFloat(f32, pt)) },
3071 64 => .{ .f64 = @sin(val.toFloat(f64, mod)) },3119 64 => .{ .f64 = @sin(val.toFloat(f64, pt)) },
3072 80 => .{ .f80 = @sin(val.toFloat(f80, mod)) },3120 80 => .{ .f80 = @sin(val.toFloat(f80, pt)) },
3073 128 => .{ .f128 = @sin(val.toFloat(f128, mod)) },3121 128 => .{ .f128 = @sin(val.toFloat(f128, pt)) },
3074 else => unreachable,3122 else => unreachable,
3075 };3123 };
3076 return Value.fromInterned((try mod.intern(.{ .float = .{3124 return Value.fromInterned(try pt.intern(.{ .float = .{
3077 .ty = float_type.toIntern(),3125 .ty = float_type.toIntern(),
3078 .storage = storage,3126 .storage = storage,
3079 } })));3127 } }));
3080}3128}
30813129
3082pub fn cos(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3130pub fn cos(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3131 const mod = pt.zcu;
3083 if (float_type.zigTypeTag(mod) == .Vector) {3132 if (float_type.zigTypeTag(mod) == .Vector) {
3084 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3133 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3085 const scalar_ty = float_type.scalarType(mod);3134 const scalar_ty = float_type.scalarType(mod);
3086 for (result_data, 0..) |*scalar, i| {3135 for (result_data, 0..) |*scalar, i| {
3087 const elem_val = try val.elemValue(mod, i);3136 const elem_val = try val.elemValue(pt, i);
3088 scalar.* = (try cosScalar(elem_val, scalar_ty, mod)).toIntern();3137 scalar.* = (try cosScalar(elem_val, scalar_ty, pt)).toIntern();
3089 }3138 }
3090 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3139 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3091 .ty = float_type.toIntern(),3140 .ty = float_type.toIntern(),
3092 .storage = .{ .elems = result_data },3141 .storage = .{ .elems = result_data },
3093 } })));3142 } }));
3094 }3143 }
3095 return cosScalar(val, float_type, mod);3144 return cosScalar(val, float_type, pt);
3096}3145}
30973146
3098pub fn cosScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3147pub fn cosScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3148 const mod = pt.zcu;
3099 const target = mod.getTarget();3149 const target = mod.getTarget();
3100 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3150 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3101 16 => .{ .f16 = @cos(val.toFloat(f16, mod)) },3151 16 => .{ .f16 = @cos(val.toFloat(f16, pt)) },
3102 32 => .{ .f32 = @cos(val.toFloat(f32, mod)) },3152 32 => .{ .f32 = @cos(val.toFloat(f32, pt)) },
3103 64 => .{ .f64 = @cos(val.toFloat(f64, mod)) },3153 64 => .{ .f64 = @cos(val.toFloat(f64, pt)) },
3104 80 => .{ .f80 = @cos(val.toFloat(f80, mod)) },3154 80 => .{ .f80 = @cos(val.toFloat(f80, pt)) },
3105 128 => .{ .f128 = @cos(val.toFloat(f128, mod)) },3155 128 => .{ .f128 = @cos(val.toFloat(f128, pt)) },
3106 else => unreachable,3156 else => unreachable,
3107 };3157 };
3108 return Value.fromInterned((try mod.intern(.{ .float = .{3158 return Value.fromInterned(try pt.intern(.{ .float = .{
3109 .ty = float_type.toIntern(),3159 .ty = float_type.toIntern(),
3110 .storage = storage,3160 .storage = storage,
3111 } })));3161 } }));
3112}3162}
31133163
3114pub fn tan(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3164pub fn tan(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3165 const mod = pt.zcu;
3115 if (float_type.zigTypeTag(mod) == .Vector) {3166 if (float_type.zigTypeTag(mod) == .Vector) {
3116 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3167 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3117 const scalar_ty = float_type.scalarType(mod);3168 const scalar_ty = float_type.scalarType(mod);
3118 for (result_data, 0..) |*scalar, i| {3169 for (result_data, 0..) |*scalar, i| {
3119 const elem_val = try val.elemValue(mod, i);3170 const elem_val = try val.elemValue(pt, i);
3120 scalar.* = (try tanScalar(elem_val, scalar_ty, mod)).toIntern();3171 scalar.* = (try tanScalar(elem_val, scalar_ty, pt)).toIntern();
3121 }3172 }
3122 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3173 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3123 .ty = float_type.toIntern(),3174 .ty = float_type.toIntern(),
3124 .storage = .{ .elems = result_data },3175 .storage = .{ .elems = result_data },
3125 } })));3176 } }));
3126 }3177 }
3127 return tanScalar(val, float_type, mod);3178 return tanScalar(val, float_type, pt);
3128}3179}
31293180
3130pub fn tanScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3181pub fn tanScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3182 const mod = pt.zcu;
3131 const target = mod.getTarget();3183 const target = mod.getTarget();
3132 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3184 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3133 16 => .{ .f16 = @tan(val.toFloat(f16, mod)) },3185 16 => .{ .f16 = @tan(val.toFloat(f16, pt)) },
3134 32 => .{ .f32 = @tan(val.toFloat(f32, mod)) },3186 32 => .{ .f32 = @tan(val.toFloat(f32, pt)) },
3135 64 => .{ .f64 = @tan(val.toFloat(f64, mod)) },3187 64 => .{ .f64 = @tan(val.toFloat(f64, pt)) },
3136 80 => .{ .f80 = @tan(val.toFloat(f80, mod)) },3188 80 => .{ .f80 = @tan(val.toFloat(f80, pt)) },
3137 128 => .{ .f128 = @tan(val.toFloat(f128, mod)) },3189 128 => .{ .f128 = @tan(val.toFloat(f128, pt)) },
3138 else => unreachable,3190 else => unreachable,
3139 };3191 };
3140 return Value.fromInterned((try mod.intern(.{ .float = .{3192 return Value.fromInterned(try pt.intern(.{ .float = .{
3141 .ty = float_type.toIntern(),3193 .ty = float_type.toIntern(),
3142 .storage = storage,3194 .storage = storage,
3143 } })));3195 } }));
3144}3196}
31453197
3146pub fn exp(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3198pub fn exp(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3199 const mod = pt.zcu;
3147 if (float_type.zigTypeTag(mod) == .Vector) {3200 if (float_type.zigTypeTag(mod) == .Vector) {
3148 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3201 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3149 const scalar_ty = float_type.scalarType(mod);3202 const scalar_ty = float_type.scalarType(mod);
3150 for (result_data, 0..) |*scalar, i| {3203 for (result_data, 0..) |*scalar, i| {
3151 const elem_val = try val.elemValue(mod, i);3204 const elem_val = try val.elemValue(pt, i);
3152 scalar.* = (try expScalar(elem_val, scalar_ty, mod)).toIntern();3205 scalar.* = (try expScalar(elem_val, scalar_ty, pt)).toIntern();
3153 }3206 }
3154 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3207 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3155 .ty = float_type.toIntern(),3208 .ty = float_type.toIntern(),
3156 .storage = .{ .elems = result_data },3209 .storage = .{ .elems = result_data },
3157 } })));3210 } }));
3158 }3211 }
3159 return expScalar(val, float_type, mod);3212 return expScalar(val, float_type, pt);
3160}3213}
31613214
3162pub fn expScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3215pub fn expScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3216 const mod = pt.zcu;
3163 const target = mod.getTarget();3217 const target = mod.getTarget();
3164 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3218 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3165 16 => .{ .f16 = @exp(val.toFloat(f16, mod)) },3219 16 => .{ .f16 = @exp(val.toFloat(f16, pt)) },
3166 32 => .{ .f32 = @exp(val.toFloat(f32, mod)) },3220 32 => .{ .f32 = @exp(val.toFloat(f32, pt)) },
3167 64 => .{ .f64 = @exp(val.toFloat(f64, mod)) },3221 64 => .{ .f64 = @exp(val.toFloat(f64, pt)) },
3168 80 => .{ .f80 = @exp(val.toFloat(f80, mod)) },3222 80 => .{ .f80 = @exp(val.toFloat(f80, pt)) },
3169 128 => .{ .f128 = @exp(val.toFloat(f128, mod)) },3223 128 => .{ .f128 = @exp(val.toFloat(f128, pt)) },
3170 else => unreachable,3224 else => unreachable,
3171 };3225 };
3172 return Value.fromInterned((try mod.intern(.{ .float = .{3226 return Value.fromInterned(try pt.intern(.{ .float = .{
3173 .ty = float_type.toIntern(),3227 .ty = float_type.toIntern(),
3174 .storage = storage,3228 .storage = storage,
3175 } })));3229 } }));
3176}3230}
31773231
3178pub fn exp2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3232pub fn exp2(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3233 const mod = pt.zcu;
3179 if (float_type.zigTypeTag(mod) == .Vector) {3234 if (float_type.zigTypeTag(mod) == .Vector) {
3180 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3235 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3181 const scalar_ty = float_type.scalarType(mod);3236 const scalar_ty = float_type.scalarType(mod);
3182 for (result_data, 0..) |*scalar, i| {3237 for (result_data, 0..) |*scalar, i| {
3183 const elem_val = try val.elemValue(mod, i);3238 const elem_val = try val.elemValue(pt, i);
3184 scalar.* = (try exp2Scalar(elem_val, scalar_ty, mod)).toIntern();3239 scalar.* = (try exp2Scalar(elem_val, scalar_ty, pt)).toIntern();
3185 }3240 }
3186 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3241 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3187 .ty = float_type.toIntern(),3242 .ty = float_type.toIntern(),
3188 .storage = .{ .elems = result_data },3243 .storage = .{ .elems = result_data },
3189 } })));3244 } }));
3190 }3245 }
3191 return exp2Scalar(val, float_type, mod);3246 return exp2Scalar(val, float_type, pt);
3192}3247}
31933248
3194pub fn exp2Scalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3249pub fn exp2Scalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3250 const mod = pt.zcu;
3195 const target = mod.getTarget();3251 const target = mod.getTarget();
3196 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3252 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3197 16 => .{ .f16 = @exp2(val.toFloat(f16, mod)) },3253 16 => .{ .f16 = @exp2(val.toFloat(f16, pt)) },
3198 32 => .{ .f32 = @exp2(val.toFloat(f32, mod)) },3254 32 => .{ .f32 = @exp2(val.toFloat(f32, pt)) },
3199 64 => .{ .f64 = @exp2(val.toFloat(f64, mod)) },3255 64 => .{ .f64 = @exp2(val.toFloat(f64, pt)) },
3200 80 => .{ .f80 = @exp2(val.toFloat(f80, mod)) },3256 80 => .{ .f80 = @exp2(val.toFloat(f80, pt)) },
3201 128 => .{ .f128 = @exp2(val.toFloat(f128, mod)) },3257 128 => .{ .f128 = @exp2(val.toFloat(f128, pt)) },
3202 else => unreachable,3258 else => unreachable,
3203 };3259 };
3204 return Value.fromInterned((try mod.intern(.{ .float = .{3260 return Value.fromInterned(try pt.intern(.{ .float = .{
3205 .ty = float_type.toIntern(),3261 .ty = float_type.toIntern(),
3206 .storage = storage,3262 .storage = storage,
3207 } })));3263 } }));
3208}3264}
32093265
3210pub fn log(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3266pub fn log(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3267 const mod = pt.zcu;
3211 if (float_type.zigTypeTag(mod) == .Vector) {3268 if (float_type.zigTypeTag(mod) == .Vector) {
3212 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3269 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3213 const scalar_ty = float_type.scalarType(mod);3270 const scalar_ty = float_type.scalarType(mod);
3214 for (result_data, 0..) |*scalar, i| {3271 for (result_data, 0..) |*scalar, i| {
3215 const elem_val = try val.elemValue(mod, i);3272 const elem_val = try val.elemValue(pt, i);
3216 scalar.* = (try logScalar(elem_val, scalar_ty, mod)).toIntern();3273 scalar.* = (try logScalar(elem_val, scalar_ty, pt)).toIntern();
3217 }3274 }
3218 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3275 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3219 .ty = float_type.toIntern(),3276 .ty = float_type.toIntern(),
3220 .storage = .{ .elems = result_data },3277 .storage = .{ .elems = result_data },
3221 } })));3278 } }));
3222 }3279 }
3223 return logScalar(val, float_type, mod);3280 return logScalar(val, float_type, pt);
3224}3281}
32253282
3226pub fn logScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3283pub fn logScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3284 const mod = pt.zcu;
3227 const target = mod.getTarget();3285 const target = mod.getTarget();
3228 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3286 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3229 16 => .{ .f16 = @log(val.toFloat(f16, mod)) },3287 16 => .{ .f16 = @log(val.toFloat(f16, pt)) },
3230 32 => .{ .f32 = @log(val.toFloat(f32, mod)) },3288 32 => .{ .f32 = @log(val.toFloat(f32, pt)) },
3231 64 => .{ .f64 = @log(val.toFloat(f64, mod)) },3289 64 => .{ .f64 = @log(val.toFloat(f64, pt)) },
3232 80 => .{ .f80 = @log(val.toFloat(f80, mod)) },3290 80 => .{ .f80 = @log(val.toFloat(f80, pt)) },
3233 128 => .{ .f128 = @log(val.toFloat(f128, mod)) },3291 128 => .{ .f128 = @log(val.toFloat(f128, pt)) },
3234 else => unreachable,3292 else => unreachable,
3235 };3293 };
3236 return Value.fromInterned((try mod.intern(.{ .float = .{3294 return Value.fromInterned(try pt.intern(.{ .float = .{
3237 .ty = float_type.toIntern(),3295 .ty = float_type.toIntern(),
3238 .storage = storage,3296 .storage = storage,
3239 } })));3297 } }));
3240}3298}
32413299
3242pub fn log2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3300pub fn log2(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3301 const mod = pt.zcu;
3243 if (float_type.zigTypeTag(mod) == .Vector) {3302 if (float_type.zigTypeTag(mod) == .Vector) {
3244 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3303 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3245 const scalar_ty = float_type.scalarType(mod);3304 const scalar_ty = float_type.scalarType(mod);
3246 for (result_data, 0..) |*scalar, i| {3305 for (result_data, 0..) |*scalar, i| {
3247 const elem_val = try val.elemValue(mod, i);3306 const elem_val = try val.elemValue(pt, i);
3248 scalar.* = (try log2Scalar(elem_val, scalar_ty, mod)).toIntern();3307 scalar.* = (try log2Scalar(elem_val, scalar_ty, pt)).toIntern();
3249 }3308 }
3250 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3309 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3251 .ty = float_type.toIntern(),3310 .ty = float_type.toIntern(),
3252 .storage = .{ .elems = result_data },3311 .storage = .{ .elems = result_data },
3253 } })));3312 } }));
3254 }3313 }
3255 return log2Scalar(val, float_type, mod);3314 return log2Scalar(val, float_type, pt);
3256}3315}
32573316
3258pub fn log2Scalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3317pub fn log2Scalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3318 const mod = pt.zcu;
3259 const target = mod.getTarget();3319 const target = mod.getTarget();
3260 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3320 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3261 16 => .{ .f16 = @log2(val.toFloat(f16, mod)) },3321 16 => .{ .f16 = @log2(val.toFloat(f16, pt)) },
3262 32 => .{ .f32 = @log2(val.toFloat(f32, mod)) },3322 32 => .{ .f32 = @log2(val.toFloat(f32, pt)) },
3263 64 => .{ .f64 = @log2(val.toFloat(f64, mod)) },3323 64 => .{ .f64 = @log2(val.toFloat(f64, pt)) },
3264 80 => .{ .f80 = @log2(val.toFloat(f80, mod)) },3324 80 => .{ .f80 = @log2(val.toFloat(f80, pt)) },
3265 128 => .{ .f128 = @log2(val.toFloat(f128, mod)) },3325 128 => .{ .f128 = @log2(val.toFloat(f128, pt)) },
3266 else => unreachable,3326 else => unreachable,
3267 };3327 };
3268 return Value.fromInterned((try mod.intern(.{ .float = .{3328 return Value.fromInterned(try pt.intern(.{ .float = .{
3269 .ty = float_type.toIntern(),3329 .ty = float_type.toIntern(),
3270 .storage = storage,3330 .storage = storage,
3271 } })));3331 } }));
3272}3332}
32733333
3274pub fn log10(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3334pub fn log10(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3335 const mod = pt.zcu;
3275 if (float_type.zigTypeTag(mod) == .Vector) {3336 if (float_type.zigTypeTag(mod) == .Vector) {
3276 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3337 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3277 const scalar_ty = float_type.scalarType(mod);3338 const scalar_ty = float_type.scalarType(mod);
3278 for (result_data, 0..) |*scalar, i| {3339 for (result_data, 0..) |*scalar, i| {
3279 const elem_val = try val.elemValue(mod, i);3340 const elem_val = try val.elemValue(pt, i);
3280 scalar.* = (try log10Scalar(elem_val, scalar_ty, mod)).toIntern();3341 scalar.* = (try log10Scalar(elem_val, scalar_ty, pt)).toIntern();
3281 }3342 }
3282 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3343 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3283 .ty = float_type.toIntern(),3344 .ty = float_type.toIntern(),
3284 .storage = .{ .elems = result_data },3345 .storage = .{ .elems = result_data },
3285 } })));3346 } }));
3286 }3347 }
3287 return log10Scalar(val, float_type, mod);3348 return log10Scalar(val, float_type, pt);
3288}3349}
32893350
3290pub fn log10Scalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3351pub fn log10Scalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3352 const mod = pt.zcu;
3291 const target = mod.getTarget();3353 const target = mod.getTarget();
3292 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3354 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3293 16 => .{ .f16 = @log10(val.toFloat(f16, mod)) },3355 16 => .{ .f16 = @log10(val.toFloat(f16, pt)) },
3294 32 => .{ .f32 = @log10(val.toFloat(f32, mod)) },3356 32 => .{ .f32 = @log10(val.toFloat(f32, pt)) },
3295 64 => .{ .f64 = @log10(val.toFloat(f64, mod)) },3357 64 => .{ .f64 = @log10(val.toFloat(f64, pt)) },
3296 80 => .{ .f80 = @log10(val.toFloat(f80, mod)) },3358 80 => .{ .f80 = @log10(val.toFloat(f80, pt)) },
3297 128 => .{ .f128 = @log10(val.toFloat(f128, mod)) },3359 128 => .{ .f128 = @log10(val.toFloat(f128, pt)) },
3298 else => unreachable,3360 else => unreachable,
3299 };3361 };
3300 return Value.fromInterned((try mod.intern(.{ .float = .{3362 return Value.fromInterned(try pt.intern(.{ .float = .{
3301 .ty = float_type.toIntern(),3363 .ty = float_type.toIntern(),
3302 .storage = storage,3364 .storage = storage,
3303 } })));3365 } }));
3304}3366}
33053367
3306pub fn abs(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value {3368pub fn abs(val: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3369 const mod = pt.zcu;
3307 if (ty.zigTypeTag(mod) == .Vector) {3370 if (ty.zigTypeTag(mod) == .Vector) {
3308 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));3371 const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod));
3309 const scalar_ty = ty.scalarType(mod);3372 const scalar_ty = ty.scalarType(mod);
3310 for (result_data, 0..) |*scalar, i| {3373 for (result_data, 0..) |*scalar, i| {
3311 const elem_val = try val.elemValue(mod, i);3374 const elem_val = try val.elemValue(pt, i);
3312 scalar.* = (try absScalar(elem_val, scalar_ty, mod, arena)).toIntern();3375 scalar.* = (try absScalar(elem_val, scalar_ty, pt, arena)).toIntern();
3313 }3376 }
3314 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3377 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3315 .ty = ty.toIntern(),3378 .ty = ty.toIntern(),
3316 .storage = .{ .elems = result_data },3379 .storage = .{ .elems = result_data },
3317 } })));3380 } }));
3318 }3381 }
3319 return absScalar(val, ty, mod, arena);3382 return absScalar(val, ty, pt, arena);
3320}3383}
33213384
3322pub fn absScalar(val: Value, ty: Type, mod: *Module, arena: Allocator) Allocator.Error!Value {3385pub fn absScalar(val: Value, ty: Type, pt: Zcu.PerThread, arena: Allocator) Allocator.Error!Value {
3386 const mod = pt.zcu;
3323 switch (ty.zigTypeTag(mod)) {3387 switch (ty.zigTypeTag(mod)) {
3324 .Int => {3388 .Int => {
3325 var buffer: Value.BigIntSpace = undefined;3389 var buffer: Value.BigIntSpace = undefined;
3326 var operand_bigint = try val.toBigInt(&buffer, mod).toManaged(arena);3390 var operand_bigint = try val.toBigInt(&buffer, pt).toManaged(arena);
3327 operand_bigint.abs();3391 operand_bigint.abs();
33283392
3329 return mod.intValue_big(try ty.toUnsigned(mod), operand_bigint.toConst());3393 return pt.intValue_big(try ty.toUnsigned(pt), operand_bigint.toConst());
3330 },3394 },
3331 .ComptimeInt => {3395 .ComptimeInt => {
3332 var buffer: Value.BigIntSpace = undefined;3396 var buffer: Value.BigIntSpace = undefined;
3333 var operand_bigint = try val.toBigInt(&buffer, mod).toManaged(arena);3397 var operand_bigint = try val.toBigInt(&buffer, pt).toManaged(arena);
3334 operand_bigint.abs();3398 operand_bigint.abs();
33353399
3336 return mod.intValue_big(ty, operand_bigint.toConst());3400 return pt.intValue_big(ty, operand_bigint.toConst());
3337 },3401 },
3338 .ComptimeFloat, .Float => {3402 .ComptimeFloat, .Float => {
3339 const target = mod.getTarget();3403 const target = mod.getTarget();
3340 const storage: InternPool.Key.Float.Storage = switch (ty.floatBits(target)) {3404 const storage: InternPool.Key.Float.Storage = switch (ty.floatBits(target)) {
3341 16 => .{ .f16 = @abs(val.toFloat(f16, mod)) },3405 16 => .{ .f16 = @abs(val.toFloat(f16, pt)) },
3342 32 => .{ .f32 = @abs(val.toFloat(f32, mod)) },3406 32 => .{ .f32 = @abs(val.toFloat(f32, pt)) },
3343 64 => .{ .f64 = @abs(val.toFloat(f64, mod)) },3407 64 => .{ .f64 = @abs(val.toFloat(f64, pt)) },
3344 80 => .{ .f80 = @abs(val.toFloat(f80, mod)) },3408 80 => .{ .f80 = @abs(val.toFloat(f80, pt)) },
3345 128 => .{ .f128 = @abs(val.toFloat(f128, mod)) },3409 128 => .{ .f128 = @abs(val.toFloat(f128, pt)) },
3346 else => unreachable,3410 else => unreachable,
3347 };3411 };
3348 return Value.fromInterned((try mod.intern(.{ .float = .{3412 return Value.fromInterned(try pt.intern(.{ .float = .{
3349 .ty = ty.toIntern(),3413 .ty = ty.toIntern(),
3350 .storage = storage,3414 .storage = storage,
3351 } })));3415 } }));
3352 },3416 },
3353 else => unreachable,3417 else => unreachable,
3354 }3418 }
3355}3419}
33563420
3357pub fn floor(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3421pub fn floor(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3422 const mod = pt.zcu;
3358 if (float_type.zigTypeTag(mod) == .Vector) {3423 if (float_type.zigTypeTag(mod) == .Vector) {
3359 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3424 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3360 const scalar_ty = float_type.scalarType(mod);3425 const scalar_ty = float_type.scalarType(mod);
3361 for (result_data, 0..) |*scalar, i| {3426 for (result_data, 0..) |*scalar, i| {
3362 const elem_val = try val.elemValue(mod, i);3427 const elem_val = try val.elemValue(pt, i);
3363 scalar.* = (try floorScalar(elem_val, scalar_ty, mod)).toIntern();3428 scalar.* = (try floorScalar(elem_val, scalar_ty, pt)).toIntern();
3364 }3429 }
3365 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3430 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3366 .ty = float_type.toIntern(),3431 .ty = float_type.toIntern(),
3367 .storage = .{ .elems = result_data },3432 .storage = .{ .elems = result_data },
3368 } })));3433 } }));
3369 }3434 }
3370 return floorScalar(val, float_type, mod);3435 return floorScalar(val, float_type, pt);
3371}3436}
33723437
3373pub fn floorScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3438pub fn floorScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3439 const mod = pt.zcu;
3374 const target = mod.getTarget();3440 const target = mod.getTarget();
3375 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3441 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3376 16 => .{ .f16 = @floor(val.toFloat(f16, mod)) },3442 16 => .{ .f16 = @floor(val.toFloat(f16, pt)) },
3377 32 => .{ .f32 = @floor(val.toFloat(f32, mod)) },3443 32 => .{ .f32 = @floor(val.toFloat(f32, pt)) },
3378 64 => .{ .f64 = @floor(val.toFloat(f64, mod)) },3444 64 => .{ .f64 = @floor(val.toFloat(f64, pt)) },
3379 80 => .{ .f80 = @floor(val.toFloat(f80, mod)) },3445 80 => .{ .f80 = @floor(val.toFloat(f80, pt)) },
3380 128 => .{ .f128 = @floor(val.toFloat(f128, mod)) },3446 128 => .{ .f128 = @floor(val.toFloat(f128, pt)) },
3381 else => unreachable,3447 else => unreachable,
3382 };3448 };
3383 return Value.fromInterned((try mod.intern(.{ .float = .{3449 return Value.fromInterned(try pt.intern(.{ .float = .{
3384 .ty = float_type.toIntern(),3450 .ty = float_type.toIntern(),
3385 .storage = storage,3451 .storage = storage,
3386 } })));3452 } }));
3387}3453}
33883454
3389pub fn ceil(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3455pub fn ceil(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3456 const mod = pt.zcu;
3390 if (float_type.zigTypeTag(mod) == .Vector) {3457 if (float_type.zigTypeTag(mod) == .Vector) {
3391 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3458 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3392 const scalar_ty = float_type.scalarType(mod);3459 const scalar_ty = float_type.scalarType(mod);
3393 for (result_data, 0..) |*scalar, i| {3460 for (result_data, 0..) |*scalar, i| {
3394 const elem_val = try val.elemValue(mod, i);3461 const elem_val = try val.elemValue(pt, i);
3395 scalar.* = (try ceilScalar(elem_val, scalar_ty, mod)).toIntern();3462 scalar.* = (try ceilScalar(elem_val, scalar_ty, pt)).toIntern();
3396 }3463 }
3397 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3464 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3398 .ty = float_type.toIntern(),3465 .ty = float_type.toIntern(),
3399 .storage = .{ .elems = result_data },3466 .storage = .{ .elems = result_data },
3400 } })));3467 } }));
3401 }3468 }
3402 return ceilScalar(val, float_type, mod);3469 return ceilScalar(val, float_type, pt);
3403}3470}
34043471
3405pub fn ceilScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3472pub fn ceilScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3473 const mod = pt.zcu;
3406 const target = mod.getTarget();3474 const target = mod.getTarget();
3407 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3475 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3408 16 => .{ .f16 = @ceil(val.toFloat(f16, mod)) },3476 16 => .{ .f16 = @ceil(val.toFloat(f16, pt)) },
3409 32 => .{ .f32 = @ceil(val.toFloat(f32, mod)) },3477 32 => .{ .f32 = @ceil(val.toFloat(f32, pt)) },
3410 64 => .{ .f64 = @ceil(val.toFloat(f64, mod)) },3478 64 => .{ .f64 = @ceil(val.toFloat(f64, pt)) },
3411 80 => .{ .f80 = @ceil(val.toFloat(f80, mod)) },3479 80 => .{ .f80 = @ceil(val.toFloat(f80, pt)) },
3412 128 => .{ .f128 = @ceil(val.toFloat(f128, mod)) },3480 128 => .{ .f128 = @ceil(val.toFloat(f128, pt)) },
3413 else => unreachable,3481 else => unreachable,
3414 };3482 };
3415 return Value.fromInterned((try mod.intern(.{ .float = .{3483 return Value.fromInterned(try pt.intern(.{ .float = .{
3416 .ty = float_type.toIntern(),3484 .ty = float_type.toIntern(),
3417 .storage = storage,3485 .storage = storage,
3418 } })));3486 } }));
3419}3487}
34203488
3421pub fn round(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3489pub fn round(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3490 const mod = pt.zcu;
3422 if (float_type.zigTypeTag(mod) == .Vector) {3491 if (float_type.zigTypeTag(mod) == .Vector) {
3423 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3492 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3424 const scalar_ty = float_type.scalarType(mod);3493 const scalar_ty = float_type.scalarType(mod);
3425 for (result_data, 0..) |*scalar, i| {3494 for (result_data, 0..) |*scalar, i| {
3426 const elem_val = try val.elemValue(mod, i);3495 const elem_val = try val.elemValue(pt, i);
3427 scalar.* = (try roundScalar(elem_val, scalar_ty, mod)).toIntern();3496 scalar.* = (try roundScalar(elem_val, scalar_ty, pt)).toIntern();
3428 }3497 }
3429 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3498 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3430 .ty = float_type.toIntern(),3499 .ty = float_type.toIntern(),
3431 .storage = .{ .elems = result_data },3500 .storage = .{ .elems = result_data },
3432 } })));3501 } }));
3433 }3502 }
3434 return roundScalar(val, float_type, mod);3503 return roundScalar(val, float_type, pt);
3435}3504}
34363505
3437pub fn roundScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3506pub fn roundScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3507 const mod = pt.zcu;
3438 const target = mod.getTarget();3508 const target = mod.getTarget();
3439 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3509 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3440 16 => .{ .f16 = @round(val.toFloat(f16, mod)) },3510 16 => .{ .f16 = @round(val.toFloat(f16, pt)) },
3441 32 => .{ .f32 = @round(val.toFloat(f32, mod)) },3511 32 => .{ .f32 = @round(val.toFloat(f32, pt)) },
3442 64 => .{ .f64 = @round(val.toFloat(f64, mod)) },3512 64 => .{ .f64 = @round(val.toFloat(f64, pt)) },
3443 80 => .{ .f80 = @round(val.toFloat(f80, mod)) },3513 80 => .{ .f80 = @round(val.toFloat(f80, pt)) },
3444 128 => .{ .f128 = @round(val.toFloat(f128, mod)) },3514 128 => .{ .f128 = @round(val.toFloat(f128, pt)) },
3445 else => unreachable,3515 else => unreachable,
3446 };3516 };
3447 return Value.fromInterned((try mod.intern(.{ .float = .{3517 return Value.fromInterned(try pt.intern(.{ .float = .{
3448 .ty = float_type.toIntern(),3518 .ty = float_type.toIntern(),
3449 .storage = storage,3519 .storage = storage,
3450 } })));3520 } }));
3451}3521}
34523522
3453pub fn trunc(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3523pub fn trunc(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value {
3524 const mod = pt.zcu;
3454 if (float_type.zigTypeTag(mod) == .Vector) {3525 if (float_type.zigTypeTag(mod) == .Vector) {
3455 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3526 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3456 const scalar_ty = float_type.scalarType(mod);3527 const scalar_ty = float_type.scalarType(mod);
3457 for (result_data, 0..) |*scalar, i| {3528 for (result_data, 0..) |*scalar, i| {
3458 const elem_val = try val.elemValue(mod, i);3529 const elem_val = try val.elemValue(pt, i);
3459 scalar.* = (try truncScalar(elem_val, scalar_ty, mod)).toIntern();3530 scalar.* = (try truncScalar(elem_val, scalar_ty, pt)).toIntern();
3460 }3531 }
3461 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3532 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3462 .ty = float_type.toIntern(),3533 .ty = float_type.toIntern(),
3463 .storage = .{ .elems = result_data },3534 .storage = .{ .elems = result_data },
3464 } })));3535 } }));
3465 }3536 }
3466 return truncScalar(val, float_type, mod);3537 return truncScalar(val, float_type, pt);
3467}3538}
34683539
3469pub fn truncScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value {3540pub fn truncScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value {
3541 const mod = pt.zcu;
3470 const target = mod.getTarget();3542 const target = mod.getTarget();
3471 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3543 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {
3472 16 => .{ .f16 = @trunc(val.toFloat(f16, mod)) },3544 16 => .{ .f16 = @trunc(val.toFloat(f16, pt)) },
3473 32 => .{ .f32 = @trunc(val.toFloat(f32, mod)) },3545 32 => .{ .f32 = @trunc(val.toFloat(f32, pt)) },
3474 64 => .{ .f64 = @trunc(val.toFloat(f64, mod)) },3546 64 => .{ .f64 = @trunc(val.toFloat(f64, pt)) },
3475 80 => .{ .f80 = @trunc(val.toFloat(f80, mod)) },3547 80 => .{ .f80 = @trunc(val.toFloat(f80, pt)) },
3476 128 => .{ .f128 = @trunc(val.toFloat(f128, mod)) },3548 128 => .{ .f128 = @trunc(val.toFloat(f128, pt)) },
3477 else => unreachable,3549 else => unreachable,
3478 };3550 };
3479 return Value.fromInterned((try mod.intern(.{ .float = .{3551 return Value.fromInterned(try pt.intern(.{ .float = .{
3480 .ty = float_type.toIntern(),3552 .ty = float_type.toIntern(),
3481 .storage = storage,3553 .storage = storage,
3482 } })));3554 } }));
3483}3555}
34843556
3485pub fn mulAdd(3557pub fn mulAdd(
...@@ -3488,23 +3560,24 @@ pub fn mulAdd(...@@ -3488,23 +3560,24 @@ pub fn mulAdd(
3488 mulend2: Value,3560 mulend2: Value,
3489 addend: Value,3561 addend: Value,
3490 arena: Allocator,3562 arena: Allocator,
3491 mod: *Module,3563 pt: Zcu.PerThread,
3492) !Value {3564) !Value {
3565 const mod = pt.zcu;
3493 if (float_type.zigTypeTag(mod) == .Vector) {3566 if (float_type.zigTypeTag(mod) == .Vector) {
3494 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));3567 const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod));
3495 const scalar_ty = float_type.scalarType(mod);3568 const scalar_ty = float_type.scalarType(mod);
3496 for (result_data, 0..) |*scalar, i| {3569 for (result_data, 0..) |*scalar, i| {
3497 const mulend1_elem = try mulend1.elemValue(mod, i);3570 const mulend1_elem = try mulend1.elemValue(pt, i);
3498 const mulend2_elem = try mulend2.elemValue(mod, i);3571 const mulend2_elem = try mulend2.elemValue(pt, i);
3499 const addend_elem = try addend.elemValue(mod, i);3572 const addend_elem = try addend.elemValue(pt, i);
3500 scalar.* = (try mulAddScalar(scalar_ty, mulend1_elem, mulend2_elem, addend_elem, mod)).toIntern();3573 scalar.* = (try mulAddScalar(scalar_ty, mulend1_elem, mulend2_elem, addend_elem, pt)).toIntern();
3501 }3574 }
3502 return Value.fromInterned((try mod.intern(.{ .aggregate = .{3575 return Value.fromInterned(try pt.intern(.{ .aggregate = .{
3503 .ty = float_type.toIntern(),3576 .ty = float_type.toIntern(),
3504 .storage = .{ .elems = result_data },3577 .storage = .{ .elems = result_data },
3505 } })));3578 } }));
3506 }3579 }
3507 return mulAddScalar(float_type, mulend1, mulend2, addend, mod);3580 return mulAddScalar(float_type, mulend1, mulend2, addend, pt);
3508}3581}
35093582
3510pub fn mulAddScalar(3583pub fn mulAddScalar(
...@@ -3512,32 +3585,33 @@ pub fn mulAddScalar(...@@ -3512,32 +3585,33 @@ pub fn mulAddScalar(
3512 mulend1: Value,3585 mulend1: Value,
3513 mulend2: Value,3586 mulend2: Value,
3514 addend: Value,3587 addend: Value,
3515 mod: *Module,3588 pt: Zcu.PerThread,
3516) Allocator.Error!Value {3589) Allocator.Error!Value {
3590 const mod = pt.zcu;
3517 const target = mod.getTarget();3591 const target = mod.getTarget();
3518 const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) {3592 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)) },3593 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)) },3594 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)) },3595 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)) },3596 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)) },3597 128 => .{ .f128 = @mulAdd(f128, mulend1.toFloat(f128, pt), mulend2.toFloat(f128, pt), addend.toFloat(f128, pt)) },
3524 else => unreachable,3598 else => unreachable,
3525 };3599 };
3526 return Value.fromInterned((try mod.intern(.{ .float = .{3600 return Value.fromInterned(try pt.intern(.{ .float = .{
3527 .ty = float_type.toIntern(),3601 .ty = float_type.toIntern(),
3528 .storage = storage,3602 .storage = storage,
3529 } })));3603 } }));
3530}3604}
35313605
3532/// If the value is represented in-memory as a series of bytes that all3606/// 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.3607/// have the same value, return that byte value, otherwise null.
3534pub fn hasRepeatedByteRepr(val: Value, ty: Type, mod: *Module) !?u8 {3608pub fn hasRepeatedByteRepr(val: Value, ty: Type, pt: Zcu.PerThread) !?u8 {
3535 const abi_size = std.math.cast(usize, ty.abiSize(mod)) orelse return null;3609 const abi_size = std.math.cast(usize, ty.abiSize(pt)) orelse return null;
3536 assert(abi_size >= 1);3610 assert(abi_size >= 1);
3537 const byte_buffer = try mod.gpa.alloc(u8, abi_size);3611 const byte_buffer = try pt.zcu.gpa.alloc(u8, abi_size);
3538 defer mod.gpa.free(byte_buffer);3612 defer pt.zcu.gpa.free(byte_buffer);
35393613
3540 writeToMemory(val, ty, mod, byte_buffer) catch |err| switch (err) {3614 writeToMemory(val, ty, pt, byte_buffer) catch |err| switch (err) {
3541 error.OutOfMemory => return error.OutOfMemory,3615 error.OutOfMemory => return error.OutOfMemory,
3542 error.ReinterpretDeclRef => return null,3616 error.ReinterpretDeclRef => return null,
3543 // TODO: The writeToMemory function was originally created for the purpose3617 // TODO: The writeToMemory function was originally created for the purpose
...@@ -3567,13 +3641,13 @@ pub fn typeOf(val: Value, zcu: *const Zcu) Type {...@@ -3567,13 +3641,13 @@ pub fn typeOf(val: Value, zcu: *const Zcu) Type {
3567/// If `val` is not undef, the bounds are both `val`.3641/// 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.3642/// 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.3643/// If `val` is undef and is a `comptime_int`, returns null.
3570pub fn intValueBounds(val: Value, mod: *Module) !?[2]Value {3644pub fn intValueBounds(val: Value, pt: Zcu.PerThread) !?[2]Value {
3571 if (!val.isUndef(mod)) return .{ val, val };3645 if (!val.isUndef(pt.zcu)) return .{ val, val };
3572 const ty = mod.intern_pool.typeOf(val.toIntern());3646 const ty = pt.zcu.intern_pool.typeOf(val.toIntern());
3573 if (ty == .comptime_int_type) return null;3647 if (ty == .comptime_int_type) return null;
3574 return .{3648 return .{
3575 try Type.fromInterned(ty).minInt(mod, Type.fromInterned(ty)),3649 try Type.fromInterned(ty).minInt(pt, Type.fromInterned(ty)),
3576 try Type.fromInterned(ty).maxInt(mod, Type.fromInterned(ty)),3650 try Type.fromInterned(ty).maxInt(pt, Type.fromInterned(ty)),
3577 };3651 };
3578}3652}
35793653
...@@ -3604,14 +3678,15 @@ pub const RuntimeIndex = InternPool.RuntimeIndex;...@@ -3604,14 +3678,15 @@ pub const RuntimeIndex = InternPool.RuntimeIndex;
3604/// `parent_ptr` must be a single-pointer to some optional.3678/// `parent_ptr` must be a single-pointer to some optional.
3605/// Returns a pointer to the payload of the optional.3679/// Returns a pointer to the payload of the optional.
3606/// May perform type resolution.3680/// May perform type resolution.
3607pub fn ptrOptPayload(parent_ptr: Value, zcu: *Zcu) !Value {3681pub fn ptrOptPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {
3682 const zcu = pt.zcu;
3608 const parent_ptr_ty = parent_ptr.typeOf(zcu);3683 const parent_ptr_ty = parent_ptr.typeOf(zcu);
3609 const opt_ty = parent_ptr_ty.childType(zcu);3684 const opt_ty = parent_ptr_ty.childType(zcu);
36103685
3611 assert(parent_ptr_ty.ptrSize(zcu) == .One);3686 assert(parent_ptr_ty.ptrSize(zcu) == .One);
3612 assert(opt_ty.zigTypeTag(zcu) == .Optional);3687 assert(opt_ty.zigTypeTag(zcu) == .Optional);
36133688
3614 const result_ty = try zcu.ptrTypeSema(info: {3689 const result_ty = try pt.ptrTypeSema(info: {
3615 var new = parent_ptr_ty.ptrInfo(zcu);3690 var new = parent_ptr_ty.ptrInfo(zcu);
3616 // We can correctly preserve alignment `.none`, since an optional has the same3691 // We can correctly preserve alignment `.none`, since an optional has the same
3617 // natural alignment as its child type.3692 // natural alignment as its child type.
...@@ -3619,15 +3694,15 @@ pub fn ptrOptPayload(parent_ptr: Value, zcu: *Zcu) !Value {...@@ -3619,15 +3694,15 @@ pub fn ptrOptPayload(parent_ptr: Value, zcu: *Zcu) !Value {
3619 break :info new;3694 break :info new;
3620 });3695 });
36213696
3622 if (parent_ptr.isUndef(zcu)) return zcu.undefValue(result_ty);3697 if (parent_ptr.isUndef(zcu)) return pt.undefValue(result_ty);
36233698
3624 if (opt_ty.isPtrLikeOptional(zcu)) {3699 if (opt_ty.isPtrLikeOptional(zcu)) {
3625 // Just reinterpret the pointer, since the layout is well-defined3700 // Just reinterpret the pointer, since the layout is well-defined
3626 return zcu.getCoerced(parent_ptr, result_ty);3701 return pt.getCoerced(parent_ptr, result_ty);
3627 }3702 }
36283703
3629 const base_ptr = try parent_ptr.canonicalizeBasePtr(.One, opt_ty, zcu);3704 const base_ptr = try parent_ptr.canonicalizeBasePtr(.One, opt_ty, pt);
3630 return Value.fromInterned(try zcu.intern(.{ .ptr = .{3705 return Value.fromInterned(try pt.intern(.{ .ptr = .{
3631 .ty = result_ty.toIntern(),3706 .ty = result_ty.toIntern(),
3632 .base_addr = .{ .opt_payload = base_ptr.toIntern() },3707 .base_addr = .{ .opt_payload = base_ptr.toIntern() },
3633 .byte_offset = 0,3708 .byte_offset = 0,
...@@ -3637,14 +3712,15 @@ pub fn ptrOptPayload(parent_ptr: Value, zcu: *Zcu) !Value {...@@ -3637,14 +3712,15 @@ pub fn ptrOptPayload(parent_ptr: Value, zcu: *Zcu) !Value {
3637/// `parent_ptr` must be a single-pointer to some error union.3712/// `parent_ptr` must be a single-pointer to some error union.
3638/// Returns a pointer to the payload of the error union.3713/// Returns a pointer to the payload of the error union.
3639/// May perform type resolution.3714/// May perform type resolution.
3640pub fn ptrEuPayload(parent_ptr: Value, zcu: *Zcu) !Value {3715pub fn ptrEuPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {
3716 const zcu = pt.zcu;
3641 const parent_ptr_ty = parent_ptr.typeOf(zcu);3717 const parent_ptr_ty = parent_ptr.typeOf(zcu);
3642 const eu_ty = parent_ptr_ty.childType(zcu);3718 const eu_ty = parent_ptr_ty.childType(zcu);
36433719
3644 assert(parent_ptr_ty.ptrSize(zcu) == .One);3720 assert(parent_ptr_ty.ptrSize(zcu) == .One);
3645 assert(eu_ty.zigTypeTag(zcu) == .ErrorUnion);3721 assert(eu_ty.zigTypeTag(zcu) == .ErrorUnion);
36463722
3647 const result_ty = try zcu.ptrTypeSema(info: {3723 const result_ty = try pt.ptrTypeSema(info: {
3648 var new = parent_ptr_ty.ptrInfo(zcu);3724 var new = parent_ptr_ty.ptrInfo(zcu);
3649 // We can correctly preserve alignment `.none`, since an error union has a3725 // 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.3726 // natural alignment greater than or equal to that of its payload type.
...@@ -3652,10 +3728,10 @@ pub fn ptrEuPayload(parent_ptr: Value, zcu: *Zcu) !Value {...@@ -3652,10 +3728,10 @@ pub fn ptrEuPayload(parent_ptr: Value, zcu: *Zcu) !Value {
3652 break :info new;3728 break :info new;
3653 });3729 });
36543730
3655 if (parent_ptr.isUndef(zcu)) return zcu.undefValue(result_ty);3731 if (parent_ptr.isUndef(zcu)) return pt.undefValue(result_ty);
36563732
3657 const base_ptr = try parent_ptr.canonicalizeBasePtr(.One, eu_ty, zcu);3733 const base_ptr = try parent_ptr.canonicalizeBasePtr(.One, eu_ty, pt);
3658 return Value.fromInterned(try zcu.intern(.{ .ptr = .{3734 return Value.fromInterned(try pt.intern(.{ .ptr = .{
3659 .ty = result_ty.toIntern(),3735 .ty = result_ty.toIntern(),
3660 .base_addr = .{ .eu_payload = base_ptr.toIntern() },3736 .base_addr = .{ .eu_payload = base_ptr.toIntern() },
3661 .byte_offset = 0,3737 .byte_offset = 0,
...@@ -3666,7 +3742,8 @@ pub fn ptrEuPayload(parent_ptr: Value, zcu: *Zcu) !Value {...@@ -3666,7 +3742,8 @@ pub fn ptrEuPayload(parent_ptr: Value, zcu: *Zcu) !Value {
3666/// Returns a pointer to the aggregate field at the specified index.3742/// Returns a pointer to the aggregate field at the specified index.
3667/// For slices, uses `slice_ptr_index` and `slice_len_index`.3743/// For slices, uses `slice_ptr_index` and `slice_len_index`.
3668/// May perform type resolution.3744/// May perform type resolution.
3669pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {3745pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value {
3746 const zcu = pt.zcu;
3670 const parent_ptr_ty = parent_ptr.typeOf(zcu);3747 const parent_ptr_ty = parent_ptr.typeOf(zcu);
3671 const aggregate_ty = parent_ptr_ty.childType(zcu);3748 const aggregate_ty = parent_ptr_ty.childType(zcu);
36723749
...@@ -3679,39 +3756,39 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {...@@ -3679,39 +3756,39 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {
3679 .Struct => field: {3756 .Struct => field: {
3680 const field_ty = aggregate_ty.structFieldType(field_idx, zcu);3757 const field_ty = aggregate_ty.structFieldType(field_idx, zcu);
3681 switch (aggregate_ty.containerLayout(zcu)) {3758 switch (aggregate_ty.containerLayout(zcu)) {
3682 .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), zcu, .sema) },3759 .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), pt, .sema) },
3683 .@"extern" => {3760 .@"extern" => {
3684 // Well-defined layout, so just offset the pointer appropriately.3761 // Well-defined layout, so just offset the pointer appropriately.
3685 const byte_off = aggregate_ty.structFieldOffset(field_idx, zcu);3762 const byte_off = aggregate_ty.structFieldOffset(field_idx, pt);
3686 const field_align = a: {3763 const field_align = a: {
3687 const parent_align = if (parent_ptr_info.flags.alignment == .none) pa: {3764 const parent_align = if (parent_ptr_info.flags.alignment == .none) pa: {
3688 break :pa (try aggregate_ty.abiAlignmentAdvanced(zcu, .sema)).scalar;3765 break :pa (try aggregate_ty.abiAlignmentAdvanced(pt, .sema)).scalar;
3689 } else parent_ptr_info.flags.alignment;3766 } else parent_ptr_info.flags.alignment;
3690 break :a InternPool.Alignment.fromLog2Units(@min(parent_align.toLog2Units(), @ctz(byte_off)));3767 break :a InternPool.Alignment.fromLog2Units(@min(parent_align.toLog2Units(), @ctz(byte_off)));
3691 };3768 };
3692 const result_ty = try zcu.ptrTypeSema(info: {3769 const result_ty = try pt.ptrTypeSema(info: {
3693 var new = parent_ptr_info;3770 var new = parent_ptr_info;
3694 new.child = field_ty.toIntern();3771 new.child = field_ty.toIntern();
3695 new.flags.alignment = field_align;3772 new.flags.alignment = field_align;
3696 break :info new;3773 break :info new;
3697 });3774 });
3698 return parent_ptr.getOffsetPtr(byte_off, result_ty, zcu);3775 return parent_ptr.getOffsetPtr(byte_off, result_ty, pt);
3699 },3776 },
3700 .@"packed" => switch (aggregate_ty.packedStructFieldPtrInfo(parent_ptr_ty, field_idx, zcu)) {3777 .@"packed" => switch (aggregate_ty.packedStructFieldPtrInfo(parent_ptr_ty, field_idx, pt)) {
3701 .bit_ptr => |packed_offset| {3778 .bit_ptr => |packed_offset| {
3702 const result_ty = try zcu.ptrType(info: {3779 const result_ty = try pt.ptrType(info: {
3703 var new = parent_ptr_info;3780 var new = parent_ptr_info;
3704 new.packed_offset = packed_offset;3781 new.packed_offset = packed_offset;
3705 new.child = field_ty.toIntern();3782 new.child = field_ty.toIntern();
3706 if (new.flags.alignment == .none) {3783 if (new.flags.alignment == .none) {
3707 new.flags.alignment = (try aggregate_ty.abiAlignmentAdvanced(zcu, .sema)).scalar;3784 new.flags.alignment = (try aggregate_ty.abiAlignmentAdvanced(pt, .sema)).scalar;
3708 }3785 }
3709 break :info new;3786 break :info new;
3710 });3787 });
3711 return zcu.getCoerced(parent_ptr, result_ty);3788 return pt.getCoerced(parent_ptr, result_ty);
3712 },3789 },
3713 .byte_ptr => |ptr_info| {3790 .byte_ptr => |ptr_info| {
3714 const result_ty = try zcu.ptrTypeSema(info: {3791 const result_ty = try pt.ptrTypeSema(info: {
3715 var new = parent_ptr_info;3792 var new = parent_ptr_info;
3716 new.child = field_ty.toIntern();3793 new.child = field_ty.toIntern();
3717 new.packed_offset = .{3794 new.packed_offset = .{
...@@ -3721,7 +3798,7 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {...@@ -3721,7 +3798,7 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {
3721 new.flags.alignment = ptr_info.alignment;3798 new.flags.alignment = ptr_info.alignment;
3722 break :info new;3799 break :info new;
3723 });3800 });
3724 return parent_ptr.getOffsetPtr(ptr_info.offset, result_ty, zcu);3801 return parent_ptr.getOffsetPtr(ptr_info.offset, result_ty, pt);
3725 },3802 },
3726 },3803 },
3727 }3804 }
...@@ -3730,46 +3807,46 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {...@@ -3730,46 +3807,46 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {
3730 const union_obj = zcu.typeToUnion(aggregate_ty).?;3807 const union_obj = zcu.typeToUnion(aggregate_ty).?;
3731 const field_ty = Type.fromInterned(union_obj.field_types.get(&zcu.intern_pool)[field_idx]);3808 const field_ty = Type.fromInterned(union_obj.field_types.get(&zcu.intern_pool)[field_idx]);
3732 switch (aggregate_ty.containerLayout(zcu)) {3809 switch (aggregate_ty.containerLayout(zcu)) {
3733 .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), zcu, .sema) },3810 .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), pt, .sema) },
3734 .@"extern" => {3811 .@"extern" => {
3735 // Point to the same address.3812 // Point to the same address.
3736 const result_ty = try zcu.ptrTypeSema(info: {3813 const result_ty = try pt.ptrTypeSema(info: {
3737 var new = parent_ptr_info;3814 var new = parent_ptr_info;
3738 new.child = field_ty.toIntern();3815 new.child = field_ty.toIntern();
3739 break :info new;3816 break :info new;
3740 });3817 });
3741 return zcu.getCoerced(parent_ptr, result_ty);3818 return pt.getCoerced(parent_ptr, result_ty);
3742 },3819 },
3743 .@"packed" => {3820 .@"packed" => {
3744 // If the field has an ABI size matching its bit size, then we can continue to use a3821 // 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.3822 // 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)) {3823 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.3824 // 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()) {3825 const byte_offset = switch (zcu.getTarget().cpu.arch.endian()) {
3749 .little => 0,3826 .little => 0,
3750 .big => (try aggregate_ty.abiSizeAdvanced(zcu, .sema)).scalar - (try field_ty.abiSizeAdvanced(zcu, .sema)).scalar,3827 .big => (try aggregate_ty.abiSizeAdvanced(pt, .sema)).scalar - (try field_ty.abiSizeAdvanced(pt, .sema)).scalar,
3751 };3828 };
3752 const result_ty = try zcu.ptrTypeSema(info: {3829 const result_ty = try pt.ptrTypeSema(info: {
3753 var new = parent_ptr_info;3830 var new = parent_ptr_info;
3754 new.child = field_ty.toIntern();3831 new.child = field_ty.toIntern();
3755 new.flags.alignment = InternPool.Alignment.fromLog2Units(3832 new.flags.alignment = InternPool.Alignment.fromLog2Units(
3756 @ctz(byte_offset | (try parent_ptr_ty.ptrAlignmentAdvanced(zcu, .sema)).toByteUnits().?),3833 @ctz(byte_offset | (try parent_ptr_ty.ptrAlignmentAdvanced(pt, .sema)).toByteUnits().?),
3757 );3834 );
3758 break :info new;3835 break :info new;
3759 });3836 });
3760 return parent_ptr.getOffsetPtr(byte_offset, result_ty, zcu);3837 return parent_ptr.getOffsetPtr(byte_offset, result_ty, pt);
3761 } else {3838 } else {
3762 // The result must be a bit-pointer if it is not already.3839 // The result must be a bit-pointer if it is not already.
3763 const result_ty = try zcu.ptrTypeSema(info: {3840 const result_ty = try pt.ptrTypeSema(info: {
3764 var new = parent_ptr_info;3841 var new = parent_ptr_info;
3765 new.child = field_ty.toIntern();3842 new.child = field_ty.toIntern();
3766 if (new.packed_offset.host_size == 0) {3843 if (new.packed_offset.host_size == 0) {
3767 new.packed_offset.host_size = @intCast(((try aggregate_ty.bitSizeAdvanced(zcu, .sema)) + 7) / 8);3844 new.packed_offset.host_size = @intCast(((try aggregate_ty.bitSizeAdvanced(pt, .sema)) + 7) / 8);
3768 assert(new.packed_offset.bit_offset == 0);3845 assert(new.packed_offset.bit_offset == 0);
3769 }3846 }
3770 break :info new;3847 break :info new;
3771 });3848 });
3772 return zcu.getCoerced(parent_ptr, result_ty);3849 return pt.getCoerced(parent_ptr, result_ty);
3773 }3850 }
3774 },3851 },
3775 }3852 }
...@@ -3777,8 +3854,8 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {...@@ -3777,8 +3854,8 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {
3777 .Pointer => field_ty: {3854 .Pointer => field_ty: {
3778 assert(aggregate_ty.isSlice(zcu));3855 assert(aggregate_ty.isSlice(zcu));
3779 break :field_ty switch (field_idx) {3856 break :field_ty switch (field_idx) {
3780 Value.slice_ptr_index => .{ aggregate_ty.slicePtrFieldType(zcu), Type.usize.abiAlignment(zcu) },3857 Value.slice_ptr_index => .{ aggregate_ty.slicePtrFieldType(zcu), Type.usize.abiAlignment(pt) },
3781 Value.slice_len_index => .{ Type.usize, Type.usize.abiAlignment(zcu) },3858 Value.slice_len_index => .{ Type.usize, Type.usize.abiAlignment(pt) },
3782 else => unreachable,3859 else => unreachable,
3783 };3860 };
3784 },3861 },
...@@ -3786,24 +3863,24 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {...@@ -3786,24 +3863,24 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {
3786 };3863 };
37873864
3788 const new_align: InternPool.Alignment = if (parent_ptr_info.flags.alignment != .none) a: {3865 const new_align: InternPool.Alignment = if (parent_ptr_info.flags.alignment != .none) a: {
3789 const ty_align = (try field_ty.abiAlignmentAdvanced(zcu, .sema)).scalar;3866 const ty_align = (try field_ty.abiAlignmentAdvanced(pt, .sema)).scalar;
3790 const true_field_align = if (field_align == .none) ty_align else field_align;3867 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);3868 const new_align = true_field_align.min(parent_ptr_info.flags.alignment);
3792 if (new_align == ty_align) break :a .none;3869 if (new_align == ty_align) break :a .none;
3793 break :a new_align;3870 break :a new_align;
3794 } else field_align;3871 } else field_align;
37953872
3796 const result_ty = try zcu.ptrTypeSema(info: {3873 const result_ty = try pt.ptrTypeSema(info: {
3797 var new = parent_ptr_info;3874 var new = parent_ptr_info;
3798 new.child = field_ty.toIntern();3875 new.child = field_ty.toIntern();
3799 new.flags.alignment = new_align;3876 new.flags.alignment = new_align;
3800 break :info new;3877 break :info new;
3801 });3878 });
38023879
3803 if (parent_ptr.isUndef(zcu)) return zcu.undefValue(result_ty);3880 if (parent_ptr.isUndef(zcu)) return pt.undefValue(result_ty);
38043881
3805 const base_ptr = try parent_ptr.canonicalizeBasePtr(.One, aggregate_ty, zcu);3882 const base_ptr = try parent_ptr.canonicalizeBasePtr(.One, aggregate_ty, pt);
3806 return Value.fromInterned(try zcu.intern(.{ .ptr = .{3883 return Value.fromInterned(try pt.intern(.{ .ptr = .{
3807 .ty = result_ty.toIntern(),3884 .ty = result_ty.toIntern(),
3808 .base_addr = .{ .field = .{3885 .base_addr = .{ .field = .{
3809 .base = base_ptr.toIntern(),3886 .base = base_ptr.toIntern(),
...@@ -3816,7 +3893,8 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {...@@ -3816,7 +3893,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.3893/// `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.3894/// Returns a pointer to the element at the specified index.
3818/// May perform type resolution.3895/// May perform type resolution.
3819pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {3896pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, pt: Zcu.PerThread) !Value {
3897 const zcu = pt.zcu;
3820 const parent_ptr = switch (orig_parent_ptr.typeOf(zcu).ptrSize(zcu)) {3898 const parent_ptr = switch (orig_parent_ptr.typeOf(zcu).ptrSize(zcu)) {
3821 .One, .Many, .C => orig_parent_ptr,3899 .One, .Many, .C => orig_parent_ptr,
3822 .Slice => orig_parent_ptr.slicePtr(zcu),3900 .Slice => orig_parent_ptr.slicePtr(zcu),
...@@ -3824,14 +3902,14 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {...@@ -3824,14 +3902,14 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {
38243902
3825 const parent_ptr_ty = parent_ptr.typeOf(zcu);3903 const parent_ptr_ty = parent_ptr.typeOf(zcu);
3826 const elem_ty = parent_ptr_ty.childType(zcu);3904 const elem_ty = parent_ptr_ty.childType(zcu);
3827 const result_ty = try parent_ptr_ty.elemPtrType(@intCast(field_idx), zcu);3905 const result_ty = try parent_ptr_ty.elemPtrType(@intCast(field_idx), pt);
38283906
3829 if (parent_ptr.isUndef(zcu)) return zcu.undefValue(result_ty);3907 if (parent_ptr.isUndef(zcu)) return pt.undefValue(result_ty);
38303908
3831 if (result_ty.ptrInfo(zcu).packed_offset.host_size != 0) {3909 if (result_ty.ptrInfo(zcu).packed_offset.host_size != 0) {
3832 // Since we have a bit-pointer, the pointer address should be unchanged.3910 // Since we have a bit-pointer, the pointer address should be unchanged.
3833 assert(elem_ty.zigTypeTag(zcu) == .Vector);3911 assert(elem_ty.zigTypeTag(zcu) == .Vector);
3834 return zcu.getCoerced(parent_ptr, result_ty);3912 return pt.getCoerced(parent_ptr, result_ty);
3835 }3913 }
38363914
3837 const PtrStrat = union(enum) {3915 const PtrStrat = union(enum) {
...@@ -3841,31 +3919,31 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {...@@ -3841,31 +3919,31 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {
38413919
3842 const strat: PtrStrat = switch (parent_ptr_ty.ptrSize(zcu)) {3920 const strat: PtrStrat = switch (parent_ptr_ty.ptrSize(zcu)) {
3843 .One => switch (elem_ty.zigTypeTag(zcu)) {3921 .One => switch (elem_ty.zigTypeTag(zcu)) {
3844 .Vector => .{ .offset = field_idx * @divExact(try elem_ty.childType(zcu).bitSizeAdvanced(zcu, .sema), 8) },3922 .Vector => .{ .offset = field_idx * @divExact(try elem_ty.childType(zcu).bitSizeAdvanced(pt, .sema), 8) },
3845 .Array => strat: {3923 .Array => strat: {
3846 const arr_elem_ty = elem_ty.childType(zcu);3924 const arr_elem_ty = elem_ty.childType(zcu);
3847 if (try arr_elem_ty.comptimeOnlyAdvanced(zcu, .sema)) {3925 if (try arr_elem_ty.comptimeOnlyAdvanced(pt, .sema)) {
3848 break :strat .{ .elem_ptr = arr_elem_ty };3926 break :strat .{ .elem_ptr = arr_elem_ty };
3849 }3927 }
3850 break :strat .{ .offset = field_idx * (try arr_elem_ty.abiSizeAdvanced(zcu, .sema)).scalar };3928 break :strat .{ .offset = field_idx * (try arr_elem_ty.abiSizeAdvanced(pt, .sema)).scalar };
3851 },3929 },
3852 else => unreachable,3930 else => unreachable,
3853 },3931 },
38543932
3855 .Many, .C => if (try elem_ty.comptimeOnlyAdvanced(zcu, .sema))3933 .Many, .C => if (try elem_ty.comptimeOnlyAdvanced(pt, .sema))
3856 .{ .elem_ptr = elem_ty }3934 .{ .elem_ptr = elem_ty }
3857 else3935 else
3858 .{ .offset = field_idx * (try elem_ty.abiSizeAdvanced(zcu, .sema)).scalar },3936 .{ .offset = field_idx * (try elem_ty.abiSizeAdvanced(pt, .sema)).scalar },
38593937
3860 .Slice => unreachable,3938 .Slice => unreachable,
3861 };3939 };
38623940
3863 switch (strat) {3941 switch (strat) {
3864 .offset => |byte_offset| {3942 .offset => |byte_offset| {
3865 return parent_ptr.getOffsetPtr(byte_offset, result_ty, zcu);3943 return parent_ptr.getOffsetPtr(byte_offset, result_ty, pt);
3866 },3944 },
3867 .elem_ptr => |manyptr_elem_ty| if (field_idx == 0) {3945 .elem_ptr => |manyptr_elem_ty| if (field_idx == 0) {
3868 return zcu.getCoerced(parent_ptr, result_ty);3946 return pt.getCoerced(parent_ptr, result_ty);
3869 } else {3947 } else {
3870 const arr_base_ty, const arr_base_len = manyptr_elem_ty.arrayBase(zcu);3948 const arr_base_ty, const arr_base_len = manyptr_elem_ty.arrayBase(zcu);
3871 const base_idx = arr_base_len * field_idx;3949 const base_idx = arr_base_len * field_idx;
...@@ -3875,7 +3953,7 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {...@@ -3875,7 +3953,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()) {3953 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.3954 // We already have a pointer to an element of an array of this type.
3877 // Just modify the index.3955 // Just modify the index.
3878 return Value.fromInterned(try zcu.intern(.{ .ptr = ptr: {3956 return Value.fromInterned(try pt.intern(.{ .ptr = ptr: {
3879 var new = parent_info;3957 var new = parent_info;
3880 new.base_addr.arr_elem.index += base_idx;3958 new.base_addr.arr_elem.index += base_idx;
3881 new.ty = result_ty.toIntern();3959 new.ty = result_ty.toIntern();
...@@ -3885,8 +3963,8 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {...@@ -3885,8 +3963,8 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {
3885 },3963 },
3886 else => {},3964 else => {},
3887 }3965 }
3888 const base_ptr = try parent_ptr.canonicalizeBasePtr(.Many, arr_base_ty, zcu);3966 const base_ptr = try parent_ptr.canonicalizeBasePtr(.Many, arr_base_ty, pt);
3889 return Value.fromInterned(try zcu.intern(.{ .ptr = .{3967 return Value.fromInterned(try pt.intern(.{ .ptr = .{
3890 .ty = result_ty.toIntern(),3968 .ty = result_ty.toIntern(),
3891 .base_addr = .{ .arr_elem = .{3969 .base_addr = .{ .arr_elem = .{
3892 .base = base_ptr.toIntern(),3970 .base = base_ptr.toIntern(),
...@@ -3898,9 +3976,9 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {...@@ -3898,9 +3976,9 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {
3898 }3976 }
3899}3977}
39003978
3901fn canonicalizeBasePtr(base_ptr: Value, want_size: std.builtin.Type.Pointer.Size, want_child: Type, zcu: *Zcu) !Value {3979fn 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);3980 const ptr_ty = base_ptr.typeOf(pt.zcu);
3903 const ptr_info = ptr_ty.ptrInfo(zcu);3981 const ptr_info = ptr_ty.ptrInfo(pt.zcu);
39043982
3905 if (ptr_info.flags.size == want_size and3983 if (ptr_info.flags.size == want_size and
3906 ptr_info.child == want_child.toIntern() and3984 ptr_info.child == want_child.toIntern() and
...@@ -3914,7 +3992,7 @@ fn canonicalizeBasePtr(base_ptr: Value, want_size: std.builtin.Type.Pointer.Size...@@ -3914,7 +3992,7 @@ fn canonicalizeBasePtr(base_ptr: Value, want_size: std.builtin.Type.Pointer.Size
3914 return base_ptr;3992 return base_ptr;
3915 }3993 }
39163994
3917 const new_ty = try zcu.ptrType(.{3995 const new_ty = try pt.ptrType(.{
3918 .child = want_child.toIntern(),3996 .child = want_child.toIntern(),
3919 .sentinel = .none,3997 .sentinel = .none,
3920 .flags = .{3998 .flags = .{
...@@ -3926,15 +4004,15 @@ fn canonicalizeBasePtr(base_ptr: Value, want_size: std.builtin.Type.Pointer.Size...@@ -3926,15 +4004,15 @@ fn canonicalizeBasePtr(base_ptr: Value, want_size: std.builtin.Type.Pointer.Size
3926 .address_space = ptr_info.flags.address_space,4004 .address_space = ptr_info.flags.address_space,
3927 },4005 },
3928 });4006 });
3929 return zcu.getCoerced(base_ptr, new_ty);4007 return pt.getCoerced(base_ptr, new_ty);
3930}4008}
39314009
3932pub fn getOffsetPtr(ptr_val: Value, byte_off: u64, new_ty: Type, zcu: *Zcu) !Value {4010pub fn getOffsetPtr(ptr_val: Value, byte_off: u64, new_ty: Type, pt: Zcu.PerThread) !Value {
3933 if (ptr_val.isUndef(zcu)) return ptr_val;4011 if (ptr_val.isUndef(pt.zcu)) return ptr_val;
3934 var ptr = zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr;4012 var ptr = pt.zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr;
3935 ptr.ty = new_ty.toIntern();4013 ptr.ty = new_ty.toIntern();
3936 ptr.byte_offset += byte_off;4014 ptr.byte_offset += byte_off;
3937 return Value.fromInterned(try zcu.intern(.{ .ptr = ptr }));4015 return Value.fromInterned(try pt.intern(.{ .ptr = ptr }));
3938}4016}
39394017
3940pub const PointerDeriveStep = union(enum) {4018pub const PointerDeriveStep = union(enum) {
...@@ -3977,21 +4055,21 @@ pub const PointerDeriveStep = union(enum) {...@@ -3977,21 +4055,21 @@ pub const PointerDeriveStep = union(enum) {
3977 new_ptr_ty: Type,4055 new_ptr_ty: Type,
3978 },4056 },
39794057
3980 pub fn ptrType(step: PointerDeriveStep, zcu: *Zcu) !Type {4058 pub fn ptrType(step: PointerDeriveStep, pt: Zcu.PerThread) !Type {
3981 return switch (step) {4059 return switch (step) {
3982 .int => |int| int.ptr_ty,4060 .int => |int| int.ptr_ty,
3983 .decl_ptr => |decl| try zcu.declPtr(decl).declPtrType(zcu),4061 .decl_ptr => |decl| try pt.zcu.declPtr(decl).declPtrType(pt),
3984 .anon_decl_ptr => |ad| Type.fromInterned(ad.orig_ty),4062 .anon_decl_ptr => |ad| Type.fromInterned(ad.orig_ty),
3985 .comptime_alloc_ptr => |info| info.ptr_ty,4063 .comptime_alloc_ptr => |info| info.ptr_ty,
3986 .comptime_field_ptr => |val| try zcu.singleConstPtrType(val.typeOf(zcu)),4064 .comptime_field_ptr => |val| try pt.singleConstPtrType(val.typeOf(pt.zcu)),
3987 .offset_and_cast => |oac| oac.new_ptr_ty,4065 .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,4066 inline .eu_payload_ptr, .opt_payload_ptr, .field_ptr, .elem_ptr => |x| x.result_ptr_ty,
3989 };4067 };
3990 }4068 }
3991};4069};
39924070
3993pub fn pointerDerivation(ptr_val: Value, arena: Allocator, zcu: *Zcu) Allocator.Error!PointerDeriveStep {4071pub 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) {4072 return ptr_val.pointerDerivationAdvanced(arena, pt, null) catch |err| switch (err) {
3995 error.OutOfMemory => |e| return e,4073 error.OutOfMemory => |e| return e,
3996 error.AnalysisFail => unreachable,4074 error.AnalysisFail => unreachable,
3997 };4075 };
...@@ -4001,7 +4079,8 @@ pub fn pointerDerivation(ptr_val: Value, arena: Allocator, zcu: *Zcu) Allocator....@@ -4001,7 +4079,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 backends4079/// 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.4080/// which prefer field/elem accesses when lowering constant pointer values.
4003/// It is also used by the Value printing logic for pointers.4081/// 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 {4082pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerThread, opt_sema: ?*Sema) !PointerDeriveStep {
4083 const zcu = pt.zcu;
4005 const ptr = zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr;4084 const ptr = zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr;
4006 const base_derive: PointerDeriveStep = switch (ptr.base_addr) {4085 const base_derive: PointerDeriveStep = switch (ptr.base_addr) {
4007 .int => return .{ .int = .{4086 .int => return .{ .int = .{
...@@ -4012,7 +4091,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4012,7 +4091,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4012 .anon_decl => |ad| base: {4091 .anon_decl => |ad| base: {
4013 // A slight tweak: `orig_ty` here is sometimes not `const`, but it ought to be.4092 // 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!4093 // TODO: fix this in the sites interning anon decls!
4015 const const_ty = try zcu.ptrType(info: {4094 const const_ty = try pt.ptrType(info: {
4016 var info = Type.fromInterned(ad.orig_ty).ptrInfo(zcu);4095 var info = Type.fromInterned(ad.orig_ty).ptrInfo(zcu);
4017 info.flags.is_const = true;4096 info.flags.is_const = true;
4018 break :info info;4097 break :info info;
...@@ -4024,11 +4103,11 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4024,11 +4103,11 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4024 },4103 },
4025 .comptime_alloc => |idx| base: {4104 .comptime_alloc => |idx| base: {
4026 const alloc = opt_sema.?.getComptimeAlloc(idx);4105 const alloc = opt_sema.?.getComptimeAlloc(idx);
4027 const val = try alloc.val.intern(zcu, opt_sema.?.arena);4106 const val = try alloc.val.intern(pt, opt_sema.?.arena);
4028 const ty = val.typeOf(zcu);4107 const ty = val.typeOf(zcu);
4029 break :base .{ .comptime_alloc_ptr = .{4108 break :base .{ .comptime_alloc_ptr = .{
4030 .val = val,4109 .val = val,
4031 .ptr_ty = try zcu.ptrType(.{4110 .ptr_ty = try pt.ptrType(.{
4032 .child = ty.toIntern(),4111 .child = ty.toIntern(),
4033 .flags = .{4112 .flags = .{
4034 .alignment = alloc.alignment,4113 .alignment = alloc.alignment,
...@@ -4041,20 +4120,20 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4041,20 +4120,20 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4041 const base_ptr = Value.fromInterned(eu_ptr);4120 const base_ptr = Value.fromInterned(eu_ptr);
4042 const base_ptr_ty = base_ptr.typeOf(zcu);4121 const base_ptr_ty = base_ptr.typeOf(zcu);
4043 const parent_step = try arena.create(PointerDeriveStep);4122 const parent_step = try arena.create(PointerDeriveStep);
4044 parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(eu_ptr), arena, zcu, opt_sema);4123 parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(eu_ptr), arena, pt, opt_sema);
4045 break :base .{ .eu_payload_ptr = .{4124 break :base .{ .eu_payload_ptr = .{
4046 .parent = parent_step,4125 .parent = parent_step,
4047 .result_ptr_ty = try zcu.adjustPtrTypeChild(base_ptr_ty, base_ptr_ty.childType(zcu).errorUnionPayload(zcu)),4126 .result_ptr_ty = try pt.adjustPtrTypeChild(base_ptr_ty, base_ptr_ty.childType(zcu).errorUnionPayload(zcu)),
4048 } };4127 } };
4049 },4128 },
4050 .opt_payload => |opt_ptr| base: {4129 .opt_payload => |opt_ptr| base: {
4051 const base_ptr = Value.fromInterned(opt_ptr);4130 const base_ptr = Value.fromInterned(opt_ptr);
4052 const base_ptr_ty = base_ptr.typeOf(zcu);4131 const base_ptr_ty = base_ptr.typeOf(zcu);
4053 const parent_step = try arena.create(PointerDeriveStep);4132 const parent_step = try arena.create(PointerDeriveStep);
4054 parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(opt_ptr), arena, zcu, opt_sema);4133 parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(opt_ptr), arena, pt, opt_sema);
4055 break :base .{ .opt_payload_ptr = .{4134 break :base .{ .opt_payload_ptr = .{
4056 .parent = parent_step,4135 .parent = parent_step,
4057 .result_ptr_ty = try zcu.adjustPtrTypeChild(base_ptr_ty, base_ptr_ty.childType(zcu).optionalChild(zcu)),4136 .result_ptr_ty = try pt.adjustPtrTypeChild(base_ptr_ty, base_ptr_ty.childType(zcu).optionalChild(zcu)),
4058 } };4137 } };
4059 },4138 },
4060 .field => |field| base: {4139 .field => |field| base: {
...@@ -4062,22 +4141,22 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4062,22 +4141,22 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4062 const base_ptr_ty = base_ptr.typeOf(zcu);4141 const base_ptr_ty = base_ptr.typeOf(zcu);
4063 const agg_ty = base_ptr_ty.childType(zcu);4142 const agg_ty = base_ptr_ty.childType(zcu);
4064 const field_ty, const field_align = switch (agg_ty.zigTypeTag(zcu)) {4143 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) },4144 .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) },4145 .Union => .{ agg_ty.unionFieldTypeByIndex(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(@intCast(field.index), pt, .sema) },
4067 .Pointer => .{ switch (field.index) {4146 .Pointer => .{ switch (field.index) {
4068 Value.slice_ptr_index => agg_ty.slicePtrFieldType(zcu),4147 Value.slice_ptr_index => agg_ty.slicePtrFieldType(zcu),
4069 Value.slice_len_index => Type.usize,4148 Value.slice_len_index => Type.usize,
4070 else => unreachable,4149 else => unreachable,
4071 }, Type.usize.abiAlignment(zcu) },4150 }, Type.usize.abiAlignment(pt) },
4072 else => unreachable,4151 else => unreachable,
4073 };4152 };
4074 const base_align = base_ptr_ty.ptrAlignment(zcu);4153 const base_align = base_ptr_ty.ptrAlignment(pt);
4075 const result_align = field_align.minStrict(base_align);4154 const result_align = field_align.minStrict(base_align);
4076 const result_ty = try zcu.ptrType(.{4155 const result_ty = try pt.ptrType(.{
4077 .child = field_ty.toIntern(),4156 .child = field_ty.toIntern(),
4078 .flags = flags: {4157 .flags = flags: {
4079 var flags = base_ptr_ty.ptrInfo(zcu).flags;4158 var flags = base_ptr_ty.ptrInfo(zcu).flags;
4080 if (result_align == field_ty.abiAlignment(zcu)) {4159 if (result_align == field_ty.abiAlignment(pt)) {
4081 flags.alignment = .none;4160 flags.alignment = .none;
4082 } else {4161 } else {
4083 flags.alignment = result_align;4162 flags.alignment = result_align;
...@@ -4086,7 +4165,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4086,7 +4165,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4086 },4165 },
4087 });4166 });
4088 const parent_step = try arena.create(PointerDeriveStep);4167 const parent_step = try arena.create(PointerDeriveStep);
4089 parent_step.* = try pointerDerivationAdvanced(base_ptr, arena, zcu, opt_sema);4168 parent_step.* = try pointerDerivationAdvanced(base_ptr, arena, pt, opt_sema);
4090 break :base .{ .field_ptr = .{4169 break :base .{ .field_ptr = .{
4091 .parent = parent_step,4170 .parent = parent_step,
4092 .field_idx = @intCast(field.index),4171 .field_idx = @intCast(field.index),
...@@ -4095,9 +4174,9 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4095,9 +4174,9 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4095 },4174 },
4096 .arr_elem => |arr_elem| base: {4175 .arr_elem => |arr_elem| base: {
4097 const parent_step = try arena.create(PointerDeriveStep);4176 const parent_step = try arena.create(PointerDeriveStep);
4098 parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(arr_elem.base), arena, zcu, opt_sema);4177 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);4178 const parent_ptr_info = (try parent_step.ptrType(pt)).ptrInfo(zcu);
4100 const result_ptr_ty = try zcu.ptrType(.{4179 const result_ptr_ty = try pt.ptrType(.{
4101 .child = parent_ptr_info.child,4180 .child = parent_ptr_info.child,
4102 .flags = flags: {4181 .flags = flags: {
4103 var flags = parent_ptr_info.flags;4182 var flags = parent_ptr_info.flags;
...@@ -4113,12 +4192,12 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4113,12 +4192,12 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4113 },4192 },
4114 };4193 };
41154194
4116 if (ptr.byte_offset == 0 and ptr.ty == (try base_derive.ptrType(zcu)).toIntern()) {4195 if (ptr.byte_offset == 0 and ptr.ty == (try base_derive.ptrType(pt)).toIntern()) {
4117 return base_derive;4196 return base_derive;
4118 }4197 }
41194198
4120 const need_child = Type.fromInterned(ptr.ty).childType(zcu);4199 const need_child = Type.fromInterned(ptr.ty).childType(zcu);
4121 if (need_child.comptimeOnly(zcu)) {4200 if (need_child.comptimeOnly(pt)) {
4122 // No refinement can happen - this pointer is presumably invalid.4201 // No refinement can happen - this pointer is presumably invalid.
4123 // Just offset it.4202 // Just offset it.
4124 const parent = try arena.create(PointerDeriveStep);4203 const parent = try arena.create(PointerDeriveStep);
...@@ -4129,7 +4208,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4129,7 +4208,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4129 .new_ptr_ty = Type.fromInterned(ptr.ty),4208 .new_ptr_ty = Type.fromInterned(ptr.ty),
4130 } };4209 } };
4131 }4210 }
4132 const need_bytes = need_child.abiSize(zcu);4211 const need_bytes = need_child.abiSize(pt);
41334212
4134 var cur_derive = base_derive;4213 var cur_derive = base_derive;
4135 var cur_offset = ptr.byte_offset;4214 var cur_offset = ptr.byte_offset;
...@@ -4137,7 +4216,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4137,7 +4216,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4137 // Refine through fields and array elements as much as possible.4216 // Refine through fields and array elements as much as possible.
41384217
4139 if (need_bytes > 0) while (true) {4218 if (need_bytes > 0) while (true) {
4140 const cur_ty = (try cur_derive.ptrType(zcu)).childType(zcu);4219 const cur_ty = (try cur_derive.ptrType(pt)).childType(zcu);
4141 if (cur_ty.toIntern() == need_child.toIntern() and cur_offset == 0) {4220 if (cur_ty.toIntern() == need_child.toIntern() and cur_offset == 0) {
4142 break;4221 break;
4143 }4222 }
...@@ -4168,7 +4247,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4168,7 +4247,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
41684247
4169 .Array => {4248 .Array => {
4170 const elem_ty = cur_ty.childType(zcu);4249 const elem_ty = cur_ty.childType(zcu);
4171 const elem_size = elem_ty.abiSize(zcu);4250 const elem_size = elem_ty.abiSize(pt);
4172 const start_idx = cur_offset / elem_size;4251 const start_idx = cur_offset / elem_size;
4173 const end_idx = (cur_offset + need_bytes + elem_size - 1) / elem_size;4252 const end_idx = (cur_offset + need_bytes + elem_size - 1) / elem_size;
4174 if (end_idx == start_idx + 1) {4253 if (end_idx == start_idx + 1) {
...@@ -4177,7 +4256,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4177,7 +4256,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4177 cur_derive = .{ .elem_ptr = .{4256 cur_derive = .{ .elem_ptr = .{
4178 .parent = parent,4257 .parent = parent,
4179 .elem_idx = start_idx,4258 .elem_idx = start_idx,
4180 .result_ptr_ty = try zcu.adjustPtrTypeChild(try parent.ptrType(zcu), elem_ty),4259 .result_ptr_ty = try pt.adjustPtrTypeChild(try parent.ptrType(pt), elem_ty),
4181 } };4260 } };
4182 cur_offset -= start_idx * elem_size;4261 cur_offset -= start_idx * elem_size;
4183 } else {4262 } else {
...@@ -4188,7 +4267,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4188,7 +4267,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4188 cur_derive = .{ .elem_ptr = .{4267 cur_derive = .{ .elem_ptr = .{
4189 .parent = parent,4268 .parent = parent,
4190 .elem_idx = start_idx,4269 .elem_idx = start_idx,
4191 .result_ptr_ty = try zcu.adjustPtrTypeChild(try parent.ptrType(zcu), elem_ty),4270 .result_ptr_ty = try pt.adjustPtrTypeChild(try parent.ptrType(pt), elem_ty),
4192 } };4271 } };
4193 cur_offset -= start_idx * elem_size;4272 cur_offset -= start_idx * elem_size;
4194 }4273 }
...@@ -4199,19 +4278,19 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4199,19 +4278,19 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4199 .auto, .@"packed" => break,4278 .auto, .@"packed" => break,
4200 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {4279 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {
4201 const field_ty = cur_ty.structFieldType(field_idx, zcu);4280 const field_ty = cur_ty.structFieldType(field_idx, zcu);
4202 const start_off = cur_ty.structFieldOffset(field_idx, zcu);4281 const start_off = cur_ty.structFieldOffset(field_idx, pt);
4203 const end_off = start_off + field_ty.abiSize(zcu);4282 const end_off = start_off + field_ty.abiSize(pt);
4204 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {4283 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {
4205 const old_ptr_ty = try cur_derive.ptrType(zcu);4284 const old_ptr_ty = try cur_derive.ptrType(pt);
4206 const parent_align = old_ptr_ty.ptrAlignment(zcu);4285 const parent_align = old_ptr_ty.ptrAlignment(pt);
4207 const field_align = InternPool.Alignment.fromLog2Units(@min(parent_align.toLog2Units(), @ctz(start_off)));4286 const field_align = InternPool.Alignment.fromLog2Units(@min(parent_align.toLog2Units(), @ctz(start_off)));
4208 const parent = try arena.create(PointerDeriveStep);4287 const parent = try arena.create(PointerDeriveStep);
4209 parent.* = cur_derive;4288 parent.* = cur_derive;
4210 const new_ptr_ty = try zcu.ptrType(.{4289 const new_ptr_ty = try pt.ptrType(.{
4211 .child = field_ty.toIntern(),4290 .child = field_ty.toIntern(),
4212 .flags = flags: {4291 .flags = flags: {
4213 var flags = old_ptr_ty.ptrInfo(zcu).flags;4292 var flags = old_ptr_ty.ptrInfo(zcu).flags;
4214 if (field_align == field_ty.abiAlignment(zcu)) {4293 if (field_align == field_ty.abiAlignment(pt)) {
4215 flags.alignment = .none;4294 flags.alignment = .none;
4216 } else {4295 } else {
4217 flags.alignment = field_align;4296 flags.alignment = field_align;
...@@ -4232,7 +4311,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4232,7 +4311,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4232 }4311 }
4233 };4312 };
42344313
4235 if (cur_offset == 0 and (try cur_derive.ptrType(zcu)).toIntern() == ptr.ty) {4314 if (cur_offset == 0 and (try cur_derive.ptrType(pt)).toIntern() == ptr.ty) {
4236 return cur_derive;4315 return cur_derive;
4237 }4316 }
42384317
...@@ -4245,20 +4324,20 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4245,20 +4324,20 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4245 } };4324 } };
4246}4325}
42474326
4248pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value {4327pub fn resolveLazy(val: Value, arena: Allocator, pt: Zcu.PerThread) Zcu.SemaError!Value {
4249 switch (zcu.intern_pool.indexToKey(val.toIntern())) {4328 switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) {
4250 .int => |int| switch (int.storage) {4329 .int => |int| switch (int.storage) {
4251 .u64, .i64, .big_int => return val,4330 .u64, .i64, .big_int => return val,
4252 .lazy_align, .lazy_size => return zcu.intValue(4331 .lazy_align, .lazy_size => return pt.intValue(
4253 Type.fromInterned(int.ty),4332 Type.fromInterned(int.ty),
4254 (try val.getUnsignedIntAdvanced(zcu, .sema)).?,4333 (try val.getUnsignedIntAdvanced(pt, .sema)).?,
4255 ),4334 ),
4256 },4335 },
4257 .slice => |slice| {4336 .slice => |slice| {
4258 const ptr = try Value.fromInterned(slice.ptr).resolveLazy(arena, zcu);4337 const ptr = try Value.fromInterned(slice.ptr).resolveLazy(arena, pt);
4259 const len = try Value.fromInterned(slice.len).resolveLazy(arena, zcu);4338 const len = try Value.fromInterned(slice.len).resolveLazy(arena, pt);
4260 if (ptr.toIntern() == slice.ptr and len.toIntern() == slice.len) return val;4339 if (ptr.toIntern() == slice.ptr and len.toIntern() == slice.len) return val;
4261 return Value.fromInterned(try zcu.intern(.{ .slice = .{4340 return Value.fromInterned(try pt.intern(.{ .slice = .{
4262 .ty = slice.ty,4341 .ty = slice.ty,
4263 .ptr = ptr.toIntern(),4342 .ptr = ptr.toIntern(),
4264 .len = len.toIntern(),4343 .len = len.toIntern(),
...@@ -4268,22 +4347,22 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value...@@ -4268,22 +4347,22 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value
4268 switch (ptr.base_addr) {4347 switch (ptr.base_addr) {
4269 .decl, .comptime_alloc, .anon_decl, .int => return val,4348 .decl, .comptime_alloc, .anon_decl, .int => return val,
4270 .comptime_field => |field_val| {4349 .comptime_field => |field_val| {
4271 const resolved_field_val = (try Value.fromInterned(field_val).resolveLazy(arena, zcu)).toIntern();4350 const resolved_field_val = (try Value.fromInterned(field_val).resolveLazy(arena, pt)).toIntern();
4272 return if (resolved_field_val == field_val)4351 return if (resolved_field_val == field_val)
4273 val4352 val
4274 else4353 else
4275 Value.fromInterned((try zcu.intern(.{ .ptr = .{4354 Value.fromInterned(try pt.intern(.{ .ptr = .{
4276 .ty = ptr.ty,4355 .ty = ptr.ty,
4277 .base_addr = .{ .comptime_field = resolved_field_val },4356 .base_addr = .{ .comptime_field = resolved_field_val },
4278 .byte_offset = ptr.byte_offset,4357 .byte_offset = ptr.byte_offset,
4279 } })));4358 } }));
4280 },4359 },
4281 .eu_payload, .opt_payload => |base| {4360 .eu_payload, .opt_payload => |base| {
4282 const resolved_base = (try Value.fromInterned(base).resolveLazy(arena, zcu)).toIntern();4361 const resolved_base = (try Value.fromInterned(base).resolveLazy(arena, pt)).toIntern();
4283 return if (resolved_base == base)4362 return if (resolved_base == base)
4284 val4363 val
4285 else4364 else
4286 Value.fromInterned((try zcu.intern(.{ .ptr = .{4365 Value.fromInterned(try pt.intern(.{ .ptr = .{
4287 .ty = ptr.ty,4366 .ty = ptr.ty,
4288 .base_addr = switch (ptr.base_addr) {4367 .base_addr = switch (ptr.base_addr) {
4289 .eu_payload => .{ .eu_payload = resolved_base },4368 .eu_payload => .{ .eu_payload = resolved_base },
...@@ -4291,14 +4370,14 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value...@@ -4291,14 +4370,14 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value
4291 else => unreachable,4370 else => unreachable,
4292 },4371 },
4293 .byte_offset = ptr.byte_offset,4372 .byte_offset = ptr.byte_offset,
4294 } })));4373 } }));
4295 },4374 },
4296 .arr_elem, .field => |base_index| {4375 .arr_elem, .field => |base_index| {
4297 const resolved_base = (try Value.fromInterned(base_index.base).resolveLazy(arena, zcu)).toIntern();4376 const resolved_base = (try Value.fromInterned(base_index.base).resolveLazy(arena, pt)).toIntern();
4298 return if (resolved_base == base_index.base)4377 return if (resolved_base == base_index.base)
4299 val4378 val
4300 else4379 else
4301 Value.fromInterned((try zcu.intern(.{ .ptr = .{4380 Value.fromInterned(try pt.intern(.{ .ptr = .{
4302 .ty = ptr.ty,4381 .ty = ptr.ty,
4303 .base_addr = switch (ptr.base_addr) {4382 .base_addr = switch (ptr.base_addr) {
4304 .arr_elem => .{ .arr_elem = .{4383 .arr_elem => .{ .arr_elem = .{
...@@ -4312,7 +4391,7 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value...@@ -4312,7 +4391,7 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value
4312 else => unreachable,4391 else => unreachable,
4313 },4392 },
4314 .byte_offset = ptr.byte_offset,4393 .byte_offset = ptr.byte_offset,
4315 } })));4394 } }));
4316 },4395 },
4317 }4396 }
4318 },4397 },
...@@ -4321,40 +4400,40 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value...@@ -4321,40 +4400,40 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value
4321 .elems => |elems| {4400 .elems => |elems| {
4322 var resolved_elems: []InternPool.Index = &.{};4401 var resolved_elems: []InternPool.Index = &.{};
4323 for (elems, 0..) |elem, i| {4402 for (elems, 0..) |elem, i| {
4324 const resolved_elem = (try Value.fromInterned(elem).resolveLazy(arena, zcu)).toIntern();4403 const resolved_elem = (try Value.fromInterned(elem).resolveLazy(arena, pt)).toIntern();
4325 if (resolved_elems.len == 0 and resolved_elem != elem) {4404 if (resolved_elems.len == 0 and resolved_elem != elem) {
4326 resolved_elems = try arena.alloc(InternPool.Index, elems.len);4405 resolved_elems = try arena.alloc(InternPool.Index, elems.len);
4327 @memcpy(resolved_elems[0..i], elems[0..i]);4406 @memcpy(resolved_elems[0..i], elems[0..i]);
4328 }4407 }
4329 if (resolved_elems.len > 0) resolved_elems[i] = resolved_elem;4408 if (resolved_elems.len > 0) resolved_elems[i] = resolved_elem;
4330 }4409 }
4331 return if (resolved_elems.len == 0) val else Value.fromInterned((try zcu.intern(.{ .aggregate = .{4410 return if (resolved_elems.len == 0) val else Value.fromInterned(try pt.intern(.{ .aggregate = .{
4332 .ty = aggregate.ty,4411 .ty = aggregate.ty,
4333 .storage = .{ .elems = resolved_elems },4412 .storage = .{ .elems = resolved_elems },
4334 } })));4413 } }));
4335 },4414 },
4336 .repeated_elem => |elem| {4415 .repeated_elem => |elem| {
4337 const resolved_elem = (try Value.fromInterned(elem).resolveLazy(arena, zcu)).toIntern();4416 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 = .{4417 return if (resolved_elem == elem) val else Value.fromInterned(try pt.intern(.{ .aggregate = .{
4339 .ty = aggregate.ty,4418 .ty = aggregate.ty,
4340 .storage = .{ .repeated_elem = resolved_elem },4419 .storage = .{ .repeated_elem = resolved_elem },
4341 } })));4420 } }));
4342 },4421 },
4343 },4422 },
4344 .un => |un| {4423 .un => |un| {
4345 const resolved_tag = if (un.tag == .none)4424 const resolved_tag = if (un.tag == .none)
4346 .none4425 .none
4347 else4426 else
4348 (try Value.fromInterned(un.tag).resolveLazy(arena, zcu)).toIntern();4427 (try Value.fromInterned(un.tag).resolveLazy(arena, pt)).toIntern();
4349 const resolved_val = (try Value.fromInterned(un.val).resolveLazy(arena, zcu)).toIntern();4428 const resolved_val = (try Value.fromInterned(un.val).resolveLazy(arena, pt)).toIntern();
4350 return if (resolved_tag == un.tag and resolved_val == un.val)4429 return if (resolved_tag == un.tag and resolved_val == un.val)
4351 val4430 val
4352 else4431 else
4353 Value.fromInterned((try zcu.intern(.{ .un = .{4432 Value.fromInterned(try pt.intern(.{ .un = .{
4354 .ty = un.ty,4433 .ty = un.ty,
4355 .tag = resolved_tag,4434 .tag = resolved_tag,
4356 .val = resolved_val,4435 .val = resolved_val,
4357 } })));4436 } }));
4358 },4437 },
4359 else => return val,4438 else => return val,
4360 }4439 }
src/Zcu.zig+103-2161
...@@ -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;
...@@ -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,
...@@ -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,
...@@ -3079,7 +3080,7 @@ pub fn markDependeeOutdated(zcu: *Zcu, dependee: InternPool.Dependee) !void {...@@ -3079,7 +3080,7 @@ pub fn markDependeeOutdated(zcu: *Zcu, dependee: InternPool.Dependee) !void {
3079 }3080 }
3080}3081}
30813082
3082fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {3083pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {
3083 var it = zcu.intern_pool.dependencyIterator(dependee);3084 var it = zcu.intern_pool.dependencyIterator(dependee);
3084 while (it.next()) |depender| {3085 while (it.next()) |depender| {
3085 if (zcu.outdated.getPtr(depender)) |po_dep_count| {3086 if (zcu.outdated.getPtr(depender)) |po_dep_count| {
...@@ -3279,7 +3280,7 @@ pub fn mapOldZirToNew(...@@ -3279,7 +3280,7 @@ pub fn mapOldZirToNew(
3279 old_inst: Zir.Inst.Index,3280 old_inst: Zir.Inst.Index,
3280 new_inst: Zir.Inst.Index,3281 new_inst: Zir.Inst.Index,
3281 };3282 };
3282 var match_stack: ArrayListUnmanaged(MatchedZirDecl) = .{};3283 var match_stack: std.ArrayListUnmanaged(MatchedZirDecl) = .{};
3283 defer match_stack.deinit(gpa);3284 defer match_stack.deinit(gpa);
32843285
3285 // Main struct inst is always matched3286 // Main struct inst is always matched
...@@ -3394,357 +3395,6 @@ pub fn mapOldZirToNew(...@@ -3394,357 +3395,6 @@ pub fn mapOldZirToNew(
3394 }3395 }
3395}3396}
33963397
3397/// Like `ensureDeclAnalyzed`, but the Decl is a file's root Decl.
3398pub fn ensureFileAnalyzed(zcu: *Zcu, file_index: File.Index) SemaError!void {
3399 if (zcu.fileRootDecl(file_index).unwrap()) |existing_root| {
3400 return zcu.ensureDeclAnalyzed(existing_root);
3401 } else {
3402 return zcu.semaFile(file_index);
3403 }
3404}
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;
3415 const decl = mod.declPtr(decl_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;
3541 const decl = zcu.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;
3569
3570 switch (decl.analysis) {
3571 .unreferenced => unreachable,
3572 .in_progress => unreachable,
3573
3574 .codegen_failure => unreachable, // functions do not perform constant value generation
3575
3576 .file_failure,
3577 .sema_failure,
3578 .dependency_failure,
3579 => return error.AnalysisFail,
3580
3581 .complete => {},
3582 }
3583
3584 const func_as_depender = AnalUnit.wrap(.{ .func = func_index });
3585 const was_outdated = zcu.outdated.swapRemove(func_as_depender) or
3586 zcu.potentially_outdated.swapRemove(func_as_depender);
3587
3588 if (was_outdated) {
3589 if (build_options.only_c) unreachable;
3590 _ = zcu.outdated_ready.swapRemove(func_as_depender);
3591 zcu.deleteUnitExports(func_as_depender);
3592 zcu.deleteUnitReferences(func_as_depender);
3593 }
3594
3595 switch (func.analysis(ip).state) {
3596 .success => if (!was_outdated) return,
3597 .sema_failure,
3598 .dependency_failure,
3599 .codegen_failure,
3600 => if (!was_outdated) return error.AnalysisFail,
3601 .none, .queued => {},
3602 .in_progress => unreachable,
3603 .inline_only => unreachable, // don't queue work for this
3604 }
3605
3606 log.debug("analyze and generate fn body '{d}'; reason='{s}'", .{
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);
3628
3629 const invalidate_ies_deps = i: {
3630 if (!was_outdated) break :i false;
3631 if (!func.analysis(ip).inferred_error_set) break :i true;
3632 const new_resolved_ies = func.resolvedErrorSet(ip).*;
3633 break :i new_resolved_ies != old_resolved_ies;
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 }
3642
3643 const comp = zcu.comp;
3644
3645 const dump_air = build_options.enable_debug_extensions and comp.verbose_air;
3646 const dump_llvm_ir = build_options.enable_debug_extensions and (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null);
3647
3648 if (comp.bin_file == null and zcu.llvm_object == null and !dump_air and !dump_llvm_ir) {
3649 air.deinit(gpa);
3650 return;
3651 }
3652
3653 try comp.work_queue.writeItem(.{ .codegen_func = .{
3654 .func = func_index,
3655 .air = air,
3656 } });
3657}
3658
3659/// Takes ownership of `air`, even on error.
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 should3398/// 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.3399/// be called whenever a potential runtime call of a function is seen.
3750///3400///
...@@ -3804,608 +3454,105 @@ pub fn ensureFuncBodyAnalysisQueued(mod: *Module, func_index: InternPool.Index)...@@ -3804,608 +3454,105 @@ pub fn ensureFuncBodyAnalysisQueued(mod: *Module, func_index: InternPool.Index)
3804 func.analysis(ip).state = .queued;3454 func.analysis(ip).state = .queued;
3805}3455}
38063456
3807pub fn semaPkg(zcu: *Zcu, pkg: *Package.Module) !void {3457pub const SemaDeclResult = packed struct {
3808 const import_file_result = try zcu.importPkg(pkg);3458 /// Whether the value of a `decl_val` of this Decl changed.
3809 const root_decl_index = zcu.fileRootDecl(import_file_result.file_index);3459 invalidate_decl_val: bool,
3810 if (root_decl_index == .none) {3460 /// Whether the type of a `decl_ref` of this Decl changed.
3811 return zcu.semaFile(import_file_result.file_index);3461 invalidate_decl_ref: bool,
3812 }3462};
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 }
38733463
3464pub fn semaAnonOwnerDecl(zcu: *Zcu, decl_index: Decl.Index) !SemaDeclResult {
3874 const decl = zcu.declPtr(decl_index);3465 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 }
39143466
3915 assert(decl.has_tv);3467 assert(decl.has_tv);
3916 assert(decl.owns_tv);3468 assert(decl.owns_tv);
39173469
3918 if (type_outdated) {3470 log.debug("semaAnonOwnerDecl '{d}'", .{@intFromEnum(decl_index)});
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);
39443471
3945 if (!type_outdated) {3472 switch (decl.typeOf(zcu).zigTypeTag(zcu)) {
3946 try zcu.scanNamespace(decl.src_namespace, decls, decl);3473 .Fn => @panic("TODO: update fn instance"),
3474 .Type => {},
3475 else => unreachable,
3947 }3476 }
39483477
3949 return false;3478 // We are the owner Decl of a type, and we were marked as outdated. That means the *structure*
3479 // of this type changed; not just its namespace. Therefore, we need a new InternPool index.
3480 //
3481 // However, as soon as we make that, the context that created us will require re-analysis anyway
3482 // (as it depends on this Decl's value), meaning the `struct_decl` (or equivalent) instruction
3483 // will be analyzed again. Since Sema already needs to be able to reconstruct types like this,
3484 // why should we bother implementing it here too when the Sema logic will be hit right after?
3485 //
3486 // So instead, let's just mark this Decl as failed - so that any remaining Decls which genuinely
3487 // reference it (via `@This`) end up silently erroring too - and we'll let Sema make a new type
3488 // with a new Decl.
3489 //
3490 // Yes, this does mean that any type owner Decl has a constant value for its entire lifetime.
3491 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, AnalUnit.wrap(.{ .decl = decl_index }));
3492 zcu.intern_pool.remove(decl.val.toIntern());
3493 decl.analysis = .dependency_failure;
3494 return .{
3495 .invalidate_decl_val = true,
3496 .invalidate_decl_ref = true,
3497 };
3950}3498}
39513499
3952/// Regardless of the file status, will create a `Decl` if none exists so that we can track3500pub const ImportFileResult = struct {
3953/// dependencies and re-analyze when the file becomes outdated.3501 file: *File,
3954fn semaFile(zcu: *Zcu, file_index: File.Index) SemaError!void {3502 file_index: File.Index,
3955 const tracy = trace(@src());3503 is_new: bool,
3956 defer tracy.end();3504 is_pkg: bool,
39573505};
3958 const file = zcu.fileByIndex(file_index);
3959 assert(zcu.fileRootDecl(file_index) == .none);
39603506
3507pub fn importPkg(zcu: *Zcu, mod: *Package.Module) !ImportFileResult {
3961 const gpa = zcu.gpa;3508 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 });
39653509
3966 // Because these three things each reference each other, `undefined`3510 // The resolved path is used as the key in the import table, to detect if
3967 // placeholders are used before being set after the struct type gains an3511 // an import refers to the same as another, despite different relative paths
3968 // InternPool index.3512 // or differently mapped package names.
3969 const new_namespace_index = try zcu.createNamespace(.{3513 const resolved_path = try std.fs.path.resolve(gpa, &.{
3970 .parent = .none,3514 mod.root.root_dir.path orelse ".",
3971 .decl_index = undefined,3515 mod.root.sub_path,
3972 .file_scope = file_index,3516 mod.root_src_path,
3973 });3517 });
3974 errdefer zcu.destroyNamespace(new_namespace_index);3518 var keep_resolved_path = false;
3519 defer if (!keep_resolved_path) gpa.free(resolved_path);
39753520
3976 const new_decl_index = try zcu.allocateNewDecl(new_namespace_index);3521 const gop = try zcu.import_table.getOrPut(gpa, resolved_path);
3977 const new_decl = zcu.declPtr(new_decl_index);3522 errdefer _ = zcu.import_table.pop();
3978 errdefer @panic("TODO error handling");3523 if (gop.found_existing) {
3524 try gop.value_ptr.*.addReference(zcu.*, .{ .root = mod });
3525 return .{
3526 .file = gop.value_ptr.*,
3527 .file_index = @enumFromInt(gop.index),
3528 .is_new = false,
3529 .is_pkg = true,
3530 };
3531 }
39793532
3980 zcu.setFileRootDecl(file_index, new_decl_index.toOptional());3533 const ip = &zcu.intern_pool;
3981 zcu.namespacePtr(new_namespace_index).decl_index = new_decl_index;
39823534
3983 new_decl.name = try file.fullyQualifiedName(zcu);3535 try ip.files.ensureUnusedCapacity(gpa, 1);
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;
39903536
3991 if (file.status != .success_zir) {3537 if (mod.builtin_file) |builtin_file| {
3992 new_decl.analysis = .file_failure;3538 keep_resolved_path = true; // It's now owned by import_table.
3993 return;3539 gop.value_ptr.* = builtin_file;
3540 try builtin_file.addReference(zcu.*, .{ .root = mod });
3541 const path_digest = computePathDigest(zcu, mod, builtin_file.sub_file_path);
3542 ip.files.putAssumeCapacityNoClobber(path_digest, .none);
3543 return .{
3544 .file = builtin_file,
3545 .file_index = @enumFromInt(ip.files.entries.len - 1),
3546 .is_new = false,
3547 .is_pkg = true,
3548 };
3994 }3549 }
3995 assert(file.zir_loaded);
39963550
3997 const struct_ty = try zcu.getFileRootStruct(new_decl_index, new_namespace_index, file_index);3551 const sub_file_path = try gpa.dupe(u8, mod.root_src_path);
3998 errdefer zcu.intern_pool.remove(struct_ty);3552 errdefer gpa.free(sub_file_path);
39993553
4000 switch (zcu.comp.cache_use) {3554 const new_file = try gpa.create(File);
4001 .whole => |whole| if (whole.cache_manifest) |man| {3555 errdefer gpa.destroy(new_file);
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;
4362
4363 // The resolved path is used as the key in the import table, to detect if
4364 // an import refers to the same as another, despite different relative paths
4365 // or differently mapped package names.
4366 const resolved_path = try std.fs.path.resolve(gpa, &.{
4367 mod.root.root_dir.path orelse ".",
4368 mod.root.sub_path,
4369 mod.root_src_path,
4370 });
4371 var keep_resolved_path = false;
4372 defer if (!keep_resolved_path) gpa.free(resolved_path);
4373
4374 const gop = try zcu.import_table.getOrPut(gpa, resolved_path);
4375 errdefer _ = zcu.import_table.pop();
4376 if (gop.found_existing) {
4377 try gop.value_ptr.*.addReference(zcu.*, .{ .root = mod });
4378 return .{
4379 .file = gop.value_ptr.*,
4380 .file_index = @enumFromInt(gop.index),
4381 .is_new = false,
4382 .is_pkg = true,
4383 };
4384 }
4385
4386 const ip = &zcu.intern_pool;
4387
4388 try ip.files.ensureUnusedCapacity(gpa, 1);
4389
4390 if (mod.builtin_file) |builtin_file| {
4391 keep_resolved_path = true; // It's now owned by import_table.
4392 gop.value_ptr.* = builtin_file;
4393 try builtin_file.addReference(zcu.*, .{ .root = mod });
4394 const path_digest = computePathDigest(zcu, mod, builtin_file.sub_file_path);
4395 ip.files.putAssumeCapacityNoClobber(path_digest, .none);
4396 return .{
4397 .file = builtin_file,
4398 .file_index = @enumFromInt(ip.files.entries.len - 1),
4399 .is_new = false,
4400 .is_pkg = true,
4401 };
4402 }
4403
4404 const sub_file_path = try gpa.dupe(u8, mod.root_src_path);
4405 errdefer gpa.free(sub_file_path);
4406
4407 const new_file = try gpa.create(File);
4408 errdefer gpa.destroy(new_file);
44093556
4410 keep_resolved_path = true; // It's now owned by import_table.3557 keep_resolved_path = true; // It's now owned by import_table.
4411 gop.value_ptr.* = new_file;3558 gop.value_ptr.* = new_file;
...@@ -4533,78 +3680,6 @@ pub fn importFile(...@@ -4533,78 +3680,6 @@ pub fn importFile(
4533 };3680 };
4534}3681}
45353682
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 {3683fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) Cache.BinDigest {
4609 const want_local_cache = mod == zcu.main_mod;3684 const want_local_cache = mod == zcu.main_mod;
4610 var path_hash: Cache.HashHelper = .{};3685 var path_hash: Cache.HashHelper = .{};
...@@ -4620,87 +3695,6 @@ fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8)...@@ -4620,87 +3695,6 @@ fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8)
4620 return bin;3695 return bin;
4621}3696}
46223697
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(3698pub fn scanNamespace(
4705 zcu: *Zcu,3699 zcu: *Zcu,
4706 namespace_index: Namespace.Index,3700 namespace_index: Namespace.Index,
...@@ -4970,13 +3964,6 @@ pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void {...@@ -4970,13 +3964,6 @@ pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void {
4970 mod.destroyDecl(decl_index);3964 mod.destroyDecl(decl_index);
4971}3965}
49723966
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 of3967/// 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).3968/// this `AnalUnit` will cause them to be re-created (or not).
4982pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void {3969pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void {
...@@ -5019,7 +4006,7 @@ pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void {...@@ -5019,7 +4006,7 @@ pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void {
50194006
5020/// Delete all references in `reference_table` which are caused by this `AnalUnit`.4007/// 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.4008/// Re-analysis of the `AnalUnit` will cause appropriate references to be recreated.
5022fn deleteUnitReferences(zcu: *Zcu, anal_unit: AnalUnit) void {4009pub fn deleteUnitReferences(zcu: *Zcu, anal_unit: AnalUnit) void {
5023 const gpa = zcu.gpa;4010 const gpa = zcu.gpa;
50244011
5025 const kv = zcu.reference_table.fetchSwapRemove(anal_unit) orelse return;4012 const kv = zcu.reference_table.fetchSwapRemove(anal_unit) orelse return;
...@@ -5058,258 +4045,13 @@ pub fn addUnitReference(zcu: *Zcu, src_unit: AnalUnit, referenced_unit: AnalUnit...@@ -5058,258 +4045,13 @@ pub fn addUnitReference(zcu: *Zcu, src_unit: AnalUnit, referenced_unit: AnalUnit
5058 gop.value_ptr.* = @intCast(ref_idx);4045 gop.value_ptr.* = @intCast(ref_idx);
5059}4046}
50604047
5061pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocator) SemaError!Air {4048pub fn createNamespace(mod: *Module, initialization: Namespace) !Namespace.Index {
5062 const tracy = trace(@src());4049 return mod.intern_pool.createNamespace(mod.gpa, initialization);
5063 defer tracy.end();4050}
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();
50834051
5084 // In the case of a generic function instance, this is the type of the4052pub fn destroyNamespace(mod: *Module, index: Namespace.Index) void {
5085 // instance, which has comptime parameters elided. In other words, it is4053 return mod.intern_pool.destroyNamespace(mod.gpa, index);
5086 // the runtime-known parameters only, not to be confused with the4054}
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 }
5277
5278 func.analysis(ip).state = .success;
5279
5280 // Finally we must resolve the return type and parameter types so that backends
5281 // have full access to type information.
5282 // Crucially, this happens *after* we set the function state to success above,
5283 // so that dependencies on the function body will now be satisfied rather than
5284 // result in circular dependency errors.
5285 sema.resolveFnTypes(fn_ty) catch |err| switch (err) {
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 };
5297
5298 try sema.flushExports();
5299
5300 return .{
5301 .instructions = sema.air_instructions.toOwnedSlice(),
5302 .extra = try sema.air_extra.toOwnedSlice(gpa),
5303 };
5304}
5305
5306pub fn createNamespace(mod: *Module, initialization: Namespace) !Namespace.Index {
5307 return mod.intern_pool.createNamespace(mod.gpa, initialization);
5308}
5309
5310pub fn destroyNamespace(mod: *Module, index: Namespace.Index) void {
5311 return mod.intern_pool.destroyNamespace(mod.gpa, index);
5312}
53134055
5314pub fn allocateNewDecl(zcu: *Zcu, namespace: Namespace.Index) !Decl.Index {4056pub fn allocateNewDecl(zcu: *Zcu, namespace: Namespace.Index) !Decl.Index {
5315 const gpa = zcu.gpa;4057 const gpa = zcu.gpa;
...@@ -5420,117 +4162,7 @@ fn lockAndClearFileCompileError(mod: *Module, file: *File) void {...@@ -5420,117 +4162,7 @@ fn lockAndClearFileCompileError(mod: *Module, file: *File) void {
5420 }4162 }
5421}4163}
54224164
5423/// Called from `Compilation.update`, after everything is done, just before4165pub 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,4166 zcu: *Zcu,
5535 export_indices: []const u32,4167 export_indices: []const u32,
5536 result: link.File.UpdateExportsError!void,4168 result: link.File.UpdateExportsError!void,
...@@ -5551,180 +4183,7 @@ fn handleUpdateExports(...@@ -5551,180 +4183,7 @@ fn handleUpdateExports(
5551 };4183 };
5552}4184}
55534185
5554pub fn populateTestFunctions(4186pub 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,4187 zcu: *Zcu,
5729 file_index: File.Index,4188 file_index: File.Index,
5730 comptime format: []const u8,4189 comptime format: []const u8,
...@@ -5795,344 +4254,6 @@ pub fn backendSupportsFeature(zcu: Module, feature: Feature) bool {...@@ -5795,344 +4254,6 @@ pub fn backendSupportsFeature(zcu: Module, feature: Feature) bool {
5795 return target_util.backendSupportsFeature(cpu_arch, ofmt, use_llvm, feature);4254 return target_util.backendSupportsFeature(cpu_arch, ofmt, use_llvm, feature);
5796}4255}
57974256
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}
6135
6136pub const AtomicPtrAlignmentError = error{4257pub const AtomicPtrAlignmentError = error{
6137 FloatTooBig,4258 FloatTooBig,
6138 IntTooBig,4259 IntTooBig,
...@@ -6371,101 +4492,6 @@ pub const UnionLayout = struct {...@@ -6371,101 +4492,6 @@ pub const UnionLayout = struct {
6371 padding: u32,4492 padding: u32,
6372};4493};
63734494
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 value4495/// 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 {4496pub fn unionTagFieldIndex(mod: *Module, loaded_union: InternPool.LoadedUnionType, enum_tag: Value) ?u32 {
6471 const ip = &mod.intern_pool;4497 const ip = &mod.intern_pool;
...@@ -6474,63 +4500,6 @@ pub fn unionTagFieldIndex(mod: *Module, loaded_union: InternPool.LoadedUnionType...@@ -6474,63 +4500,6 @@ pub fn unionTagFieldIndex(mod: *Module, loaded_union: InternPool.LoadedUnionType
6474 return loaded_union.loadTagType(ip).tagValueIndex(ip, enum_tag.toIntern());4500 return loaded_union.loadTagType(ip).tagValueIndex(ip, enum_tag.toIntern());
6475}4501}
64764502
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 {4503pub const ResolvedReference = struct {
6535 referencer: AnalUnit,4504 referencer: AnalUnit,
6536 src: LazySrcLoc,4505 src: LazySrcLoc,
...@@ -6564,33 +4533,6 @@ pub fn resolveReferences(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, Resolved...@@ -6564,33 +4533,6 @@ pub fn resolveReferences(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, Resolved
6564 return result;4533 return result;
6565}4534}
65664535
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 {4536pub fn fileByIndex(zcu: *const Zcu, i: File.Index) *File {
6595 return zcu.import_table.values()[@intFromEnum(i)];4537 return zcu.import_table.values()[@intFromEnum(i)];
6596}4538}
src/Zcu/PerThread.zig created+2102
...@@ -0,0 +1,2102 @@
1zcu: *Zcu,
2
3/// Dense, per-thread unique index.
4tid: Id,
5
6pub const Id = if (builtin.single_threaded) enum { main } else enum(usize) { main, _ };
7
8/// Like `ensureDeclAnalyzed`, but the Decl is a file's root Decl.
9pub fn ensureFileAnalyzed(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
10 if (pt.zcu.fileRootDecl(file_index).unwrap()) |existing_root| {
11 return pt.ensureDeclAnalyzed(existing_root);
12 } else {
13 return pt.semaFile(file_index);
14 }
15}
16
17/// This ensures that the Decl will have an up-to-date Type and Value populated.
18/// However the resolution status of the Type may not be fully resolved.
19/// For example an inferred error set is not resolved until after `analyzeFnBody`.
20/// is called.
21pub fn ensureDeclAnalyzed(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Zcu.SemaError!void {
22 const tracy = trace(@src());
23 defer tracy.end();
24
25 const mod = pt.zcu;
26 const ip = &mod.intern_pool;
27 const decl = mod.declPtr(decl_index);
28
29 log.debug("ensureDeclAnalyzed '{d}' (name '{}')", .{
30 @intFromEnum(decl_index),
31 decl.name.fmt(ip),
32 });
33
34 // Determine whether or not this Decl is outdated, i.e. requires re-analysis
35 // even if `complete`. If a Decl is PO, we pessismistically assume that it
36 // *does* require re-analysis, to ensure that the Decl is definitely
37 // up-to-date when this function returns.
38
39 // If analysis occurs in a poor order, this could result in over-analysis.
40 // We do our best to avoid this by the other dependency logic in this file
41 // which tries to limit re-analysis to Decls whose previously listed
42 // dependencies are all up-to-date.
43
44 const decl_as_depender = InternPool.AnalUnit.wrap(.{ .decl = decl_index });
45 const decl_was_outdated = mod.outdated.swapRemove(decl_as_depender) or
46 mod.potentially_outdated.swapRemove(decl_as_depender);
47
48 if (decl_was_outdated) {
49 _ = mod.outdated_ready.swapRemove(decl_as_depender);
50 }
51
52 const was_outdated = mod.outdated_file_root.swapRemove(decl_index) or decl_was_outdated;
53
54 switch (decl.analysis) {
55 .in_progress => unreachable,
56
57 .file_failure => return error.AnalysisFail,
58
59 .sema_failure,
60 .dependency_failure,
61 .codegen_failure,
62 => if (!was_outdated) return error.AnalysisFail,
63
64 .complete => if (!was_outdated) return,
65
66 .unreferenced => {},
67 }
68
69 if (was_outdated) {
70 // The exports this Decl performs will be re-discovered, so we remove them here
71 // prior to re-analysis.
72 if (build_options.only_c) unreachable;
73 mod.deleteUnitExports(decl_as_depender);
74 mod.deleteUnitReferences(decl_as_depender);
75 }
76
77 const sema_result: Zcu.SemaDeclResult = blk: {
78 if (decl.zir_decl_index == .none and !mod.declIsRoot(decl_index)) {
79 // Anonymous decl. We don't semantically analyze these.
80 break :blk .{
81 .invalidate_decl_val = false,
82 .invalidate_decl_ref = false,
83 };
84 }
85
86 if (mod.declIsRoot(decl_index)) {
87 const changed = try pt.semaFileUpdate(decl.getFileScopeIndex(mod), decl_was_outdated);
88 break :blk .{
89 .invalidate_decl_val = changed,
90 .invalidate_decl_ref = changed,
91 };
92 }
93
94 const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(mod)).toSlice(ip), 0);
95 defer decl_prog_node.end();
96
97 break :blk pt.semaDecl(decl_index) catch |err| switch (err) {
98 error.AnalysisFail => {
99 if (decl.analysis == .in_progress) {
100 // If this decl caused the compile error, the analysis field would
101 // be changed to indicate it was this Decl's fault. Because this
102 // did not happen, we infer here that it was a dependency failure.
103 decl.analysis = .dependency_failure;
104 }
105 return error.AnalysisFail;
106 },
107 error.GenericPoison => unreachable,
108 else => |e| {
109 decl.analysis = .sema_failure;
110 try mod.failed_analysis.ensureUnusedCapacity(mod.gpa, 1);
111 try mod.retryable_failures.append(mod.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));
112 mod.failed_analysis.putAssumeCapacityNoClobber(InternPool.AnalUnit.wrap(.{ .decl = decl_index }), try Zcu.ErrorMsg.create(
113 mod.gpa,
114 decl.navSrcLoc(mod),
115 "unable to analyze: {s}",
116 .{@errorName(e)},
117 ));
118 return error.AnalysisFail;
119 },
120 };
121 };
122
123 // TODO: we do not yet have separate dependencies for decl values vs types.
124 if (decl_was_outdated) {
125 if (sema_result.invalidate_decl_val or sema_result.invalidate_decl_ref) {
126 log.debug("Decl tv invalidated ('{d}')", .{@intFromEnum(decl_index)});
127 // This dependency was marked as PO, meaning dependees were waiting
128 // on its analysis result, and it has turned out to be outdated.
129 // Update dependees accordingly.
130 try mod.markDependeeOutdated(.{ .decl_val = decl_index });
131 } else {
132 log.debug("Decl tv up-to-date ('{d}')", .{@intFromEnum(decl_index)});
133 // This dependency was previously PO, but turned out to be up-to-date.
134 // We do not need to queue successive analysis.
135 try mod.markPoDependeeUpToDate(.{ .decl_val = decl_index });
136 }
137 }
138}
139
140pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: InternPool.Index) Zcu.SemaError!void {
141 const tracy = trace(@src());
142 defer tracy.end();
143
144 const zcu = pt.zcu;
145 const gpa = zcu.gpa;
146 const ip = &zcu.intern_pool;
147
148 // We only care about the uncoerced function.
149 // We need to do this for the "orphaned function" check below to be valid.
150 const func_index = ip.unwrapCoercedFunc(maybe_coerced_func_index);
151
152 const func = zcu.funcInfo(maybe_coerced_func_index);
153 const decl_index = func.owner_decl;
154 const decl = zcu.declPtr(decl_index);
155
156 log.debug("ensureFuncBodyAnalyzed '{d}' (instance of '{}')", .{
157 @intFromEnum(func_index),
158 decl.name.fmt(ip),
159 });
160
161 // First, our owner decl must be up-to-date. This will always be the case
162 // during the first update, but may not on successive updates if we happen
163 // to get analyzed before our parent decl.
164 try pt.ensureDeclAnalyzed(decl_index);
165
166 // On an update, it's possible this function changed such that our owner
167 // decl now refers to a different function, making this one orphaned. If
168 // that's the case, we should remove this function from the binary.
169 if (decl.val.ip_index != func_index) {
170 try zcu.markDependeeOutdated(.{ .func_ies = func_index });
171 ip.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));
172 ip.remove(func_index);
173 @panic("TODO: remove orphaned function from binary");
174 }
175
176 // We'll want to remember what the IES used to be before the update for
177 // dependency invalidation purposes.
178 const old_resolved_ies = if (func.analysis(ip).inferred_error_set)
179 func.resolvedErrorSet(ip).*
180 else
181 .none;
182
183 switch (decl.analysis) {
184 .unreferenced => unreachable,
185 .in_progress => unreachable,
186
187 .codegen_failure => unreachable, // functions do not perform constant value generation
188
189 .file_failure,
190 .sema_failure,
191 .dependency_failure,
192 => return error.AnalysisFail,
193
194 .complete => {},
195 }
196
197 const func_as_depender = InternPool.AnalUnit.wrap(.{ .func = func_index });
198 const was_outdated = zcu.outdated.swapRemove(func_as_depender) or
199 zcu.potentially_outdated.swapRemove(func_as_depender);
200
201 if (was_outdated) {
202 if (build_options.only_c) unreachable;
203 _ = zcu.outdated_ready.swapRemove(func_as_depender);
204 zcu.deleteUnitExports(func_as_depender);
205 zcu.deleteUnitReferences(func_as_depender);
206 }
207
208 switch (func.analysis(ip).state) {
209 .success => if (!was_outdated) return,
210 .sema_failure,
211 .dependency_failure,
212 .codegen_failure,
213 => if (!was_outdated) return error.AnalysisFail,
214 .none, .queued => {},
215 .in_progress => unreachable,
216 .inline_only => unreachable, // don't queue work for this
217 }
218
219 log.debug("analyze and generate fn body '{d}'; reason='{s}'", .{
220 @intFromEnum(func_index),
221 if (was_outdated) "outdated" else "never analyzed",
222 });
223
224 var tmp_arena = std.heap.ArenaAllocator.init(gpa);
225 defer tmp_arena.deinit();
226 const sema_arena = tmp_arena.allocator();
227
228 var air = pt.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
229 error.AnalysisFail => {
230 if (func.analysis(ip).state == .in_progress) {
231 // If this decl caused the compile error, the analysis field would
232 // be changed to indicate it was this Decl's fault. Because this
233 // did not happen, we infer here that it was a dependency failure.
234 func.analysis(ip).state = .dependency_failure;
235 }
236 return error.AnalysisFail;
237 },
238 error.OutOfMemory => return error.OutOfMemory,
239 };
240 errdefer air.deinit(gpa);
241
242 const invalidate_ies_deps = i: {
243 if (!was_outdated) break :i false;
244 if (!func.analysis(ip).inferred_error_set) break :i true;
245 const new_resolved_ies = func.resolvedErrorSet(ip).*;
246 break :i new_resolved_ies != old_resolved_ies;
247 };
248 if (invalidate_ies_deps) {
249 log.debug("func IES invalidated ('{d}')", .{@intFromEnum(func_index)});
250 try zcu.markDependeeOutdated(.{ .func_ies = func_index });
251 } else if (was_outdated) {
252 log.debug("func IES up-to-date ('{d}')", .{@intFromEnum(func_index)});
253 try zcu.markPoDependeeUpToDate(.{ .func_ies = func_index });
254 }
255
256 const comp = zcu.comp;
257
258 const dump_air = build_options.enable_debug_extensions and comp.verbose_air;
259 const dump_llvm_ir = build_options.enable_debug_extensions and (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null);
260
261 if (comp.bin_file == null and zcu.llvm_object == null and !dump_air and !dump_llvm_ir) {
262 air.deinit(gpa);
263 return;
264 }
265
266 try comp.work_queue.writeItem(.{ .codegen_func = .{
267 .func = func_index,
268 .air = air,
269 } });
270}
271
272/// Takes ownership of `air`, even on error.
273/// If any types referenced by `air` are unresolved, marks the codegen as failed.
274pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Air) Allocator.Error!void {
275 const zcu = pt.zcu;
276 const gpa = zcu.gpa;
277 const ip = &zcu.intern_pool;
278 const comp = zcu.comp;
279
280 defer {
281 var air_mut = air;
282 air_mut.deinit(gpa);
283 }
284
285 const func = zcu.funcInfo(func_index);
286 const decl_index = func.owner_decl;
287 const decl = zcu.declPtr(decl_index);
288
289 var liveness = try Liveness.analyze(gpa, air, ip);
290 defer liveness.deinit(gpa);
291
292 if (build_options.enable_debug_extensions and comp.verbose_air) {
293 const fqn = try decl.fullyQualifiedName(zcu);
294 std.debug.print("# Begin Function AIR: {}:\n", .{fqn.fmt(ip)});
295 @import("../print_air.zig").dump(pt, air, liveness);
296 std.debug.print("# End Function AIR: {}\n\n", .{fqn.fmt(ip)});
297 }
298
299 if (std.debug.runtime_safety) {
300 var verify: Liveness.Verify = .{
301 .gpa = gpa,
302 .air = air,
303 .liveness = liveness,
304 .intern_pool = ip,
305 };
306 defer verify.deinit();
307
308 verify.verify() catch |err| switch (err) {
309 error.OutOfMemory => return error.OutOfMemory,
310 else => {
311 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
312 zcu.failed_analysis.putAssumeCapacityNoClobber(
313 InternPool.AnalUnit.wrap(.{ .func = func_index }),
314 try Zcu.ErrorMsg.create(
315 gpa,
316 decl.navSrcLoc(zcu),
317 "invalid liveness: {s}",
318 .{@errorName(err)},
319 ),
320 );
321 func.analysis(ip).state = .codegen_failure;
322 return;
323 },
324 };
325 }
326
327 const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(zcu)).toSlice(ip), 0);
328 defer codegen_prog_node.end();
329
330 if (!air.typesFullyResolved(zcu)) {
331 // A type we depend on failed to resolve. This is a transitive failure.
332 // Correcting this failure will involve changing a type this function
333 // depends on, hence triggering re-analysis of this function, so this
334 // interacts correctly with incremental compilation.
335 func.analysis(ip).state = .codegen_failure;
336 } else if (comp.bin_file) |lf| {
337 lf.updateFunc(pt, func_index, air, liveness) catch |err| switch (err) {
338 error.OutOfMemory => return error.OutOfMemory,
339 error.AnalysisFail => {
340 func.analysis(ip).state = .codegen_failure;
341 },
342 else => {
343 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
344 zcu.failed_analysis.putAssumeCapacityNoClobber(InternPool.AnalUnit.wrap(.{ .func = func_index }), try Zcu.ErrorMsg.create(
345 gpa,
346 decl.navSrcLoc(zcu),
347 "unable to codegen: {s}",
348 .{@errorName(err)},
349 ));
350 func.analysis(ip).state = .codegen_failure;
351 try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));
352 },
353 };
354 } else if (zcu.llvm_object) |llvm_object| {
355 if (build_options.only_c) unreachable;
356 llvm_object.updateFunc(pt, func_index, air, liveness) catch |err| switch (err) {
357 error.OutOfMemory => return error.OutOfMemory,
358 };
359 }
360}
361
362/// https://github.com/ziglang/zig/issues/14307
363pub fn semaPkg(pt: Zcu.PerThread, pkg: *Module) !void {
364 const import_file_result = try pt.zcu.importPkg(pkg);
365 const root_decl_index = pt.zcu.fileRootDecl(import_file_result.file_index);
366 if (root_decl_index == .none) {
367 return pt.semaFile(import_file_result.file_index);
368 }
369}
370
371fn getFileRootStruct(
372 pt: Zcu.PerThread,
373 decl_index: Zcu.Decl.Index,
374 namespace_index: Zcu.Namespace.Index,
375 file_index: Zcu.File.Index,
376) Allocator.Error!InternPool.Index {
377 const zcu = pt.zcu;
378 const gpa = zcu.gpa;
379 const ip = &zcu.intern_pool;
380 const file = zcu.fileByIndex(file_index);
381 const extended = file.zir.instructions.items(.data)[@intFromEnum(Zir.Inst.Index.main_struct_inst)].extended;
382 assert(extended.opcode == .struct_decl);
383 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
384 assert(!small.has_captures_len);
385 assert(!small.has_backing_int);
386 assert(small.layout == .auto);
387 var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len;
388 const fields_len = if (small.has_fields_len) blk: {
389 const fields_len = file.zir.extra[extra_index];
390 extra_index += 1;
391 break :blk fields_len;
392 } else 0;
393 const decls_len = if (small.has_decls_len) blk: {
394 const decls_len = file.zir.extra[extra_index];
395 extra_index += 1;
396 break :blk decls_len;
397 } else 0;
398 const decls = file.zir.bodySlice(extra_index, decls_len);
399 extra_index += decls_len;
400
401 const tracked_inst = try ip.trackZir(gpa, file_index, .main_struct_inst);
402 const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{
403 .layout = .auto,
404 .fields_len = fields_len,
405 .known_non_opv = small.known_non_opv,
406 .requires_comptime = if (small.known_comptime_only) .yes else .unknown,
407 .is_tuple = small.is_tuple,
408 .any_comptime_fields = small.any_comptime_fields,
409 .any_default_inits = small.any_default_inits,
410 .inits_resolved = false,
411 .any_aligned_fields = small.any_aligned_fields,
412 .has_namespace = true,
413 .key = .{ .declared = .{
414 .zir_index = tracked_inst,
415 .captures = &.{},
416 } },
417 })) {
418 .existing => unreachable, // we wouldn't be analysing the file root if this type existed
419 .wip => |wip| wip,
420 };
421 errdefer wip_ty.cancel(ip);
422
423 if (zcu.comp.debug_incremental) {
424 try ip.addDependency(
425 gpa,
426 InternPool.AnalUnit.wrap(.{ .decl = decl_index }),
427 .{ .src_hash = tracked_inst },
428 );
429 }
430
431 const decl = zcu.declPtr(decl_index);
432 decl.val = Value.fromInterned(wip_ty.index);
433 decl.has_tv = true;
434 decl.owns_tv = true;
435 decl.analysis = .complete;
436
437 try zcu.scanNamespace(namespace_index, decls, decl);
438 try zcu.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
439 return wip_ty.finish(ip, decl_index, namespace_index.toOptional());
440}
441
442/// Re-analyze the root Decl of a file on an incremental update.
443/// If `type_outdated`, the struct type itself is considered outdated and is
444/// reconstructed at a new InternPool index. Otherwise, the namespace is just
445/// re-analyzed. Returns whether the decl's tyval was invalidated.
446fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated: bool) Zcu.SemaError!bool {
447 const zcu = pt.zcu;
448 const ip = &zcu.intern_pool;
449 const file = zcu.fileByIndex(file_index);
450 const decl = zcu.declPtr(zcu.fileRootDecl(file_index).unwrap().?);
451
452 log.debug("semaFileUpdate mod={s} sub_file_path={s} type_outdated={}", .{
453 file.mod.fully_qualified_name,
454 file.sub_file_path,
455 type_outdated,
456 });
457
458 if (file.status != .success_zir) {
459 if (decl.analysis == .file_failure) {
460 return false;
461 } else {
462 decl.analysis = .file_failure;
463 return true;
464 }
465 }
466
467 if (decl.analysis == .file_failure) {
468 // No struct type currently exists. Create one!
469 const root_decl = zcu.fileRootDecl(file_index);
470 _ = try pt.getFileRootStruct(root_decl.unwrap().?, decl.src_namespace, file_index);
471 return true;
472 }
473
474 assert(decl.has_tv);
475 assert(decl.owns_tv);
476
477 if (type_outdated) {
478 // Invalidate the existing type, reusing the decl and namespace.
479 const file_root_decl = zcu.fileRootDecl(file_index).unwrap().?;
480 ip.removeDependenciesForDepender(zcu.gpa, InternPool.AnalUnit.wrap(.{
481 .decl = file_root_decl,
482 }));
483 ip.remove(decl.val.toIntern());
484 decl.val = undefined;
485 _ = try pt.getFileRootStruct(file_root_decl, decl.src_namespace, file_index);
486 return true;
487 }
488
489 // Only the struct's namespace is outdated.
490 // Preserve the type - just scan the namespace again.
491
492 const extended = file.zir.instructions.items(.data)[@intFromEnum(Zir.Inst.Index.main_struct_inst)].extended;
493 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
494
495 var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len;
496 extra_index += @intFromBool(small.has_fields_len);
497 const decls_len = if (small.has_decls_len) blk: {
498 const decls_len = file.zir.extra[extra_index];
499 extra_index += 1;
500 break :blk decls_len;
501 } else 0;
502 const decls = file.zir.bodySlice(extra_index, decls_len);
503
504 if (!type_outdated) {
505 try zcu.scanNamespace(decl.src_namespace, decls, decl);
506 }
507
508 return false;
509}
510
511/// Regardless of the file status, will create a `Decl` if none exists so that we can track
512/// dependencies and re-analyze when the file becomes outdated.
513fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
514 const tracy = trace(@src());
515 defer tracy.end();
516
517 const zcu = pt.zcu;
518 const gpa = zcu.gpa;
519 const file = zcu.fileByIndex(file_index);
520 assert(zcu.fileRootDecl(file_index) == .none);
521 log.debug("semaFile zcu={s} sub_file_path={s}", .{
522 file.mod.fully_qualified_name, file.sub_file_path,
523 });
524
525 // Because these three things each reference each other, `undefined`
526 // placeholders are used before being set after the struct type gains an
527 // InternPool index.
528 const new_namespace_index = try zcu.createNamespace(.{
529 .parent = .none,
530 .decl_index = undefined,
531 .file_scope = file_index,
532 });
533 errdefer zcu.destroyNamespace(new_namespace_index);
534
535 const new_decl_index = try zcu.allocateNewDecl(new_namespace_index);
536 const new_decl = zcu.declPtr(new_decl_index);
537 errdefer @panic("TODO error handling");
538
539 zcu.setFileRootDecl(file_index, new_decl_index.toOptional());
540 zcu.namespacePtr(new_namespace_index).decl_index = new_decl_index;
541
542 new_decl.name = try file.fullyQualifiedName(zcu);
543 new_decl.name_fully_qualified = true;
544 new_decl.is_pub = true;
545 new_decl.is_exported = false;
546 new_decl.alignment = .none;
547 new_decl.@"linksection" = .none;
548 new_decl.analysis = .in_progress;
549
550 if (file.status != .success_zir) {
551 new_decl.analysis = .file_failure;
552 return;
553 }
554 assert(file.zir_loaded);
555
556 const struct_ty = try pt.getFileRootStruct(new_decl_index, new_namespace_index, file_index);
557 errdefer zcu.intern_pool.remove(struct_ty);
558
559 switch (zcu.comp.cache_use) {
560 .whole => |whole| if (whole.cache_manifest) |man| {
561 const source = file.getSource(gpa) catch |err| {
562 try Zcu.reportRetryableFileError(zcu, file_index, "unable to load source: {s}", .{@errorName(err)});
563 return error.AnalysisFail;
564 };
565
566 const resolved_path = std.fs.path.resolve(gpa, &.{
567 file.mod.root.root_dir.path orelse ".",
568 file.mod.root.sub_path,
569 file.sub_file_path,
570 }) catch |err| {
571 try Zcu.reportRetryableFileError(zcu, file_index, "unable to resolve path: {s}", .{@errorName(err)});
572 return error.AnalysisFail;
573 };
574 errdefer gpa.free(resolved_path);
575
576 whole.cache_manifest_mutex.lock();
577 defer whole.cache_manifest_mutex.unlock();
578 try man.addFilePostContents(resolved_path, source.bytes, source.stat);
579 },
580 .incremental => {},
581 }
582}
583
584fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
585 const tracy = trace(@src());
586 defer tracy.end();
587
588 const zcu = pt.zcu;
589 const decl = zcu.declPtr(decl_index);
590 const ip = &zcu.intern_pool;
591
592 if (decl.getFileScope(zcu).status != .success_zir) {
593 return error.AnalysisFail;
594 }
595
596 assert(!zcu.declIsRoot(decl_index));
597
598 if (decl.zir_decl_index == .none and decl.owns_tv) {
599 // We are re-analyzing an anonymous owner Decl (for a function or a namespace type).
600 return zcu.semaAnonOwnerDecl(decl_index);
601 }
602
603 log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)});
604 log.debug("decl name '{}'", .{(try decl.fullyQualifiedName(zcu)).fmt(ip)});
605 defer blk: {
606 log.debug("finish decl name '{}'", .{(decl.fullyQualifiedName(zcu) catch break :blk).fmt(ip)});
607 }
608
609 const old_has_tv = decl.has_tv;
610 // The following values are ignored if `!old_has_tv`
611 const old_ty = if (old_has_tv) decl.typeOf(zcu) else undefined;
612 const old_val = decl.val;
613 const old_align = decl.alignment;
614 const old_linksection = decl.@"linksection";
615 const old_addrspace = decl.@"addrspace";
616 const old_is_inline = if (decl.getOwnedFunction(zcu)) |prev_func|
617 prev_func.analysis(ip).state == .inline_only
618 else
619 false;
620
621 const decl_inst = decl.zir_decl_index.unwrap().?.resolve(ip);
622
623 const gpa = zcu.gpa;
624 const zir = decl.getFileScope(zcu).zir;
625
626 const builtin_type_target_index: InternPool.Index = ip_index: {
627 const std_mod = zcu.std_mod;
628 if (decl.getFileScope(zcu).mod != std_mod) break :ip_index .none;
629 // We're in the std module.
630 const std_file_imported = try zcu.importPkg(std_mod);
631 const std_file_root_decl_index = zcu.fileRootDecl(std_file_imported.file_index);
632 const std_decl = zcu.declPtr(std_file_root_decl_index.unwrap().?);
633 const std_namespace = std_decl.getInnerNamespace(zcu).?;
634 const builtin_str = try ip.getOrPutString(gpa, "builtin", .no_embedded_nulls);
635 const builtin_decl = zcu.declPtr(std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse break :ip_index .none);
636 const builtin_namespace = builtin_decl.getInnerNamespaceIndex(zcu).unwrap() orelse break :ip_index .none;
637 if (decl.src_namespace != builtin_namespace) break :ip_index .none;
638 // We're in builtin.zig. This could be a builtin we need to add to a specific InternPool index.
639 for ([_][]const u8{
640 "AtomicOrder",
641 "AtomicRmwOp",
642 "CallingConvention",
643 "AddressSpace",
644 "FloatMode",
645 "ReduceOp",
646 "CallModifier",
647 "PrefetchOptions",
648 "ExportOptions",
649 "ExternOptions",
650 "Type",
651 }, [_]InternPool.Index{
652 .atomic_order_type,
653 .atomic_rmw_op_type,
654 .calling_convention_type,
655 .address_space_type,
656 .float_mode_type,
657 .reduce_op_type,
658 .call_modifier_type,
659 .prefetch_options_type,
660 .export_options_type,
661 .extern_options_type,
662 .type_info_type,
663 }) |type_name, type_ip| {
664 if (decl.name.eqlSlice(type_name, ip)) break :ip_index type_ip;
665 }
666 break :ip_index .none;
667 };
668
669 zcu.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));
670
671 decl.analysis = .in_progress;
672
673 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
674 defer analysis_arena.deinit();
675
676 var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa);
677 defer comptime_err_ret_trace.deinit();
678
679 var sema: Sema = .{
680 .pt = pt,
681 .gpa = gpa,
682 .arena = analysis_arena.allocator(),
683 .code = zir,
684 .owner_decl = decl,
685 .owner_decl_index = decl_index,
686 .func_index = .none,
687 .func_is_naked = false,
688 .fn_ret_ty = Type.void,
689 .fn_ret_ty_ies = null,
690 .owner_func_index = .none,
691 .comptime_err_ret_trace = &comptime_err_ret_trace,
692 .builtin_type_target_index = builtin_type_target_index,
693 };
694 defer sema.deinit();
695
696 // Every Decl (other than file root Decls, which do not have a ZIR index) has a dependency on its own source.
697 try sema.declareDependency(.{ .src_hash = try ip.trackZir(
698 gpa,
699 decl.getFileScopeIndex(zcu),
700 decl_inst,
701 ) });
702
703 var block_scope: Sema.Block = .{
704 .parent = null,
705 .sema = &sema,
706 .namespace = decl.src_namespace,
707 .instructions = .{},
708 .inlining = null,
709 .is_comptime = true,
710 .src_base_inst = decl.zir_decl_index.unwrap().?,
711 .type_name_ctx = decl.name,
712 };
713 defer block_scope.instructions.deinit(gpa);
714
715 const decl_bodies = decl.zirBodies(zcu);
716
717 const result_ref = try sema.resolveInlineBody(&block_scope, decl_bodies.value_body, decl_inst);
718 // We'll do some other bits with the Sema. Clear the type target index just
719 // in case they analyze any type.
720 sema.builtin_type_target_index = .none;
721 const align_src = block_scope.src(.{ .node_offset_var_decl_align = 0 });
722 const section_src = block_scope.src(.{ .node_offset_var_decl_section = 0 });
723 const address_space_src = block_scope.src(.{ .node_offset_var_decl_addrspace = 0 });
724 const ty_src = block_scope.src(.{ .node_offset_var_decl_ty = 0 });
725 const init_src = block_scope.src(.{ .node_offset_var_decl_init = 0 });
726 const decl_val = try sema.resolveFinalDeclValue(&block_scope, init_src, result_ref);
727 const decl_ty = decl_val.typeOf(zcu);
728
729 // Note this resolves the type of the Decl, not the value; if this Decl
730 // is a struct, for example, this resolves `type` (which needs no resolution),
731 // not the struct itself.
732 try decl_ty.resolveLayout(pt);
733
734 if (decl.kind == .@"usingnamespace") {
735 if (!decl_ty.eql(Type.type, zcu)) {
736 return sema.fail(&block_scope, ty_src, "expected type, found {}", .{decl_ty.fmt(pt)});
737 }
738 const ty = decl_val.toType();
739 if (ty.getNamespace(zcu) == null) {
740 return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(pt)});
741 }
742
743 decl.val = ty.toValue();
744 decl.alignment = .none;
745 decl.@"linksection" = .none;
746 decl.has_tv = true;
747 decl.owns_tv = false;
748 decl.analysis = .complete;
749
750 // TODO: usingnamespace cannot currently participate in incremental compilation
751 return .{
752 .invalidate_decl_val = true,
753 .invalidate_decl_ref = true,
754 };
755 }
756
757 var queue_linker_work = true;
758 var is_func = false;
759 var is_inline = false;
760 switch (decl_val.toIntern()) {
761 .generic_poison => unreachable,
762 .unreachable_value => unreachable,
763 else => switch (ip.indexToKey(decl_val.toIntern())) {
764 .variable => |variable| {
765 decl.owns_tv = variable.decl == decl_index;
766 queue_linker_work = decl.owns_tv;
767 },
768
769 .extern_func => |extern_func| {
770 decl.owns_tv = extern_func.decl == decl_index;
771 queue_linker_work = decl.owns_tv;
772 is_func = decl.owns_tv;
773 },
774
775 .func => |func| {
776 decl.owns_tv = func.owner_decl == decl_index;
777 queue_linker_work = false;
778 is_inline = decl.owns_tv and decl_ty.fnCallingConvention(zcu) == .Inline;
779 is_func = decl.owns_tv;
780 },
781
782 else => {},
783 },
784 }
785
786 decl.val = decl_val;
787 // Function linksection, align, and addrspace were already set by Sema
788 if (!is_func) {
789 decl.alignment = blk: {
790 const align_body = decl_bodies.align_body orelse break :blk .none;
791 const align_ref = try sema.resolveInlineBody(&block_scope, align_body, decl_inst);
792 break :blk try sema.analyzeAsAlign(&block_scope, align_src, align_ref);
793 };
794 decl.@"linksection" = blk: {
795 const linksection_body = decl_bodies.linksection_body orelse break :blk .none;
796 const linksection_ref = try sema.resolveInlineBody(&block_scope, linksection_body, decl_inst);
797 const bytes = try sema.toConstString(&block_scope, section_src, linksection_ref, .{
798 .needed_comptime_reason = "linksection must be comptime-known",
799 });
800 if (std.mem.indexOfScalar(u8, bytes, 0) != null) {
801 return sema.fail(&block_scope, section_src, "linksection cannot contain null bytes", .{});
802 } else if (bytes.len == 0) {
803 return sema.fail(&block_scope, section_src, "linksection cannot be empty", .{});
804 }
805 break :blk try ip.getOrPutStringOpt(gpa, bytes, .no_embedded_nulls);
806 };
807 decl.@"addrspace" = blk: {
808 const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_val.toIntern())) {
809 .variable => .variable,
810 .extern_func, .func => .function,
811 else => .constant,
812 };
813
814 const target = zcu.getTarget();
815
816 const addrspace_body = decl_bodies.addrspace_body orelse break :blk switch (addrspace_ctx) {
817 .function => target_util.defaultAddressSpace(target, .function),
818 .variable => target_util.defaultAddressSpace(target, .global_mutable),
819 .constant => target_util.defaultAddressSpace(target, .global_constant),
820 else => unreachable,
821 };
822 const addrspace_ref = try sema.resolveInlineBody(&block_scope, addrspace_body, decl_inst);
823 break :blk try sema.analyzeAsAddressSpace(&block_scope, address_space_src, addrspace_ref, addrspace_ctx);
824 };
825 }
826 decl.has_tv = true;
827 decl.analysis = .complete;
828
829 const result: Zcu.SemaDeclResult = if (old_has_tv) .{
830 .invalidate_decl_val = !decl_ty.eql(old_ty, zcu) or
831 !decl.val.eql(old_val, decl_ty, zcu) or
832 is_inline != old_is_inline,
833 .invalidate_decl_ref = !decl_ty.eql(old_ty, zcu) or
834 decl.alignment != old_align or
835 decl.@"linksection" != old_linksection or
836 decl.@"addrspace" != old_addrspace or
837 is_inline != old_is_inline,
838 } else .{
839 .invalidate_decl_val = true,
840 .invalidate_decl_ref = true,
841 };
842
843 const has_runtime_bits = queue_linker_work and (is_func or try sema.typeHasRuntimeBits(decl_ty));
844 if (has_runtime_bits) {
845 // Needed for codegen_decl which will call updateDecl and then the
846 // codegen backend wants full access to the Decl Type.
847 try decl_ty.resolveFully(pt);
848
849 try zcu.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
850
851 if (result.invalidate_decl_ref and zcu.emit_h != null) {
852 try zcu.comp.work_queue.writeItem(.{ .emit_h_decl = decl_index });
853 }
854 }
855
856 if (decl.is_exported) {
857 const export_src = block_scope.src(.{ .token_offset = @intFromBool(decl.is_pub) });
858 if (is_inline) return sema.fail(&block_scope, export_src, "export of inline function", .{});
859 // The scope needs to have the decl in it.
860 try sema.analyzeExport(&block_scope, export_src, .{ .name = decl.name }, decl_index);
861 }
862
863 try sema.flushExports();
864
865 return result;
866}
867
868pub fn embedFile(
869 pt: Zcu.PerThread,
870 cur_file: *Zcu.File,
871 import_string: []const u8,
872 src_loc: Zcu.LazySrcLoc,
873) !InternPool.Index {
874 const mod = pt.zcu;
875 const gpa = mod.gpa;
876
877 if (cur_file.mod.deps.get(import_string)) |pkg| {
878 const resolved_path = try std.fs.path.resolve(gpa, &.{
879 pkg.root.root_dir.path orelse ".",
880 pkg.root.sub_path,
881 pkg.root_src_path,
882 });
883 var keep_resolved_path = false;
884 defer if (!keep_resolved_path) gpa.free(resolved_path);
885
886 const gop = try mod.embed_table.getOrPut(gpa, resolved_path);
887 errdefer {
888 assert(std.mem.eql(u8, mod.embed_table.pop().key, resolved_path));
889 keep_resolved_path = false;
890 }
891 if (gop.found_existing) return gop.value_ptr.*.val;
892 keep_resolved_path = true;
893
894 const sub_file_path = try gpa.dupe(u8, pkg.root_src_path);
895 errdefer gpa.free(sub_file_path);
896
897 return pt.newEmbedFile(pkg, sub_file_path, resolved_path, gop.value_ptr, src_loc);
898 }
899
900 // The resolved path is used as the key in the table, to detect if a file
901 // refers to the same as another, despite different relative paths.
902 const resolved_path = try std.fs.path.resolve(gpa, &.{
903 cur_file.mod.root.root_dir.path orelse ".",
904 cur_file.mod.root.sub_path,
905 cur_file.sub_file_path,
906 "..",
907 import_string,
908 });
909
910 var keep_resolved_path = false;
911 defer if (!keep_resolved_path) gpa.free(resolved_path);
912
913 const gop = try mod.embed_table.getOrPut(gpa, resolved_path);
914 errdefer {
915 assert(std.mem.eql(u8, mod.embed_table.pop().key, resolved_path));
916 keep_resolved_path = false;
917 }
918 if (gop.found_existing) return gop.value_ptr.*.val;
919 keep_resolved_path = true;
920
921 const resolved_root_path = try std.fs.path.resolve(gpa, &.{
922 cur_file.mod.root.root_dir.path orelse ".",
923 cur_file.mod.root.sub_path,
924 });
925 defer gpa.free(resolved_root_path);
926
927 const sub_file_path = p: {
928 const relative = try std.fs.path.relative(gpa, resolved_root_path, resolved_path);
929 errdefer gpa.free(relative);
930
931 if (!isUpDir(relative) and !std.fs.path.isAbsolute(relative)) {
932 break :p relative;
933 }
934 return error.ImportOutsideModulePath;
935 };
936 defer gpa.free(sub_file_path);
937
938 return pt.newEmbedFile(cur_file.mod, sub_file_path, resolved_path, gop.value_ptr, src_loc);
939}
940
941/// Finalize the creation of an anon decl.
942pub fn finalizeAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Allocator.Error!void {
943 if (pt.zcu.declPtr(decl_index).typeOf(pt.zcu).isFnOrHasRuntimeBits(pt)) {
944 try pt.zcu.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
945 }
946}
947
948/// https://github.com/ziglang/zig/issues/14307
949fn newEmbedFile(
950 pt: Zcu.PerThread,
951 pkg: *Module,
952 sub_file_path: []const u8,
953 resolved_path: []const u8,
954 result: **Zcu.EmbedFile,
955 src_loc: Zcu.LazySrcLoc,
956) !InternPool.Index {
957 const mod = pt.zcu;
958 const gpa = mod.gpa;
959 const ip = &mod.intern_pool;
960
961 const new_file = try gpa.create(Zcu.EmbedFile);
962 errdefer gpa.destroy(new_file);
963
964 var file = try pkg.root.openFile(sub_file_path, .{});
965 defer file.close();
966
967 const actual_stat = try file.stat();
968 const stat: Cache.File.Stat = .{
969 .size = actual_stat.size,
970 .inode = actual_stat.inode,
971 .mtime = actual_stat.mtime,
972 };
973 const size = std.math.cast(usize, actual_stat.size) orelse return error.Overflow;
974
975 const bytes = try ip.string_bytes.addManyAsSlice(gpa, try std.math.add(usize, size, 1));
976 const actual_read = try file.readAll(bytes[0..size]);
977 if (actual_read != size) return error.UnexpectedEndOfFile;
978 bytes[size] = 0;
979
980 const comp = mod.comp;
981 switch (comp.cache_use) {
982 .whole => |whole| if (whole.cache_manifest) |man| {
983 const copied_resolved_path = try gpa.dupe(u8, resolved_path);
984 errdefer gpa.free(copied_resolved_path);
985 whole.cache_manifest_mutex.lock();
986 defer whole.cache_manifest_mutex.unlock();
987 try man.addFilePostContents(copied_resolved_path, bytes[0..size], stat);
988 },
989 .incremental => {},
990 }
991
992 const array_ty = try pt.intern(.{ .array_type = .{
993 .len = size,
994 .sentinel = .zero_u8,
995 .child = .u8_type,
996 } });
997 const array_val = try pt.intern(.{ .aggregate = .{
998 .ty = array_ty,
999 .storage = .{ .bytes = try ip.getOrPutTrailingString(gpa, bytes.len, .maybe_embedded_nulls) },
1000 } });
1001
1002 const ptr_ty = (try pt.ptrType(.{
1003 .child = array_ty,
1004 .flags = .{
1005 .alignment = .none,
1006 .is_const = true,
1007 .address_space = .generic,
1008 },
1009 })).toIntern();
1010 const ptr_val = try pt.intern(.{ .ptr = .{
1011 .ty = ptr_ty,
1012 .base_addr = .{ .anon_decl = .{
1013 .val = array_val,
1014 .orig_ty = ptr_ty,
1015 } },
1016 .byte_offset = 0,
1017 } });
1018
1019 result.* = new_file;
1020 new_file.* = .{
1021 .sub_file_path = try ip.getOrPutString(gpa, sub_file_path, .no_embedded_nulls),
1022 .owner = pkg,
1023 .stat = stat,
1024 .val = ptr_val,
1025 .src_loc = src_loc,
1026 };
1027 return ptr_val;
1028}
1029
1030pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: Allocator) Zcu.SemaError!Air {
1031 const tracy = trace(@src());
1032 defer tracy.end();
1033
1034 const mod = pt.zcu;
1035 const gpa = mod.gpa;
1036 const ip = &mod.intern_pool;
1037 const func = mod.funcInfo(func_index);
1038 const decl_index = func.owner_decl;
1039 const decl = mod.declPtr(decl_index);
1040
1041 log.debug("func name '{}'", .{(try decl.fullyQualifiedName(mod)).fmt(ip)});
1042 defer blk: {
1043 log.debug("finish func name '{}'", .{(decl.fullyQualifiedName(mod) catch break :blk).fmt(ip)});
1044 }
1045
1046 const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(mod)).toSlice(ip), 0);
1047 defer decl_prog_node.end();
1048
1049 mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));
1050
1051 var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa);
1052 defer comptime_err_ret_trace.deinit();
1053
1054 // In the case of a generic function instance, this is the type of the
1055 // instance, which has comptime parameters elided. In other words, it is
1056 // the runtime-known parameters only, not to be confused with the
1057 // generic_owner function type, which potentially has more parameters,
1058 // including comptime parameters.
1059 const fn_ty = decl.typeOf(mod);
1060 const fn_ty_info = mod.typeToFunc(fn_ty).?;
1061
1062 var sema: Sema = .{
1063 .pt = pt,
1064 .gpa = gpa,
1065 .arena = arena,
1066 .code = decl.getFileScope(mod).zir,
1067 .owner_decl = decl,
1068 .owner_decl_index = decl_index,
1069 .func_index = func_index,
1070 .func_is_naked = fn_ty_info.cc == .Naked,
1071 .fn_ret_ty = Type.fromInterned(fn_ty_info.return_type),
1072 .fn_ret_ty_ies = null,
1073 .owner_func_index = func_index,
1074 .branch_quota = @max(func.branchQuota(ip).*, Sema.default_branch_quota),
1075 .comptime_err_ret_trace = &comptime_err_ret_trace,
1076 };
1077 defer sema.deinit();
1078
1079 // Every runtime function has a dependency on the source of the Decl it originates from.
1080 // It also depends on the value of its owner Decl.
1081 try sema.declareDependency(.{ .src_hash = decl.zir_decl_index.unwrap().? });
1082 try sema.declareDependency(.{ .decl_val = decl_index });
1083
1084 if (func.analysis(ip).inferred_error_set) {
1085 const ies = try arena.create(Sema.InferredErrorSet);
1086 ies.* = .{ .func = func_index };
1087 sema.fn_ret_ty_ies = ies;
1088 }
1089
1090 // reset in case calls to errorable functions are removed.
1091 func.analysis(ip).calls_or_awaits_errorable_fn = false;
1092
1093 // First few indexes of extra are reserved and set at the end.
1094 const reserved_count = @typeInfo(Air.ExtraIndex).Enum.fields.len;
1095 try sema.air_extra.ensureTotalCapacity(gpa, reserved_count);
1096 sema.air_extra.items.len += reserved_count;
1097
1098 var inner_block: Sema.Block = .{
1099 .parent = null,
1100 .sema = &sema,
1101 .namespace = decl.src_namespace,
1102 .instructions = .{},
1103 .inlining = null,
1104 .is_comptime = false,
1105 .src_base_inst = inst: {
1106 const owner_info = if (func.generic_owner == .none)
1107 func
1108 else
1109 mod.funcInfo(func.generic_owner);
1110 const orig_decl = mod.declPtr(owner_info.owner_decl);
1111 break :inst orig_decl.zir_decl_index.unwrap().?;
1112 },
1113 .type_name_ctx = decl.name,
1114 };
1115 defer inner_block.instructions.deinit(gpa);
1116
1117 const fn_info = sema.code.getFnInfo(func.zirBodyInst(ip).resolve(ip));
1118
1119 // Here we are performing "runtime semantic analysis" for a function body, which means
1120 // we must map the parameter ZIR instructions to `arg` AIR instructions.
1121 // AIR requires the `arg` parameters to be the first N instructions.
1122 // This could be a generic function instantiation, however, in which case we need to
1123 // map the comptime parameters to constant values and only emit arg AIR instructions
1124 // for the runtime ones.
1125 const runtime_params_len = fn_ty_info.param_types.len;
1126 try inner_block.instructions.ensureTotalCapacityPrecise(gpa, runtime_params_len);
1127 try sema.air_instructions.ensureUnusedCapacity(gpa, fn_info.total_params_len);
1128 try sema.inst_map.ensureSpaceForInstructions(gpa, fn_info.param_body);
1129
1130 // In the case of a generic function instance, pre-populate all the comptime args.
1131 if (func.comptime_args.len != 0) {
1132 for (
1133 fn_info.param_body[0..func.comptime_args.len],
1134 func.comptime_args.get(ip),
1135 ) |inst, comptime_arg| {
1136 if (comptime_arg == .none) continue;
1137 sema.inst_map.putAssumeCapacityNoClobber(inst, Air.internedToRef(comptime_arg));
1138 }
1139 }
1140
1141 const src_params_len = if (func.comptime_args.len != 0)
1142 func.comptime_args.len
1143 else
1144 runtime_params_len;
1145
1146 var runtime_param_index: usize = 0;
1147 for (fn_info.param_body[0..src_params_len], 0..) |inst, src_param_index| {
1148 const gop = sema.inst_map.getOrPutAssumeCapacity(inst);
1149 if (gop.found_existing) continue; // provided above by comptime arg
1150
1151 const param_ty = fn_ty_info.param_types.get(ip)[runtime_param_index];
1152 runtime_param_index += 1;
1153
1154 const opt_opv = sema.typeHasOnePossibleValue(Type.fromInterned(param_ty)) catch |err| switch (err) {
1155 error.GenericPoison => unreachable,
1156 error.ComptimeReturn => unreachable,
1157 error.ComptimeBreak => unreachable,
1158 else => |e| return e,
1159 };
1160 if (opt_opv) |opv| {
1161 gop.value_ptr.* = Air.internedToRef(opv.toIntern());
1162 continue;
1163 }
1164 const arg_index: Air.Inst.Index = @enumFromInt(sema.air_instructions.len);
1165 gop.value_ptr.* = arg_index.toRef();
1166 inner_block.instructions.appendAssumeCapacity(arg_index);
1167 sema.air_instructions.appendAssumeCapacity(.{
1168 .tag = .arg,
1169 .data = .{ .arg = .{
1170 .ty = Air.internedToRef(param_ty),
1171 .src_index = @intCast(src_param_index),
1172 } },
1173 });
1174 }
1175
1176 func.analysis(ip).state = .in_progress;
1177
1178 const last_arg_index = inner_block.instructions.items.len;
1179
1180 // Save the error trace as our first action in the function.
1181 // If this is unnecessary after all, Liveness will clean it up for us.
1182 const error_return_trace_index = try sema.analyzeSaveErrRetIndex(&inner_block);
1183 sema.error_return_trace_index_on_fn_entry = error_return_trace_index;
1184 inner_block.error_return_trace_index = error_return_trace_index;
1185
1186 sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) {
1187 // TODO make these unreachable instead of @panic
1188 error.GenericPoison => @panic("zig compiler bug: GenericPoison"),
1189 error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"),
1190 else => |e| return e,
1191 };
1192
1193 for (sema.unresolved_inferred_allocs.keys()) |ptr_inst| {
1194 // The lack of a resolve_inferred_alloc means that this instruction
1195 // is unused so it just has to be a no-op.
1196 sema.air_instructions.set(@intFromEnum(ptr_inst), .{
1197 .tag = .alloc,
1198 .data = .{ .ty = Type.single_const_pointer_to_comptime_int },
1199 });
1200 }
1201
1202 // If we don't get an error return trace from a caller, create our own.
1203 if (func.analysis(ip).calls_or_awaits_errorable_fn and
1204 mod.comp.config.any_error_tracing and
1205 !sema.fn_ret_ty.isError(mod))
1206 {
1207 sema.setupErrorReturnTrace(&inner_block, last_arg_index) catch |err| switch (err) {
1208 // TODO make these unreachable instead of @panic
1209 error.GenericPoison => @panic("zig compiler bug: GenericPoison"),
1210 error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"),
1211 error.ComptimeBreak => @panic("zig compiler bug: ComptimeBreak"),
1212 else => |e| return e,
1213 };
1214 }
1215
1216 // Copy the block into place and mark that as the main block.
1217 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len +
1218 inner_block.instructions.items.len);
1219 const main_block_index = sema.addExtraAssumeCapacity(Air.Block{
1220 .body_len = @intCast(inner_block.instructions.items.len),
1221 });
1222 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(inner_block.instructions.items));
1223 sema.air_extra.items[@intFromEnum(Air.ExtraIndex.main_block)] = main_block_index;
1224
1225 // Resolving inferred error sets is done *before* setting the function
1226 // state to success, so that "unable to resolve inferred error set" errors
1227 // can be emitted here.
1228 if (sema.fn_ret_ty_ies) |ies| {
1229 sema.resolveInferredErrorSetPtr(&inner_block, .{
1230 .base_node_inst = inner_block.src_base_inst,
1231 .offset = Zcu.LazySrcLoc.Offset.nodeOffset(0),
1232 }, ies) catch |err| switch (err) {
1233 error.GenericPoison => unreachable,
1234 error.ComptimeReturn => unreachable,
1235 error.ComptimeBreak => unreachable,
1236 error.AnalysisFail => {
1237 // In this case our function depends on a type that had a compile error.
1238 // We should not try to lower this function.
1239 decl.analysis = .dependency_failure;
1240 return error.AnalysisFail;
1241 },
1242 else => |e| return e,
1243 };
1244 assert(ies.resolved != .none);
1245 ip.funcIesResolved(func_index).* = ies.resolved;
1246 }
1247
1248 func.analysis(ip).state = .success;
1249
1250 // Finally we must resolve the return type and parameter types so that backends
1251 // have full access to type information.
1252 // Crucially, this happens *after* we set the function state to success above,
1253 // so that dependencies on the function body will now be satisfied rather than
1254 // result in circular dependency errors.
1255 sema.resolveFnTypes(fn_ty) catch |err| switch (err) {
1256 error.GenericPoison => unreachable,
1257 error.ComptimeReturn => unreachable,
1258 error.ComptimeBreak => unreachable,
1259 error.AnalysisFail => {
1260 // In this case our function depends on a type that had a compile error.
1261 // We should not try to lower this function.
1262 decl.analysis = .dependency_failure;
1263 return error.AnalysisFail;
1264 },
1265 else => |e| return e,
1266 };
1267
1268 try sema.flushExports();
1269
1270 return .{
1271 .instructions = sema.air_instructions.toOwnedSlice(),
1272 .extra = try sema.air_extra.toOwnedSlice(gpa),
1273 };
1274}
1275
1276/// Called from `Compilation.update`, after everything is done, just before
1277/// reporting compile errors. In this function we emit exported symbol collision
1278/// errors and communicate exported symbols to the linker backend.
1279pub fn processExports(pt: Zcu.PerThread) !void {
1280 const zcu = pt.zcu;
1281 const gpa = zcu.gpa;
1282
1283 // First, construct a mapping of every exported value and Decl to the indices of all its different exports.
1284 var decl_exports: std.AutoArrayHashMapUnmanaged(Zcu.Decl.Index, std.ArrayListUnmanaged(u32)) = .{};
1285 var value_exports: std.AutoArrayHashMapUnmanaged(InternPool.Index, std.ArrayListUnmanaged(u32)) = .{};
1286 defer {
1287 for (decl_exports.values()) |*exports| {
1288 exports.deinit(gpa);
1289 }
1290 decl_exports.deinit(gpa);
1291 for (value_exports.values()) |*exports| {
1292 exports.deinit(gpa);
1293 }
1294 value_exports.deinit(gpa);
1295 }
1296
1297 // We note as a heuristic:
1298 // * It is rare to export a value.
1299 // * It is rare for one Decl to be exported multiple times.
1300 // So, this ensureTotalCapacity serves as a reasonable (albeit very approximate) optimization.
1301 try decl_exports.ensureTotalCapacity(gpa, zcu.single_exports.count() + zcu.multi_exports.count());
1302
1303 for (zcu.single_exports.values()) |export_idx| {
1304 const exp = zcu.all_exports.items[export_idx];
1305 const value_ptr, const found_existing = switch (exp.exported) {
1306 .decl_index => |i| gop: {
1307 const gop = try decl_exports.getOrPut(gpa, i);
1308 break :gop .{ gop.value_ptr, gop.found_existing };
1309 },
1310 .value => |i| gop: {
1311 const gop = try value_exports.getOrPut(gpa, i);
1312 break :gop .{ gop.value_ptr, gop.found_existing };
1313 },
1314 };
1315 if (!found_existing) value_ptr.* = .{};
1316 try value_ptr.append(gpa, export_idx);
1317 }
1318
1319 for (zcu.multi_exports.values()) |info| {
1320 for (zcu.all_exports.items[info.index..][0..info.len], info.index..) |exp, export_idx| {
1321 const value_ptr, const found_existing = switch (exp.exported) {
1322 .decl_index => |i| gop: {
1323 const gop = try decl_exports.getOrPut(gpa, i);
1324 break :gop .{ gop.value_ptr, gop.found_existing };
1325 },
1326 .value => |i| gop: {
1327 const gop = try value_exports.getOrPut(gpa, i);
1328 break :gop .{ gop.value_ptr, gop.found_existing };
1329 },
1330 };
1331 if (!found_existing) value_ptr.* = .{};
1332 try value_ptr.append(gpa, @intCast(export_idx));
1333 }
1334 }
1335
1336 // Map symbol names to `Export` for name collision detection.
1337 var symbol_exports: SymbolExports = .{};
1338 defer symbol_exports.deinit(gpa);
1339
1340 for (decl_exports.keys(), decl_exports.values()) |exported_decl, exports_list| {
1341 const exported: Zcu.Exported = .{ .decl_index = exported_decl };
1342 try pt.processExportsInner(&symbol_exports, exported, exports_list.items);
1343 }
1344
1345 for (value_exports.keys(), value_exports.values()) |exported_value, exports_list| {
1346 const exported: Zcu.Exported = .{ .value = exported_value };
1347 try pt.processExportsInner(&symbol_exports, exported, exports_list.items);
1348 }
1349}
1350
1351const SymbolExports = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, u32);
1352
1353fn processExportsInner(
1354 pt: Zcu.PerThread,
1355 symbol_exports: *SymbolExports,
1356 exported: Zcu.Exported,
1357 export_indices: []const u32,
1358) error{OutOfMemory}!void {
1359 const zcu = pt.zcu;
1360 const gpa = zcu.gpa;
1361
1362 for (export_indices) |export_idx| {
1363 const new_export = &zcu.all_exports.items[export_idx];
1364 const gop = try symbol_exports.getOrPut(gpa, new_export.opts.name);
1365 if (gop.found_existing) {
1366 new_export.status = .failed_retryable;
1367 try zcu.failed_exports.ensureUnusedCapacity(gpa, 1);
1368 const msg = try Zcu.ErrorMsg.create(gpa, new_export.src, "exported symbol collision: {}", .{
1369 new_export.opts.name.fmt(&zcu.intern_pool),
1370 });
1371 errdefer msg.destroy(gpa);
1372 const other_export = zcu.all_exports.items[gop.value_ptr.*];
1373 try zcu.errNote(other_export.src, msg, "other symbol here", .{});
1374 zcu.failed_exports.putAssumeCapacityNoClobber(export_idx, msg);
1375 new_export.status = .failed;
1376 } else {
1377 gop.value_ptr.* = export_idx;
1378 }
1379 }
1380 if (zcu.comp.bin_file) |lf| {
1381 try zcu.handleUpdateExports(export_indices, lf.updateExports(pt, exported, export_indices));
1382 } else if (zcu.llvm_object) |llvm_object| {
1383 if (build_options.only_c) unreachable;
1384 try zcu.handleUpdateExports(export_indices, llvm_object.updateExports(pt, exported, export_indices));
1385 }
1386}
1387
1388pub fn populateTestFunctions(
1389 pt: Zcu.PerThread,
1390 main_progress_node: std.Progress.Node,
1391) !void {
1392 const zcu = pt.zcu;
1393 const gpa = zcu.gpa;
1394 const ip = &zcu.intern_pool;
1395 const builtin_mod = zcu.root_mod.getBuiltinDependency();
1396 const builtin_file_index = (zcu.importPkg(builtin_mod) catch unreachable).file_index;
1397 const root_decl_index = zcu.fileRootDecl(builtin_file_index);
1398 const root_decl = zcu.declPtr(root_decl_index.unwrap().?);
1399 const builtin_namespace = zcu.namespacePtr(root_decl.src_namespace);
1400 const test_functions_str = try ip.getOrPutString(gpa, "test_functions", .no_embedded_nulls);
1401 const decl_index = builtin_namespace.decls.getKeyAdapted(
1402 test_functions_str,
1403 Zcu.DeclAdapter{ .zcu = zcu },
1404 ).?;
1405 {
1406 // We have to call `ensureDeclAnalyzed` here in case `builtin.test_functions`
1407 // was not referenced by start code.
1408 zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);
1409 defer {
1410 zcu.sema_prog_node.end();
1411 zcu.sema_prog_node = undefined;
1412 }
1413 try pt.ensureDeclAnalyzed(decl_index);
1414 }
1415
1416 const decl = zcu.declPtr(decl_index);
1417 const test_fn_ty = decl.typeOf(zcu).slicePtrFieldType(zcu).childType(zcu);
1418
1419 const array_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = array: {
1420 // Add zcu.test_functions to an array decl then make the test_functions
1421 // decl reference it as a slice.
1422 const test_fn_vals = try gpa.alloc(InternPool.Index, zcu.test_functions.count());
1423 defer gpa.free(test_fn_vals);
1424
1425 for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_decl_index| {
1426 const test_decl = zcu.declPtr(test_decl_index);
1427 const test_decl_name = try test_decl.fullyQualifiedName(zcu);
1428 const test_decl_name_len = test_decl_name.length(ip);
1429 const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = n: {
1430 const test_name_ty = try pt.arrayType(.{
1431 .len = test_decl_name_len,
1432 .child = .u8_type,
1433 });
1434 const test_name_val = try pt.intern(.{ .aggregate = .{
1435 .ty = test_name_ty.toIntern(),
1436 .storage = .{ .bytes = test_decl_name.toString() },
1437 } });
1438 break :n .{
1439 .orig_ty = (try pt.singleConstPtrType(test_name_ty)).toIntern(),
1440 .val = test_name_val,
1441 };
1442 };
1443
1444 const test_fn_fields = .{
1445 // name
1446 try pt.intern(.{ .slice = .{
1447 .ty = .slice_const_u8_type,
1448 .ptr = try pt.intern(.{ .ptr = .{
1449 .ty = .manyptr_const_u8_type,
1450 .base_addr = .{ .anon_decl = test_name_anon_decl },
1451 .byte_offset = 0,
1452 } }),
1453 .len = try pt.intern(.{ .int = .{
1454 .ty = .usize_type,
1455 .storage = .{ .u64 = test_decl_name_len },
1456 } }),
1457 } }),
1458 // func
1459 try pt.intern(.{ .ptr = .{
1460 .ty = try pt.intern(.{ .ptr_type = .{
1461 .child = test_decl.typeOf(zcu).toIntern(),
1462 .flags = .{
1463 .is_const = true,
1464 },
1465 } }),
1466 .base_addr = .{ .decl = test_decl_index },
1467 .byte_offset = 0,
1468 } }),
1469 };
1470 test_fn_val.* = try pt.intern(.{ .aggregate = .{
1471 .ty = test_fn_ty.toIntern(),
1472 .storage = .{ .elems = &test_fn_fields },
1473 } });
1474 }
1475
1476 const array_ty = try pt.arrayType(.{
1477 .len = test_fn_vals.len,
1478 .child = test_fn_ty.toIntern(),
1479 .sentinel = .none,
1480 });
1481 const array_val = try pt.intern(.{ .aggregate = .{
1482 .ty = array_ty.toIntern(),
1483 .storage = .{ .elems = test_fn_vals },
1484 } });
1485 break :array .{
1486 .orig_ty = (try pt.singleConstPtrType(array_ty)).toIntern(),
1487 .val = array_val,
1488 };
1489 };
1490
1491 {
1492 const new_ty = try pt.ptrType(.{
1493 .child = test_fn_ty.toIntern(),
1494 .flags = .{
1495 .is_const = true,
1496 .size = .Slice,
1497 },
1498 });
1499 const new_val = decl.val;
1500 const new_init = try pt.intern(.{ .slice = .{
1501 .ty = new_ty.toIntern(),
1502 .ptr = try pt.intern(.{ .ptr = .{
1503 .ty = new_ty.slicePtrFieldType(zcu).toIntern(),
1504 .base_addr = .{ .anon_decl = array_anon_decl },
1505 .byte_offset = 0,
1506 } }),
1507 .len = (try pt.intValue(Type.usize, zcu.test_functions.count())).toIntern(),
1508 } });
1509 ip.mutateVarInit(decl.val.toIntern(), new_init);
1510
1511 // Since we are replacing the Decl's value we must perform cleanup on the
1512 // previous value.
1513 decl.val = new_val;
1514 decl.has_tv = true;
1515 }
1516 {
1517 zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0);
1518 defer {
1519 zcu.codegen_prog_node.end();
1520 zcu.codegen_prog_node = undefined;
1521 }
1522
1523 try pt.linkerUpdateDecl(decl_index);
1524 }
1525}
1526
1527pub fn linkerUpdateDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !void {
1528 const zcu = pt.zcu;
1529 const comp = zcu.comp;
1530
1531 const decl = zcu.declPtr(decl_index);
1532
1533 const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(zcu)).toSlice(&zcu.intern_pool), 0);
1534 defer codegen_prog_node.end();
1535
1536 if (comp.bin_file) |lf| {
1537 lf.updateDecl(pt, decl_index) catch |err| switch (err) {
1538 error.OutOfMemory => return error.OutOfMemory,
1539 error.AnalysisFail => {
1540 decl.analysis = .codegen_failure;
1541 },
1542 else => {
1543 const gpa = zcu.gpa;
1544 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
1545 zcu.failed_analysis.putAssumeCapacityNoClobber(InternPool.AnalUnit.wrap(.{ .decl = decl_index }), try Zcu.ErrorMsg.create(
1546 gpa,
1547 decl.navSrcLoc(zcu),
1548 "unable to codegen: {s}",
1549 .{@errorName(err)},
1550 ));
1551 decl.analysis = .codegen_failure;
1552 try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));
1553 },
1554 };
1555 } else if (zcu.llvm_object) |llvm_object| {
1556 if (build_options.only_c) unreachable;
1557 llvm_object.updateDecl(pt, decl_index) catch |err| switch (err) {
1558 error.OutOfMemory => return error.OutOfMemory,
1559 };
1560 }
1561}
1562
1563/// Shortcut for calling `intern_pool.get`.
1564pub fn intern(pt: Zcu.PerThread, key: InternPool.Key) Allocator.Error!InternPool.Index {
1565 return pt.zcu.intern_pool.get(pt.zcu.gpa, pt.tid, key);
1566}
1567
1568/// Shortcut for calling `intern_pool.getCoerced`.
1569pub fn getCoerced(pt: Zcu.PerThread, val: Value, new_ty: Type) Allocator.Error!Value {
1570 return Value.fromInterned(try pt.zcu.intern_pool.getCoerced(pt.zcu.gpa, pt.tid, val.toIntern(), new_ty.toIntern()));
1571}
1572
1573pub fn intType(pt: Zcu.PerThread, signedness: std.builtin.Signedness, bits: u16) Allocator.Error!Type {
1574 return Type.fromInterned(try pt.intern(.{ .int_type = .{
1575 .signedness = signedness,
1576 .bits = bits,
1577 } }));
1578}
1579
1580pub fn errorIntType(pt: Zcu.PerThread) std.mem.Allocator.Error!Type {
1581 return pt.intType(.unsigned, pt.zcu.errorSetBits());
1582}
1583
1584pub fn arrayType(pt: Zcu.PerThread, info: InternPool.Key.ArrayType) Allocator.Error!Type {
1585 return Type.fromInterned(try pt.intern(.{ .array_type = info }));
1586}
1587
1588pub fn vectorType(pt: Zcu.PerThread, info: InternPool.Key.VectorType) Allocator.Error!Type {
1589 return Type.fromInterned(try pt.intern(.{ .vector_type = info }));
1590}
1591
1592pub fn optionalType(pt: Zcu.PerThread, child_type: InternPool.Index) Allocator.Error!Type {
1593 return Type.fromInterned(try pt.intern(.{ .opt_type = child_type }));
1594}
1595
1596pub fn ptrType(pt: Zcu.PerThread, info: InternPool.Key.PtrType) Allocator.Error!Type {
1597 var canon_info = info;
1598
1599 if (info.flags.size == .C) canon_info.flags.is_allowzero = true;
1600
1601 // Canonicalize non-zero alignment. If it matches the ABI alignment of the pointee
1602 // type, we change it to 0 here. If this causes an assertion trip because the
1603 // pointee type needs to be resolved more, that needs to be done before calling
1604 // this ptr() function.
1605 if (info.flags.alignment != .none and
1606 info.flags.alignment == Type.fromInterned(info.child).abiAlignment(pt))
1607 {
1608 canon_info.flags.alignment = .none;
1609 }
1610
1611 switch (info.flags.vector_index) {
1612 // Canonicalize host_size. If it matches the bit size of the pointee type,
1613 // we change it to 0 here. If this causes an assertion trip, the pointee type
1614 // needs to be resolved before calling this ptr() function.
1615 .none => if (info.packed_offset.host_size != 0) {
1616 const elem_bit_size = Type.fromInterned(info.child).bitSize(pt);
1617 assert(info.packed_offset.bit_offset + elem_bit_size <= info.packed_offset.host_size * 8);
1618 if (info.packed_offset.host_size * 8 == elem_bit_size) {
1619 canon_info.packed_offset.host_size = 0;
1620 }
1621 },
1622 .runtime => {},
1623 _ => assert(@intFromEnum(info.flags.vector_index) < info.packed_offset.host_size),
1624 }
1625
1626 return Type.fromInterned(try pt.intern(.{ .ptr_type = canon_info }));
1627}
1628
1629/// Like `ptrType`, but if `info` specifies an `alignment`, first ensures the pointer
1630/// child type's alignment is resolved so that an invalid alignment is not used.
1631/// In general, prefer this function during semantic analysis.
1632pub fn ptrTypeSema(pt: Zcu.PerThread, info: InternPool.Key.PtrType) Zcu.SemaError!Type {
1633 if (info.flags.alignment != .none) {
1634 _ = try Type.fromInterned(info.child).abiAlignmentAdvanced(pt, .sema);
1635 }
1636 return pt.ptrType(info);
1637}
1638
1639pub fn singleMutPtrType(pt: Zcu.PerThread, child_type: Type) Allocator.Error!Type {
1640 return pt.ptrType(.{ .child = child_type.toIntern() });
1641}
1642
1643pub fn singleConstPtrType(pt: Zcu.PerThread, child_type: Type) Allocator.Error!Type {
1644 return pt.ptrType(.{
1645 .child = child_type.toIntern(),
1646 .flags = .{
1647 .is_const = true,
1648 },
1649 });
1650}
1651
1652pub fn manyConstPtrType(pt: Zcu.PerThread, child_type: Type) Allocator.Error!Type {
1653 return pt.ptrType(.{
1654 .child = child_type.toIntern(),
1655 .flags = .{
1656 .size = .Many,
1657 .is_const = true,
1658 },
1659 });
1660}
1661
1662pub fn adjustPtrTypeChild(pt: Zcu.PerThread, ptr_ty: Type, new_child: Type) Allocator.Error!Type {
1663 var info = ptr_ty.ptrInfo(pt.zcu);
1664 info.child = new_child.toIntern();
1665 return pt.ptrType(info);
1666}
1667
1668pub fn funcType(pt: Zcu.PerThread, key: InternPool.GetFuncTypeKey) Allocator.Error!Type {
1669 return Type.fromInterned(try pt.zcu.intern_pool.getFuncType(pt.zcu.gpa, pt.tid, key));
1670}
1671
1672/// Use this for `anyframe->T` only.
1673/// For `anyframe`, use the `InternPool.Index.anyframe` tag directly.
1674pub fn anyframeType(pt: Zcu.PerThread, payload_ty: Type) Allocator.Error!Type {
1675 return Type.fromInterned(try pt.intern(.{ .anyframe_type = payload_ty.toIntern() }));
1676}
1677
1678pub fn errorUnionType(pt: Zcu.PerThread, error_set_ty: Type, payload_ty: Type) Allocator.Error!Type {
1679 return Type.fromInterned(try pt.intern(.{ .error_union_type = .{
1680 .error_set_type = error_set_ty.toIntern(),
1681 .payload_type = payload_ty.toIntern(),
1682 } }));
1683}
1684
1685pub fn singleErrorSetType(pt: Zcu.PerThread, name: InternPool.NullTerminatedString) Allocator.Error!Type {
1686 const names: *const [1]InternPool.NullTerminatedString = &name;
1687 return Type.fromInterned(try pt.zcu.intern_pool.getErrorSetType(pt.zcu.gpa, pt.tid, names));
1688}
1689
1690/// Sorts `names` in place.
1691pub fn errorSetFromUnsortedNames(
1692 pt: Zcu.PerThread,
1693 names: []InternPool.NullTerminatedString,
1694) Allocator.Error!Type {
1695 std.mem.sort(
1696 InternPool.NullTerminatedString,
1697 names,
1698 {},
1699 InternPool.NullTerminatedString.indexLessThan,
1700 );
1701 const new_ty = try pt.zcu.intern_pool.getErrorSetType(pt.zcu.gpa, pt.tid, names);
1702 return Type.fromInterned(new_ty);
1703}
1704
1705/// Supports only pointers, not pointer-like optionals.
1706pub fn ptrIntValue(pt: Zcu.PerThread, ty: Type, x: u64) Allocator.Error!Value {
1707 const mod = pt.zcu;
1708 assert(ty.zigTypeTag(mod) == .Pointer and !ty.isSlice(mod));
1709 assert(x != 0 or ty.isAllowzeroPtr(mod));
1710 return Value.fromInterned(try pt.intern(.{ .ptr = .{
1711 .ty = ty.toIntern(),
1712 .base_addr = .int,
1713 .byte_offset = x,
1714 } }));
1715}
1716
1717/// Creates an enum tag value based on the integer tag value.
1718pub fn enumValue(pt: Zcu.PerThread, ty: Type, tag_int: InternPool.Index) Allocator.Error!Value {
1719 if (std.debug.runtime_safety) {
1720 const tag = ty.zigTypeTag(pt.zcu);
1721 assert(tag == .Enum);
1722 }
1723 return Value.fromInterned(try pt.intern(.{ .enum_tag = .{
1724 .ty = ty.toIntern(),
1725 .int = tag_int,
1726 } }));
1727}
1728
1729/// Creates an enum tag value based on the field index according to source code
1730/// declaration order.
1731pub fn enumValueFieldIndex(pt: Zcu.PerThread, ty: Type, field_index: u32) Allocator.Error!Value {
1732 const ip = &pt.zcu.intern_pool;
1733 const enum_type = ip.loadEnumType(ty.toIntern());
1734
1735 if (enum_type.values.len == 0) {
1736 // Auto-numbered fields.
1737 return Value.fromInterned(try pt.intern(.{ .enum_tag = .{
1738 .ty = ty.toIntern(),
1739 .int = try pt.intern(.{ .int = .{
1740 .ty = enum_type.tag_ty,
1741 .storage = .{ .u64 = field_index },
1742 } }),
1743 } }));
1744 }
1745
1746 return Value.fromInterned(try pt.intern(.{ .enum_tag = .{
1747 .ty = ty.toIntern(),
1748 .int = enum_type.values.get(ip)[field_index],
1749 } }));
1750}
1751
1752pub fn undefValue(pt: Zcu.PerThread, ty: Type) Allocator.Error!Value {
1753 return Value.fromInterned(try pt.intern(.{ .undef = ty.toIntern() }));
1754}
1755
1756pub fn undefRef(pt: Zcu.PerThread, ty: Type) Allocator.Error!Air.Inst.Ref {
1757 return Air.internedToRef((try pt.undefValue(ty)).toIntern());
1758}
1759
1760pub fn intValue(pt: Zcu.PerThread, ty: Type, x: anytype) Allocator.Error!Value {
1761 if (std.math.cast(u64, x)) |casted| return pt.intValue_u64(ty, casted);
1762 if (std.math.cast(i64, x)) |casted| return pt.intValue_i64(ty, casted);
1763 var limbs_buffer: [4]usize = undefined;
1764 var big_int = BigIntMutable.init(&limbs_buffer, x);
1765 return pt.intValue_big(ty, big_int.toConst());
1766}
1767
1768pub fn intRef(pt: Zcu.PerThread, ty: Type, x: anytype) Allocator.Error!Air.Inst.Ref {
1769 return Air.internedToRef((try pt.intValue(ty, x)).toIntern());
1770}
1771
1772pub fn intValue_big(pt: Zcu.PerThread, ty: Type, x: BigIntConst) Allocator.Error!Value {
1773 return Value.fromInterned(try pt.intern(.{ .int = .{
1774 .ty = ty.toIntern(),
1775 .storage = .{ .big_int = x },
1776 } }));
1777}
1778
1779pub fn intValue_u64(pt: Zcu.PerThread, ty: Type, x: u64) Allocator.Error!Value {
1780 return Value.fromInterned(try pt.intern(.{ .int = .{
1781 .ty = ty.toIntern(),
1782 .storage = .{ .u64 = x },
1783 } }));
1784}
1785
1786pub fn intValue_i64(pt: Zcu.PerThread, ty: Type, x: i64) Allocator.Error!Value {
1787 return Value.fromInterned(try pt.intern(.{ .int = .{
1788 .ty = ty.toIntern(),
1789 .storage = .{ .i64 = x },
1790 } }));
1791}
1792
1793pub fn unionValue(pt: Zcu.PerThread, union_ty: Type, tag: Value, val: Value) Allocator.Error!Value {
1794 return Value.fromInterned(try pt.intern(.{ .un = .{
1795 .ty = union_ty.toIntern(),
1796 .tag = tag.toIntern(),
1797 .val = val.toIntern(),
1798 } }));
1799}
1800
1801/// This function casts the float representation down to the representation of the type, potentially
1802/// losing data if the representation wasn't correct.
1803pub fn floatValue(pt: Zcu.PerThread, ty: Type, x: anytype) Allocator.Error!Value {
1804 const storage: InternPool.Key.Float.Storage = switch (ty.floatBits(pt.zcu.getTarget())) {
1805 16 => .{ .f16 = @as(f16, @floatCast(x)) },
1806 32 => .{ .f32 = @as(f32, @floatCast(x)) },
1807 64 => .{ .f64 = @as(f64, @floatCast(x)) },
1808 80 => .{ .f80 = @as(f80, @floatCast(x)) },
1809 128 => .{ .f128 = @as(f128, @floatCast(x)) },
1810 else => unreachable,
1811 };
1812 return Value.fromInterned(try pt.intern(.{ .float = .{
1813 .ty = ty.toIntern(),
1814 .storage = storage,
1815 } }));
1816}
1817
1818pub fn nullValue(pt: Zcu.PerThread, opt_ty: Type) Allocator.Error!Value {
1819 assert(pt.zcu.intern_pool.isOptionalType(opt_ty.toIntern()));
1820 return Value.fromInterned(try pt.intern(.{ .opt = .{
1821 .ty = opt_ty.toIntern(),
1822 .val = .none,
1823 } }));
1824}
1825
1826pub fn smallestUnsignedInt(pt: Zcu.PerThread, max: u64) Allocator.Error!Type {
1827 return pt.intType(.unsigned, Type.smallestUnsignedBits(max));
1828}
1829
1830/// Returns the smallest possible integer type containing both `min` and
1831/// `max`. Asserts that neither value is undef.
1832/// TODO: if #3806 is implemented, this becomes trivial
1833pub fn intFittingRange(pt: Zcu.PerThread, min: Value, max: Value) !Type {
1834 const mod = pt.zcu;
1835 assert(!min.isUndef(mod));
1836 assert(!max.isUndef(mod));
1837
1838 if (std.debug.runtime_safety) {
1839 assert(Value.order(min, max, pt).compare(.lte));
1840 }
1841
1842 const sign = min.orderAgainstZero(pt) == .lt;
1843
1844 const min_val_bits = pt.intBitsForValue(min, sign);
1845 const max_val_bits = pt.intBitsForValue(max, sign);
1846
1847 return pt.intType(
1848 if (sign) .signed else .unsigned,
1849 @max(min_val_bits, max_val_bits),
1850 );
1851}
1852
1853/// Given a value representing an integer, returns the number of bits necessary to represent
1854/// this value in an integer. If `sign` is true, returns the number of bits necessary in a
1855/// twos-complement integer; otherwise in an unsigned integer.
1856/// Asserts that `val` is not undef. If `val` is negative, asserts that `sign` is true.
1857pub fn intBitsForValue(pt: Zcu.PerThread, val: Value, sign: bool) u16 {
1858 const mod = pt.zcu;
1859 assert(!val.isUndef(mod));
1860
1861 const key = mod.intern_pool.indexToKey(val.toIntern());
1862 switch (key.int.storage) {
1863 .i64 => |x| {
1864 if (std.math.cast(u64, x)) |casted| return Type.smallestUnsignedBits(casted) + @intFromBool(sign);
1865 assert(sign);
1866 // Protect against overflow in the following negation.
1867 if (x == std.math.minInt(i64)) return 64;
1868 return Type.smallestUnsignedBits(@as(u64, @intCast(-(x + 1)))) + 1;
1869 },
1870 .u64 => |x| {
1871 return Type.smallestUnsignedBits(x) + @intFromBool(sign);
1872 },
1873 .big_int => |big| {
1874 if (big.positive) return @as(u16, @intCast(big.bitCountAbs() + @intFromBool(sign)));
1875
1876 // Zero is still a possibility, in which case unsigned is fine
1877 if (big.eqlZero()) return 0;
1878
1879 return @as(u16, @intCast(big.bitCountTwosComp()));
1880 },
1881 .lazy_align => |lazy_ty| {
1882 return Type.smallestUnsignedBits(Type.fromInterned(lazy_ty).abiAlignment(pt).toByteUnits() orelse 0) + @intFromBool(sign);
1883 },
1884 .lazy_size => |lazy_ty| {
1885 return Type.smallestUnsignedBits(Type.fromInterned(lazy_ty).abiSize(pt)) + @intFromBool(sign);
1886 },
1887 }
1888}
1889
1890pub fn getUnionLayout(pt: Zcu.PerThread, loaded_union: InternPool.LoadedUnionType) Zcu.UnionLayout {
1891 const mod = pt.zcu;
1892 const ip = &mod.intern_pool;
1893 assert(loaded_union.haveLayout(ip));
1894 var most_aligned_field: u32 = undefined;
1895 var most_aligned_field_size: u64 = undefined;
1896 var biggest_field: u32 = undefined;
1897 var payload_size: u64 = 0;
1898 var payload_align: InternPool.Alignment = .@"1";
1899 for (loaded_union.field_types.get(ip), 0..) |field_ty, field_index| {
1900 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue;
1901
1902 const explicit_align = loaded_union.fieldAlign(ip, field_index);
1903 const field_align = if (explicit_align != .none)
1904 explicit_align
1905 else
1906 Type.fromInterned(field_ty).abiAlignment(pt);
1907 const field_size = Type.fromInterned(field_ty).abiSize(pt);
1908 if (field_size > payload_size) {
1909 payload_size = field_size;
1910 biggest_field = @intCast(field_index);
1911 }
1912 if (field_align.compare(.gte, payload_align)) {
1913 payload_align = field_align;
1914 most_aligned_field = @intCast(field_index);
1915 most_aligned_field_size = field_size;
1916 }
1917 }
1918 const have_tag = loaded_union.flagsPtr(ip).runtime_tag.hasTag();
1919 if (!have_tag or !Type.fromInterned(loaded_union.enum_tag_ty).hasRuntimeBits(pt)) {
1920 return .{
1921 .abi_size = payload_align.forward(payload_size),
1922 .abi_align = payload_align,
1923 .most_aligned_field = most_aligned_field,
1924 .most_aligned_field_size = most_aligned_field_size,
1925 .biggest_field = biggest_field,
1926 .payload_size = payload_size,
1927 .payload_align = payload_align,
1928 .tag_align = .none,
1929 .tag_size = 0,
1930 .padding = 0,
1931 };
1932 }
1933
1934 const tag_size = Type.fromInterned(loaded_union.enum_tag_ty).abiSize(pt);
1935 const tag_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(pt).max(.@"1");
1936 return .{
1937 .abi_size = loaded_union.size(ip).*,
1938 .abi_align = tag_align.max(payload_align),
1939 .most_aligned_field = most_aligned_field,
1940 .most_aligned_field_size = most_aligned_field_size,
1941 .biggest_field = biggest_field,
1942 .payload_size = payload_size,
1943 .payload_align = payload_align,
1944 .tag_align = tag_align,
1945 .tag_size = tag_size,
1946 .padding = loaded_union.padding(ip).*,
1947 };
1948}
1949
1950pub fn unionAbiSize(mod: *Module, loaded_union: InternPool.LoadedUnionType) u64 {
1951 return mod.getUnionLayout(loaded_union).abi_size;
1952}
1953
1954/// Returns 0 if the union is represented with 0 bits at runtime.
1955pub fn unionAbiAlignment(pt: Zcu.PerThread, loaded_union: InternPool.LoadedUnionType) InternPool.Alignment {
1956 const mod = pt.zcu;
1957 const ip = &mod.intern_pool;
1958 const have_tag = loaded_union.flagsPtr(ip).runtime_tag.hasTag();
1959 var max_align: InternPool.Alignment = .none;
1960 if (have_tag) max_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(pt);
1961 for (loaded_union.field_types.get(ip), 0..) |field_ty, field_index| {
1962 if (!Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue;
1963
1964 const field_align = mod.unionFieldNormalAlignment(loaded_union, @intCast(field_index));
1965 max_align = max_align.max(field_align);
1966 }
1967 return max_align;
1968}
1969
1970/// Returns the field alignment of a non-packed union. Asserts the layout is not packed.
1971pub fn unionFieldNormalAlignment(
1972 pt: Zcu.PerThread,
1973 loaded_union: InternPool.LoadedUnionType,
1974 field_index: u32,
1975) InternPool.Alignment {
1976 return pt.unionFieldNormalAlignmentAdvanced(loaded_union, field_index, .normal) catch unreachable;
1977}
1978
1979/// Returns the field alignment of a non-packed union. Asserts the layout is not packed.
1980/// If `strat` is `.sema`, may perform type resolution.
1981pub fn unionFieldNormalAlignmentAdvanced(
1982 pt: Zcu.PerThread,
1983 loaded_union: InternPool.LoadedUnionType,
1984 field_index: u32,
1985 strat: Type.ResolveStrat,
1986) Zcu.SemaError!InternPool.Alignment {
1987 const ip = &pt.zcu.intern_pool;
1988 assert(loaded_union.flagsPtr(ip).layout != .@"packed");
1989 const field_align = loaded_union.fieldAlign(ip, field_index);
1990 if (field_align != .none) return field_align;
1991 const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
1992 if (field_ty.isNoReturn(pt.zcu)) return .none;
1993 return (try field_ty.abiAlignmentAdvanced(pt, strat.toLazy())).scalar;
1994}
1995
1996/// Returns the field alignment of a non-packed struct. Asserts the layout is not packed.
1997pub fn structFieldAlignment(
1998 pt: Zcu.PerThread,
1999 explicit_alignment: InternPool.Alignment,
2000 field_ty: Type,
2001 layout: std.builtin.Type.ContainerLayout,
2002) InternPool.Alignment {
2003 return pt.structFieldAlignmentAdvanced(explicit_alignment, field_ty, layout, .normal) catch unreachable;
2004}
2005
2006/// Returns the field alignment of a non-packed struct. Asserts the layout is not packed.
2007/// If `strat` is `.sema`, may perform type resolution.
2008pub fn structFieldAlignmentAdvanced(
2009 pt: Zcu.PerThread,
2010 explicit_alignment: InternPool.Alignment,
2011 field_ty: Type,
2012 layout: std.builtin.Type.ContainerLayout,
2013 strat: Type.ResolveStrat,
2014) Zcu.SemaError!InternPool.Alignment {
2015 assert(layout != .@"packed");
2016 if (explicit_alignment != .none) return explicit_alignment;
2017 const ty_abi_align = (try field_ty.abiAlignmentAdvanced(pt, strat.toLazy())).scalar;
2018 switch (layout) {
2019 .@"packed" => unreachable,
2020 .auto => if (pt.zcu.getTarget().ofmt != .c) return ty_abi_align,
2021 .@"extern" => {},
2022 }
2023 // extern
2024 if (field_ty.isAbiInt(pt.zcu) and field_ty.intInfo(pt.zcu).bits >= 128) {
2025 return ty_abi_align.maxStrict(.@"16");
2026 }
2027 return ty_abi_align;
2028}
2029
2030/// https://github.com/ziglang/zig/issues/17178 explored storing these bit offsets
2031/// into the packed struct InternPool data rather than computing this on the
2032/// fly, however it was found to perform worse when measured on real world
2033/// projects.
2034pub fn structPackedFieldBitOffset(
2035 pt: Zcu.PerThread,
2036 struct_type: InternPool.LoadedStructType,
2037 field_index: u32,
2038) u16 {
2039 const mod = pt.zcu;
2040 const ip = &mod.intern_pool;
2041 assert(struct_type.layout == .@"packed");
2042 assert(struct_type.haveLayout(ip));
2043 var bit_sum: u64 = 0;
2044 for (0..struct_type.field_types.len) |i| {
2045 if (i == field_index) {
2046 return @intCast(bit_sum);
2047 }
2048 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
2049 bit_sum += field_ty.bitSize(pt);
2050 }
2051 unreachable; // index out of bounds
2052}
2053
2054pub fn getBuiltin(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Air.Inst.Ref {
2055 const decl_index = try pt.getBuiltinDecl(name);
2056 pt.ensureDeclAnalyzed(decl_index) catch @panic("std.builtin is corrupt");
2057 return Air.internedToRef(pt.zcu.declPtr(decl_index).val.toIntern());
2058}
2059
2060pub fn getBuiltinDecl(pt: Zcu.PerThread, name: []const u8) Allocator.Error!InternPool.DeclIndex {
2061 const zcu = pt.zcu;
2062 const gpa = zcu.gpa;
2063 const ip = &zcu.intern_pool;
2064 const std_file_imported = zcu.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig");
2065 const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index).unwrap().?;
2066 const std_namespace = zcu.declPtr(std_file_root_decl).getOwnedInnerNamespace(zcu).?;
2067 const builtin_str = try ip.getOrPutString(gpa, "builtin", .no_embedded_nulls);
2068 const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse @panic("lib/std.zig is corrupt and missing 'builtin'");
2069 pt.ensureDeclAnalyzed(builtin_decl) catch @panic("std.builtin is corrupt");
2070 const builtin_namespace = zcu.declPtr(builtin_decl).getInnerNamespace(zcu) orelse @panic("std.builtin is corrupt");
2071 const name_str = try ip.getOrPutString(gpa, name, .no_embedded_nulls);
2072 return builtin_namespace.decls.getKeyAdapted(name_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse @panic("lib/std/builtin.zig is corrupt");
2073}
2074
2075pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type {
2076 const ty_inst = try pt.getBuiltin(name);
2077 const ty = Type.fromInterned(ty_inst.toInterned() orelse @panic("std.builtin is corrupt"));
2078 ty.resolveFully(pt) catch @panic("std.builtin is corrupt");
2079 return ty;
2080}
2081
2082const Air = @import("../Air.zig");
2083const Allocator = std.mem.Allocator;
2084const assert = std.debug.assert;
2085const BigIntConst = std.math.big.int.Const;
2086const BigIntMutable = std.math.big.int.Mutable;
2087const build_options = @import("build_options");
2088const builtin = @import("builtin");
2089const Cache = std.Build.Cache;
2090const InternPool = @import("../InternPool.zig");
2091const isUpDir = @import("../introspect.zig").isUpDir;
2092const Liveness = @import("../Liveness.zig");
2093const log = std.log.scoped(.zcu);
2094const Module = @import("../Package.zig").Module;
2095const Sema = @import("../Sema.zig");
2096const std = @import("std");
2097const target_util = @import("../target.zig");
2098const trace = @import("../tracy.zig").trace;
2099const Type = @import("../Type.zig");
2100const Value = @import("../Value.zig");
2101const Zcu = @import("../Zcu.zig");
2102const 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+532-429
...@@ -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,10 +2198,10 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2184,10 +2198,10 @@ 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(function.owner_decl);
...@@ -2195,7 +2209,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2195,7 +2209,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
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(extern_func.decl);
2201 const atom = func.bin_file.getAtomPtr(atom_index);2215 const atom = func.bin_file.getAtomPtr(atom_index);
...@@ -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,7 +3223,7 @@ fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u...@@ -3195,7 +3223,7 @@ 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
...@@ -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
...@@ -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+140-129
...@@ -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,14 +744,14 @@ fn lowerDeclRef(...@@ -739,14 +744,14 @@ 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 }
...@@ -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+751-680
...@@ -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),
...@@ -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,14 +2510,14 @@ pub const Object = struct {...@@ -2502,14 +2510,14 @@ 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, "{d}", .{field_index}, .no_embedded_nulls);
...@@ -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,7 +2807,7 @@ pub const Object = struct {...@@ -2799,7 +2807,7 @@ 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 zcu = o.pt.zcu;
28032811
2804 const std_mod = zcu.std_mod;2812 const std_mod = zcu.std_mod;
2805 const std_file_imported = zcu.importPkg(std_mod) catch unreachable;2813 const std_file_imported = zcu.importPkg(std_mod) catch unreachable;
...@@ -2807,13 +2815,13 @@ pub const Object = struct {...@@ -2807,13 +2815,13 @@ pub const Object = struct {
2807 const builtin_str = try zcu.intern_pool.getOrPutString(zcu.gpa, "builtin", .no_embedded_nulls);2815 const builtin_str = try zcu.intern_pool.getOrPutString(zcu.gpa, "builtin", .no_embedded_nulls);
2808 const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index);2816 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);2817 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 }).?;2818 const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }).?;
28112819
2812 const stack_trace_str = try zcu.intern_pool.getOrPutString(zcu.gpa, "StackTrace", .no_embedded_nulls);2820 const stack_trace_str = try zcu.intern_pool.getOrPutString(zcu.gpa, "StackTrace", .no_embedded_nulls);
2813 // buffer is only used for int_type, `builtin` is a struct.2821 // buffer is only used for int_type, `builtin` is a struct.
2814 const builtin_ty = zcu.declPtr(builtin_decl).val.toType();2822 const builtin_ty = zcu.declPtr(builtin_decl).val.toType();
2815 const builtin_namespace = zcu.namespacePtrUnwrap(builtin_ty.getNamespaceIndex(zcu)).?;2823 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 }).?;2824 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);2825 const stack_trace_decl = zcu.declPtr(stack_trace_decl_index);
28182826
2819 // Sema should have ensured that StackTrace was analyzed.2827 // Sema should have ensured that StackTrace was analyzed.
...@@ -2824,7 +2832,7 @@ pub const Object = struct {...@@ -2824,7 +2832,7 @@ pub const Object = struct {
2824 fn allocTypeName(o: *Object, ty: Type) Allocator.Error![:0]const u8 {2832 fn allocTypeName(o: *Object, ty: Type) Allocator.Error![:0]const u8 {
2825 var buffer = std.ArrayList(u8).init(o.gpa);2833 var buffer = std.ArrayList(u8).init(o.gpa);
2826 errdefer buffer.deinit();2834 errdefer buffer.deinit();
2827 try ty.print(buffer.writer(), o.module);2835 try ty.print(buffer.writer(), o.pt);
2828 return buffer.toOwnedSliceSentinel(0);2836 return buffer.toOwnedSliceSentinel(0);
2829 }2837 }
28302838
...@@ -2835,7 +2843,8 @@ pub const Object = struct {...@@ -2835,7 +2843,8 @@ pub const Object = struct {
2835 o: *Object,2843 o: *Object,
2836 decl_index: InternPool.DeclIndex,2844 decl_index: InternPool.DeclIndex,
2837 ) Allocator.Error!Builder.Function.Index {2845 ) Allocator.Error!Builder.Function.Index {
2838 const zcu = o.module;2846 const pt = o.pt;
2847 const zcu = pt.zcu;
2839 const ip = &zcu.intern_pool;2848 const ip = &zcu.intern_pool;
2840 const gpa = o.gpa;2849 const gpa = o.gpa;
2841 const decl = zcu.declPtr(decl_index);2850 const decl = zcu.declPtr(decl_index);
...@@ -2848,7 +2857,7 @@ pub const Object = struct {...@@ -2848,7 +2857,7 @@ pub const Object = struct {
2848 assert(decl.has_tv);2857 assert(decl.has_tv);
2849 const fn_info = zcu.typeToFunc(zig_fn_type).?;2858 const fn_info = zcu.typeToFunc(zig_fn_type).?;
2850 const target = owner_mod.resolved_target.result;2859 const target = owner_mod.resolved_target.result;
2851 const sret = firstParamSRet(fn_info, zcu, target);2860 const sret = firstParamSRet(fn_info, pt, target);
28522861
2853 const is_extern = decl.isExtern(zcu);2862 const is_extern = decl.isExtern(zcu);
2854 const function_index = try o.builder.addFunction(2863 const function_index = try o.builder.addFunction(
...@@ -2929,14 +2938,14 @@ pub const Object = struct {...@@ -2929,14 +2938,14 @@ pub const Object = struct {
2929 .byval => {2938 .byval => {
2930 const param_index = it.zig_index - 1;2939 const param_index = it.zig_index - 1;
2931 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);2940 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);
2932 if (!isByRef(param_ty, zcu)) {2941 if (!isByRef(param_ty, pt)) {
2933 try o.addByValParamAttrs(&attributes, param_ty, param_index, fn_info, it.llvm_index - 1);2942 try o.addByValParamAttrs(&attributes, param_ty, param_index, fn_info, it.llvm_index - 1);
2934 }2943 }
2935 },2944 },
2936 .byref => {2945 .byref => {
2937 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);2946 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);2947 const param_llvm_ty = try o.lowerType(param_ty);
2939 const alignment = param_ty.abiAlignment(zcu);2948 const alignment = param_ty.abiAlignment(pt);
2940 try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment.toLlvm(), it.byval_attr, param_llvm_ty);2949 try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment.toLlvm(), it.byval_attr, param_llvm_ty);
2941 },2950 },
2942 .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder),2951 .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder),
...@@ -2964,7 +2973,7 @@ pub const Object = struct {...@@ -2964,7 +2973,7 @@ pub const Object = struct {
2964 attributes: *Builder.FunctionAttributes.Wip,2973 attributes: *Builder.FunctionAttributes.Wip,
2965 owner_mod: *Package.Module,2974 owner_mod: *Package.Module,
2966 ) Allocator.Error!void {2975 ) Allocator.Error!void {
2967 const comp = o.module.comp;2976 const comp = o.pt.zcu.comp;
29682977
2969 if (!owner_mod.red_zone) {2978 if (!owner_mod.red_zone) {
2970 try attributes.addFnAttr(.noredzone, &o.builder);2979 try attributes.addFnAttr(.noredzone, &o.builder);
...@@ -3039,7 +3048,7 @@ pub const Object = struct {...@@ -3039,7 +3048,7 @@ pub const Object = struct {
3039 }3048 }
3040 errdefer assert(o.anon_decl_map.remove(decl_val));3049 errdefer assert(o.anon_decl_map.remove(decl_val));
30413050
3042 const mod = o.module;3051 const mod = o.pt.zcu;
3043 const decl_ty = mod.intern_pool.typeOf(decl_val);3052 const decl_ty = mod.intern_pool.typeOf(decl_val);
30443053
3045 const variable_index = try o.builder.addVariable(3054 const variable_index = try o.builder.addVariable(
...@@ -3065,7 +3074,7 @@ pub const Object = struct {...@@ -3065,7 +3074,7 @@ pub const Object = struct {
3065 if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.variable;3074 if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.variable;
3066 errdefer assert(o.decl_map.remove(decl_index));3075 errdefer assert(o.decl_map.remove(decl_index));
30673076
3068 const zcu = o.module;3077 const zcu = o.pt.zcu;
3069 const decl = zcu.declPtr(decl_index);3078 const decl = zcu.declPtr(decl_index);
3070 const is_extern = decl.isExtern(zcu);3079 const is_extern = decl.isExtern(zcu);
30713080
...@@ -3100,11 +3109,12 @@ pub const Object = struct {...@@ -3100,11 +3109,12 @@ pub const Object = struct {
3100 }3109 }
31013110
3102 fn errorIntType(o: *Object) Allocator.Error!Builder.Type {3111 fn errorIntType(o: *Object) Allocator.Error!Builder.Type {
3103 return o.builder.intType(o.module.errorSetBits());3112 return o.builder.intType(o.pt.zcu.errorSetBits());
3104 }3113 }
31053114
3106 fn lowerType(o: *Object, t: Type) Allocator.Error!Builder.Type {3115 fn lowerType(o: *Object, t: Type) Allocator.Error!Builder.Type {
3107 const mod = o.module;3116 const pt = o.pt;
3117 const mod = pt.zcu;
3108 const target = mod.getTarget();3118 const target = mod.getTarget();
3109 const ip = &mod.intern_pool;3119 const ip = &mod.intern_pool;
3110 return switch (t.toIntern()) {3120 return switch (t.toIntern()) {
...@@ -3230,7 +3240,7 @@ pub const Object = struct {...@@ -3230,7 +3240,7 @@ pub const Object = struct {
3230 ),3240 ),
3231 .opt_type => |child_ty| {3241 .opt_type => |child_ty| {
3232 // Must stay in sync with `opt_payload` logic in `lowerPtr`.3242 // Must stay in sync with `opt_payload` logic in `lowerPtr`.
3233 if (!Type.fromInterned(child_ty).hasRuntimeBitsIgnoreComptime(mod)) return .i8;3243 if (!Type.fromInterned(child_ty).hasRuntimeBitsIgnoreComptime(pt)) return .i8;
32343244
3235 const payload_ty = try o.lowerType(Type.fromInterned(child_ty));3245 const payload_ty = try o.lowerType(Type.fromInterned(child_ty));
3236 if (t.optionalReprIsPayload(mod)) return payload_ty;3246 if (t.optionalReprIsPayload(mod)) return payload_ty;
...@@ -3238,8 +3248,8 @@ pub const Object = struct {...@@ -3238,8 +3248,8 @@ pub const Object = struct {
3238 comptime assert(optional_layout_version == 3);3248 comptime assert(optional_layout_version == 3);
3239 var fields: [3]Builder.Type = .{ payload_ty, .i8, undefined };3249 var fields: [3]Builder.Type = .{ payload_ty, .i8, undefined };
3240 var fields_len: usize = 2;3250 var fields_len: usize = 2;
3241 const offset = Type.fromInterned(child_ty).abiSize(mod) + 1;3251 const offset = Type.fromInterned(child_ty).abiSize(pt) + 1;
3242 const abi_size = t.abiSize(mod);3252 const abi_size = t.abiSize(pt);
3243 const padding_len = abi_size - offset;3253 const padding_len = abi_size - offset;
3244 if (padding_len > 0) {3254 if (padding_len > 0) {
3245 fields[2] = try o.builder.arrayType(padding_len, .i8);3255 fields[2] = try o.builder.arrayType(padding_len, .i8);
...@@ -3252,16 +3262,16 @@ pub const Object = struct {...@@ -3252,16 +3262,16 @@ pub const Object = struct {
3252 // Must stay in sync with `codegen.errUnionPayloadOffset`.3262 // Must stay in sync with `codegen.errUnionPayloadOffset`.
3253 // See logic in `lowerPtr`.3263 // See logic in `lowerPtr`.
3254 const error_type = try o.errorIntType();3264 const error_type = try o.errorIntType();
3255 if (!Type.fromInterned(error_union_type.payload_type).hasRuntimeBitsIgnoreComptime(mod))3265 if (!Type.fromInterned(error_union_type.payload_type).hasRuntimeBitsIgnoreComptime(pt))
3256 return error_type;3266 return error_type;
3257 const payload_type = try o.lowerType(Type.fromInterned(error_union_type.payload_type));3267 const payload_type = try o.lowerType(Type.fromInterned(error_union_type.payload_type));
3258 const err_int_ty = try mod.errorIntType();3268 const err_int_ty = try o.pt.errorIntType();
32593269
3260 const payload_align = Type.fromInterned(error_union_type.payload_type).abiAlignment(mod);3270 const payload_align = Type.fromInterned(error_union_type.payload_type).abiAlignment(pt);
3261 const error_align = err_int_ty.abiAlignment(mod);3271 const error_align = err_int_ty.abiAlignment(pt);
32623272
3263 const payload_size = Type.fromInterned(error_union_type.payload_type).abiSize(mod);3273 const payload_size = Type.fromInterned(error_union_type.payload_type).abiSize(pt);
3264 const error_size = err_int_ty.abiSize(mod);3274 const error_size = err_int_ty.abiSize(pt);
32653275
3266 var fields: [3]Builder.Type = undefined;3276 var fields: [3]Builder.Type = undefined;
3267 var fields_len: usize = 2;3277 var fields_len: usize = 2;
...@@ -3317,12 +3327,12 @@ pub const Object = struct {...@@ -3317,12 +3327,12 @@ pub const Object = struct {
3317 var it = struct_type.iterateRuntimeOrder(ip);3327 var it = struct_type.iterateRuntimeOrder(ip);
3318 while (it.next()) |field_index| {3328 while (it.next()) |field_index| {
3319 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);3329 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
3320 const field_align = mod.structFieldAlignment(3330 const field_align = pt.structFieldAlignment(
3321 struct_type.fieldAlign(ip, field_index),3331 struct_type.fieldAlign(ip, field_index),
3322 field_ty,3332 field_ty,
3323 struct_type.layout,3333 struct_type.layout,
3324 );3334 );
3325 const field_ty_align = field_ty.abiAlignment(mod);3335 const field_ty_align = field_ty.abiAlignment(pt);
3326 if (field_align.compare(.lt, field_ty_align)) struct_kind = .@"packed";3336 if (field_align.compare(.lt, field_ty_align)) struct_kind = .@"packed";
3327 big_align = big_align.max(field_align);3337 big_align = big_align.max(field_align);
3328 const prev_offset = offset;3338 const prev_offset = offset;
...@@ -3334,7 +3344,7 @@ pub const Object = struct {...@@ -3334,7 +3344,7 @@ pub const Object = struct {
3334 try o.builder.arrayType(padding_len, .i8),3344 try o.builder.arrayType(padding_len, .i8),
3335 );3345 );
33363346
3337 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {3347 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) {
3338 // This is a zero-bit field. If there are runtime bits after this field,3348 // 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't3349 // 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.3350 // map the field, indicating it's at the end of the struct.
...@@ -3353,7 +3363,7 @@ pub const Object = struct {...@@ -3353,7 +3363,7 @@ pub const Object = struct {
3353 }, @intCast(llvm_field_types.items.len));3363 }, @intCast(llvm_field_types.items.len));
3354 try llvm_field_types.append(o.gpa, try o.lowerType(field_ty));3364 try llvm_field_types.append(o.gpa, try o.lowerType(field_ty));
33553365
3356 offset += field_ty.abiSize(mod);3366 offset += field_ty.abiSize(pt);
3357 }3367 }
3358 {3368 {
3359 const prev_offset = offset;3369 const prev_offset = offset;
...@@ -3386,7 +3396,7 @@ pub const Object = struct {...@@ -3386,7 +3396,7 @@ pub const Object = struct {
3386 var offset: u64 = 0;3396 var offset: u64 = 0;
3387 var big_align: InternPool.Alignment = .none;3397 var big_align: InternPool.Alignment = .none;
33883398
3389 const struct_size = t.abiSize(mod);3399 const struct_size = t.abiSize(pt);
33903400
3391 for (3401 for (
3392 anon_struct_type.types.get(ip),3402 anon_struct_type.types.get(ip),
...@@ -3395,7 +3405,7 @@ pub const Object = struct {...@@ -3395,7 +3405,7 @@ pub const Object = struct {
3395 ) |field_ty, field_val, field_index| {3405 ) |field_ty, field_val, field_index| {
3396 if (field_val != .none) continue;3406 if (field_val != .none) continue;
33973407
3398 const field_align = Type.fromInterned(field_ty).abiAlignment(mod);3408 const field_align = Type.fromInterned(field_ty).abiAlignment(pt);
3399 big_align = big_align.max(field_align);3409 big_align = big_align.max(field_align);
3400 const prev_offset = offset;3410 const prev_offset = offset;
3401 offset = field_align.forward(offset);3411 offset = field_align.forward(offset);
...@@ -3405,7 +3415,7 @@ pub const Object = struct {...@@ -3405,7 +3415,7 @@ pub const Object = struct {
3405 o.gpa,3415 o.gpa,
3406 try o.builder.arrayType(padding_len, .i8),3416 try o.builder.arrayType(padding_len, .i8),
3407 );3417 );
3408 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) {3418 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) {
3409 // This is a zero-bit field. If there are runtime bits after this field,3419 // 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't3420 // 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.3421 // map the field, indicating it's at the end of the struct.
...@@ -3423,7 +3433,7 @@ pub const Object = struct {...@@ -3423,7 +3433,7 @@ pub const Object = struct {
3423 }, @intCast(llvm_field_types.items.len));3433 }, @intCast(llvm_field_types.items.len));
3424 try llvm_field_types.append(o.gpa, try o.lowerType(Type.fromInterned(field_ty)));3434 try llvm_field_types.append(o.gpa, try o.lowerType(Type.fromInterned(field_ty)));
34253435
3426 offset += Type.fromInterned(field_ty).abiSize(mod);3436 offset += Type.fromInterned(field_ty).abiSize(pt);
3427 }3437 }
3428 {3438 {
3429 const prev_offset = offset;3439 const prev_offset = offset;
...@@ -3440,10 +3450,10 @@ pub const Object = struct {...@@ -3440,10 +3450,10 @@ pub const Object = struct {
3440 if (o.type_map.get(t.toIntern())) |value| return value;3450 if (o.type_map.get(t.toIntern())) |value| return value;
34413451
3442 const union_obj = ip.loadUnionType(t.toIntern());3452 const union_obj = ip.loadUnionType(t.toIntern());
3443 const layout = mod.getUnionLayout(union_obj);3453 const layout = pt.getUnionLayout(union_obj);
34443454
3445 if (union_obj.flagsPtr(ip).layout == .@"packed") {3455 if (union_obj.flagsPtr(ip).layout == .@"packed") {
3446 const int_ty = try o.builder.intType(@intCast(t.bitSize(mod)));3456 const int_ty = try o.builder.intType(@intCast(t.bitSize(pt)));
3447 try o.type_map.put(o.gpa, t.toIntern(), int_ty);3457 try o.type_map.put(o.gpa, t.toIntern(), int_ty);
3448 return int_ty;3458 return int_ty;
3449 }3459 }
...@@ -3552,18 +3562,20 @@ pub const Object = struct {...@@ -3552,18 +3562,20 @@ pub const Object = struct {
3552 /// being a zero bit type, but it should still be lowered as an i8 in such case.3562 /// 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.3563 /// There are other similar cases handled here as well.
3554 fn lowerPtrElemTy(o: *Object, elem_ty: Type) Allocator.Error!Builder.Type {3564 fn lowerPtrElemTy(o: *Object, elem_ty: Type) Allocator.Error!Builder.Type {
3555 const mod = o.module;3565 const pt = o.pt;
3566 const mod = pt.zcu;
3556 const lower_elem_ty = switch (elem_ty.zigTypeTag(mod)) {3567 const lower_elem_ty = switch (elem_ty.zigTypeTag(mod)) {
3557 .Opaque => true,3568 .Opaque => true,
3558 .Fn => !mod.typeToFunc(elem_ty).?.is_generic,3569 .Fn => !mod.typeToFunc(elem_ty).?.is_generic,
3559 .Array => elem_ty.childType(mod).hasRuntimeBitsIgnoreComptime(mod),3570 .Array => elem_ty.childType(mod).hasRuntimeBitsIgnoreComptime(pt),
3560 else => elem_ty.hasRuntimeBitsIgnoreComptime(mod),3571 else => elem_ty.hasRuntimeBitsIgnoreComptime(pt),
3561 };3572 };
3562 return if (lower_elem_ty) try o.lowerType(elem_ty) else .i8;3573 return if (lower_elem_ty) try o.lowerType(elem_ty) else .i8;
3563 }3574 }
35643575
3565 fn lowerTypeFn(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {3576 fn lowerTypeFn(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {
3566 const mod = o.module;3577 const pt = o.pt;
3578 const mod = pt.zcu;
3567 const ip = &mod.intern_pool;3579 const ip = &mod.intern_pool;
3568 const target = mod.getTarget();3580 const target = mod.getTarget();
3569 const ret_ty = try lowerFnRetTy(o, fn_info);3581 const ret_ty = try lowerFnRetTy(o, fn_info);
...@@ -3571,14 +3583,14 @@ pub const Object = struct {...@@ -3571,14 +3583,14 @@ pub const Object = struct {
3571 var llvm_params = std.ArrayListUnmanaged(Builder.Type){};3583 var llvm_params = std.ArrayListUnmanaged(Builder.Type){};
3572 defer llvm_params.deinit(o.gpa);3584 defer llvm_params.deinit(o.gpa);
35733585
3574 if (firstParamSRet(fn_info, mod, target)) {3586 if (firstParamSRet(fn_info, pt, target)) {
3575 try llvm_params.append(o.gpa, .ptr);3587 try llvm_params.append(o.gpa, .ptr);
3576 }3588 }
35773589
3578 if (Type.fromInterned(fn_info.return_type).isError(mod) and3590 if (Type.fromInterned(fn_info.return_type).isError(mod) and
3579 mod.comp.config.any_error_tracing)3591 mod.comp.config.any_error_tracing)
3580 {3592 {
3581 const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType());3593 const ptr_ty = try pt.singleMutPtrType(try o.getStackTraceType());
3582 try llvm_params.append(o.gpa, try o.lowerType(ptr_ty));3594 try llvm_params.append(o.gpa, try o.lowerType(ptr_ty));
3583 }3595 }
35843596
...@@ -3595,7 +3607,7 @@ pub const Object = struct {...@@ -3595,7 +3607,7 @@ pub const Object = struct {
3595 .abi_sized_int => {3607 .abi_sized_int => {
3596 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);3608 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(3609 try llvm_params.append(o.gpa, try o.builder.intType(
3598 @intCast(param_ty.abiSize(mod) * 8),3610 @intCast(param_ty.abiSize(pt) * 8),
3599 ));3611 ));
3600 },3612 },
3601 .slice => {3613 .slice => {
...@@ -3633,7 +3645,8 @@ pub const Object = struct {...@@ -3633,7 +3645,8 @@ pub const Object = struct {
3633 }3645 }
36343646
3635 fn lowerValueToInt(o: *Object, llvm_int_ty: Builder.Type, arg_val: InternPool.Index) Error!Builder.Constant {3647 fn lowerValueToInt(o: *Object, llvm_int_ty: Builder.Type, arg_val: InternPool.Index) Error!Builder.Constant {
3636 const mod = o.module;3648 const pt = o.pt;
3649 const mod = pt.zcu;
3637 const ip = &mod.intern_pool;3650 const ip = &mod.intern_pool;
3638 const target = mod.getTarget();3651 const target = mod.getTarget();
36393652
...@@ -3666,15 +3679,15 @@ pub const Object = struct {...@@ -3666,15 +3679,15 @@ pub const Object = struct {
3666 var running_int = try o.builder.intConst(llvm_int_ty, 0);3679 var running_int = try o.builder.intConst(llvm_int_ty, 0);
3667 var running_bits: u16 = 0;3680 var running_bits: u16 = 0;
3668 for (struct_type.field_types.get(ip), 0..) |field_ty, field_index| {3681 for (struct_type.field_types.get(ip), 0..) |field_ty, field_index| {
3669 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) continue;3682 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue;
36703683
3671 const shift_rhs = try o.builder.intConst(llvm_int_ty, running_bits);3684 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());3685 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);3686 const shifted = try o.builder.binConst(.shl, field_val, shift_rhs);
36743687
3675 running_int = try o.builder.binConst(.xor, running_int, shifted);3688 running_int = try o.builder.binConst(.xor, running_int, shifted);
36763689
3677 const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(mod));3690 const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(pt));
3678 running_bits += ty_bit_size;3691 running_bits += ty_bit_size;
3679 }3692 }
3680 return running_int;3693 return running_int;
...@@ -3683,7 +3696,7 @@ pub const Object = struct {...@@ -3683,7 +3696,7 @@ pub const Object = struct {
3683 else => unreachable,3696 else => unreachable,
3684 },3697 },
3685 .un => |un| {3698 .un => |un| {
3686 const layout = ty.unionGetLayout(mod);3699 const layout = ty.unionGetLayout(pt);
3687 if (layout.payload_size == 0) return o.lowerValue(un.tag);3700 if (layout.payload_size == 0) return o.lowerValue(un.tag);
36883701
3689 const union_obj = mod.typeToUnion(ty).?;3702 const union_obj = mod.typeToUnion(ty).?;
...@@ -3701,7 +3714,7 @@ pub const Object = struct {...@@ -3701,7 +3714,7 @@ pub const Object = struct {
3701 }3714 }
3702 const field_index = mod.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?;3715 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]);3716 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);3717 if (!field_ty.hasRuntimeBits(pt)) return o.builder.intConst(llvm_int_ty, 0);
3705 return o.lowerValueToInt(llvm_int_ty, un.val);3718 return o.lowerValueToInt(llvm_int_ty, un.val);
3706 },3719 },
3707 .simple_value => |simple_value| switch (simple_value) {3720 .simple_value => |simple_value| switch (simple_value) {
...@@ -3715,7 +3728,7 @@ pub const Object = struct {...@@ -3715,7 +3728,7 @@ pub const Object = struct {
3715 .opt => {}, // pointer like optional expected3728 .opt => {}, // pointer like optional expected
3716 else => unreachable,3729 else => unreachable,
3717 }3730 }
3718 const bits = ty.bitSize(mod);3731 const bits = ty.bitSize(pt);
3719 const bytes: usize = @intCast(std.mem.alignForward(u64, bits, 8) / 8);3732 const bytes: usize = @intCast(std.mem.alignForward(u64, bits, 8) / 8);
37203733
3721 var stack = std.heap.stackFallback(32, o.gpa);3734 var stack = std.heap.stackFallback(32, o.gpa);
...@@ -3729,12 +3742,7 @@ pub const Object = struct {...@@ -3729,12 +3742,7 @@ pub const Object = struct {
3729 defer allocator.free(limbs);3742 defer allocator.free(limbs);
3730 @memset(limbs, 0);3743 @memset(limbs, 0);
37313744
3732 val.writeToPackedMemory(3745 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;
37383746
3739 if (builtin.target.cpu.arch.endian() == .little) {3747 if (builtin.target.cpu.arch.endian() == .little) {
3740 if (target.cpu.arch.endian() == .big)3748 if (target.cpu.arch.endian() == .big)
...@@ -3752,7 +3760,8 @@ pub const Object = struct {...@@ -3752,7 +3760,8 @@ pub const Object = struct {
3752 }3760 }
37533761
3754 fn lowerValue(o: *Object, arg_val: InternPool.Index) Error!Builder.Constant {3762 fn lowerValue(o: *Object, arg_val: InternPool.Index) Error!Builder.Constant {
3755 const mod = o.module;3763 const pt = o.pt;
3764 const mod = pt.zcu;
3756 const ip = &mod.intern_pool;3765 const ip = &mod.intern_pool;
3757 const target = mod.getTarget();3766 const target = mod.getTarget();
37583767
...@@ -3811,7 +3820,7 @@ pub const Object = struct {...@@ -3811,7 +3820,7 @@ pub const Object = struct {
3811 },3820 },
3812 .int => {3821 .int => {
3813 var bigint_space: Value.BigIntSpace = undefined;3822 var bigint_space: Value.BigIntSpace = undefined;
3814 const bigint = val.toBigInt(&bigint_space, mod);3823 const bigint = val.toBigInt(&bigint_space, pt);
3815 return lowerBigInt(o, ty, bigint);3824 return lowerBigInt(o, ty, bigint);
3816 },3825 },
3817 .err => |err| {3826 .err => |err| {
...@@ -3821,24 +3830,24 @@ pub const Object = struct {...@@ -3821,24 +3830,24 @@ pub const Object = struct {
3821 },3830 },
3822 .error_union => |error_union| {3831 .error_union => |error_union| {
3823 const err_val = switch (error_union.val) {3832 const err_val = switch (error_union.val) {
3824 .err_name => |err_name| try mod.intern(.{ .err = .{3833 .err_name => |err_name| try pt.intern(.{ .err = .{
3825 .ty = ty.errorUnionSet(mod).toIntern(),3834 .ty = ty.errorUnionSet(mod).toIntern(),
3826 .name = err_name,3835 .name = err_name,
3827 } }),3836 } }),
3828 .payload => (try mod.intValue(try mod.errorIntType(), 0)).toIntern(),3837 .payload => (try pt.intValue(try pt.errorIntType(), 0)).toIntern(),
3829 };3838 };
3830 const err_int_ty = try mod.errorIntType();3839 const err_int_ty = try pt.errorIntType();
3831 const payload_type = ty.errorUnionPayload(mod);3840 const payload_type = ty.errorUnionPayload(mod);
3832 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {3841 if (!payload_type.hasRuntimeBitsIgnoreComptime(pt)) {
3833 // We use the error type directly as the type.3842 // We use the error type directly as the type.
3834 return o.lowerValue(err_val);3843 return o.lowerValue(err_val);
3835 }3844 }
38363845
3837 const payload_align = payload_type.abiAlignment(mod);3846 const payload_align = payload_type.abiAlignment(pt);
3838 const error_align = err_int_ty.abiAlignment(mod);3847 const error_align = err_int_ty.abiAlignment(pt);
3839 const llvm_error_value = try o.lowerValue(err_val);3848 const llvm_error_value = try o.lowerValue(err_val);
3840 const llvm_payload_value = try o.lowerValue(switch (error_union.val) {3849 const llvm_payload_value = try o.lowerValue(switch (error_union.val) {
3841 .err_name => try mod.intern(.{ .undef = payload_type.toIntern() }),3850 .err_name => try pt.intern(.{ .undef = payload_type.toIntern() }),
3842 .payload => |payload| payload,3851 .payload => |payload| payload,
3843 });3852 });
38443853
...@@ -3869,16 +3878,16 @@ pub const Object = struct {...@@ -3869,16 +3878,16 @@ pub const Object = struct {
3869 .enum_tag => |enum_tag| o.lowerValue(enum_tag.int),3878 .enum_tag => |enum_tag| o.lowerValue(enum_tag.int),
3870 .float => switch (ty.floatBits(target)) {3879 .float => switch (ty.floatBits(target)) {
3871 16 => if (backendSupportsF16(target))3880 16 => if (backendSupportsF16(target))
3872 try o.builder.halfConst(val.toFloat(f16, mod))3881 try o.builder.halfConst(val.toFloat(f16, pt))
3873 else3882 else
3874 try o.builder.intConst(.i16, @as(i16, @bitCast(val.toFloat(f16, mod)))),3883 try o.builder.intConst(.i16, @as(i16, @bitCast(val.toFloat(f16, pt)))),
3875 32 => try o.builder.floatConst(val.toFloat(f32, mod)),3884 32 => try o.builder.floatConst(val.toFloat(f32, pt)),
3876 64 => try o.builder.doubleConst(val.toFloat(f64, mod)),3885 64 => try o.builder.doubleConst(val.toFloat(f64, pt)),
3877 80 => if (backendSupportsF80(target))3886 80 => if (backendSupportsF80(target))
3878 try o.builder.x86_fp80Const(val.toFloat(f80, mod))3887 try o.builder.x86_fp80Const(val.toFloat(f80, pt))
3879 else3888 else
3880 try o.builder.intConst(.i80, @as(i80, @bitCast(val.toFloat(f80, mod)))),3889 try o.builder.intConst(.i80, @as(i80, @bitCast(val.toFloat(f80, pt)))),
3881 128 => try o.builder.fp128Const(val.toFloat(f128, mod)),3890 128 => try o.builder.fp128Const(val.toFloat(f128, pt)),
3882 else => unreachable,3891 else => unreachable,
3883 },3892 },
3884 .ptr => try o.lowerPtr(arg_val, 0),3893 .ptr => try o.lowerPtr(arg_val, 0),
...@@ -3891,7 +3900,7 @@ pub const Object = struct {...@@ -3891,7 +3900,7 @@ pub const Object = struct {
3891 const payload_ty = ty.optionalChild(mod);3900 const payload_ty = ty.optionalChild(mod);
38923901
3893 const non_null_bit = try o.builder.intConst(.i8, @intFromBool(opt.val != .none));3902 const non_null_bit = try o.builder.intConst(.i8, @intFromBool(opt.val != .none));
3894 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {3903 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
3895 return non_null_bit;3904 return non_null_bit;
3896 }3905 }
3897 const llvm_ty = try o.lowerType(ty);3906 const llvm_ty = try o.lowerType(ty);
...@@ -3909,7 +3918,7 @@ pub const Object = struct {...@@ -3909,7 +3918,7 @@ pub const Object = struct {
3909 var fields: [3]Builder.Type = undefined;3918 var fields: [3]Builder.Type = undefined;
3910 var vals: [3]Builder.Constant = undefined;3919 var vals: [3]Builder.Constant = undefined;
3911 vals[0] = try o.lowerValue(switch (opt.val) {3920 vals[0] = try o.lowerValue(switch (opt.val) {
3912 .none => try mod.intern(.{ .undef = payload_ty.toIntern() }),3921 .none => try pt.intern(.{ .undef = payload_ty.toIntern() }),
3913 else => |payload| payload,3922 else => |payload| payload,
3914 });3923 });
3915 vals[1] = non_null_bit;3924 vals[1] = non_null_bit;
...@@ -4058,9 +4067,9 @@ pub const Object = struct {...@@ -4058,9 +4067,9 @@ pub const Object = struct {
4058 0..,4067 0..,
4059 ) |field_ty, field_val, field_index| {4068 ) |field_ty, field_val, field_index| {
4060 if (field_val != .none) continue;4069 if (field_val != .none) continue;
4061 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) continue;4070 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue;
40624071
4063 const field_align = Type.fromInterned(field_ty).abiAlignment(mod);4072 const field_align = Type.fromInterned(field_ty).abiAlignment(pt);
4064 big_align = big_align.max(field_align);4073 big_align = big_align.max(field_align);
4065 const prev_offset = offset;4074 const prev_offset = offset;
4066 offset = field_align.forward(offset);4075 offset = field_align.forward(offset);
...@@ -4076,13 +4085,13 @@ pub const Object = struct {...@@ -4076,13 +4085,13 @@ pub const Object = struct {
4076 }4085 }
40774086
4078 vals[llvm_index] =4087 vals[llvm_index] =
4079 try o.lowerValue((try val.fieldValue(mod, field_index)).toIntern());4088 try o.lowerValue((try val.fieldValue(pt, field_index)).toIntern());
4080 fields[llvm_index] = vals[llvm_index].typeOf(&o.builder);4089 fields[llvm_index] = vals[llvm_index].typeOf(&o.builder);
4081 if (fields[llvm_index] != struct_ty.structFields(&o.builder)[llvm_index])4090 if (fields[llvm_index] != struct_ty.structFields(&o.builder)[llvm_index])
4082 need_unnamed = true;4091 need_unnamed = true;
4083 llvm_index += 1;4092 llvm_index += 1;
40844093
4085 offset += Type.fromInterned(field_ty).abiSize(mod);4094 offset += Type.fromInterned(field_ty).abiSize(pt);
4086 }4095 }
4087 {4096 {
4088 const prev_offset = offset;4097 const prev_offset = offset;
...@@ -4109,7 +4118,7 @@ pub const Object = struct {...@@ -4109,7 +4118,7 @@ pub const Object = struct {
4109 if (struct_type.layout == .@"packed") {4118 if (struct_type.layout == .@"packed") {
4110 comptime assert(Type.packed_struct_layout_version == 2);4119 comptime assert(Type.packed_struct_layout_version == 2);
41114120
4112 const bits = ty.bitSize(mod);4121 const bits = ty.bitSize(pt);
4113 const llvm_int_ty = try o.builder.intType(@intCast(bits));4122 const llvm_int_ty = try o.builder.intType(@intCast(bits));
41144123
4115 return o.lowerValueToInt(llvm_int_ty, arg_val);4124 return o.lowerValueToInt(llvm_int_ty, arg_val);
...@@ -4138,7 +4147,7 @@ pub const Object = struct {...@@ -4138,7 +4147,7 @@ pub const Object = struct {
4138 var field_it = struct_type.iterateRuntimeOrder(ip);4147 var field_it = struct_type.iterateRuntimeOrder(ip);
4139 while (field_it.next()) |field_index| {4148 while (field_it.next()) |field_index| {
4140 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);4149 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
4141 const field_align = mod.structFieldAlignment(4150 const field_align = pt.structFieldAlignment(
4142 struct_type.fieldAlign(ip, field_index),4151 struct_type.fieldAlign(ip, field_index),
4143 field_ty,4152 field_ty,
4144 struct_type.layout,4153 struct_type.layout,
...@@ -4158,20 +4167,20 @@ pub const Object = struct {...@@ -4158,20 +4167,20 @@ pub const Object = struct {
4158 llvm_index += 1;4167 llvm_index += 1;
4159 }4168 }
41604169
4161 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {4170 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) {
4162 // This is a zero-bit field - we only needed it for the alignment.4171 // This is a zero-bit field - we only needed it for the alignment.
4163 continue;4172 continue;
4164 }4173 }
41654174
4166 vals[llvm_index] = try o.lowerValue(4175 vals[llvm_index] = try o.lowerValue(
4167 (try val.fieldValue(mod, field_index)).toIntern(),4176 (try val.fieldValue(pt, field_index)).toIntern(),
4168 );4177 );
4169 fields[llvm_index] = vals[llvm_index].typeOf(&o.builder);4178 fields[llvm_index] = vals[llvm_index].typeOf(&o.builder);
4170 if (fields[llvm_index] != struct_ty.structFields(&o.builder)[llvm_index])4179 if (fields[llvm_index] != struct_ty.structFields(&o.builder)[llvm_index])
4171 need_unnamed = true;4180 need_unnamed = true;
4172 llvm_index += 1;4181 llvm_index += 1;
41734182
4174 offset += field_ty.abiSize(mod);4183 offset += field_ty.abiSize(pt);
4175 }4184 }
4176 {4185 {
4177 const prev_offset = offset;4186 const prev_offset = offset;
...@@ -4195,7 +4204,7 @@ pub const Object = struct {...@@ -4195,7 +4204,7 @@ pub const Object = struct {
4195 },4204 },
4196 .un => |un| {4205 .un => |un| {
4197 const union_ty = try o.lowerType(ty);4206 const union_ty = try o.lowerType(ty);
4198 const layout = ty.unionGetLayout(mod);4207 const layout = ty.unionGetLayout(pt);
4199 if (layout.payload_size == 0) return o.lowerValue(un.tag);4208 if (layout.payload_size == 0) return o.lowerValue(un.tag);
42004209
4201 const union_obj = mod.typeToUnion(ty).?;4210 const union_obj = mod.typeToUnion(ty).?;
...@@ -4206,8 +4215,8 @@ pub const Object = struct {...@@ -4206,8 +4215,8 @@ pub const Object = struct {
4206 const field_index = mod.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?;4215 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]);4216 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
4208 if (container_layout == .@"packed") {4217 if (container_layout == .@"packed") {
4209 if (!field_ty.hasRuntimeBits(mod)) return o.builder.intConst(union_ty, 0);4218 if (!field_ty.hasRuntimeBits(pt)) return o.builder.intConst(union_ty, 0);
4210 const bits = ty.bitSize(mod);4219 const bits = ty.bitSize(pt);
4211 const llvm_int_ty = try o.builder.intType(@intCast(bits));4220 const llvm_int_ty = try o.builder.intType(@intCast(bits));
42124221
4213 return o.lowerValueToInt(llvm_int_ty, arg_val);4222 return o.lowerValueToInt(llvm_int_ty, arg_val);
...@@ -4219,7 +4228,7 @@ pub const Object = struct {...@@ -4219,7 +4228,7 @@ pub const Object = struct {
4219 // must pointer cast to the expected type before accessing the union.4228 // must pointer cast to the expected type before accessing the union.
4220 need_unnamed = layout.most_aligned_field != field_index;4229 need_unnamed = layout.most_aligned_field != field_index;
42214230
4222 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {4231 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) {
4223 const padding_len = layout.payload_size;4232 const padding_len = layout.payload_size;
4224 break :p try o.builder.undefConst(try o.builder.arrayType(padding_len, .i8));4233 break :p try o.builder.undefConst(try o.builder.arrayType(padding_len, .i8));
4225 }4234 }
...@@ -4228,7 +4237,7 @@ pub const Object = struct {...@@ -4228,7 +4237,7 @@ pub const Object = struct {
4228 if (payload_ty != union_ty.structFields(&o.builder)[4237 if (payload_ty != union_ty.structFields(&o.builder)[
4229 @intFromBool(layout.tag_align.compare(.gte, layout.payload_align))4238 @intFromBool(layout.tag_align.compare(.gte, layout.payload_align))
4230 ]) need_unnamed = true;4239 ]) need_unnamed = true;
4231 const field_size = field_ty.abiSize(mod);4240 const field_size = field_ty.abiSize(pt);
4232 if (field_size == layout.payload_size) break :p payload;4241 if (field_size == layout.payload_size) break :p payload;
4233 const padding_len = layout.payload_size - field_size;4242 const padding_len = layout.payload_size - field_size;
4234 const padding_ty = try o.builder.arrayType(padding_len, .i8);4243 const padding_ty = try o.builder.arrayType(padding_len, .i8);
...@@ -4239,7 +4248,7 @@ pub const Object = struct {...@@ -4239,7 +4248,7 @@ pub const Object = struct {
4239 } else p: {4248 } else p: {
4240 assert(layout.tag_size == 0);4249 assert(layout.tag_size == 0);
4241 if (container_layout == .@"packed") {4250 if (container_layout == .@"packed") {
4242 const bits = ty.bitSize(mod);4251 const bits = ty.bitSize(pt);
4243 const llvm_int_ty = try o.builder.intType(@intCast(bits));4252 const llvm_int_ty = try o.builder.intType(@intCast(bits));
42444253
4245 return o.lowerValueToInt(llvm_int_ty, arg_val);4254 return o.lowerValueToInt(llvm_int_ty, arg_val);
...@@ -4286,7 +4295,7 @@ pub const Object = struct {...@@ -4286,7 +4295,7 @@ pub const Object = struct {
4286 ty: Type,4295 ty: Type,
4287 bigint: std.math.big.int.Const,4296 bigint: std.math.big.int.Const,
4288 ) Allocator.Error!Builder.Constant {4297 ) Allocator.Error!Builder.Constant {
4289 const mod = o.module;4298 const mod = o.pt.zcu;
4290 return o.builder.bigIntConst(try o.builder.intType(ty.intInfo(mod).bits), bigint);4299 return o.builder.bigIntConst(try o.builder.intType(ty.intInfo(mod).bits), bigint);
4291 }4300 }
42924301
...@@ -4295,7 +4304,8 @@ pub const Object = struct {...@@ -4295,7 +4304,8 @@ pub const Object = struct {
4295 ptr_val: InternPool.Index,4304 ptr_val: InternPool.Index,
4296 prev_offset: u64,4305 prev_offset: u64,
4297 ) Error!Builder.Constant {4306 ) Error!Builder.Constant {
4298 const zcu = o.module;4307 const pt = o.pt;
4308 const zcu = pt.zcu;
4299 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;4309 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;
4300 const offset: u64 = prev_offset + ptr.byte_offset;4310 const offset: u64 = prev_offset + ptr.byte_offset;
4301 return switch (ptr.base_addr) {4311 return switch (ptr.base_addr) {
...@@ -4320,7 +4330,7 @@ pub const Object = struct {...@@ -4320,7 +4330,7 @@ pub const Object = struct {
4320 eu_ptr,4330 eu_ptr,
4321 offset + @import("../codegen.zig").errUnionPayloadOffset(4331 offset + @import("../codegen.zig").errUnionPayloadOffset(
4322 Value.fromInterned(eu_ptr).typeOf(zcu).childType(zcu),4332 Value.fromInterned(eu_ptr).typeOf(zcu).childType(zcu),
4323 zcu,4333 pt,
4324 ),4334 ),
4325 ),4335 ),
4326 .opt_payload => |opt_ptr| try o.lowerPtr(opt_ptr, offset),4336 .opt_payload => |opt_ptr| try o.lowerPtr(opt_ptr, offset),
...@@ -4336,7 +4346,7 @@ pub const Object = struct {...@@ -4336,7 +4346,7 @@ pub const Object = struct {
4336 };4346 };
4337 },4347 },
4338 .Struct, .Union => switch (agg_ty.containerLayout(zcu)) {4348 .Struct, .Union => switch (agg_ty.containerLayout(zcu)) {
4339 .auto => agg_ty.structFieldOffset(@intCast(field.index), zcu),4349 .auto => agg_ty.structFieldOffset(@intCast(field.index), pt),
4340 .@"extern", .@"packed" => unreachable,4350 .@"extern", .@"packed" => unreachable,
4341 },4351 },
4342 else => unreachable,4352 else => unreachable,
...@@ -4353,7 +4363,8 @@ pub const Object = struct {...@@ -4353,7 +4363,8 @@ pub const Object = struct {
4353 o: *Object,4363 o: *Object,
4354 anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl,4364 anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl,
4355 ) Error!Builder.Constant {4365 ) Error!Builder.Constant {
4356 const mod = o.module;4366 const pt = o.pt;
4367 const mod = pt.zcu;
4357 const ip = &mod.intern_pool;4368 const ip = &mod.intern_pool;
4358 const decl_val = anon_decl.val;4369 const decl_val = anon_decl.val;
4359 const decl_ty = Type.fromInterned(ip.typeOf(decl_val));4370 const decl_ty = Type.fromInterned(ip.typeOf(decl_val));
...@@ -4370,14 +4381,14 @@ pub const Object = struct {...@@ -4370,14 +4381,14 @@ pub const Object = struct {
4370 const ptr_ty = Type.fromInterned(anon_decl.orig_ty);4381 const ptr_ty = Type.fromInterned(anon_decl.orig_ty);
43714382
4372 const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;4383 const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;
4373 if ((!is_fn_body and !decl_ty.hasRuntimeBits(mod)) or4384 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);4385 (is_fn_body and mod.typeToFunc(decl_ty).?.is_generic)) return o.lowerPtrToVoid(ptr_ty);
43754386
4376 if (is_fn_body)4387 if (is_fn_body)
4377 @panic("TODO");4388 @panic("TODO");
43784389
4379 const llvm_addr_space = toLlvmAddressSpace(ptr_ty.ptrAddressSpace(mod), target);4390 const llvm_addr_space = toLlvmAddressSpace(ptr_ty.ptrAddressSpace(mod), target);
4380 const alignment = ptr_ty.ptrAlignment(mod);4391 const alignment = ptr_ty.ptrAlignment(pt);
4381 const llvm_global = (try o.resolveGlobalAnonDecl(decl_val, llvm_addr_space, alignment)).ptrConst(&o.builder).global;4392 const llvm_global = (try o.resolveGlobalAnonDecl(decl_val, llvm_addr_space, alignment)).ptrConst(&o.builder).global;
43824393
4383 const llvm_val = try o.builder.convConst(4394 const llvm_val = try o.builder.convConst(
...@@ -4389,7 +4400,8 @@ pub const Object = struct {...@@ -4389,7 +4400,8 @@ pub const Object = struct {
4389 }4400 }
43904401
4391 fn lowerDeclRefValue(o: *Object, decl_index: InternPool.DeclIndex) Allocator.Error!Builder.Constant {4402 fn lowerDeclRefValue(o: *Object, decl_index: InternPool.DeclIndex) Allocator.Error!Builder.Constant {
4392 const mod = o.module;4403 const pt = o.pt;
4404 const mod = pt.zcu;
43934405
4394 // In the case of something like:4406 // In the case of something like:
4395 // fn foo() void {}4407 // fn foo() void {}
...@@ -4408,10 +4420,10 @@ pub const Object = struct {...@@ -4408,10 +4420,10 @@ pub const Object = struct {
4408 }4420 }
44094421
4410 const decl_ty = decl.typeOf(mod);4422 const decl_ty = decl.typeOf(mod);
4411 const ptr_ty = try decl.declPtrType(mod);4423 const ptr_ty = try decl.declPtrType(pt);
44124424
4413 const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;4425 const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;
4414 if ((!is_fn_body and !decl_ty.hasRuntimeBits(mod)) or4426 if ((!is_fn_body and !decl_ty.hasRuntimeBits(pt)) or
4415 (is_fn_body and mod.typeToFunc(decl_ty).?.is_generic))4427 (is_fn_body and mod.typeToFunc(decl_ty).?.is_generic))
4416 {4428 {
4417 return o.lowerPtrToVoid(ptr_ty);4429 return o.lowerPtrToVoid(ptr_ty);
...@@ -4431,7 +4443,7 @@ pub const Object = struct {...@@ -4431,7 +4443,7 @@ pub const Object = struct {
4431 }4443 }
44324444
4433 fn lowerPtrToVoid(o: *Object, ptr_ty: Type) Allocator.Error!Builder.Constant {4445 fn lowerPtrToVoid(o: *Object, ptr_ty: Type) Allocator.Error!Builder.Constant {
4434 const mod = o.module;4446 const mod = o.pt.zcu;
4435 // Even though we are pointing at something which has zero bits (e.g. `void`),4447 // 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.4448 // Pointers are defined to have bits. So we must return something here.
4437 // The value cannot be undefined, because we use the `nonnull` annotation4449 // The value cannot be undefined, because we use the `nonnull` annotation
...@@ -4459,20 +4471,21 @@ pub const Object = struct {...@@ -4459,20 +4471,21 @@ pub const Object = struct {
4459 /// RMW exchange of floating-point values is bitcasted to same-sized integer4471 /// RMW exchange of floating-point values is bitcasted to same-sized integer
4460 /// types to work around a LLVM deficiency when targeting ARM/AArch64.4472 /// 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 {4473 fn getAtomicAbiType(o: *Object, ty: Type, is_rmw_xchg: bool) Allocator.Error!Builder.Type {
4462 const mod = o.module;4474 const pt = o.pt;
4475 const mod = pt.zcu;
4463 const int_ty = switch (ty.zigTypeTag(mod)) {4476 const int_ty = switch (ty.zigTypeTag(mod)) {
4464 .Int => ty,4477 .Int => ty,
4465 .Enum => ty.intTagType(mod),4478 .Enum => ty.intTagType(mod),
4466 .Float => {4479 .Float => {
4467 if (!is_rmw_xchg) return .none;4480 if (!is_rmw_xchg) return .none;
4468 return o.builder.intType(@intCast(ty.abiSize(mod) * 8));4481 return o.builder.intType(@intCast(ty.abiSize(pt) * 8));
4469 },4482 },
4470 .Bool => return .i8,4483 .Bool => return .i8,
4471 else => return .none,4484 else => return .none,
4472 };4485 };
4473 const bit_count = int_ty.intInfo(mod).bits;4486 const bit_count = int_ty.intInfo(mod).bits;
4474 if (!std.math.isPowerOfTwo(bit_count) or (bit_count % 8) != 0) {4487 if (!std.math.isPowerOfTwo(bit_count) or (bit_count % 8) != 0) {
4475 return o.builder.intType(@intCast(int_ty.abiSize(mod) * 8));4488 return o.builder.intType(@intCast(int_ty.abiSize(pt) * 8));
4476 } else {4489 } else {
4477 return .none;4490 return .none;
4478 }4491 }
...@@ -4486,7 +4499,8 @@ pub const Object = struct {...@@ -4486,7 +4499,8 @@ pub const Object = struct {
4486 fn_info: InternPool.Key.FuncType,4499 fn_info: InternPool.Key.FuncType,
4487 llvm_arg_i: u32,4500 llvm_arg_i: u32,
4488 ) Allocator.Error!void {4501 ) Allocator.Error!void {
4489 const mod = o.module;4502 const pt = o.pt;
4503 const mod = pt.zcu;
4490 if (param_ty.isPtrAtRuntime(mod)) {4504 if (param_ty.isPtrAtRuntime(mod)) {
4491 const ptr_info = param_ty.ptrInfo(mod);4505 const ptr_info = param_ty.ptrInfo(mod);
4492 if (math.cast(u5, param_index)) |i| {4506 if (math.cast(u5, param_index)) |i| {
...@@ -4507,7 +4521,7 @@ pub const Object = struct {...@@ -4507,7 +4521,7 @@ pub const Object = struct {
4507 const elem_align = if (ptr_info.flags.alignment != .none)4521 const elem_align = if (ptr_info.flags.alignment != .none)
4508 ptr_info.flags.alignment4522 ptr_info.flags.alignment
4509 else4523 else
4510 Type.fromInterned(ptr_info.child).abiAlignment(mod).max(.@"1");4524 Type.fromInterned(ptr_info.child).abiAlignment(pt).max(.@"1");
4511 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align.toLlvm() }, &o.builder);4525 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) {4526 } else if (ccAbiPromoteInt(fn_info.cc, mod, param_ty)) |s| switch (s) {
4513 .signed => try attributes.addParamAttr(llvm_arg_i, .signext, &o.builder),4527 .signed => try attributes.addParamAttr(llvm_arg_i, .signext, &o.builder),
...@@ -4540,7 +4554,7 @@ pub const Object = struct {...@@ -4540,7 +4554,7 @@ pub const Object = struct {
4540 const name = try o.builder.strtabString(lt_errors_fn_name);4554 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;4555 if (o.builder.getGlobal(name)) |llvm_fn| return llvm_fn.ptrConst(&o.builder).kind.function;
45424556
4543 const zcu = o.module;4557 const zcu = o.pt.zcu;
4544 const target = zcu.root_mod.resolved_target.result;4558 const target = zcu.root_mod.resolved_target.result;
4545 const function_index = try o.builder.addFunction(4559 const function_index = try o.builder.addFunction(
4546 try o.builder.fnType(.i1, &.{try o.errorIntType()}, .normal),4560 try o.builder.fnType(.i1, &.{try o.errorIntType()}, .normal),
...@@ -4559,7 +4573,8 @@ pub const Object = struct {...@@ -4559,7 +4573,8 @@ pub const Object = struct {
4559 }4573 }
45604574
4561 fn getEnumTagNameFunction(o: *Object, enum_ty: Type) !Builder.Function.Index {4575 fn getEnumTagNameFunction(o: *Object, enum_ty: Type) !Builder.Function.Index {
4562 const zcu = o.module;4576 const pt = o.pt;
4577 const zcu = pt.zcu;
4563 const ip = &zcu.intern_pool;4578 const ip = &zcu.intern_pool;
4564 const enum_type = ip.loadEnumType(enum_ty.toIntern());4579 const enum_type = ip.loadEnumType(enum_ty.toIntern());
45654580
...@@ -4618,7 +4633,7 @@ pub const Object = struct {...@@ -4618,7 +4633,7 @@ pub const Object = struct {
46184633
4619 const return_block = try wip.block(1, "Name");4634 const return_block = try wip.block(1, "Name");
4620 const this_tag_int_value = try o.lowerValue(4635 const this_tag_int_value = try o.lowerValue(
4621 (try zcu.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(),4636 (try pt.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(),
4622 );4637 );
4623 try wip_switch.addCase(this_tag_int_value, return_block, &wip);4638 try wip_switch.addCase(this_tag_int_value, return_block, &wip);
46244639
...@@ -4636,13 +4651,13 @@ pub const Object = struct {...@@ -4636,13 +4651,13 @@ pub const Object = struct {
46364651
4637pub const DeclGen = struct {4652pub const DeclGen = struct {
4638 object: *Object,4653 object: *Object,
4639 decl: *Module.Decl,4654 decl: *Zcu.Decl,
4640 decl_index: InternPool.DeclIndex,4655 decl_index: InternPool.DeclIndex,
4641 err_msg: ?*Module.ErrorMsg,4656 err_msg: ?*Zcu.ErrorMsg,
46424657
4643 fn ownerModule(dg: DeclGen) *Package.Module {4658 fn ownerModule(dg: DeclGen) *Package.Module {
4644 const o = dg.object;4659 const o = dg.object;
4645 const zcu = o.module;4660 const zcu = o.pt.zcu;
4646 const namespace = zcu.namespacePtr(dg.decl.src_namespace);4661 const namespace = zcu.namespacePtr(dg.decl.src_namespace);
4647 const file_scope = namespace.fileScope(zcu);4662 const file_scope = namespace.fileScope(zcu);
4648 return file_scope.mod;4663 return file_scope.mod;
...@@ -4653,15 +4668,15 @@ pub const DeclGen = struct {...@@ -4653,15 +4668,15 @@ pub const DeclGen = struct {
4653 assert(dg.err_msg == null);4668 assert(dg.err_msg == null);
4654 const o = dg.object;4669 const o = dg.object;
4655 const gpa = o.gpa;4670 const gpa = o.gpa;
4656 const mod = o.module;4671 const src_loc = dg.decl.navSrcLoc(o.pt.zcu);
4657 const src_loc = dg.decl.navSrcLoc(mod);4672 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;4673 return error.CodegenFail;
4660 }4674 }
46614675
4662 fn genDecl(dg: *DeclGen) !void {4676 fn genDecl(dg: *DeclGen) !void {
4663 const o = dg.object;4677 const o = dg.object;
4664 const zcu = o.module;4678 const pt = o.pt;
4679 const zcu = pt.zcu;
4665 const ip = &zcu.intern_pool;4680 const ip = &zcu.intern_pool;
4666 const decl = dg.decl;4681 const decl = dg.decl;
4667 const decl_index = dg.decl_index;4682 const decl_index = dg.decl_index;
...@@ -4672,7 +4687,7 @@ pub const DeclGen = struct {...@@ -4672,7 +4687,7 @@ pub const DeclGen = struct {
4672 } else {4687 } else {
4673 const variable_index = try o.resolveGlobalDecl(decl_index);4688 const variable_index = try o.resolveGlobalDecl(decl_index);
4674 variable_index.setAlignment(4689 variable_index.setAlignment(
4675 decl.getAlignment(zcu).toLlvm(),4690 decl.getAlignment(pt).toLlvm(),
4676 &o.builder,4691 &o.builder,
4677 );4692 );
4678 if (decl.@"linksection".toSlice(ip)) |section|4693 if (decl.@"linksection".toSlice(ip)) |section|
...@@ -4833,23 +4848,21 @@ pub const FuncGen = struct {...@@ -4833,23 +4848,21 @@ pub const FuncGen = struct {
4833 const gop = try self.func_inst_table.getOrPut(gpa, inst);4848 const gop = try self.func_inst_table.getOrPut(gpa, inst);
4834 if (gop.found_existing) return gop.value_ptr.*;4849 if (gop.found_existing) return gop.value_ptr.*;
48354850
4836 const o = self.dg.object;4851 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();4852 gop.value_ptr.* = llvm_val.toValue();
4840 return llvm_val.toValue();4853 return llvm_val.toValue();
4841 }4854 }
48424855
4843 fn resolveValue(self: *FuncGen, val: Value) Error!Builder.Constant {4856 fn resolveValue(self: *FuncGen, val: Value) Error!Builder.Constant {
4844 const o = self.dg.object;4857 const o = self.dg.object;
4845 const mod = o.module;4858 const pt = o.pt;
4846 const ty = val.typeOf(mod);4859 const ty = val.typeOf(pt.zcu);
4847 const llvm_val = try o.lowerValue(val.toIntern());4860 const llvm_val = try o.lowerValue(val.toIntern());
4848 if (!isByRef(ty, mod)) return llvm_val;4861 if (!isByRef(ty, pt)) return llvm_val;
48494862
4850 // We have an LLVM value but we need to create a global constant and4863 // 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.4864 // set the value as its initializer, and then return a pointer to the global.
4852 const target = mod.getTarget();4865 const target = pt.zcu.getTarget();
4853 const variable_index = try o.builder.addVariable(4866 const variable_index = try o.builder.addVariable(
4854 .empty,4867 .empty,
4855 llvm_val.typeOf(&o.builder),4868 llvm_val.typeOf(&o.builder),
...@@ -4859,7 +4872,7 @@ pub const FuncGen = struct {...@@ -4859,7 +4872,7 @@ pub const FuncGen = struct {
4859 variable_index.setLinkage(.private, &o.builder);4872 variable_index.setLinkage(.private, &o.builder);
4860 variable_index.setMutability(.constant, &o.builder);4873 variable_index.setMutability(.constant, &o.builder);
4861 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);4874 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
4862 variable_index.setAlignment(ty.abiAlignment(mod).toLlvm(), &o.builder);4875 variable_index.setAlignment(ty.abiAlignment(pt).toLlvm(), &o.builder);
4863 return o.builder.convConst(4876 return o.builder.convConst(
4864 variable_index.toConst(&o.builder),4877 variable_index.toConst(&o.builder),
4865 try o.builder.ptrType(toLlvmAddressSpace(.generic, target)),4878 try o.builder.ptrType(toLlvmAddressSpace(.generic, target)),
...@@ -4868,10 +4881,10 @@ pub const FuncGen = struct {...@@ -4868,10 +4881,10 @@ pub const FuncGen = struct {
48684881
4869 fn resolveNullOptUsize(self: *FuncGen) Error!Builder.Constant {4882 fn resolveNullOptUsize(self: *FuncGen) Error!Builder.Constant {
4870 const o = self.dg.object;4883 const o = self.dg.object;
4871 const mod = o.module;4884 const pt = o.pt;
4872 if (o.null_opt_usize == .no_init) {4885 if (o.null_opt_usize == .no_init) {
4873 o.null_opt_usize = try self.resolveValue(Value.fromInterned(try mod.intern(.{ .opt = .{4886 o.null_opt_usize = try self.resolveValue(Value.fromInterned(try pt.intern(.{ .opt = .{
4874 .ty = try mod.intern(.{ .opt_type = .usize_type }),4887 .ty = try pt.intern(.{ .opt_type = .usize_type }),
4875 .val = .none,4888 .val = .none,
4876 } })));4889 } })));
4877 }4890 }
...@@ -4880,7 +4893,7 @@ pub const FuncGen = struct {...@@ -4880,7 +4893,7 @@ pub const FuncGen = struct {
48804893
4881 fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {4894 fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {
4882 const o = self.dg.object;4895 const o = self.dg.object;
4883 const mod = o.module;4896 const mod = o.pt.zcu;
4884 const ip = &mod.intern_pool;4897 const ip = &mod.intern_pool;
4885 const air_tags = self.air.instructions.items(.tag);4898 const air_tags = self.air.instructions.items(.tag);
4886 for (body, 0..) |inst, i| {4899 for (body, 0..) |inst, i| {
...@@ -5145,7 +5158,8 @@ pub const FuncGen = struct {...@@ -5145,7 +5158,8 @@ pub const FuncGen = struct {
51455158
5146 if (maybe_inline_func) |inline_func| {5159 if (maybe_inline_func) |inline_func| {
5147 const o = self.dg.object;5160 const o = self.dg.object;
5148 const zcu = o.module;5161 const pt = o.pt;
5162 const zcu = pt.zcu;
51495163
5150 const func = zcu.funcInfo(inline_func);5164 const func = zcu.funcInfo(inline_func);
5151 const decl_index = func.owner_decl;5165 const decl_index = func.owner_decl;
...@@ -5161,7 +5175,7 @@ pub const FuncGen = struct {...@@ -5161,7 +5175,7 @@ pub const FuncGen = struct {
51615175
5162 const fqn = try decl.fullyQualifiedName(zcu);5176 const fqn = try decl.fullyQualifiedName(zcu);
51635177
5164 const fn_ty = try zcu.funcType(.{5178 const fn_ty = try pt.funcType(.{
5165 .param_types = &.{},5179 .param_types = &.{},
5166 .return_type = .void_type,5180 .return_type = .void_type,
5167 });5181 });
...@@ -5228,7 +5242,8 @@ pub const FuncGen = struct {...@@ -5228,7 +5242,8 @@ pub const FuncGen = struct {
5228 const extra = self.air.extraData(Air.Call, pl_op.payload);5242 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]);5243 const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]);
5230 const o = self.dg.object;5244 const o = self.dg.object;
5231 const mod = o.module;5245 const pt = o.pt;
5246 const mod = pt.zcu;
5232 const ip = &mod.intern_pool;5247 const ip = &mod.intern_pool;
5233 const callee_ty = self.typeOf(pl_op.operand);5248 const callee_ty = self.typeOf(pl_op.operand);
5234 const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) {5249 const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) {
...@@ -5240,7 +5255,7 @@ pub const FuncGen = struct {...@@ -5240,7 +5255,7 @@ pub const FuncGen = struct {
5240 const return_type = Type.fromInterned(fn_info.return_type);5255 const return_type = Type.fromInterned(fn_info.return_type);
5241 const llvm_fn = try self.resolveInst(pl_op.operand);5256 const llvm_fn = try self.resolveInst(pl_op.operand);
5242 const target = mod.getTarget();5257 const target = mod.getTarget();
5243 const sret = firstParamSRet(fn_info, mod, target);5258 const sret = firstParamSRet(fn_info, pt, target);
52445259
5245 var llvm_args = std.ArrayList(Builder.Value).init(self.gpa);5260 var llvm_args = std.ArrayList(Builder.Value).init(self.gpa);
5246 defer llvm_args.deinit();5261 defer llvm_args.deinit();
...@@ -5258,14 +5273,13 @@ pub const FuncGen = struct {...@@ -5258,14 +5273,13 @@ pub const FuncGen = struct {
5258 const llvm_ret_ty = try o.lowerType(return_type);5273 const llvm_ret_ty = try o.lowerType(return_type);
5259 try attributes.addParamAttr(0, .{ .sret = llvm_ret_ty }, &o.builder);5274 try attributes.addParamAttr(0, .{ .sret = llvm_ret_ty }, &o.builder);
52605275
5261 const alignment = return_type.abiAlignment(mod).toLlvm();5276 const alignment = return_type.abiAlignment(pt).toLlvm();
5262 const ret_ptr = try self.buildAllocaWorkaround(return_type, alignment);5277 const ret_ptr = try self.buildAllocaWorkaround(return_type, alignment);
5263 try llvm_args.append(ret_ptr);5278 try llvm_args.append(ret_ptr);
5264 break :blk ret_ptr;5279 break :blk ret_ptr;
5265 };5280 };
52665281
5267 const err_return_tracing = return_type.isError(mod) and5282 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) {5283 if (err_return_tracing) {
5270 assert(self.err_ret_trace != .none);5284 assert(self.err_ret_trace != .none);
5271 try llvm_args.append(self.err_ret_trace);5285 try llvm_args.append(self.err_ret_trace);
...@@ -5279,8 +5293,8 @@ pub const FuncGen = struct {...@@ -5279,8 +5293,8 @@ pub const FuncGen = struct {
5279 const param_ty = self.typeOf(arg);5293 const param_ty = self.typeOf(arg);
5280 const llvm_arg = try self.resolveInst(arg);5294 const llvm_arg = try self.resolveInst(arg);
5281 const llvm_param_ty = try o.lowerType(param_ty);5295 const llvm_param_ty = try o.lowerType(param_ty);
5282 if (isByRef(param_ty, mod)) {5296 if (isByRef(param_ty, pt)) {
5283 const alignment = param_ty.abiAlignment(mod).toLlvm();5297 const alignment = param_ty.abiAlignment(pt).toLlvm();
5284 const loaded = try self.wip.load(.normal, llvm_param_ty, llvm_arg, alignment, "");5298 const loaded = try self.wip.load(.normal, llvm_param_ty, llvm_arg, alignment, "");
5285 try llvm_args.append(loaded);5299 try llvm_args.append(loaded);
5286 } else {5300 } else {
...@@ -5291,10 +5305,10 @@ pub const FuncGen = struct {...@@ -5291,10 +5305,10 @@ pub const FuncGen = struct {
5291 const arg = args[it.zig_index - 1];5305 const arg = args[it.zig_index - 1];
5292 const param_ty = self.typeOf(arg);5306 const param_ty = self.typeOf(arg);
5293 const llvm_arg = try self.resolveInst(arg);5307 const llvm_arg = try self.resolveInst(arg);
5294 if (isByRef(param_ty, mod)) {5308 if (isByRef(param_ty, pt)) {
5295 try llvm_args.append(llvm_arg);5309 try llvm_args.append(llvm_arg);
5296 } else {5310 } else {
5297 const alignment = param_ty.abiAlignment(mod).toLlvm();5311 const alignment = param_ty.abiAlignment(pt).toLlvm();
5298 const param_llvm_ty = llvm_arg.typeOfWip(&self.wip);5312 const param_llvm_ty = llvm_arg.typeOfWip(&self.wip);
5299 const arg_ptr = try self.buildAlloca(param_llvm_ty, alignment);5313 const arg_ptr = try self.buildAlloca(param_llvm_ty, alignment);
5300 _ = try self.wip.store(.normal, llvm_arg, arg_ptr, alignment);5314 _ = try self.wip.store(.normal, llvm_arg, arg_ptr, alignment);
...@@ -5306,10 +5320,10 @@ pub const FuncGen = struct {...@@ -5306,10 +5320,10 @@ pub const FuncGen = struct {
5306 const param_ty = self.typeOf(arg);5320 const param_ty = self.typeOf(arg);
5307 const llvm_arg = try self.resolveInst(arg);5321 const llvm_arg = try self.resolveInst(arg);
53085322
5309 const alignment = param_ty.abiAlignment(mod).toLlvm();5323 const alignment = param_ty.abiAlignment(pt).toLlvm();
5310 const param_llvm_ty = try o.lowerType(param_ty);5324 const param_llvm_ty = try o.lowerType(param_ty);
5311 const arg_ptr = try self.buildAllocaWorkaround(param_ty, alignment);5325 const arg_ptr = try self.buildAllocaWorkaround(param_ty, alignment);
5312 if (isByRef(param_ty, mod)) {5326 if (isByRef(param_ty, pt)) {
5313 const loaded = try self.wip.load(.normal, param_llvm_ty, llvm_arg, alignment, "");5327 const loaded = try self.wip.load(.normal, param_llvm_ty, llvm_arg, alignment, "");
5314 _ = try self.wip.store(.normal, loaded, arg_ptr, alignment);5328 _ = try self.wip.store(.normal, loaded, arg_ptr, alignment);
5315 } else {5329 } else {
...@@ -5321,16 +5335,16 @@ pub const FuncGen = struct {...@@ -5321,16 +5335,16 @@ pub const FuncGen = struct {
5321 const arg = args[it.zig_index - 1];5335 const arg = args[it.zig_index - 1];
5322 const param_ty = self.typeOf(arg);5336 const param_ty = self.typeOf(arg);
5323 const llvm_arg = try self.resolveInst(arg);5337 const llvm_arg = try self.resolveInst(arg);
5324 const int_llvm_ty = try o.builder.intType(@intCast(param_ty.abiSize(mod) * 8));5338 const int_llvm_ty = try o.builder.intType(@intCast(param_ty.abiSize(pt) * 8));
53255339
5326 if (isByRef(param_ty, mod)) {5340 if (isByRef(param_ty, pt)) {
5327 const alignment = param_ty.abiAlignment(mod).toLlvm();5341 const alignment = param_ty.abiAlignment(pt).toLlvm();
5328 const loaded = try self.wip.load(.normal, int_llvm_ty, llvm_arg, alignment, "");5342 const loaded = try self.wip.load(.normal, int_llvm_ty, llvm_arg, alignment, "");
5329 try llvm_args.append(loaded);5343 try llvm_args.append(loaded);
5330 } else {5344 } else {
5331 // LLVM does not allow bitcasting structs so we must allocate5345 // LLVM does not allow bitcasting structs so we must allocate
5332 // a local, store as one type, and then load as another type.5346 // a local, store as one type, and then load as another type.
5333 const alignment = param_ty.abiAlignment(mod).toLlvm();5347 const alignment = param_ty.abiAlignment(pt).toLlvm();
5334 const int_ptr = try self.buildAllocaWorkaround(param_ty, alignment);5348 const int_ptr = try self.buildAllocaWorkaround(param_ty, alignment);
5335 _ = try self.wip.store(.normal, llvm_arg, int_ptr, alignment);5349 _ = try self.wip.store(.normal, llvm_arg, int_ptr, alignment);
5336 const loaded = try self.wip.load(.normal, int_llvm_ty, int_ptr, alignment, "");5350 const loaded = try self.wip.load(.normal, int_llvm_ty, int_ptr, alignment, "");
...@@ -5349,9 +5363,9 @@ pub const FuncGen = struct {...@@ -5349,9 +5363,9 @@ pub const FuncGen = struct {
5349 const param_ty = self.typeOf(arg);5363 const param_ty = self.typeOf(arg);
5350 const llvm_types = it.types_buffer[0..it.types_len];5364 const llvm_types = it.types_buffer[0..it.types_len];
5351 const llvm_arg = try self.resolveInst(arg);5365 const llvm_arg = try self.resolveInst(arg);
5352 const is_by_ref = isByRef(param_ty, mod);5366 const is_by_ref = isByRef(param_ty, pt);
5353 const arg_ptr = if (is_by_ref) llvm_arg else ptr: {5367 const arg_ptr = if (is_by_ref) llvm_arg else ptr: {
5354 const alignment = param_ty.abiAlignment(mod).toLlvm();5368 const alignment = param_ty.abiAlignment(pt).toLlvm();
5355 const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment);5369 const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment);
5356 _ = try self.wip.store(.normal, llvm_arg, ptr, alignment);5370 _ = try self.wip.store(.normal, llvm_arg, ptr, alignment);
5357 break :ptr ptr;5371 break :ptr ptr;
...@@ -5377,8 +5391,8 @@ pub const FuncGen = struct {...@@ -5377,8 +5391,8 @@ pub const FuncGen = struct {
5377 const arg = args[it.zig_index - 1];5391 const arg = args[it.zig_index - 1];
5378 const arg_ty = self.typeOf(arg);5392 const arg_ty = self.typeOf(arg);
5379 var llvm_arg = try self.resolveInst(arg);5393 var llvm_arg = try self.resolveInst(arg);
5380 const alignment = arg_ty.abiAlignment(mod).toLlvm();5394 const alignment = arg_ty.abiAlignment(pt).toLlvm();
5381 if (!isByRef(arg_ty, mod)) {5395 if (!isByRef(arg_ty, pt)) {
5382 const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment);5396 const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment);
5383 _ = try self.wip.store(.normal, llvm_arg, ptr, alignment);5397 _ = try self.wip.store(.normal, llvm_arg, ptr, alignment);
5384 llvm_arg = ptr;5398 llvm_arg = ptr;
...@@ -5395,8 +5409,8 @@ pub const FuncGen = struct {...@@ -5395,8 +5409,8 @@ pub const FuncGen = struct {
5395 const arg = args[it.zig_index - 1];5409 const arg = args[it.zig_index - 1];
5396 const arg_ty = self.typeOf(arg);5410 const arg_ty = self.typeOf(arg);
5397 var llvm_arg = try self.resolveInst(arg);5411 var llvm_arg = try self.resolveInst(arg);
5398 const alignment = arg_ty.abiAlignment(mod).toLlvm();5412 const alignment = arg_ty.abiAlignment(pt).toLlvm();
5399 if (!isByRef(arg_ty, mod)) {5413 if (!isByRef(arg_ty, pt)) {
5400 const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment);5414 const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment);
5401 _ = try self.wip.store(.normal, llvm_arg, ptr, alignment);5415 _ = try self.wip.store(.normal, llvm_arg, ptr, alignment);
5402 llvm_arg = ptr;5416 llvm_arg = ptr;
...@@ -5418,7 +5432,7 @@ pub const FuncGen = struct {...@@ -5418,7 +5432,7 @@ pub const FuncGen = struct {
5418 .byval => {5432 .byval => {
5419 const param_index = it.zig_index - 1;5433 const param_index = it.zig_index - 1;
5420 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);5434 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);
5421 if (!isByRef(param_ty, mod)) {5435 if (!isByRef(param_ty, pt)) {
5422 try o.addByValParamAttrs(&attributes, param_ty, param_index, fn_info, it.llvm_index - 1);5436 try o.addByValParamAttrs(&attributes, param_ty, param_index, fn_info, it.llvm_index - 1);
5423 }5437 }
5424 },5438 },
...@@ -5426,7 +5440,7 @@ pub const FuncGen = struct {...@@ -5426,7 +5440,7 @@ pub const FuncGen = struct {
5426 const param_index = it.zig_index - 1;5440 const param_index = it.zig_index - 1;
5427 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);5441 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);
5428 const param_llvm_ty = try o.lowerType(param_ty);5442 const param_llvm_ty = try o.lowerType(param_ty);
5429 const alignment = param_ty.abiAlignment(mod).toLlvm();5443 const alignment = param_ty.abiAlignment(pt).toLlvm();
5430 try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);5444 try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);
5431 },5445 },
5432 .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder),5446 .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder),
...@@ -5460,7 +5474,7 @@ pub const FuncGen = struct {...@@ -5460,7 +5474,7 @@ pub const FuncGen = struct {
5460 const elem_align = (if (ptr_info.flags.alignment != .none)5474 const elem_align = (if (ptr_info.flags.alignment != .none)
5461 @as(InternPool.Alignment, ptr_info.flags.alignment)5475 @as(InternPool.Alignment, ptr_info.flags.alignment)
5462 else5476 else
5463 Type.fromInterned(ptr_info.child).abiAlignment(mod).max(.@"1")).toLlvm();5477 Type.fromInterned(ptr_info.child).abiAlignment(pt).max(.@"1")).toLlvm();
5464 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder);5478 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder);
5465 },5479 },
5466 };5480 };
...@@ -5485,17 +5499,17 @@ pub const FuncGen = struct {...@@ -5485,17 +5499,17 @@ pub const FuncGen = struct {
5485 return .none;5499 return .none;
5486 }5500 }
54875501
5488 if (self.liveness.isUnused(inst) or !return_type.hasRuntimeBitsIgnoreComptime(mod)) {5502 if (self.liveness.isUnused(inst) or !return_type.hasRuntimeBitsIgnoreComptime(pt)) {
5489 return .none;5503 return .none;
5490 }5504 }
54915505
5492 const llvm_ret_ty = try o.lowerType(return_type);5506 const llvm_ret_ty = try o.lowerType(return_type);
5493 if (ret_ptr) |rp| {5507 if (ret_ptr) |rp| {
5494 if (isByRef(return_type, mod)) {5508 if (isByRef(return_type, pt)) {
5495 return rp;5509 return rp;
5496 } else {5510 } else {
5497 // our by-ref status disagrees with sret so we must load.5511 // our by-ref status disagrees with sret so we must load.
5498 const return_alignment = return_type.abiAlignment(mod).toLlvm();5512 const return_alignment = return_type.abiAlignment(pt).toLlvm();
5499 return self.wip.load(.normal, llvm_ret_ty, rp, return_alignment, "");5513 return self.wip.load(.normal, llvm_ret_ty, rp, return_alignment, "");
5500 }5514 }
5501 }5515 }
...@@ -5506,19 +5520,19 @@ pub const FuncGen = struct {...@@ -5506,19 +5520,19 @@ pub const FuncGen = struct {
5506 // In this case the function return type is honoring the calling convention by having5520 // 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 callsite5521 // 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.5522 // by using our canonical type, then loading it if necessary.
5509 const alignment = return_type.abiAlignment(mod).toLlvm();5523 const alignment = return_type.abiAlignment(pt).toLlvm();
5510 const rp = try self.buildAlloca(abi_ret_ty, alignment);5524 const rp = try self.buildAlloca(abi_ret_ty, alignment);
5511 _ = try self.wip.store(.normal, call, rp, alignment);5525 _ = try self.wip.store(.normal, call, rp, alignment);
5512 return if (isByRef(return_type, mod))5526 return if (isByRef(return_type, pt))
5513 rp5527 rp
5514 else5528 else
5515 try self.wip.load(.normal, llvm_ret_ty, rp, alignment, "");5529 try self.wip.load(.normal, llvm_ret_ty, rp, alignment, "");
5516 }5530 }
55175531
5518 if (isByRef(return_type, mod)) {5532 if (isByRef(return_type, pt)) {
5519 // our by-ref status disagrees with sret so we must allocate, store,5533 // our by-ref status disagrees with sret so we must allocate, store,
5520 // and return the allocation pointer.5534 // and return the allocation pointer.
5521 const alignment = return_type.abiAlignment(mod).toLlvm();5535 const alignment = return_type.abiAlignment(pt).toLlvm();
5522 const rp = try self.buildAlloca(llvm_ret_ty, alignment);5536 const rp = try self.buildAlloca(llvm_ret_ty, alignment);
5523 _ = try self.wip.store(.normal, call, rp, alignment);5537 _ = try self.wip.store(.normal, call, rp, alignment);
5524 return rp;5538 return rp;
...@@ -5527,9 +5541,9 @@ pub const FuncGen = struct {...@@ -5527,9 +5541,9 @@ pub const FuncGen = struct {
5527 }5541 }
5528 }5542 }
55295543
5530 fn buildSimplePanic(fg: *FuncGen, panic_id: Module.PanicId) !void {5544 fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.PanicId) !void {
5531 const o = fg.dg.object;5545 const o = fg.dg.object;
5532 const mod = o.module;5546 const mod = o.pt.zcu;
5533 const msg_decl_index = mod.panic_messages[@intFromEnum(panic_id)].unwrap().?;5547 const msg_decl_index = mod.panic_messages[@intFromEnum(panic_id)].unwrap().?;
5534 const msg_decl = mod.declPtr(msg_decl_index);5548 const msg_decl = mod.declPtr(msg_decl_index);
5535 const msg_len = msg_decl.typeOf(mod).childType(mod).arrayLen(mod);5549 const msg_len = msg_decl.typeOf(mod).childType(mod).arrayLen(mod);
...@@ -5567,15 +5581,16 @@ pub const FuncGen = struct {...@@ -5567,15 +5581,16 @@ pub const FuncGen = struct {
55675581
5568 fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {5582 fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {
5569 const o = self.dg.object;5583 const o = self.dg.object;
5570 const mod = o.module;5584 const pt = o.pt;
5585 const mod = pt.zcu;
5571 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5586 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
5572 const ret_ty = self.typeOf(un_op);5587 const ret_ty = self.typeOf(un_op);
55735588
5574 if (self.ret_ptr != .none) {5589 if (self.ret_ptr != .none) {
5575 const ptr_ty = try mod.singleMutPtrType(ret_ty);5590 const ptr_ty = try pt.singleMutPtrType(ret_ty);
55765591
5577 const operand = try self.resolveInst(un_op);5592 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;5593 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: {5594 if (val_is_undef and safety) undef: {
5580 const ptr_info = ptr_ty.ptrInfo(mod);5595 const ptr_info = ptr_ty.ptrInfo(mod);
5581 const needs_bitmask = (ptr_info.packed_offset.host_size != 0);5596 const needs_bitmask = (ptr_info.packed_offset.host_size != 0);
...@@ -5585,10 +5600,10 @@ pub const FuncGen = struct {...@@ -5585,10 +5600,10 @@ pub const FuncGen = struct {
5585 // https://github.com/ziglang/zig/issues/153375600 // https://github.com/ziglang/zig/issues/15337
5586 break :undef;5601 break :undef;
5587 }5602 }
5588 const len = try o.builder.intValue(try o.lowerType(Type.usize), ret_ty.abiSize(mod));5603 const len = try o.builder.intValue(try o.lowerType(Type.usize), ret_ty.abiSize(pt));
5589 _ = try self.wip.callMemSet(5604 _ = try self.wip.callMemSet(
5590 self.ret_ptr,5605 self.ret_ptr,
5591 ptr_ty.ptrAlignment(mod).toLlvm(),5606 ptr_ty.ptrAlignment(pt).toLlvm(),
5592 try o.builder.intValue(.i8, 0xaa),5607 try o.builder.intValue(.i8, 0xaa),
5593 len,5608 len,
5594 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal,5609 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal,
...@@ -5615,7 +5630,7 @@ pub const FuncGen = struct {...@@ -5615,7 +5630,7 @@ pub const FuncGen = struct {
5615 return .none;5630 return .none;
5616 }5631 }
5617 const fn_info = mod.typeToFunc(self.dg.decl.typeOf(mod)).?;5632 const fn_info = mod.typeToFunc(self.dg.decl.typeOf(mod)).?;
5618 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {5633 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
5619 if (Type.fromInterned(fn_info.return_type).isError(mod)) {5634 if (Type.fromInterned(fn_info.return_type).isError(mod)) {
5620 // Functions with an empty error set are emitted with an error code5635 // Functions with an empty error set are emitted with an error code
5621 // return type and return zero so they can be function pointers coerced5636 // return type and return zero so they can be function pointers coerced
...@@ -5629,13 +5644,13 @@ pub const FuncGen = struct {...@@ -5629,13 +5644,13 @@ pub const FuncGen = struct {
56295644
5630 const abi_ret_ty = try lowerFnRetTy(o, fn_info);5645 const abi_ret_ty = try lowerFnRetTy(o, fn_info);
5631 const operand = try self.resolveInst(un_op);5646 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;5647 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();5648 const alignment = ret_ty.abiAlignment(pt).toLlvm();
56345649
5635 if (val_is_undef and safety) {5650 if (val_is_undef and safety) {
5636 const llvm_ret_ty = operand.typeOfWip(&self.wip);5651 const llvm_ret_ty = operand.typeOfWip(&self.wip);
5637 const rp = try self.buildAlloca(llvm_ret_ty, alignment);5652 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));5653 const len = try o.builder.intValue(try o.lowerType(Type.usize), ret_ty.abiSize(pt));
5639 _ = try self.wip.callMemSet(5654 _ = try self.wip.callMemSet(
5640 rp,5655 rp,
5641 alignment,5656 alignment,
...@@ -5651,7 +5666,7 @@ pub const FuncGen = struct {...@@ -5651,7 +5666,7 @@ pub const FuncGen = struct {
5651 return .none;5666 return .none;
5652 }5667 }
56535668
5654 if (isByRef(ret_ty, mod)) {5669 if (isByRef(ret_ty, pt)) {
5655 // operand is a pointer however self.ret_ptr is null so that means5670 // operand is a pointer however self.ret_ptr is null so that means
5656 // we need to return a value.5671 // we need to return a value.
5657 _ = try self.wip.ret(try self.wip.load(.normal, abi_ret_ty, operand, alignment, ""));5672 _ = try self.wip.ret(try self.wip.load(.normal, abi_ret_ty, operand, alignment, ""));
...@@ -5672,12 +5687,13 @@ pub const FuncGen = struct {...@@ -5672,12 +5687,13 @@ pub const FuncGen = struct {
56725687
5673 fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5688 fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5674 const o = self.dg.object;5689 const o = self.dg.object;
5675 const mod = o.module;5690 const pt = o.pt;
5691 const mod = pt.zcu;
5676 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5692 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
5677 const ptr_ty = self.typeOf(un_op);5693 const ptr_ty = self.typeOf(un_op);
5678 const ret_ty = ptr_ty.childType(mod);5694 const ret_ty = ptr_ty.childType(mod);
5679 const fn_info = mod.typeToFunc(self.dg.decl.typeOf(mod)).?;5695 const fn_info = mod.typeToFunc(self.dg.decl.typeOf(mod)).?;
5680 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {5696 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
5681 if (Type.fromInterned(fn_info.return_type).isError(mod)) {5697 if (Type.fromInterned(fn_info.return_type).isError(mod)) {
5682 // Functions with an empty error set are emitted with an error code5698 // Functions with an empty error set are emitted with an error code
5683 // return type and return zero so they can be function pointers coerced5699 // return type and return zero so they can be function pointers coerced
...@@ -5694,7 +5710,7 @@ pub const FuncGen = struct {...@@ -5694,7 +5710,7 @@ pub const FuncGen = struct {
5694 }5710 }
5695 const ptr = try self.resolveInst(un_op);5711 const ptr = try self.resolveInst(un_op);
5696 const abi_ret_ty = try lowerFnRetTy(o, fn_info);5712 const abi_ret_ty = try lowerFnRetTy(o, fn_info);
5697 const alignment = ret_ty.abiAlignment(mod).toLlvm();5713 const alignment = ret_ty.abiAlignment(pt).toLlvm();
5698 _ = try self.wip.ret(try self.wip.load(.normal, abi_ret_ty, ptr, alignment, ""));5714 _ = try self.wip.ret(try self.wip.load(.normal, abi_ret_ty, ptr, alignment, ""));
5699 return .none;5715 return .none;
5700 }5716 }
...@@ -5711,17 +5727,17 @@ pub const FuncGen = struct {...@@ -5711,17 +5727,17 @@ pub const FuncGen = struct {
57115727
5712 fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5728 fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5713 const o = self.dg.object;5729 const o = self.dg.object;
5730 const pt = o.pt;
5714 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5731 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5715 const src_list = try self.resolveInst(ty_op.operand);5732 const src_list = try self.resolveInst(ty_op.operand);
5716 const va_list_ty = ty_op.ty.toType();5733 const va_list_ty = ty_op.ty.toType();
5717 const llvm_va_list_ty = try o.lowerType(va_list_ty);5734 const llvm_va_list_ty = try o.lowerType(va_list_ty);
5718 const mod = o.module;
57195735
5720 const result_alignment = va_list_ty.abiAlignment(mod).toLlvm();5736 const result_alignment = va_list_ty.abiAlignment(pt).toLlvm();
5721 const dest_list = try self.buildAllocaWorkaround(va_list_ty, result_alignment);5737 const dest_list = try self.buildAllocaWorkaround(va_list_ty, result_alignment);
57225738
5723 _ = try self.wip.callIntrinsic(.normal, .none, .va_copy, &.{}, &.{ dest_list, src_list }, "");5739 _ = try self.wip.callIntrinsic(.normal, .none, .va_copy, &.{}, &.{ dest_list, src_list }, "");
5724 return if (isByRef(va_list_ty, mod))5740 return if (isByRef(va_list_ty, pt))
5725 dest_list5741 dest_list
5726 else5742 else
5727 try self.wip.load(.normal, llvm_va_list_ty, dest_list, result_alignment, "");5743 try self.wip.load(.normal, llvm_va_list_ty, dest_list, result_alignment, "");
...@@ -5737,15 +5753,15 @@ pub const FuncGen = struct {...@@ -5737,15 +5753,15 @@ pub const FuncGen = struct {
57375753
5738 fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5754 fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5739 const o = self.dg.object;5755 const o = self.dg.object;
5740 const mod = o.module;5756 const pt = o.pt;
5741 const va_list_ty = self.typeOfIndex(inst);5757 const va_list_ty = self.typeOfIndex(inst);
5742 const llvm_va_list_ty = try o.lowerType(va_list_ty);5758 const llvm_va_list_ty = try o.lowerType(va_list_ty);
57435759
5744 const result_alignment = va_list_ty.abiAlignment(mod).toLlvm();5760 const result_alignment = va_list_ty.abiAlignment(pt).toLlvm();
5745 const dest_list = try self.buildAllocaWorkaround(va_list_ty, result_alignment);5761 const dest_list = try self.buildAllocaWorkaround(va_list_ty, result_alignment);
57465762
5747 _ = try self.wip.callIntrinsic(.normal, .none, .va_start, &.{}, &.{dest_list}, "");5763 _ = try self.wip.callIntrinsic(.normal, .none, .va_start, &.{}, &.{dest_list}, "");
5748 return if (isByRef(va_list_ty, mod))5764 return if (isByRef(va_list_ty, pt))
5749 dest_list5765 dest_list
5750 else5766 else
5751 try self.wip.load(.normal, llvm_va_list_ty, dest_list, result_alignment, "");5767 try self.wip.load(.normal, llvm_va_list_ty, dest_list, result_alignment, "");
...@@ -5802,21 +5818,22 @@ pub const FuncGen = struct {...@@ -5802,21 +5818,22 @@ pub const FuncGen = struct {
5802 rhs: Builder.Value,5818 rhs: Builder.Value,
5803 ) Allocator.Error!Builder.Value {5819 ) Allocator.Error!Builder.Value {
5804 const o = self.dg.object;5820 const o = self.dg.object;
5805 const mod = o.module;5821 const pt = o.pt;
5822 const mod = pt.zcu;
5806 const scalar_ty = operand_ty.scalarType(mod);5823 const scalar_ty = operand_ty.scalarType(mod);
5807 const int_ty = switch (scalar_ty.zigTypeTag(mod)) {5824 const int_ty = switch (scalar_ty.zigTypeTag(mod)) {
5808 .Enum => scalar_ty.intTagType(mod),5825 .Enum => scalar_ty.intTagType(mod),
5809 .Int, .Bool, .Pointer, .ErrorSet => scalar_ty,5826 .Int, .Bool, .Pointer, .ErrorSet => scalar_ty,
5810 .Optional => blk: {5827 .Optional => blk: {
5811 const payload_ty = operand_ty.optionalChild(mod);5828 const payload_ty = operand_ty.optionalChild(mod);
5812 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or5829 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt) or
5813 operand_ty.optionalReprIsPayload(mod))5830 operand_ty.optionalReprIsPayload(mod))
5814 {5831 {
5815 break :blk operand_ty;5832 break :blk operand_ty;
5816 }5833 }
5817 // We need to emit instructions to check for equality/inequality5834 // We need to emit instructions to check for equality/inequality
5818 // of optionals that are not pointers.5835 // of optionals that are not pointers.
5819 const is_by_ref = isByRef(scalar_ty, mod);5836 const is_by_ref = isByRef(scalar_ty, pt);
5820 const opt_llvm_ty = try o.lowerType(scalar_ty);5837 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);5838 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);5839 const rhs_non_null = try self.optCmpNull(.ne, opt_llvm_ty, rhs, is_by_ref);
...@@ -5908,7 +5925,8 @@ pub const FuncGen = struct {...@@ -5908,7 +5925,8 @@ pub const FuncGen = struct {
5908 body: []const Air.Inst.Index,5925 body: []const Air.Inst.Index,
5909 ) !Builder.Value {5926 ) !Builder.Value {
5910 const o = self.dg.object;5927 const o = self.dg.object;
5911 const mod = o.module;5928 const pt = o.pt;
5929 const mod = pt.zcu;
5912 const inst_ty = self.typeOfIndex(inst);5930 const inst_ty = self.typeOfIndex(inst);
59135931
5914 if (inst_ty.isNoReturn(mod)) {5932 if (inst_ty.isNoReturn(mod)) {
...@@ -5916,7 +5934,7 @@ pub const FuncGen = struct {...@@ -5916,7 +5934,7 @@ pub const FuncGen = struct {
5916 return .none;5934 return .none;
5917 }5935 }
59185936
5919 const have_block_result = inst_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod);5937 const have_block_result = inst_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt);
59205938
5921 var breaks: BreakList = if (have_block_result) .{ .list = .{} } else .{ .len = 0 };5939 var breaks: BreakList = if (have_block_result) .{ .list = .{} } else .{ .len = 0 };
5922 defer if (have_block_result) breaks.list.deinit(self.gpa);5940 defer if (have_block_result) breaks.list.deinit(self.gpa);
...@@ -5940,7 +5958,7 @@ pub const FuncGen = struct {...@@ -5940,7 +5958,7 @@ pub const FuncGen = struct {
5940 // a pointer to it. LLVM IR allows the call instruction to use function bodies instead5958 // 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 therefore5959 // of function pointers, however the phi makes it a runtime value and therefore
5942 // the LLVM type has to be wrapped in a pointer.5960 // the LLVM type has to be wrapped in a pointer.
5943 if (inst_ty.zigTypeTag(mod) == .Fn or isByRef(inst_ty, mod)) {5961 if (inst_ty.zigTypeTag(mod) == .Fn or isByRef(inst_ty, pt)) {
5944 break :ty .ptr;5962 break :ty .ptr;
5945 }5963 }
5946 break :ty raw_llvm_ty;5964 break :ty raw_llvm_ty;
...@@ -5958,13 +5976,13 @@ pub const FuncGen = struct {...@@ -5958,13 +5976,13 @@ pub const FuncGen = struct {
59585976
5959 fn airBr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5977 fn airBr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5960 const o = self.dg.object;5978 const o = self.dg.object;
5979 const pt = o.pt;
5961 const branch = self.air.instructions.items(.data)[@intFromEnum(inst)].br;5980 const branch = self.air.instructions.items(.data)[@intFromEnum(inst)].br;
5962 const block = self.blocks.get(branch.block_inst).?;5981 const block = self.blocks.get(branch.block_inst).?;
59635982
5964 // Add the values to the lists only if the break provides a value.5983 // Add the values to the lists only if the break provides a value.
5965 const operand_ty = self.typeOf(branch.operand);5984 const operand_ty = self.typeOf(branch.operand);
5966 const mod = o.module;5985 if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) {
5967 if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {
5968 const val = try self.resolveInst(branch.operand);5986 const val = try self.resolveInst(branch.operand);
59695987
5970 // For the phi node, we need the basic blocks and the values of the5988 // For the phi node, we need the basic blocks and the values of the
...@@ -5998,7 +6016,7 @@ pub const FuncGen = struct {...@@ -5998,7 +6016,7 @@ pub const FuncGen = struct {
59986016
5999 fn airTry(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {6017 fn airTry(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
6000 const o = self.dg.object;6018 const o = self.dg.object;
6001 const mod = o.module;6019 const pt = o.pt;
6002 const inst = body_tail[0];6020 const inst = body_tail[0];
6003 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6021 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6004 const err_union = try self.resolveInst(pl_op.operand);6022 const err_union = try self.resolveInst(pl_op.operand);
...@@ -6006,14 +6024,14 @@ pub const FuncGen = struct {...@@ -6006,14 +6024,14 @@ pub const FuncGen = struct {
6006 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);6024 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);6025 const err_union_ty = self.typeOf(pl_op.operand);
6008 const payload_ty = self.typeOfIndex(inst);6026 const payload_ty = self.typeOfIndex(inst);
6009 const can_elide_load = if (isByRef(payload_ty, mod)) self.canElideLoad(body_tail) else false;6027 const can_elide_load = if (isByRef(payload_ty, pt)) self.canElideLoad(body_tail) else false;
6010 const is_unused = self.liveness.isUnused(inst);6028 const is_unused = self.liveness.isUnused(inst);
6011 return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused);6029 return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused);
6012 }6030 }
60136031
6014 fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6032 fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6015 const o = self.dg.object;6033 const o = self.dg.object;
6016 const mod = o.module;6034 const mod = o.pt.zcu;
6017 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6035 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6018 const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);6036 const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);
6019 const err_union_ptr = try self.resolveInst(extra.data.ptr);6037 const err_union_ptr = try self.resolveInst(extra.data.ptr);
...@@ -6033,9 +6051,10 @@ pub const FuncGen = struct {...@@ -6033,9 +6051,10 @@ pub const FuncGen = struct {
6033 is_unused: bool,6051 is_unused: bool,
6034 ) !Builder.Value {6052 ) !Builder.Value {
6035 const o = fg.dg.object;6053 const o = fg.dg.object;
6036 const mod = o.module;6054 const pt = o.pt;
6055 const mod = pt.zcu;
6037 const payload_ty = err_union_ty.errorUnionPayload(mod);6056 const payload_ty = err_union_ty.errorUnionPayload(mod);
6038 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod);6057 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(pt);
6039 const err_union_llvm_ty = try o.lowerType(err_union_ty);6058 const err_union_llvm_ty = try o.lowerType(err_union_ty);
6040 const error_type = try o.errorIntType();6059 const error_type = try o.errorIntType();
60416060
...@@ -6048,8 +6067,8 @@ pub const FuncGen = struct {...@@ -6048,8 +6067,8 @@ pub const FuncGen = struct {
6048 else6067 else
6049 err_union;6068 err_union;
6050 }6069 }
6051 const err_field_index = try errUnionErrorOffset(payload_ty, mod);6070 const err_field_index = try errUnionErrorOffset(payload_ty, pt);
6052 if (operand_is_ptr or isByRef(err_union_ty, mod)) {6071 if (operand_is_ptr or isByRef(err_union_ty, pt)) {
6053 const err_field_ptr =6072 const err_field_ptr =
6054 try fg.wip.gepStruct(err_union_llvm_ty, err_union, err_field_index, "");6073 try fg.wip.gepStruct(err_union_llvm_ty, err_union, err_field_index, "");
6055 // TODO add alignment to this load6074 // TODO add alignment to this load
...@@ -6077,13 +6096,13 @@ pub const FuncGen = struct {...@@ -6077,13 +6096,13 @@ pub const FuncGen = struct {
6077 }6096 }
6078 if (is_unused) return .none;6097 if (is_unused) return .none;
6079 if (!payload_has_bits) return if (operand_is_ptr) err_union else .none;6098 if (!payload_has_bits) return if (operand_is_ptr) err_union else .none;
6080 const offset = try errUnionPayloadOffset(payload_ty, mod);6099 const offset = try errUnionPayloadOffset(payload_ty, pt);
6081 if (operand_is_ptr) {6100 if (operand_is_ptr) {
6082 return fg.wip.gepStruct(err_union_llvm_ty, err_union, offset, "");6101 return fg.wip.gepStruct(err_union_llvm_ty, err_union, offset, "");
6083 } else if (isByRef(err_union_ty, mod)) {6102 } else if (isByRef(err_union_ty, pt)) {
6084 const payload_ptr = try fg.wip.gepStruct(err_union_llvm_ty, err_union, offset, "");6103 const payload_ptr = try fg.wip.gepStruct(err_union_llvm_ty, err_union, offset, "");
6085 const payload_alignment = payload_ty.abiAlignment(mod).toLlvm();6104 const payload_alignment = payload_ty.abiAlignment(pt).toLlvm();
6086 if (isByRef(payload_ty, mod)) {6105 if (isByRef(payload_ty, pt)) {
6087 if (can_elide_load)6106 if (can_elide_load)
6088 return payload_ptr;6107 return payload_ptr;
60896108
...@@ -6161,7 +6180,7 @@ pub const FuncGen = struct {...@@ -6161,7 +6180,7 @@ pub const FuncGen = struct {
61616180
6162 fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6181 fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6163 const o = self.dg.object;6182 const o = self.dg.object;
6164 const mod = o.module;6183 const mod = o.pt.zcu;
6165 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6184 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6166 const loop = self.air.extraData(Air.Block, ty_pl.payload);6185 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]);6186 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[loop.end..][0..loop.data.body_len]);
...@@ -6185,7 +6204,8 @@ pub const FuncGen = struct {...@@ -6185,7 +6204,8 @@ pub const FuncGen = struct {
61856204
6186 fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6205 fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6187 const o = self.dg.object;6206 const o = self.dg.object;
6188 const mod = o.module;6207 const pt = o.pt;
6208 const mod = pt.zcu;
6189 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6209 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
6190 const operand_ty = self.typeOf(ty_op.operand);6210 const operand_ty = self.typeOf(ty_op.operand);
6191 const array_ty = operand_ty.childType(mod);6211 const array_ty = operand_ty.childType(mod);
...@@ -6193,7 +6213,7 @@ pub const FuncGen = struct {...@@ -6193,7 +6213,7 @@ pub const FuncGen = struct {
6193 const len = try o.builder.intValue(llvm_usize, array_ty.arrayLen(mod));6213 const len = try o.builder.intValue(llvm_usize, array_ty.arrayLen(mod));
6194 const slice_llvm_ty = try o.lowerType(self.typeOfIndex(inst));6214 const slice_llvm_ty = try o.lowerType(self.typeOfIndex(inst));
6195 const operand = try self.resolveInst(ty_op.operand);6215 const operand = try self.resolveInst(ty_op.operand);
6196 if (!array_ty.hasRuntimeBitsIgnoreComptime(mod))6216 if (!array_ty.hasRuntimeBitsIgnoreComptime(pt))
6197 return self.wip.buildAggregate(slice_llvm_ty, &.{ operand, len }, "");6217 return self.wip.buildAggregate(slice_llvm_ty, &.{ operand, len }, "");
6198 const ptr = try self.wip.gep(.inbounds, try o.lowerType(array_ty), operand, &.{6218 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),6219 try o.builder.intValue(llvm_usize, 0), try o.builder.intValue(llvm_usize, 0),
...@@ -6203,7 +6223,8 @@ pub const FuncGen = struct {...@@ -6203,7 +6223,8 @@ pub const FuncGen = struct {
62036223
6204 fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6224 fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6205 const o = self.dg.object;6225 const o = self.dg.object;
6206 const mod = o.module;6226 const pt = o.pt;
6227 const mod = pt.zcu;
6207 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6228 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
62086229
6209 const workaround_operand = try self.resolveInst(ty_op.operand);6230 const workaround_operand = try self.resolveInst(ty_op.operand);
...@@ -6213,7 +6234,7 @@ pub const FuncGen = struct {...@@ -6213,7 +6234,7 @@ pub const FuncGen = struct {
62136234
6214 const operand = o: {6235 const operand = o: {
6215 // Work around LLVM bug. See https://github.com/ziglang/zig/issues/17381.6236 // Work around LLVM bug. See https://github.com/ziglang/zig/issues/17381.
6216 const bit_size = operand_scalar_ty.bitSize(mod);6237 const bit_size = operand_scalar_ty.bitSize(pt);
6217 for ([_]u8{ 8, 16, 32, 64, 128 }) |b| {6238 for ([_]u8{ 8, 16, 32, 64, 128 }) |b| {
6218 if (bit_size < b) {6239 if (bit_size < b) {
6219 break :o try self.wip.cast(6240 break :o try self.wip.cast(
...@@ -6241,7 +6262,7 @@ pub const FuncGen = struct {...@@ -6241,7 +6262,7 @@ pub const FuncGen = struct {
6241 "",6262 "",
6242 );6263 );
62436264
6244 const rt_int_bits = compilerRtIntBits(@intCast(operand_scalar_ty.bitSize(mod)));6265 const rt_int_bits = compilerRtIntBits(@intCast(operand_scalar_ty.bitSize(pt)));
6245 const rt_int_ty = try o.builder.intType(rt_int_bits);6266 const rt_int_ty = try o.builder.intType(rt_int_bits);
6246 var extended = try self.wip.conv(6267 var extended = try self.wip.conv(
6247 if (is_signed_int) .signed else .unsigned,6268 if (is_signed_int) .signed else .unsigned,
...@@ -6287,7 +6308,8 @@ pub const FuncGen = struct {...@@ -6287,7 +6308,8 @@ pub const FuncGen = struct {
6287 _ = fast;6308 _ = fast;
62886309
6289 const o = self.dg.object;6310 const o = self.dg.object;
6290 const mod = o.module;6311 const pt = o.pt;
6312 const mod = pt.zcu;
6291 const target = mod.getTarget();6313 const target = mod.getTarget();
6292 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6314 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
62936315
...@@ -6309,7 +6331,7 @@ pub const FuncGen = struct {...@@ -6309,7 +6331,7 @@ pub const FuncGen = struct {
6309 );6331 );
6310 }6332 }
63116333
6312 const rt_int_bits = compilerRtIntBits(@intCast(dest_scalar_ty.bitSize(mod)));6334 const rt_int_bits = compilerRtIntBits(@intCast(dest_scalar_ty.bitSize(pt)));
6313 const ret_ty = try o.builder.intType(rt_int_bits);6335 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: {6336 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 standard6337 // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard
...@@ -6348,19 +6370,20 @@ pub const FuncGen = struct {...@@ -6348,19 +6370,20 @@ pub const FuncGen = struct {
63486370
6349 fn sliceOrArrayPtr(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value {6371 fn sliceOrArrayPtr(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value {
6350 const o = fg.dg.object;6372 const o = fg.dg.object;
6351 const mod = o.module;6373 const mod = o.pt.zcu;
6352 return if (ty.isSlice(mod)) fg.wip.extractValue(ptr, &.{0}, "") else ptr;6374 return if (ty.isSlice(mod)) fg.wip.extractValue(ptr, &.{0}, "") else ptr;
6353 }6375 }
63546376
6355 fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value {6377 fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value {
6356 const o = fg.dg.object;6378 const o = fg.dg.object;
6357 const mod = o.module;6379 const pt = o.pt;
6380 const mod = pt.zcu;
6358 const llvm_usize = try o.lowerType(Type.usize);6381 const llvm_usize = try o.lowerType(Type.usize);
6359 switch (ty.ptrSize(mod)) {6382 switch (ty.ptrSize(mod)) {
6360 .Slice => {6383 .Slice => {
6361 const len = try fg.wip.extractValue(ptr, &.{1}, "");6384 const len = try fg.wip.extractValue(ptr, &.{1}, "");
6362 const elem_ty = ty.childType(mod);6385 const elem_ty = ty.childType(mod);
6363 const abi_size = elem_ty.abiSize(mod);6386 const abi_size = elem_ty.abiSize(pt);
6364 if (abi_size == 1) return len;6387 if (abi_size == 1) return len;
6365 const abi_size_llvm_val = try o.builder.intValue(llvm_usize, abi_size);6388 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, "");6389 return fg.wip.bin(.@"mul nuw", len, abi_size_llvm_val, "");
...@@ -6368,7 +6391,7 @@ pub const FuncGen = struct {...@@ -6368,7 +6391,7 @@ pub const FuncGen = struct {
6368 .One => {6391 .One => {
6369 const array_ty = ty.childType(mod);6392 const array_ty = ty.childType(mod);
6370 const elem_ty = array_ty.childType(mod);6393 const elem_ty = array_ty.childType(mod);
6371 const abi_size = elem_ty.abiSize(mod);6394 const abi_size = elem_ty.abiSize(pt);
6372 return o.builder.intValue(llvm_usize, array_ty.arrayLen(mod) * abi_size);6395 return o.builder.intValue(llvm_usize, array_ty.arrayLen(mod) * abi_size);
6373 },6396 },
6374 .Many, .C => unreachable,6397 .Many, .C => unreachable,
...@@ -6383,7 +6406,7 @@ pub const FuncGen = struct {...@@ -6383,7 +6406,7 @@ pub const FuncGen = struct {
63836406
6384 fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !Builder.Value {6407 fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !Builder.Value {
6385 const o = self.dg.object;6408 const o = self.dg.object;
6386 const mod = o.module;6409 const mod = o.pt.zcu;
6387 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6410 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
6388 const slice_ptr = try self.resolveInst(ty_op.operand);6411 const slice_ptr = try self.resolveInst(ty_op.operand);
6389 const slice_ptr_ty = self.typeOf(ty_op.operand);6412 const slice_ptr_ty = self.typeOf(ty_op.operand);
...@@ -6394,7 +6417,8 @@ pub const FuncGen = struct {...@@ -6394,7 +6417,8 @@ pub const FuncGen = struct {
63946417
6395 fn airSliceElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {6418 fn airSliceElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
6396 const o = self.dg.object;6419 const o = self.dg.object;
6397 const mod = o.module;6420 const pt = o.pt;
6421 const mod = pt.zcu;
6398 const inst = body_tail[0];6422 const inst = body_tail[0];
6399 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;6423 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
6400 const slice_ty = self.typeOf(bin_op.lhs);6424 const slice_ty = self.typeOf(bin_op.lhs);
...@@ -6404,11 +6428,11 @@ pub const FuncGen = struct {...@@ -6404,11 +6428,11 @@ pub const FuncGen = struct {
6404 const llvm_elem_ty = try o.lowerPtrElemTy(elem_ty);6428 const llvm_elem_ty = try o.lowerPtrElemTy(elem_ty);
6405 const base_ptr = try self.wip.extractValue(slice, &.{0}, "");6429 const base_ptr = try self.wip.extractValue(slice, &.{0}, "");
6406 const ptr = try self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{index}, "");6430 const ptr = try self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{index}, "");
6407 if (isByRef(elem_ty, mod)) {6431 if (isByRef(elem_ty, pt)) {
6408 if (self.canElideLoad(body_tail))6432 if (self.canElideLoad(body_tail))
6409 return ptr;6433 return ptr;
64106434
6411 const elem_alignment = elem_ty.abiAlignment(mod).toLlvm();6435 const elem_alignment = elem_ty.abiAlignment(pt).toLlvm();
6412 return self.loadByRef(ptr, elem_ty, elem_alignment, .normal);6436 return self.loadByRef(ptr, elem_ty, elem_alignment, .normal);
6413 }6437 }
64146438
...@@ -6417,7 +6441,7 @@ pub const FuncGen = struct {...@@ -6417,7 +6441,7 @@ pub const FuncGen = struct {
64176441
6418 fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6442 fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6419 const o = self.dg.object;6443 const o = self.dg.object;
6420 const mod = o.module;6444 const mod = o.pt.zcu;
6421 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6445 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;6446 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
6423 const slice_ty = self.typeOf(bin_op.lhs);6447 const slice_ty = self.typeOf(bin_op.lhs);
...@@ -6431,7 +6455,8 @@ pub const FuncGen = struct {...@@ -6431,7 +6455,8 @@ pub const FuncGen = struct {
64316455
6432 fn airArrayElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {6456 fn airArrayElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
6433 const o = self.dg.object;6457 const o = self.dg.object;
6434 const mod = o.module;6458 const pt = o.pt;
6459 const mod = pt.zcu;
6435 const inst = body_tail[0];6460 const inst = body_tail[0];
64366461
6437 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;6462 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -6440,15 +6465,15 @@ pub const FuncGen = struct {...@@ -6440,15 +6465,15 @@ pub const FuncGen = struct {
6440 const rhs = try self.resolveInst(bin_op.rhs);6465 const rhs = try self.resolveInst(bin_op.rhs);
6441 const array_llvm_ty = try o.lowerType(array_ty);6466 const array_llvm_ty = try o.lowerType(array_ty);
6442 const elem_ty = array_ty.childType(mod);6467 const elem_ty = array_ty.childType(mod);
6443 if (isByRef(array_ty, mod)) {6468 if (isByRef(array_ty, pt)) {
6444 const indices: [2]Builder.Value = .{6469 const indices: [2]Builder.Value = .{
6445 try o.builder.intValue(try o.lowerType(Type.usize), 0), rhs,6470 try o.builder.intValue(try o.lowerType(Type.usize), 0), rhs,
6446 };6471 };
6447 if (isByRef(elem_ty, mod)) {6472 if (isByRef(elem_ty, pt)) {
6448 const elem_ptr =6473 const elem_ptr =
6449 try self.wip.gep(.inbounds, array_llvm_ty, array_llvm_val, &indices, "");6474 try self.wip.gep(.inbounds, array_llvm_ty, array_llvm_val, &indices, "");
6450 if (canElideLoad(self, body_tail)) return elem_ptr;6475 if (canElideLoad(self, body_tail)) return elem_ptr;
6451 const elem_alignment = elem_ty.abiAlignment(mod).toLlvm();6476 const elem_alignment = elem_ty.abiAlignment(pt).toLlvm();
6452 return self.loadByRef(elem_ptr, elem_ty, elem_alignment, .normal);6477 return self.loadByRef(elem_ptr, elem_ty, elem_alignment, .normal);
6453 } else {6478 } else {
6454 const elem_ptr =6479 const elem_ptr =
...@@ -6463,7 +6488,8 @@ pub const FuncGen = struct {...@@ -6463,7 +6488,8 @@ pub const FuncGen = struct {
64636488
6464 fn airPtrElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {6489 fn airPtrElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
6465 const o = self.dg.object;6490 const o = self.dg.object;
6466 const mod = o.module;6491 const pt = o.pt;
6492 const mod = pt.zcu;
6467 const inst = body_tail[0];6493 const inst = body_tail[0];
6468 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;6494 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
6469 const ptr_ty = self.typeOf(bin_op.lhs);6495 const ptr_ty = self.typeOf(bin_op.lhs);
...@@ -6477,9 +6503,9 @@ pub const FuncGen = struct {...@@ -6477,9 +6503,9 @@ pub const FuncGen = struct {
6477 &.{ try o.builder.intValue(try o.lowerType(Type.usize), 0), rhs }6503 &.{ try o.builder.intValue(try o.lowerType(Type.usize), 0), rhs }
6478 else6504 else
6479 &.{rhs}, "");6505 &.{rhs}, "");
6480 if (isByRef(elem_ty, mod)) {6506 if (isByRef(elem_ty, pt)) {
6481 if (self.canElideLoad(body_tail)) return ptr;6507 if (self.canElideLoad(body_tail)) return ptr;
6482 const elem_alignment = elem_ty.abiAlignment(mod).toLlvm();6508 const elem_alignment = elem_ty.abiAlignment(pt).toLlvm();
6483 return self.loadByRef(ptr, elem_ty, elem_alignment, .normal);6509 return self.loadByRef(ptr, elem_ty, elem_alignment, .normal);
6484 }6510 }
64856511
...@@ -6488,12 +6514,13 @@ pub const FuncGen = struct {...@@ -6488,12 +6514,13 @@ pub const FuncGen = struct {
64886514
6489 fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6515 fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6490 const o = self.dg.object;6516 const o = self.dg.object;
6491 const mod = o.module;6517 const pt = o.pt;
6518 const mod = pt.zcu;
6492 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6519 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;6520 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
6494 const ptr_ty = self.typeOf(bin_op.lhs);6521 const ptr_ty = self.typeOf(bin_op.lhs);
6495 const elem_ty = ptr_ty.childType(mod);6522 const elem_ty = ptr_ty.childType(mod);
6496 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return self.resolveInst(bin_op.lhs);6523 if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) return self.resolveInst(bin_op.lhs);
64976524
6498 const base_ptr = try self.resolveInst(bin_op.lhs);6525 const base_ptr = try self.resolveInst(bin_op.lhs);
6499 const rhs = try self.resolveInst(bin_op.rhs);6526 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -6530,7 +6557,8 @@ pub const FuncGen = struct {...@@ -6530,7 +6557,8 @@ pub const FuncGen = struct {
65306557
6531 fn airStructFieldVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {6558 fn airStructFieldVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
6532 const o = self.dg.object;6559 const o = self.dg.object;
6533 const mod = o.module;6560 const pt = o.pt;
6561 const mod = pt.zcu;
6534 const inst = body_tail[0];6562 const inst = body_tail[0];
6535 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6563 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;6564 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
...@@ -6538,27 +6566,27 @@ pub const FuncGen = struct {...@@ -6538,27 +6566,27 @@ pub const FuncGen = struct {
6538 const struct_llvm_val = try self.resolveInst(struct_field.struct_operand);6566 const struct_llvm_val = try self.resolveInst(struct_field.struct_operand);
6539 const field_index = struct_field.field_index;6567 const field_index = struct_field.field_index;
6540 const field_ty = struct_ty.structFieldType(field_index, mod);6568 const field_ty = struct_ty.structFieldType(field_index, mod);
6541 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;6569 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) return .none;
65426570
6543 if (!isByRef(struct_ty, mod)) {6571 if (!isByRef(struct_ty, pt)) {
6544 assert(!isByRef(field_ty, mod));6572 assert(!isByRef(field_ty, pt));
6545 switch (struct_ty.zigTypeTag(mod)) {6573 switch (struct_ty.zigTypeTag(mod)) {
6546 .Struct => switch (struct_ty.containerLayout(mod)) {6574 .Struct => switch (struct_ty.containerLayout(mod)) {
6547 .@"packed" => {6575 .@"packed" => {
6548 const struct_type = mod.typeToStruct(struct_ty).?;6576 const struct_type = mod.typeToStruct(struct_ty).?;
6549 const bit_offset = mod.structPackedFieldBitOffset(struct_type, field_index);6577 const bit_offset = pt.structPackedFieldBitOffset(struct_type, field_index);
6550 const containing_int = struct_llvm_val;6578 const containing_int = struct_llvm_val;
6551 const shift_amt =6579 const shift_amt =
6552 try o.builder.intValue(containing_int.typeOfWip(&self.wip), bit_offset);6580 try o.builder.intValue(containing_int.typeOfWip(&self.wip), bit_offset);
6553 const shifted_value = try self.wip.bin(.lshr, containing_int, shift_amt, "");6581 const shifted_value = try self.wip.bin(.lshr, containing_int, shift_amt, "");
6554 const elem_llvm_ty = try o.lowerType(field_ty);6582 const elem_llvm_ty = try o.lowerType(field_ty);
6555 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {6583 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)));6584 const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(pt)));
6557 const truncated_int =6585 const truncated_int =
6558 try self.wip.cast(.trunc, shifted_value, same_size_int, "");6586 try self.wip.cast(.trunc, shifted_value, same_size_int, "");
6559 return self.wip.cast(.bitcast, truncated_int, elem_llvm_ty, "");6587 return self.wip.cast(.bitcast, truncated_int, elem_llvm_ty, "");
6560 } else if (field_ty.isPtrAtRuntime(mod)) {6588 } else if (field_ty.isPtrAtRuntime(mod)) {
6561 const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(mod)));6589 const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(pt)));
6562 const truncated_int =6590 const truncated_int =
6563 try self.wip.cast(.trunc, shifted_value, same_size_int, "");6591 try self.wip.cast(.trunc, shifted_value, same_size_int, "");
6564 return self.wip.cast(.inttoptr, truncated_int, elem_llvm_ty, "");6592 return self.wip.cast(.inttoptr, truncated_int, elem_llvm_ty, "");
...@@ -6575,12 +6603,12 @@ pub const FuncGen = struct {...@@ -6575,12 +6603,12 @@ pub const FuncGen = struct {
6575 const containing_int = struct_llvm_val;6603 const containing_int = struct_llvm_val;
6576 const elem_llvm_ty = try o.lowerType(field_ty);6604 const elem_llvm_ty = try o.lowerType(field_ty);
6577 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {6605 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)));6606 const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(pt)));
6579 const truncated_int =6607 const truncated_int =
6580 try self.wip.cast(.trunc, containing_int, same_size_int, "");6608 try self.wip.cast(.trunc, containing_int, same_size_int, "");
6581 return self.wip.cast(.bitcast, truncated_int, elem_llvm_ty, "");6609 return self.wip.cast(.bitcast, truncated_int, elem_llvm_ty, "");
6582 } else if (field_ty.isPtrAtRuntime(mod)) {6610 } else if (field_ty.isPtrAtRuntime(mod)) {
6583 const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(mod)));6611 const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(pt)));
6584 const truncated_int =6612 const truncated_int =
6585 try self.wip.cast(.trunc, containing_int, same_size_int, "");6613 try self.wip.cast(.trunc, containing_int, same_size_int, "");
6586 return self.wip.cast(.inttoptr, truncated_int, elem_llvm_ty, "");6614 return self.wip.cast(.inttoptr, truncated_int, elem_llvm_ty, "");
...@@ -6599,12 +6627,12 @@ pub const FuncGen = struct {...@@ -6599,12 +6627,12 @@ pub const FuncGen = struct {
6599 const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?;6627 const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?;
6600 const field_ptr =6628 const field_ptr =
6601 try self.wip.gepStruct(struct_llvm_ty, struct_llvm_val, llvm_field_index, "");6629 try self.wip.gepStruct(struct_llvm_ty, struct_llvm_val, llvm_field_index, "");
6602 const alignment = struct_ty.structFieldAlign(field_index, mod);6630 const alignment = struct_ty.structFieldAlign(field_index, pt);
6603 const field_ptr_ty = try mod.ptrType(.{6631 const field_ptr_ty = try pt.ptrType(.{
6604 .child = field_ty.toIntern(),6632 .child = field_ty.toIntern(),
6605 .flags = .{ .alignment = alignment },6633 .flags = .{ .alignment = alignment },
6606 });6634 });
6607 if (isByRef(field_ty, mod)) {6635 if (isByRef(field_ty, pt)) {
6608 if (canElideLoad(self, body_tail))6636 if (canElideLoad(self, body_tail))
6609 return field_ptr;6637 return field_ptr;
66106638
...@@ -6617,12 +6645,12 @@ pub const FuncGen = struct {...@@ -6617,12 +6645,12 @@ pub const FuncGen = struct {
6617 },6645 },
6618 .Union => {6646 .Union => {
6619 const union_llvm_ty = try o.lowerType(struct_ty);6647 const union_llvm_ty = try o.lowerType(struct_ty);
6620 const layout = struct_ty.unionGetLayout(mod);6648 const layout = struct_ty.unionGetLayout(pt);
6621 const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align));6649 const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align));
6622 const field_ptr =6650 const field_ptr =
6623 try self.wip.gepStruct(union_llvm_ty, struct_llvm_val, payload_index, "");6651 try self.wip.gepStruct(union_llvm_ty, struct_llvm_val, payload_index, "");
6624 const payload_alignment = layout.payload_align.toLlvm();6652 const payload_alignment = layout.payload_align.toLlvm();
6625 if (isByRef(field_ty, mod)) {6653 if (isByRef(field_ty, pt)) {
6626 if (canElideLoad(self, body_tail)) return field_ptr;6654 if (canElideLoad(self, body_tail)) return field_ptr;
6627 return self.loadByRef(field_ptr, field_ty, payload_alignment, .normal);6655 return self.loadByRef(field_ptr, field_ty, payload_alignment, .normal);
6628 } else {6656 } else {
...@@ -6635,14 +6663,15 @@ pub const FuncGen = struct {...@@ -6635,14 +6663,15 @@ pub const FuncGen = struct {
66356663
6636 fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6664 fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6637 const o = self.dg.object;6665 const o = self.dg.object;
6638 const mod = o.module;6666 const pt = o.pt;
6667 const mod = pt.zcu;
6639 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6668 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6640 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;6669 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
66416670
6642 const field_ptr = try self.resolveInst(extra.field_ptr);6671 const field_ptr = try self.resolveInst(extra.field_ptr);
66436672
6644 const parent_ty = ty_pl.ty.toType().childType(mod);6673 const parent_ty = ty_pl.ty.toType().childType(mod);
6645 const field_offset = parent_ty.structFieldOffset(extra.field_index, mod);6674 const field_offset = parent_ty.structFieldOffset(extra.field_index, pt);
6646 if (field_offset == 0) return field_ptr;6675 if (field_offset == 0) return field_ptr;
66476676
6648 const res_ty = try o.lowerType(ty_pl.ty.toType());6677 const res_ty = try o.lowerType(ty_pl.ty.toType());
...@@ -6696,7 +6725,7 @@ pub const FuncGen = struct {...@@ -6696,7 +6725,7 @@ pub const FuncGen = struct {
66966725
6697 fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6726 fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6698 const o = self.dg.object;6727 const o = self.dg.object;
6699 const mod = o.module;6728 const mod = o.pt.zcu;
6700 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6729 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6701 const operand = try self.resolveInst(pl_op.operand);6730 const operand = try self.resolveInst(pl_op.operand);
6702 const name = self.air.nullTerminatedString(pl_op.payload);6731 const name = self.air.nullTerminatedString(pl_op.payload);
...@@ -6743,9 +6772,9 @@ pub const FuncGen = struct {...@@ -6743,9 +6772,9 @@ pub const FuncGen = struct {
6743 try o.lowerDebugType(operand_ty),6772 try o.lowerDebugType(operand_ty),
6744 );6773 );
67456774
6746 const zcu = o.module;6775 const pt = o.pt;
6747 const owner_mod = self.dg.ownerModule();6776 const owner_mod = self.dg.ownerModule();
6748 if (isByRef(operand_ty, zcu)) {6777 if (isByRef(operand_ty, pt)) {
6749 _ = try self.wip.callIntrinsic(6778 _ = try self.wip.callIntrinsic(
6750 .normal,6779 .normal,
6751 .none,6780 .none,
...@@ -6759,7 +6788,7 @@ pub const FuncGen = struct {...@@ -6759,7 +6788,7 @@ pub const FuncGen = struct {
6759 "",6788 "",
6760 );6789 );
6761 } else if (owner_mod.optimize_mode == .Debug) {6790 } else if (owner_mod.optimize_mode == .Debug) {
6762 const alignment = operand_ty.abiAlignment(zcu).toLlvm();6791 const alignment = operand_ty.abiAlignment(pt).toLlvm();
6763 const alloca = try self.buildAlloca(operand.typeOfWip(&self.wip), alignment);6792 const alloca = try self.buildAlloca(operand.typeOfWip(&self.wip), alignment);
6764 _ = try self.wip.store(.normal, operand, alloca, alignment);6793 _ = try self.wip.store(.normal, operand, alloca, alignment);
6765 _ = try self.wip.callIntrinsic(6794 _ = try self.wip.callIntrinsic(
...@@ -6830,7 +6859,8 @@ pub const FuncGen = struct {...@@ -6830,7 +6859,8 @@ pub const FuncGen = struct {
6830 // This stores whether we need to add an elementtype attribute and6859 // This stores whether we need to add an elementtype attribute and
6831 // if so, the element type itself.6860 // if so, the element type itself.
6832 const llvm_param_attrs = try arena.alloc(Builder.Type, max_param_count);6861 const llvm_param_attrs = try arena.alloc(Builder.Type, max_param_count);
6833 const mod = o.module;6862 const pt = o.pt;
6863 const mod = pt.zcu;
6834 const target = mod.getTarget();6864 const target = mod.getTarget();
68356865
6836 var llvm_ret_i: usize = 0;6866 var llvm_ret_i: usize = 0;
...@@ -6930,13 +6960,13 @@ pub const FuncGen = struct {...@@ -6930,13 +6960,13 @@ pub const FuncGen = struct {
69306960
6931 const arg_llvm_value = try self.resolveInst(input);6961 const arg_llvm_value = try self.resolveInst(input);
6932 const arg_ty = self.typeOf(input);6962 const arg_ty = self.typeOf(input);
6933 const is_by_ref = isByRef(arg_ty, mod);6963 const is_by_ref = isByRef(arg_ty, pt);
6934 if (is_by_ref) {6964 if (is_by_ref) {
6935 if (constraintAllowsMemory(constraint)) {6965 if (constraintAllowsMemory(constraint)) {
6936 llvm_param_values[llvm_param_i] = arg_llvm_value;6966 llvm_param_values[llvm_param_i] = arg_llvm_value;
6937 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip);6967 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip);
6938 } else {6968 } else {
6939 const alignment = arg_ty.abiAlignment(mod).toLlvm();6969 const alignment = arg_ty.abiAlignment(pt).toLlvm();
6940 const arg_llvm_ty = try o.lowerType(arg_ty);6970 const arg_llvm_ty = try o.lowerType(arg_ty);
6941 const load_inst =6971 const load_inst =
6942 try self.wip.load(.normal, arg_llvm_ty, arg_llvm_value, alignment, "");6972 try self.wip.load(.normal, arg_llvm_ty, arg_llvm_value, alignment, "");
...@@ -6948,7 +6978,7 @@ pub const FuncGen = struct {...@@ -6948,7 +6978,7 @@ pub const FuncGen = struct {
6948 llvm_param_values[llvm_param_i] = arg_llvm_value;6978 llvm_param_values[llvm_param_i] = arg_llvm_value;
6949 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip);6979 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip);
6950 } else {6980 } else {
6951 const alignment = arg_ty.abiAlignment(mod).toLlvm();6981 const alignment = arg_ty.abiAlignment(pt).toLlvm();
6952 const arg_ptr = try self.buildAlloca(arg_llvm_value.typeOfWip(&self.wip), alignment);6982 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);6983 _ = try self.wip.store(.normal, arg_llvm_value, arg_ptr, alignment);
6954 llvm_param_values[llvm_param_i] = arg_ptr;6984 llvm_param_values[llvm_param_i] = arg_ptr;
...@@ -7000,7 +7030,7 @@ pub const FuncGen = struct {...@@ -7000,7 +7030,7 @@ pub const FuncGen = struct {
7000 llvm_param_values[llvm_param_i] = llvm_rw_val;7030 llvm_param_values[llvm_param_i] = llvm_rw_val;
7001 llvm_param_types[llvm_param_i] = llvm_rw_val.typeOfWip(&self.wip);7031 llvm_param_types[llvm_param_i] = llvm_rw_val.typeOfWip(&self.wip);
7002 } else {7032 } else {
7003 const alignment = rw_ty.abiAlignment(mod).toLlvm();7033 const alignment = rw_ty.abiAlignment(pt).toLlvm();
7004 const loaded = try self.wip.load(.normal, llvm_elem_ty, llvm_rw_val, alignment, "");7034 const loaded = try self.wip.load(.normal, llvm_elem_ty, llvm_rw_val, alignment, "");
7005 llvm_param_values[llvm_param_i] = loaded;7035 llvm_param_values[llvm_param_i] = loaded;
7006 llvm_param_types[llvm_param_i] = llvm_elem_ty;7036 llvm_param_types[llvm_param_i] = llvm_elem_ty;
...@@ -7161,7 +7191,7 @@ pub const FuncGen = struct {...@@ -7161,7 +7191,7 @@ pub const FuncGen = struct {
7161 const output_ptr = try self.resolveInst(output);7191 const output_ptr = try self.resolveInst(output);
7162 const output_ptr_ty = self.typeOf(output);7192 const output_ptr_ty = self.typeOf(output);
71637193
7164 const alignment = output_ptr_ty.ptrAlignment(mod).toLlvm();7194 const alignment = output_ptr_ty.ptrAlignment(pt).toLlvm();
7165 _ = try self.wip.store(.normal, output_value, output_ptr, alignment);7195 _ = try self.wip.store(.normal, output_value, output_ptr, alignment);
7166 } else {7196 } else {
7167 ret_val = output_value;7197 ret_val = output_value;
...@@ -7179,7 +7209,8 @@ pub const FuncGen = struct {...@@ -7179,7 +7209,8 @@ pub const FuncGen = struct {
7179 cond: Builder.IntegerCondition,7209 cond: Builder.IntegerCondition,
7180 ) !Builder.Value {7210 ) !Builder.Value {
7181 const o = self.dg.object;7211 const o = self.dg.object;
7182 const mod = o.module;7212 const pt = o.pt;
7213 const mod = pt.zcu;
7183 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;7214 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
7184 const operand = try self.resolveInst(un_op);7215 const operand = try self.resolveInst(un_op);
7185 const operand_ty = self.typeOf(un_op);7216 const operand_ty = self.typeOf(un_op);
...@@ -7204,7 +7235,7 @@ pub const FuncGen = struct {...@@ -7204,7 +7235,7 @@ pub const FuncGen = struct {
72047235
7205 comptime assert(optional_layout_version == 3);7236 comptime assert(optional_layout_version == 3);
72067237
7207 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7238 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
7208 const loaded = if (operand_is_ptr)7239 const loaded = if (operand_is_ptr)
7209 try self.wip.load(.normal, optional_llvm_ty, operand, .default, "")7240 try self.wip.load(.normal, optional_llvm_ty, operand, .default, "")
7210 else7241 else
...@@ -7212,7 +7243,7 @@ pub const FuncGen = struct {...@@ -7212,7 +7243,7 @@ pub const FuncGen = struct {
7212 return self.wip.icmp(cond, loaded, try o.builder.intValue(.i8, 0), "");7243 return self.wip.icmp(cond, loaded, try o.builder.intValue(.i8, 0), "");
7213 }7244 }
72147245
7215 const is_by_ref = operand_is_ptr or isByRef(optional_ty, mod);7246 const is_by_ref = operand_is_ptr or isByRef(optional_ty, pt);
7216 return self.optCmpNull(cond, optional_llvm_ty, operand, is_by_ref);7247 return self.optCmpNull(cond, optional_llvm_ty, operand, is_by_ref);
7217 }7248 }
72187249
...@@ -7223,7 +7254,8 @@ pub const FuncGen = struct {...@@ -7223,7 +7254,8 @@ pub const FuncGen = struct {
7223 operand_is_ptr: bool,7254 operand_is_ptr: bool,
7224 ) !Builder.Value {7255 ) !Builder.Value {
7225 const o = self.dg.object;7256 const o = self.dg.object;
7226 const mod = o.module;7257 const pt = o.pt;
7258 const mod = pt.zcu;
7227 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;7259 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
7228 const operand = try self.resolveInst(un_op);7260 const operand = try self.resolveInst(un_op);
7229 const operand_ty = self.typeOf(un_op);7261 const operand_ty = self.typeOf(un_op);
...@@ -7241,7 +7273,7 @@ pub const FuncGen = struct {...@@ -7241,7 +7273,7 @@ pub const FuncGen = struct {
7241 return val.toValue();7273 return val.toValue();
7242 }7274 }
72437275
7244 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7276 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
7245 const loaded = if (operand_is_ptr)7277 const loaded = if (operand_is_ptr)
7246 try self.wip.load(.normal, try o.lowerType(err_union_ty), operand, .default, "")7278 try self.wip.load(.normal, try o.lowerType(err_union_ty), operand, .default, "")
7247 else7279 else
...@@ -7249,9 +7281,9 @@ pub const FuncGen = struct {...@@ -7249,9 +7281,9 @@ pub const FuncGen = struct {
7249 return self.wip.icmp(cond, loaded, zero, "");7281 return self.wip.icmp(cond, loaded, zero, "");
7250 }7282 }
72517283
7252 const err_field_index = try errUnionErrorOffset(payload_ty, mod);7284 const err_field_index = try errUnionErrorOffset(payload_ty, pt);
72537285
7254 const loaded = if (operand_is_ptr or isByRef(err_union_ty, mod)) loaded: {7286 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);7287 const err_union_llvm_ty = try o.lowerType(err_union_ty);
7256 const err_field_ptr =7288 const err_field_ptr =
7257 try self.wip.gepStruct(err_union_llvm_ty, operand, err_field_index, "");7289 try self.wip.gepStruct(err_union_llvm_ty, operand, err_field_index, "");
...@@ -7262,12 +7294,13 @@ pub const FuncGen = struct {...@@ -7262,12 +7294,13 @@ pub const FuncGen = struct {
72627294
7263 fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7295 fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7264 const o = self.dg.object;7296 const o = self.dg.object;
7265 const mod = o.module;7297 const pt = o.pt;
7298 const mod = pt.zcu;
7266 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7299 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
7267 const operand = try self.resolveInst(ty_op.operand);7300 const operand = try self.resolveInst(ty_op.operand);
7268 const optional_ty = self.typeOf(ty_op.operand).childType(mod);7301 const optional_ty = self.typeOf(ty_op.operand).childType(mod);
7269 const payload_ty = optional_ty.optionalChild(mod);7302 const payload_ty = optional_ty.optionalChild(mod);
7270 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7303 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
7271 // We have a pointer to a zero-bit value and we need to return7304 // We have a pointer to a zero-bit value and we need to return
7272 // a pointer to a zero-bit value.7305 // a pointer to a zero-bit value.
7273 return operand;7306 return operand;
...@@ -7283,13 +7316,14 @@ pub const FuncGen = struct {...@@ -7283,13 +7316,14 @@ pub const FuncGen = struct {
7283 comptime assert(optional_layout_version == 3);7316 comptime assert(optional_layout_version == 3);
72847317
7285 const o = self.dg.object;7318 const o = self.dg.object;
7286 const mod = o.module;7319 const pt = o.pt;
7320 const mod = pt.zcu;
7287 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7321 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
7288 const operand = try self.resolveInst(ty_op.operand);7322 const operand = try self.resolveInst(ty_op.operand);
7289 const optional_ty = self.typeOf(ty_op.operand).childType(mod);7323 const optional_ty = self.typeOf(ty_op.operand).childType(mod);
7290 const payload_ty = optional_ty.optionalChild(mod);7324 const payload_ty = optional_ty.optionalChild(mod);
7291 const non_null_bit = try o.builder.intValue(.i8, 1);7325 const non_null_bit = try o.builder.intValue(.i8, 1);
7292 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7326 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.7327 // 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);7328 _ = try self.wip.store(.normal, non_null_bit, operand, .default);
7295 return operand;7329 return operand;
...@@ -7314,13 +7348,14 @@ pub const FuncGen = struct {...@@ -7314,13 +7348,14 @@ pub const FuncGen = struct {
73147348
7315 fn airOptionalPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {7349 fn airOptionalPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
7316 const o = self.dg.object;7350 const o = self.dg.object;
7317 const mod = o.module;7351 const pt = o.pt;
7352 const mod = pt.zcu;
7318 const inst = body_tail[0];7353 const inst = body_tail[0];
7319 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7354 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
7320 const operand = try self.resolveInst(ty_op.operand);7355 const operand = try self.resolveInst(ty_op.operand);
7321 const optional_ty = self.typeOf(ty_op.operand);7356 const optional_ty = self.typeOf(ty_op.operand);
7322 const payload_ty = self.typeOfIndex(inst);7357 const payload_ty = self.typeOfIndex(inst);
7323 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;7358 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return .none;
73247359
7325 if (optional_ty.optionalReprIsPayload(mod)) {7360 if (optional_ty.optionalReprIsPayload(mod)) {
7326 // Payload value is the same as the optional value.7361 // Payload value is the same as the optional value.
...@@ -7328,7 +7363,7 @@ pub const FuncGen = struct {...@@ -7328,7 +7363,7 @@ pub const FuncGen = struct {
7328 }7363 }
73297364
7330 const opt_llvm_ty = try o.lowerType(optional_ty);7365 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;7366 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);7367 return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty, can_elide_load);
7333 }7368 }
73347369
...@@ -7338,7 +7373,8 @@ pub const FuncGen = struct {...@@ -7338,7 +7373,8 @@ pub const FuncGen = struct {
7338 operand_is_ptr: bool,7373 operand_is_ptr: bool,
7339 ) !Builder.Value {7374 ) !Builder.Value {
7340 const o = self.dg.object;7375 const o = self.dg.object;
7341 const mod = o.module;7376 const pt = o.pt;
7377 const mod = pt.zcu;
7342 const inst = body_tail[0];7378 const inst = body_tail[0];
7343 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7379 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
7344 const operand = try self.resolveInst(ty_op.operand);7380 const operand = try self.resolveInst(ty_op.operand);
...@@ -7347,17 +7383,17 @@ pub const FuncGen = struct {...@@ -7347,17 +7383,17 @@ pub const FuncGen = struct {
7347 const result_ty = self.typeOfIndex(inst);7383 const result_ty = self.typeOfIndex(inst);
7348 const payload_ty = if (operand_is_ptr) result_ty.childType(mod) else result_ty;7384 const payload_ty = if (operand_is_ptr) result_ty.childType(mod) else result_ty;
73497385
7350 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7386 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
7351 return if (operand_is_ptr) operand else .none;7387 return if (operand_is_ptr) operand else .none;
7352 }7388 }
7353 const offset = try errUnionPayloadOffset(payload_ty, mod);7389 const offset = try errUnionPayloadOffset(payload_ty, pt);
7354 const err_union_llvm_ty = try o.lowerType(err_union_ty);7390 const err_union_llvm_ty = try o.lowerType(err_union_ty);
7355 if (operand_is_ptr) {7391 if (operand_is_ptr) {
7356 return self.wip.gepStruct(err_union_llvm_ty, operand, offset, "");7392 return self.wip.gepStruct(err_union_llvm_ty, operand, offset, "");
7357 } else if (isByRef(err_union_ty, mod)) {7393 } else if (isByRef(err_union_ty, pt)) {
7358 const payload_alignment = payload_ty.abiAlignment(mod).toLlvm();7394 const payload_alignment = payload_ty.abiAlignment(pt).toLlvm();
7359 const payload_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, offset, "");7395 const payload_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, offset, "");
7360 if (isByRef(payload_ty, mod)) {7396 if (isByRef(payload_ty, pt)) {
7361 if (self.canElideLoad(body_tail)) return payload_ptr;7397 if (self.canElideLoad(body_tail)) return payload_ptr;
7362 return self.loadByRef(payload_ptr, payload_ty, payload_alignment, .normal);7398 return self.loadByRef(payload_ptr, payload_ty, payload_alignment, .normal);
7363 }7399 }
...@@ -7373,7 +7409,8 @@ pub const FuncGen = struct {...@@ -7373,7 +7409,8 @@ pub const FuncGen = struct {
7373 operand_is_ptr: bool,7409 operand_is_ptr: bool,
7374 ) !Builder.Value {7410 ) !Builder.Value {
7375 const o = self.dg.object;7411 const o = self.dg.object;
7376 const mod = o.module;7412 const pt = o.pt;
7413 const mod = pt.zcu;
7377 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7414 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
7378 const operand = try self.resolveInst(ty_op.operand);7415 const operand = try self.resolveInst(ty_op.operand);
7379 const operand_ty = self.typeOf(ty_op.operand);7416 const operand_ty = self.typeOf(ty_op.operand);
...@@ -7388,14 +7425,14 @@ pub const FuncGen = struct {...@@ -7388,14 +7425,14 @@ pub const FuncGen = struct {
7388 }7425 }
73897426
7390 const payload_ty = err_union_ty.errorUnionPayload(mod);7427 const payload_ty = err_union_ty.errorUnionPayload(mod);
7391 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7428 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
7392 if (!operand_is_ptr) return operand;7429 if (!operand_is_ptr) return operand;
7393 return self.wip.load(.normal, error_type, operand, .default, "");7430 return self.wip.load(.normal, error_type, operand, .default, "");
7394 }7431 }
73957432
7396 const offset = try errUnionErrorOffset(payload_ty, mod);7433 const offset = try errUnionErrorOffset(payload_ty, pt);
73977434
7398 if (operand_is_ptr or isByRef(err_union_ty, mod)) {7435 if (operand_is_ptr or isByRef(err_union_ty, pt)) {
7399 const err_union_llvm_ty = try o.lowerType(err_union_ty);7436 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, "");7437 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, "");7438 return self.wip.load(.normal, error_type, err_field_ptr, .default, "");
...@@ -7406,22 +7443,23 @@ pub const FuncGen = struct {...@@ -7406,22 +7443,23 @@ pub const FuncGen = struct {
74067443
7407 fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7444 fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7408 const o = self.dg.object;7445 const o = self.dg.object;
7409 const mod = o.module;7446 const pt = o.pt;
7447 const mod = pt.zcu;
7410 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7448 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
7411 const operand = try self.resolveInst(ty_op.operand);7449 const operand = try self.resolveInst(ty_op.operand);
7412 const err_union_ty = self.typeOf(ty_op.operand).childType(mod);7450 const err_union_ty = self.typeOf(ty_op.operand).childType(mod);
74137451
7414 const payload_ty = err_union_ty.errorUnionPayload(mod);7452 const payload_ty = err_union_ty.errorUnionPayload(mod);
7415 const non_error_val = try o.builder.intValue(try o.errorIntType(), 0);7453 const non_error_val = try o.builder.intValue(try o.errorIntType(), 0);
7416 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7454 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
7417 _ = try self.wip.store(.normal, non_error_val, operand, .default);7455 _ = try self.wip.store(.normal, non_error_val, operand, .default);
7418 return operand;7456 return operand;
7419 }7457 }
7420 const err_union_llvm_ty = try o.lowerType(err_union_ty);7458 const err_union_llvm_ty = try o.lowerType(err_union_ty);
7421 {7459 {
7422 const err_int_ty = try mod.errorIntType();7460 const err_int_ty = try pt.errorIntType();
7423 const error_alignment = err_int_ty.abiAlignment(mod).toLlvm();7461 const error_alignment = err_int_ty.abiAlignment(pt).toLlvm();
7424 const error_offset = try errUnionErrorOffset(payload_ty, mod);7462 const error_offset = try errUnionErrorOffset(payload_ty, pt);
7425 // First set the non-error value.7463 // First set the non-error value.
7426 const non_null_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, error_offset, "");7464 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);7465 _ = try self.wip.store(.normal, non_error_val, non_null_ptr, error_alignment);
...@@ -7429,7 +7467,7 @@ pub const FuncGen = struct {...@@ -7429,7 +7467,7 @@ pub const FuncGen = struct {
7429 // Then return the payload pointer (only if it is used).7467 // Then return the payload pointer (only if it is used).
7430 if (self.liveness.isUnused(inst)) return .none;7468 if (self.liveness.isUnused(inst)) return .none;
74317469
7432 const payload_offset = try errUnionPayloadOffset(payload_ty, mod);7470 const payload_offset = try errUnionPayloadOffset(payload_ty, pt);
7433 return self.wip.gepStruct(err_union_llvm_ty, operand, payload_offset, "");7471 return self.wip.gepStruct(err_union_llvm_ty, operand, payload_offset, "");
7434 }7472 }
74357473
...@@ -7446,19 +7484,21 @@ pub const FuncGen = struct {...@@ -7446,19 +7484,21 @@ pub const FuncGen = struct {
74467484
7447 fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7485 fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7448 const o = self.dg.object;7486 const o = self.dg.object;
7487 const pt = o.pt;
7488 const mod = pt.zcu;
7489
7449 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;7490 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
7450 const struct_ty = ty_pl.ty.toType();7491 const struct_ty = ty_pl.ty.toType();
7451 const field_index = ty_pl.payload;7492 const field_index = ty_pl.payload;
74527493
7453 const mod = o.module;
7454 const struct_llvm_ty = try o.lowerType(struct_ty);7494 const struct_llvm_ty = try o.lowerType(struct_ty);
7455 const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?;7495 const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?;
7456 assert(self.err_ret_trace != .none);7496 assert(self.err_ret_trace != .none);
7457 const field_ptr =7497 const field_ptr =
7458 try self.wip.gepStruct(struct_llvm_ty, self.err_ret_trace, llvm_field_index, "");7498 try self.wip.gepStruct(struct_llvm_ty, self.err_ret_trace, llvm_field_index, "");
7459 const field_alignment = struct_ty.structFieldAlign(field_index, mod);7499 const field_alignment = struct_ty.structFieldAlign(field_index, pt);
7460 const field_ty = struct_ty.structFieldType(field_index, mod);7500 const field_ty = struct_ty.structFieldType(field_index, mod);
7461 const field_ptr_ty = try mod.ptrType(.{7501 const field_ptr_ty = try pt.ptrType(.{
7462 .child = field_ty.toIntern(),7502 .child = field_ty.toIntern(),
7463 .flags = .{ .alignment = field_alignment },7503 .flags = .{ .alignment = field_alignment },
7464 });7504 });
...@@ -7490,29 +7530,30 @@ pub const FuncGen = struct {...@@ -7490,29 +7530,30 @@ pub const FuncGen = struct {
74907530
7491 fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {7531 fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
7492 const o = self.dg.object;7532 const o = self.dg.object;
7493 const mod = o.module;7533 const pt = o.pt;
7534 const mod = pt.zcu;
7494 const inst = body_tail[0];7535 const inst = body_tail[0];
7495 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7536 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
7496 const payload_ty = self.typeOf(ty_op.operand);7537 const payload_ty = self.typeOf(ty_op.operand);
7497 const non_null_bit = try o.builder.intValue(.i8, 1);7538 const non_null_bit = try o.builder.intValue(.i8, 1);
7498 comptime assert(optional_layout_version == 3);7539 comptime assert(optional_layout_version == 3);
7499 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return non_null_bit;7540 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return non_null_bit;
7500 const operand = try self.resolveInst(ty_op.operand);7541 const operand = try self.resolveInst(ty_op.operand);
7501 const optional_ty = self.typeOfIndex(inst);7542 const optional_ty = self.typeOfIndex(inst);
7502 if (optional_ty.optionalReprIsPayload(mod)) return operand;7543 if (optional_ty.optionalReprIsPayload(mod)) return operand;
7503 const llvm_optional_ty = try o.lowerType(optional_ty);7544 const llvm_optional_ty = try o.lowerType(optional_ty);
7504 if (isByRef(optional_ty, mod)) {7545 if (isByRef(optional_ty, pt)) {
7505 const directReturn = self.isNextRet(body_tail);7546 const directReturn = self.isNextRet(body_tail);
7506 const optional_ptr = if (directReturn)7547 const optional_ptr = if (directReturn)
7507 self.ret_ptr7548 self.ret_ptr
7508 else brk: {7549 else brk: {
7509 const alignment = optional_ty.abiAlignment(mod).toLlvm();7550 const alignment = optional_ty.abiAlignment(pt).toLlvm();
7510 const optional_ptr = try self.buildAllocaWorkaround(optional_ty, alignment);7551 const optional_ptr = try self.buildAllocaWorkaround(optional_ty, alignment);
7511 break :brk optional_ptr;7552 break :brk optional_ptr;
7512 };7553 };
75137554
7514 const payload_ptr = try self.wip.gepStruct(llvm_optional_ty, optional_ptr, 0, "");7555 const payload_ptr = try self.wip.gepStruct(llvm_optional_ty, optional_ptr, 0, "");
7515 const payload_ptr_ty = try mod.singleMutPtrType(payload_ty);7556 const payload_ptr_ty = try pt.singleMutPtrType(payload_ty);
7516 try self.store(payload_ptr, payload_ptr_ty, operand, .none);7557 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, "");7558 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);7559 _ = try self.wip.store(.normal, non_null_bit, non_null_ptr, .default);
...@@ -7523,36 +7564,36 @@ pub const FuncGen = struct {...@@ -7523,36 +7564,36 @@ pub const FuncGen = struct {
75237564
7524 fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {7565 fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
7525 const o = self.dg.object;7566 const o = self.dg.object;
7526 const mod = o.module;7567 const pt = o.pt;
7527 const inst = body_tail[0];7568 const inst = body_tail[0];
7528 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7569 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
7529 const err_un_ty = self.typeOfIndex(inst);7570 const err_un_ty = self.typeOfIndex(inst);
7530 const operand = try self.resolveInst(ty_op.operand);7571 const operand = try self.resolveInst(ty_op.operand);
7531 const payload_ty = self.typeOf(ty_op.operand);7572 const payload_ty = self.typeOf(ty_op.operand);
7532 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7573 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
7533 return operand;7574 return operand;
7534 }7575 }
7535 const ok_err_code = try o.builder.intValue(try o.errorIntType(), 0);7576 const ok_err_code = try o.builder.intValue(try o.errorIntType(), 0);
7536 const err_un_llvm_ty = try o.lowerType(err_un_ty);7577 const err_un_llvm_ty = try o.lowerType(err_un_ty);
75377578
7538 const payload_offset = try errUnionPayloadOffset(payload_ty, mod);7579 const payload_offset = try errUnionPayloadOffset(payload_ty, pt);
7539 const error_offset = try errUnionErrorOffset(payload_ty, mod);7580 const error_offset = try errUnionErrorOffset(payload_ty, pt);
7540 if (isByRef(err_un_ty, mod)) {7581 if (isByRef(err_un_ty, pt)) {
7541 const directReturn = self.isNextRet(body_tail);7582 const directReturn = self.isNextRet(body_tail);
7542 const result_ptr = if (directReturn)7583 const result_ptr = if (directReturn)
7543 self.ret_ptr7584 self.ret_ptr
7544 else brk: {7585 else brk: {
7545 const alignment = err_un_ty.abiAlignment(mod).toLlvm();7586 const alignment = err_un_ty.abiAlignment(pt).toLlvm();
7546 const result_ptr = try self.buildAllocaWorkaround(err_un_ty, alignment);7587 const result_ptr = try self.buildAllocaWorkaround(err_un_ty, alignment);
7547 break :brk result_ptr;7588 break :brk result_ptr;
7548 };7589 };
75497590
7550 const err_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, error_offset, "");7591 const err_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, error_offset, "");
7551 const err_int_ty = try mod.errorIntType();7592 const err_int_ty = try pt.errorIntType();
7552 const error_alignment = err_int_ty.abiAlignment(mod).toLlvm();7593 const error_alignment = err_int_ty.abiAlignment(pt).toLlvm();
7553 _ = try self.wip.store(.normal, ok_err_code, err_ptr, error_alignment);7594 _ = 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, "");7595 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);7596 const payload_ptr_ty = try pt.singleMutPtrType(payload_ty);
7556 try self.store(payload_ptr, payload_ptr_ty, operand, .none);7597 try self.store(payload_ptr, payload_ptr_ty, operand, .none);
7557 return result_ptr;7598 return result_ptr;
7558 }7599 }
...@@ -7564,33 +7605,34 @@ pub const FuncGen = struct {...@@ -7564,33 +7605,34 @@ pub const FuncGen = struct {
75647605
7565 fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {7606 fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
7566 const o = self.dg.object;7607 const o = self.dg.object;
7567 const mod = o.module;7608 const pt = o.pt;
7609 const mod = pt.zcu;
7568 const inst = body_tail[0];7610 const inst = body_tail[0];
7569 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7611 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
7570 const err_un_ty = self.typeOfIndex(inst);7612 const err_un_ty = self.typeOfIndex(inst);
7571 const payload_ty = err_un_ty.errorUnionPayload(mod);7613 const payload_ty = err_un_ty.errorUnionPayload(mod);
7572 const operand = try self.resolveInst(ty_op.operand);7614 const operand = try self.resolveInst(ty_op.operand);
7573 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return operand;7615 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return operand;
7574 const err_un_llvm_ty = try o.lowerType(err_un_ty);7616 const err_un_llvm_ty = try o.lowerType(err_un_ty);
75757617
7576 const payload_offset = try errUnionPayloadOffset(payload_ty, mod);7618 const payload_offset = try errUnionPayloadOffset(payload_ty, pt);
7577 const error_offset = try errUnionErrorOffset(payload_ty, mod);7619 const error_offset = try errUnionErrorOffset(payload_ty, pt);
7578 if (isByRef(err_un_ty, mod)) {7620 if (isByRef(err_un_ty, pt)) {
7579 const directReturn = self.isNextRet(body_tail);7621 const directReturn = self.isNextRet(body_tail);
7580 const result_ptr = if (directReturn)7622 const result_ptr = if (directReturn)
7581 self.ret_ptr7623 self.ret_ptr
7582 else brk: {7624 else brk: {
7583 const alignment = err_un_ty.abiAlignment(mod).toLlvm();7625 const alignment = err_un_ty.abiAlignment(pt).toLlvm();
7584 const result_ptr = try self.buildAllocaWorkaround(err_un_ty, alignment);7626 const result_ptr = try self.buildAllocaWorkaround(err_un_ty, alignment);
7585 break :brk result_ptr;7627 break :brk result_ptr;
7586 };7628 };
75877629
7588 const err_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, error_offset, "");7630 const err_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, error_offset, "");
7589 const err_int_ty = try mod.errorIntType();7631 const err_int_ty = try pt.errorIntType();
7590 const error_alignment = err_int_ty.abiAlignment(mod).toLlvm();7632 const error_alignment = err_int_ty.abiAlignment(pt).toLlvm();
7591 _ = try self.wip.store(.normal, operand, err_ptr, error_alignment);7633 _ = 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, "");7634 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);7635 const payload_ptr_ty = try pt.singleMutPtrType(payload_ty);
7594 // TODO store undef to payload_ptr7636 // TODO store undef to payload_ptr
7595 _ = payload_ptr;7637 _ = payload_ptr;
7596 _ = payload_ptr_ty;7638 _ = payload_ptr_ty;
...@@ -7624,7 +7666,8 @@ pub const FuncGen = struct {...@@ -7624,7 +7666,8 @@ pub const FuncGen = struct {
76247666
7625 fn airVectorStoreElem(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7667 fn airVectorStoreElem(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7626 const o = self.dg.object;7668 const o = self.dg.object;
7627 const mod = o.module;7669 const pt = o.pt;
7670 const mod = pt.zcu;
7628 const data = self.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem;7671 const data = self.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem;
7629 const extra = self.air.extraData(Air.Bin, data.payload).data;7672 const extra = self.air.extraData(Air.Bin, data.payload).data;
76307673
...@@ -7636,7 +7679,7 @@ pub const FuncGen = struct {...@@ -7636,7 +7679,7 @@ pub const FuncGen = struct {
7636 const access_kind: Builder.MemoryAccessKind =7679 const access_kind: Builder.MemoryAccessKind =
7637 if (vector_ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal;7680 if (vector_ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal;
7638 const elem_llvm_ty = try o.lowerType(vector_ptr_ty.childType(mod));7681 const elem_llvm_ty = try o.lowerType(vector_ptr_ty.childType(mod));
7639 const alignment = vector_ptr_ty.ptrAlignment(mod).toLlvm();7682 const alignment = vector_ptr_ty.ptrAlignment(pt).toLlvm();
7640 const loaded = try self.wip.load(access_kind, elem_llvm_ty, vector_ptr, alignment, "");7683 const loaded = try self.wip.load(access_kind, elem_llvm_ty, vector_ptr, alignment, "");
76417684
7642 const new_vector = try self.wip.insertElement(loaded, operand, index, "");7685 const new_vector = try self.wip.insertElement(loaded, operand, index, "");
...@@ -7646,7 +7689,7 @@ pub const FuncGen = struct {...@@ -7646,7 +7689,7 @@ pub const FuncGen = struct {
76467689
7647 fn airMin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7690 fn airMin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7648 const o = self.dg.object;7691 const o = self.dg.object;
7649 const mod = o.module;7692 const mod = o.pt.zcu;
7650 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7693 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7651 const lhs = try self.resolveInst(bin_op.lhs);7694 const lhs = try self.resolveInst(bin_op.lhs);
7652 const rhs = try self.resolveInst(bin_op.rhs);7695 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7666,7 +7709,7 @@ pub const FuncGen = struct {...@@ -7666,7 +7709,7 @@ pub const FuncGen = struct {
76667709
7667 fn airMax(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7710 fn airMax(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7668 const o = self.dg.object;7711 const o = self.dg.object;
7669 const mod = o.module;7712 const mod = o.pt.zcu;
7670 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7713 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7671 const lhs = try self.resolveInst(bin_op.lhs);7714 const lhs = try self.resolveInst(bin_op.lhs);
7672 const rhs = try self.resolveInst(bin_op.rhs);7715 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7696,7 +7739,7 @@ pub const FuncGen = struct {...@@ -7696,7 +7739,7 @@ pub const FuncGen = struct {
76967739
7697 fn airAdd(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7740 fn airAdd(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7698 const o = self.dg.object;7741 const o = self.dg.object;
7699 const mod = o.module;7742 const mod = o.pt.zcu;
7700 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7743 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7701 const lhs = try self.resolveInst(bin_op.lhs);7744 const lhs = try self.resolveInst(bin_op.lhs);
7702 const rhs = try self.resolveInst(bin_op.rhs);7745 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7714,7 +7757,7 @@ pub const FuncGen = struct {...@@ -7714,7 +7757,7 @@ pub const FuncGen = struct {
7714 unsigned_intrinsic: Builder.Intrinsic,7757 unsigned_intrinsic: Builder.Intrinsic,
7715 ) !Builder.Value {7758 ) !Builder.Value {
7716 const o = fg.dg.object;7759 const o = fg.dg.object;
7717 const mod = o.module;7760 const mod = o.pt.zcu;
77187761
7719 const bin_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7762 const bin_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7720 const lhs = try fg.resolveInst(bin_op.lhs);7763 const lhs = try fg.resolveInst(bin_op.lhs);
...@@ -7762,7 +7805,7 @@ pub const FuncGen = struct {...@@ -7762,7 +7805,7 @@ pub const FuncGen = struct {
77627805
7763 fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7806 fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7764 const o = self.dg.object;7807 const o = self.dg.object;
7765 const mod = o.module;7808 const mod = o.pt.zcu;
7766 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7809 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7767 const lhs = try self.resolveInst(bin_op.lhs);7810 const lhs = try self.resolveInst(bin_op.lhs);
7768 const rhs = try self.resolveInst(bin_op.rhs);7811 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7782,7 +7825,7 @@ pub const FuncGen = struct {...@@ -7782,7 +7825,7 @@ pub const FuncGen = struct {
77827825
7783 fn airSub(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7826 fn airSub(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7784 const o = self.dg.object;7827 const o = self.dg.object;
7785 const mod = o.module;7828 const mod = o.pt.zcu;
7786 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7829 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7787 const lhs = try self.resolveInst(bin_op.lhs);7830 const lhs = try self.resolveInst(bin_op.lhs);
7788 const rhs = try self.resolveInst(bin_op.rhs);7831 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7803,7 +7846,7 @@ pub const FuncGen = struct {...@@ -7803,7 +7846,7 @@ pub const FuncGen = struct {
78037846
7804 fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7847 fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7805 const o = self.dg.object;7848 const o = self.dg.object;
7806 const mod = o.module;7849 const mod = o.pt.zcu;
7807 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7850 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7808 const lhs = try self.resolveInst(bin_op.lhs);7851 const lhs = try self.resolveInst(bin_op.lhs);
7809 const rhs = try self.resolveInst(bin_op.rhs);7852 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7823,7 +7866,7 @@ pub const FuncGen = struct {...@@ -7823,7 +7866,7 @@ pub const FuncGen = struct {
78237866
7824 fn airMul(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7867 fn airMul(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7825 const o = self.dg.object;7868 const o = self.dg.object;
7826 const mod = o.module;7869 const mod = o.pt.zcu;
7827 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7870 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7828 const lhs = try self.resolveInst(bin_op.lhs);7871 const lhs = try self.resolveInst(bin_op.lhs);
7829 const rhs = try self.resolveInst(bin_op.rhs);7872 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7844,7 +7887,7 @@ pub const FuncGen = struct {...@@ -7844,7 +7887,7 @@ pub const FuncGen = struct {
78447887
7845 fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7888 fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7846 const o = self.dg.object;7889 const o = self.dg.object;
7847 const mod = o.module;7890 const mod = o.pt.zcu;
7848 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7891 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7849 const lhs = try self.resolveInst(bin_op.lhs);7892 const lhs = try self.resolveInst(bin_op.lhs);
7850 const rhs = try self.resolveInst(bin_op.rhs);7893 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7873,7 +7916,7 @@ pub const FuncGen = struct {...@@ -7873,7 +7916,7 @@ pub const FuncGen = struct {
78737916
7874 fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7917 fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7875 const o = self.dg.object;7918 const o = self.dg.object;
7876 const mod = o.module;7919 const mod = o.pt.zcu;
7877 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7920 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7878 const lhs = try self.resolveInst(bin_op.lhs);7921 const lhs = try self.resolveInst(bin_op.lhs);
7879 const rhs = try self.resolveInst(bin_op.rhs);7922 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7889,7 +7932,7 @@ pub const FuncGen = struct {...@@ -7889,7 +7932,7 @@ pub const FuncGen = struct {
78897932
7890 fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7933 fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7891 const o = self.dg.object;7934 const o = self.dg.object;
7892 const mod = o.module;7935 const mod = o.pt.zcu;
7893 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7936 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7894 const lhs = try self.resolveInst(bin_op.lhs);7937 const lhs = try self.resolveInst(bin_op.lhs);
7895 const rhs = try self.resolveInst(bin_op.rhs);7938 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7921,7 +7964,7 @@ pub const FuncGen = struct {...@@ -7921,7 +7964,7 @@ pub const FuncGen = struct {
79217964
7922 fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7965 fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7923 const o = self.dg.object;7966 const o = self.dg.object;
7924 const mod = o.module;7967 const mod = o.pt.zcu;
7925 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7968 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7926 const lhs = try self.resolveInst(bin_op.lhs);7969 const lhs = try self.resolveInst(bin_op.lhs);
7927 const rhs = try self.resolveInst(bin_op.rhs);7970 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7939,7 +7982,7 @@ pub const FuncGen = struct {...@@ -7939,7 +7982,7 @@ pub const FuncGen = struct {
79397982
7940 fn airRem(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7983 fn airRem(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7941 const o = self.dg.object;7984 const o = self.dg.object;
7942 const mod = o.module;7985 const mod = o.pt.zcu;
7943 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7986 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7944 const lhs = try self.resolveInst(bin_op.lhs);7987 const lhs = try self.resolveInst(bin_op.lhs);
7945 const rhs = try self.resolveInst(bin_op.rhs);7988 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7956,7 +7999,7 @@ pub const FuncGen = struct {...@@ -7956,7 +7999,7 @@ pub const FuncGen = struct {
79567999
7957 fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {8000 fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7958 const o = self.dg.object;8001 const o = self.dg.object;
7959 const mod = o.module;8002 const mod = o.pt.zcu;
7960 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;8003 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7961 const lhs = try self.resolveInst(bin_op.lhs);8004 const lhs = try self.resolveInst(bin_op.lhs);
7962 const rhs = try self.resolveInst(bin_op.rhs);8005 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7992,7 +8035,7 @@ pub const FuncGen = struct {...@@ -7992,7 +8035,7 @@ pub const FuncGen = struct {
79928035
7993 fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8036 fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7994 const o = self.dg.object;8037 const o = self.dg.object;
7995 const mod = o.module;8038 const mod = o.pt.zcu;
7996 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;8039 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;8040 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
7998 const ptr = try self.resolveInst(bin_op.lhs);8041 const ptr = try self.resolveInst(bin_op.lhs);
...@@ -8014,7 +8057,7 @@ pub const FuncGen = struct {...@@ -8014,7 +8057,7 @@ pub const FuncGen = struct {
80148057
8015 fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8058 fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8016 const o = self.dg.object;8059 const o = self.dg.object;
8017 const mod = o.module;8060 const mod = o.pt.zcu;
8018 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;8061 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;8062 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
8020 const ptr = try self.resolveInst(bin_op.lhs);8063 const ptr = try self.resolveInst(bin_op.lhs);
...@@ -8042,7 +8085,8 @@ pub const FuncGen = struct {...@@ -8042,7 +8085,8 @@ pub const FuncGen = struct {
8042 unsigned_intrinsic: Builder.Intrinsic,8085 unsigned_intrinsic: Builder.Intrinsic,
8043 ) !Builder.Value {8086 ) !Builder.Value {
8044 const o = self.dg.object;8087 const o = self.dg.object;
8045 const mod = o.module;8088 const pt = o.pt;
8089 const mod = pt.zcu;
8046 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;8090 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
8047 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;8091 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
80488092
...@@ -8065,8 +8109,8 @@ pub const FuncGen = struct {...@@ -8065,8 +8109,8 @@ pub const FuncGen = struct {
8065 const result_index = o.llvmFieldIndex(inst_ty, 0).?;8109 const result_index = o.llvmFieldIndex(inst_ty, 0).?;
8066 const overflow_index = o.llvmFieldIndex(inst_ty, 1).?;8110 const overflow_index = o.llvmFieldIndex(inst_ty, 1).?;
80678111
8068 if (isByRef(inst_ty, mod)) {8112 if (isByRef(inst_ty, pt)) {
8069 const result_alignment = inst_ty.abiAlignment(mod).toLlvm();8113 const result_alignment = inst_ty.abiAlignment(pt).toLlvm();
8070 const alloca_inst = try self.buildAllocaWorkaround(inst_ty, result_alignment);8114 const alloca_inst = try self.buildAllocaWorkaround(inst_ty, result_alignment);
8071 {8115 {
8072 const field_ptr = try self.wip.gepStruct(llvm_inst_ty, alloca_inst, result_index, "");8116 const field_ptr = try self.wip.gepStruct(llvm_inst_ty, alloca_inst, result_index, "");
...@@ -8135,7 +8179,7 @@ pub const FuncGen = struct {...@@ -8135,7 +8179,7 @@ pub const FuncGen = struct {
8135 return o.builder.addFunction(8179 return o.builder.addFunction(
8136 try o.builder.fnType(return_type, param_types, .normal),8180 try o.builder.fnType(return_type, param_types, .normal),
8137 fn_name,8181 fn_name,
8138 toLlvmAddressSpace(.generic, o.module.getTarget()),8182 toLlvmAddressSpace(.generic, o.pt.zcu.getTarget()),
8139 );8183 );
8140 }8184 }
81418185
...@@ -8149,8 +8193,8 @@ pub const FuncGen = struct {...@@ -8149,8 +8193,8 @@ pub const FuncGen = struct {
8149 params: [2]Builder.Value,8193 params: [2]Builder.Value,
8150 ) !Builder.Value {8194 ) !Builder.Value {
8151 const o = self.dg.object;8195 const o = self.dg.object;
8152 const mod = o.module;8196 const mod = o.pt.zcu;
8153 const target = o.module.getTarget();8197 const target = mod.getTarget();
8154 const scalar_ty = ty.scalarType(mod);8198 const scalar_ty = ty.scalarType(mod);
8155 const scalar_llvm_ty = try o.lowerType(scalar_ty);8199 const scalar_llvm_ty = try o.lowerType(scalar_ty);
81568200
...@@ -8255,7 +8299,7 @@ pub const FuncGen = struct {...@@ -8255,7 +8299,7 @@ pub const FuncGen = struct {
8255 params: [params_len]Builder.Value,8299 params: [params_len]Builder.Value,
8256 ) !Builder.Value {8300 ) !Builder.Value {
8257 const o = self.dg.object;8301 const o = self.dg.object;
8258 const mod = o.module;8302 const mod = o.pt.zcu;
8259 const target = mod.getTarget();8303 const target = mod.getTarget();
8260 const scalar_ty = ty.scalarType(mod);8304 const scalar_ty = ty.scalarType(mod);
8261 const llvm_ty = try o.lowerType(ty);8305 const llvm_ty = try o.lowerType(ty);
...@@ -8396,7 +8440,8 @@ pub const FuncGen = struct {...@@ -8396,7 +8440,8 @@ pub const FuncGen = struct {
83968440
8397 fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8441 fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8398 const o = self.dg.object;8442 const o = self.dg.object;
8399 const mod = o.module;8443 const pt = o.pt;
8444 const mod = pt.zcu;
8400 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;8445 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
8401 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;8446 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
84028447
...@@ -8422,8 +8467,8 @@ pub const FuncGen = struct {...@@ -8422,8 +8467,8 @@ pub const FuncGen = struct {
8422 const result_index = o.llvmFieldIndex(dest_ty, 0).?;8467 const result_index = o.llvmFieldIndex(dest_ty, 0).?;
8423 const overflow_index = o.llvmFieldIndex(dest_ty, 1).?;8468 const overflow_index = o.llvmFieldIndex(dest_ty, 1).?;
84248469
8425 if (isByRef(dest_ty, mod)) {8470 if (isByRef(dest_ty, pt)) {
8426 const result_alignment = dest_ty.abiAlignment(mod).toLlvm();8471 const result_alignment = dest_ty.abiAlignment(pt).toLlvm();
8427 const alloca_inst = try self.buildAllocaWorkaround(dest_ty, result_alignment);8472 const alloca_inst = try self.buildAllocaWorkaround(dest_ty, result_alignment);
8428 {8473 {
8429 const field_ptr = try self.wip.gepStruct(llvm_dest_ty, alloca_inst, result_index, "");8474 const field_ptr = try self.wip.gepStruct(llvm_dest_ty, alloca_inst, result_index, "");
...@@ -8466,7 +8511,7 @@ pub const FuncGen = struct {...@@ -8466,7 +8511,7 @@ pub const FuncGen = struct {
84668511
8467 fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8512 fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8468 const o = self.dg.object;8513 const o = self.dg.object;
8469 const mod = o.module;8514 const mod = o.pt.zcu;
8470 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;8515 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
84718516
8472 const lhs = try self.resolveInst(bin_op.lhs);8517 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -8497,7 +8542,8 @@ pub const FuncGen = struct {...@@ -8497,7 +8542,8 @@ pub const FuncGen = struct {
84978542
8498 fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8543 fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8499 const o = self.dg.object;8544 const o = self.dg.object;
8500 const mod = o.module;8545 const pt = o.pt;
8546 const mod = pt.zcu;
8501 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;8547 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
85028548
8503 const lhs = try self.resolveInst(bin_op.lhs);8549 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -8505,7 +8551,7 @@ pub const FuncGen = struct {...@@ -8505,7 +8551,7 @@ pub const FuncGen = struct {
85058551
8506 const lhs_ty = self.typeOf(bin_op.lhs);8552 const lhs_ty = self.typeOf(bin_op.lhs);
8507 const lhs_scalar_ty = lhs_ty.scalarType(mod);8553 const lhs_scalar_ty = lhs_ty.scalarType(mod);
8508 const lhs_bits = lhs_scalar_ty.bitSize(mod);8554 const lhs_bits = lhs_scalar_ty.bitSize(pt);
85098555
8510 const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty), "");8556 const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty), "");
85118557
...@@ -8539,7 +8585,7 @@ pub const FuncGen = struct {...@@ -8539,7 +8585,7 @@ pub const FuncGen = struct {
85398585
8540 fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !Builder.Value {8586 fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !Builder.Value {
8541 const o = self.dg.object;8587 const o = self.dg.object;
8542 const mod = o.module;8588 const mod = o.pt.zcu;
8543 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;8589 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
85448590
8545 const lhs = try self.resolveInst(bin_op.lhs);8591 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -8558,7 +8604,7 @@ pub const FuncGen = struct {...@@ -8558,7 +8604,7 @@ pub const FuncGen = struct {
85588604
8559 fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8605 fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8560 const o = self.dg.object;8606 const o = self.dg.object;
8561 const mod = o.module;8607 const mod = o.pt.zcu;
8562 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;8608 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
8563 const operand = try self.resolveInst(ty_op.operand);8609 const operand = try self.resolveInst(ty_op.operand);
8564 const operand_ty = self.typeOf(ty_op.operand);8610 const operand_ty = self.typeOf(ty_op.operand);
...@@ -8580,7 +8626,7 @@ pub const FuncGen = struct {...@@ -8580,7 +8626,7 @@ pub const FuncGen = struct {
85808626
8581 fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8627 fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8582 const o = self.dg.object;8628 const o = self.dg.object;
8583 const mod = o.module;8629 const mod = o.pt.zcu;
8584 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;8630 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
8585 const dest_ty = self.typeOfIndex(inst);8631 const dest_ty = self.typeOfIndex(inst);
8586 const dest_llvm_ty = try o.lowerType(dest_ty);8632 const dest_llvm_ty = try o.lowerType(dest_ty);
...@@ -8604,7 +8650,7 @@ pub const FuncGen = struct {...@@ -8604,7 +8650,7 @@ pub const FuncGen = struct {
86048650
8605 fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8651 fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8606 const o = self.dg.object;8652 const o = self.dg.object;
8607 const mod = o.module;8653 const mod = o.pt.zcu;
8608 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;8654 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
8609 const operand = try self.resolveInst(ty_op.operand);8655 const operand = try self.resolveInst(ty_op.operand);
8610 const operand_ty = self.typeOf(ty_op.operand);8656 const operand_ty = self.typeOf(ty_op.operand);
...@@ -8638,7 +8684,7 @@ pub const FuncGen = struct {...@@ -8638,7 +8684,7 @@ pub const FuncGen = struct {
86388684
8639 fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8685 fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8640 const o = self.dg.object;8686 const o = self.dg.object;
8641 const mod = o.module;8687 const mod = o.pt.zcu;
8642 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;8688 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
8643 const operand = try self.resolveInst(ty_op.operand);8689 const operand = try self.resolveInst(ty_op.operand);
8644 const operand_ty = self.typeOf(ty_op.operand);8690 const operand_ty = self.typeOf(ty_op.operand);
...@@ -8696,9 +8742,10 @@ pub const FuncGen = struct {...@@ -8696,9 +8742,10 @@ pub const FuncGen = struct {
86968742
8697 fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Type) !Builder.Value {8743 fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Type) !Builder.Value {
8698 const o = self.dg.object;8744 const o = self.dg.object;
8699 const mod = o.module;8745 const pt = o.pt;
8700 const operand_is_ref = isByRef(operand_ty, mod);8746 const mod = pt.zcu;
8701 const result_is_ref = isByRef(inst_ty, mod);8747 const operand_is_ref = isByRef(operand_ty, pt);
8748 const result_is_ref = isByRef(inst_ty, pt);
8702 const llvm_dest_ty = try o.lowerType(inst_ty);8749 const llvm_dest_ty = try o.lowerType(inst_ty);
87038750
8704 if (operand_is_ref and result_is_ref) {8751 if (operand_is_ref and result_is_ref) {
...@@ -8721,9 +8768,9 @@ pub const FuncGen = struct {...@@ -8721,9 +8768,9 @@ pub const FuncGen = struct {
8721 if (!result_is_ref) {8768 if (!result_is_ref) {
8722 return self.dg.todo("implement bitcast vector to non-ref array", .{});8769 return self.dg.todo("implement bitcast vector to non-ref array", .{});
8723 }8770 }
8724 const alignment = inst_ty.abiAlignment(mod).toLlvm();8771 const alignment = inst_ty.abiAlignment(pt).toLlvm();
8725 const array_ptr = try self.buildAllocaWorkaround(inst_ty, alignment);8772 const array_ptr = try self.buildAllocaWorkaround(inst_ty, alignment);
8726 const bitcast_ok = elem_ty.bitSize(mod) == elem_ty.abiSize(mod) * 8;8773 const bitcast_ok = elem_ty.bitSize(pt) == elem_ty.abiSize(pt) * 8;
8727 if (bitcast_ok) {8774 if (bitcast_ok) {
8728 _ = try self.wip.store(.normal, operand, array_ptr, alignment);8775 _ = try self.wip.store(.normal, operand, array_ptr, alignment);
8729 } else {8776 } else {
...@@ -8748,11 +8795,11 @@ pub const FuncGen = struct {...@@ -8748,11 +8795,11 @@ pub const FuncGen = struct {
8748 const llvm_vector_ty = try o.lowerType(inst_ty);8795 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", .{});8796 if (!operand_is_ref) return self.dg.todo("implement bitcast non-ref array to vector", .{});
87508797
8751 const bitcast_ok = elem_ty.bitSize(mod) == elem_ty.abiSize(mod) * 8;8798 const bitcast_ok = elem_ty.bitSize(pt) == elem_ty.abiSize(pt) * 8;
8752 if (bitcast_ok) {8799 if (bitcast_ok) {
8753 // The array is aligned to the element's alignment, while the vector might have a completely8800 // 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.8801 // different alignment. This means we need to enforce the alignment of this load.
8755 const alignment = elem_ty.abiAlignment(mod).toLlvm();8802 const alignment = elem_ty.abiAlignment(pt).toLlvm();
8756 return self.wip.load(.normal, llvm_vector_ty, operand, alignment, "");8803 return self.wip.load(.normal, llvm_vector_ty, operand, alignment, "");
8757 } else {8804 } else {
8758 // If the ABI size of the element type is not evenly divisible by size in bits;8805 // If the ABI size of the element type is not evenly divisible by size in bits;
...@@ -8777,24 +8824,25 @@ pub const FuncGen = struct {...@@ -8777,24 +8824,25 @@ pub const FuncGen = struct {
8777 }8824 }
87788825
8779 if (operand_is_ref) {8826 if (operand_is_ref) {
8780 const alignment = operand_ty.abiAlignment(mod).toLlvm();8827 const alignment = operand_ty.abiAlignment(pt).toLlvm();
8781 return self.wip.load(.normal, llvm_dest_ty, operand, alignment, "");8828 return self.wip.load(.normal, llvm_dest_ty, operand, alignment, "");
8782 }8829 }
87838830
8784 if (result_is_ref) {8831 if (result_is_ref) {
8785 const alignment = operand_ty.abiAlignment(mod).max(inst_ty.abiAlignment(mod)).toLlvm();8832 const alignment = operand_ty.abiAlignment(pt).max(inst_ty.abiAlignment(pt)).toLlvm();
8786 const result_ptr = try self.buildAllocaWorkaround(inst_ty, alignment);8833 const result_ptr = try self.buildAllocaWorkaround(inst_ty, alignment);
8787 _ = try self.wip.store(.normal, operand, result_ptr, alignment);8834 _ = try self.wip.store(.normal, operand, result_ptr, alignment);
8788 return result_ptr;8835 return result_ptr;
8789 }8836 }
87908837
8791 if (llvm_dest_ty.isStruct(&o.builder) or8838 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)))8839 ((operand_ty.zigTypeTag(mod) == .Vector or inst_ty.zigTypeTag(mod) == .Vector) and
8840 operand_ty.bitSize(pt) != inst_ty.bitSize(pt)))
8793 {8841 {
8794 // Both our operand and our result are values, not pointers,8842 // 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.8843 // 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.8844 // Therefore, we store operand to alloca, then load for result.
8797 const alignment = operand_ty.abiAlignment(mod).max(inst_ty.abiAlignment(mod)).toLlvm();8845 const alignment = operand_ty.abiAlignment(pt).max(inst_ty.abiAlignment(pt)).toLlvm();
8798 const result_ptr = try self.buildAllocaWorkaround(inst_ty, alignment);8846 const result_ptr = try self.buildAllocaWorkaround(inst_ty, alignment);
8799 _ = try self.wip.store(.normal, operand, result_ptr, alignment);8847 _ = try self.wip.store(.normal, operand, result_ptr, alignment);
8800 return self.wip.load(.normal, llvm_dest_ty, result_ptr, alignment, "");8848 return self.wip.load(.normal, llvm_dest_ty, result_ptr, alignment, "");
...@@ -8811,7 +8859,8 @@ pub const FuncGen = struct {...@@ -8811,7 +8859,8 @@ pub const FuncGen = struct {
88118859
8812 fn airArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8860 fn airArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8813 const o = self.dg.object;8861 const o = self.dg.object;
8814 const mod = o.module;8862 const pt = o.pt;
8863 const mod = pt.zcu;
8815 const arg_val = self.args[self.arg_index];8864 const arg_val = self.args[self.arg_index];
8816 self.arg_index += 1;8865 self.arg_index += 1;
88178866
...@@ -8847,7 +8896,7 @@ pub const FuncGen = struct {...@@ -8847,7 +8896,7 @@ pub const FuncGen = struct {
8847 };8896 };
88488897
8849 const owner_mod = self.dg.ownerModule();8898 const owner_mod = self.dg.ownerModule();
8850 if (isByRef(inst_ty, mod)) {8899 if (isByRef(inst_ty, pt)) {
8851 _ = try self.wip.callIntrinsic(8900 _ = try self.wip.callIntrinsic(
8852 .normal,8901 .normal,
8853 .none,8902 .none,
...@@ -8861,7 +8910,7 @@ pub const FuncGen = struct {...@@ -8861,7 +8910,7 @@ pub const FuncGen = struct {
8861 "",8910 "",
8862 );8911 );
8863 } else if (owner_mod.optimize_mode == .Debug) {8912 } else if (owner_mod.optimize_mode == .Debug) {
8864 const alignment = inst_ty.abiAlignment(mod).toLlvm();8913 const alignment = inst_ty.abiAlignment(pt).toLlvm();
8865 const alloca = try self.buildAlloca(arg_val.typeOfWip(&self.wip), alignment);8914 const alloca = try self.buildAlloca(arg_val.typeOfWip(&self.wip), alignment);
8866 _ = try self.wip.store(.normal, arg_val, alloca, alignment);8915 _ = try self.wip.store(.normal, arg_val, alloca, alignment);
8867 _ = try self.wip.callIntrinsic(8916 _ = try self.wip.callIntrinsic(
...@@ -8897,27 +8946,29 @@ pub const FuncGen = struct {...@@ -8897,27 +8946,29 @@ pub const FuncGen = struct {
88978946
8898 fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8947 fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8899 const o = self.dg.object;8948 const o = self.dg.object;
8900 const mod = o.module;8949 const pt = o.pt;
8950 const mod = pt.zcu;
8901 const ptr_ty = self.typeOfIndex(inst);8951 const ptr_ty = self.typeOfIndex(inst);
8902 const pointee_type = ptr_ty.childType(mod);8952 const pointee_type = ptr_ty.childType(mod);
8903 if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(mod))8953 if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(pt))
8904 return (try o.lowerPtrToVoid(ptr_ty)).toValue();8954 return (try o.lowerPtrToVoid(ptr_ty)).toValue();
89058955
8906 //const pointee_llvm_ty = try o.lowerType(pointee_type);8956 //const pointee_llvm_ty = try o.lowerType(pointee_type);
8907 const alignment = ptr_ty.ptrAlignment(mod).toLlvm();8957 const alignment = ptr_ty.ptrAlignment(pt).toLlvm();
8908 return self.buildAllocaWorkaround(pointee_type, alignment);8958 return self.buildAllocaWorkaround(pointee_type, alignment);
8909 }8959 }
89108960
8911 fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8961 fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8912 const o = self.dg.object;8962 const o = self.dg.object;
8913 const mod = o.module;8963 const pt = o.pt;
8964 const mod = pt.zcu;
8914 const ptr_ty = self.typeOfIndex(inst);8965 const ptr_ty = self.typeOfIndex(inst);
8915 const ret_ty = ptr_ty.childType(mod);8966 const ret_ty = ptr_ty.childType(mod);
8916 if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod))8967 if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt))
8917 return (try o.lowerPtrToVoid(ptr_ty)).toValue();8968 return (try o.lowerPtrToVoid(ptr_ty)).toValue();
8918 if (self.ret_ptr != .none) return self.ret_ptr;8969 if (self.ret_ptr != .none) return self.ret_ptr;
8919 //const ret_llvm_ty = try o.lowerType(ret_ty);8970 //const ret_llvm_ty = try o.lowerType(ret_ty);
8920 const alignment = ptr_ty.ptrAlignment(mod).toLlvm();8971 const alignment = ptr_ty.ptrAlignment(pt).toLlvm();
8921 return self.buildAllocaWorkaround(ret_ty, alignment);8972 return self.buildAllocaWorkaround(ret_ty, alignment);
8922 }8973 }
89238974
...@@ -8928,7 +8979,7 @@ pub const FuncGen = struct {...@@ -8928,7 +8979,7 @@ pub const FuncGen = struct {
8928 llvm_ty: Builder.Type,8979 llvm_ty: Builder.Type,
8929 alignment: Builder.Alignment,8980 alignment: Builder.Alignment,
8930 ) Allocator.Error!Builder.Value {8981 ) Allocator.Error!Builder.Value {
8931 const target = self.dg.object.module.getTarget();8982 const target = self.dg.object.pt.zcu.getTarget();
8932 return buildAllocaInner(&self.wip, llvm_ty, alignment, target);8983 return buildAllocaInner(&self.wip, llvm_ty, alignment, target);
8933 }8984 }
89348985
...@@ -8939,18 +8990,19 @@ pub const FuncGen = struct {...@@ -8939,18 +8990,19 @@ pub const FuncGen = struct {
8939 alignment: Builder.Alignment,8990 alignment: Builder.Alignment,
8940 ) Allocator.Error!Builder.Value {8991 ) Allocator.Error!Builder.Value {
8941 const o = self.dg.object;8992 const o = self.dg.object;
8942 return self.buildAlloca(try o.builder.arrayType(ty.abiSize(o.module), .i8), alignment);8993 return self.buildAlloca(try o.builder.arrayType(ty.abiSize(o.pt), .i8), alignment);
8943 }8994 }
89448995
8945 fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {8996 fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {
8946 const o = self.dg.object;8997 const o = self.dg.object;
8947 const mod = o.module;8998 const pt = o.pt;
8999 const mod = pt.zcu;
8948 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;9000 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
8949 const dest_ptr = try self.resolveInst(bin_op.lhs);9001 const dest_ptr = try self.resolveInst(bin_op.lhs);
8950 const ptr_ty = self.typeOf(bin_op.lhs);9002 const ptr_ty = self.typeOf(bin_op.lhs);
8951 const operand_ty = ptr_ty.childType(mod);9003 const operand_ty = ptr_ty.childType(mod);
89529004
8953 const val_is_undef = if (try self.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep(mod) else false;9005 const val_is_undef = if (try self.air.value(bin_op.rhs, pt)) |val| val.isUndefDeep(mod) else false;
8954 if (val_is_undef) {9006 if (val_is_undef) {
8955 const ptr_info = ptr_ty.ptrInfo(mod);9007 const ptr_info = ptr_ty.ptrInfo(mod);
8956 const needs_bitmask = (ptr_info.packed_offset.host_size != 0);9008 const needs_bitmask = (ptr_info.packed_offset.host_size != 0);
...@@ -8964,10 +9016,10 @@ pub const FuncGen = struct {...@@ -8964,10 +9016,10 @@ pub const FuncGen = struct {
8964 // Even if safety is disabled, we still emit a memset to undefined since it conveys9016 // 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 using9017 // extra information to LLVM. However, safety makes the difference between using
8966 // 0xaa or actual undefined for the fill byte.9018 // 0xaa or actual undefined for the fill byte.
8967 const len = try o.builder.intValue(try o.lowerType(Type.usize), operand_ty.abiSize(mod));9019 const len = try o.builder.intValue(try o.lowerType(Type.usize), operand_ty.abiSize(pt));
8968 _ = try self.wip.callMemSet(9020 _ = try self.wip.callMemSet(
8969 dest_ptr,9021 dest_ptr,
8970 ptr_ty.ptrAlignment(mod).toLlvm(),9022 ptr_ty.ptrAlignment(pt).toLlvm(),
8971 if (safety) try o.builder.intValue(.i8, 0xaa) else try o.builder.undefValue(.i8),9023 if (safety) try o.builder.intValue(.i8, 0xaa) else try o.builder.undefValue(.i8),
8972 len,9024 len,
8973 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal,9025 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal,
...@@ -8992,7 +9044,7 @@ pub const FuncGen = struct {...@@ -8992,7 +9044,7 @@ pub const FuncGen = struct {
8992 /// The first instruction of `body_tail` is the one whose copy we want to elide.9044 /// 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 {9045 fn canElideLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) bool {
8994 const o = fg.dg.object;9046 const o = fg.dg.object;
8995 const mod = o.module;9047 const mod = o.pt.zcu;
8996 const ip = &mod.intern_pool;9048 const ip = &mod.intern_pool;
8997 for (body_tail[1..]) |body_inst| {9049 for (body_tail[1..]) |body_inst| {
8998 switch (fg.liveness.categorizeOperand(fg.air, body_inst, body_tail[0], ip)) {9050 switch (fg.liveness.categorizeOperand(fg.air, body_inst, body_tail[0], ip)) {
...@@ -9008,7 +9060,8 @@ pub const FuncGen = struct {...@@ -9008,7 +9060,8 @@ pub const FuncGen = struct {
90089060
9009 fn airLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {9061 fn airLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
9010 const o = fg.dg.object;9062 const o = fg.dg.object;
9011 const mod = o.module;9063 const pt = o.pt;
9064 const mod = pt.zcu;
9012 const inst = body_tail[0];9065 const inst = body_tail[0];
9013 const ty_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;9066 const ty_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
9014 const ptr_ty = fg.typeOf(ty_op.operand);9067 const ptr_ty = fg.typeOf(ty_op.operand);
...@@ -9016,7 +9069,7 @@ pub const FuncGen = struct {...@@ -9016,7 +9069,7 @@ pub const FuncGen = struct {
9016 const ptr = try fg.resolveInst(ty_op.operand);9069 const ptr = try fg.resolveInst(ty_op.operand);
90179070
9018 elide: {9071 elide: {
9019 if (!isByRef(Type.fromInterned(ptr_info.child), mod)) break :elide;9072 if (!isByRef(Type.fromInterned(ptr_info.child), pt)) break :elide;
9020 if (!canElideLoad(fg, body_tail)) break :elide;9073 if (!canElideLoad(fg, body_tail)) break :elide;
9021 return ptr;9074 return ptr;
9022 }9075 }
...@@ -9040,7 +9093,7 @@ pub const FuncGen = struct {...@@ -9040,7 +9093,7 @@ pub const FuncGen = struct {
9040 _ = inst;9093 _ = inst;
9041 const o = self.dg.object;9094 const o = self.dg.object;
9042 const llvm_usize = try o.lowerType(Type.usize);9095 const llvm_usize = try o.lowerType(Type.usize);
9043 if (!target_util.supportsReturnAddress(o.module.getTarget())) {9096 if (!target_util.supportsReturnAddress(o.pt.zcu.getTarget())) {
9044 // https://github.com/ziglang/zig/issues/119469097 // https://github.com/ziglang/zig/issues/11946
9045 return o.builder.intValue(llvm_usize, 0);9098 return o.builder.intValue(llvm_usize, 0);
9046 }9099 }
...@@ -9068,7 +9121,8 @@ pub const FuncGen = struct {...@@ -9068,7 +9121,8 @@ pub const FuncGen = struct {
9068 kind: Builder.Function.Instruction.CmpXchg.Kind,9121 kind: Builder.Function.Instruction.CmpXchg.Kind,
9069 ) !Builder.Value {9122 ) !Builder.Value {
9070 const o = self.dg.object;9123 const o = self.dg.object;
9071 const mod = o.module;9124 const pt = o.pt;
9125 const mod = pt.zcu;
9072 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;9126 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
9073 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;9127 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
9074 const ptr = try self.resolveInst(extra.ptr);9128 const ptr = try self.resolveInst(extra.ptr);
...@@ -9095,7 +9149,7 @@ pub const FuncGen = struct {...@@ -9095,7 +9149,7 @@ pub const FuncGen = struct {
9095 self.sync_scope,9149 self.sync_scope,
9096 toLlvmAtomicOrdering(extra.successOrder()),9150 toLlvmAtomicOrdering(extra.successOrder()),
9097 toLlvmAtomicOrdering(extra.failureOrder()),9151 toLlvmAtomicOrdering(extra.failureOrder()),
9098 ptr_ty.ptrAlignment(mod).toLlvm(),9152 ptr_ty.ptrAlignment(pt).toLlvm(),
9099 "",9153 "",
9100 );9154 );
91019155
...@@ -9118,7 +9172,8 @@ pub const FuncGen = struct {...@@ -9118,7 +9172,8 @@ pub const FuncGen = struct {
91189172
9119 fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9173 fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9120 const o = self.dg.object;9174 const o = self.dg.object;
9121 const mod = o.module;9175 const pt = o.pt;
9176 const mod = pt.zcu;
9122 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;9177 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
9123 const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data;9178 const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data;
9124 const ptr = try self.resolveInst(pl_op.operand);9179 const ptr = try self.resolveInst(pl_op.operand);
...@@ -9134,7 +9189,7 @@ pub const FuncGen = struct {...@@ -9134,7 +9189,7 @@ pub const FuncGen = struct {
91349189
9135 const access_kind: Builder.MemoryAccessKind =9190 const access_kind: Builder.MemoryAccessKind =
9136 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal;9191 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal;
9137 const ptr_alignment = ptr_ty.ptrAlignment(mod).toLlvm();9192 const ptr_alignment = ptr_ty.ptrAlignment(pt).toLlvm();
91389193
9139 if (llvm_abi_ty != .none) {9194 if (llvm_abi_ty != .none) {
9140 // operand needs widening and truncating or bitcasting.9195 // operand needs widening and truncating or bitcasting.
...@@ -9181,19 +9236,20 @@ pub const FuncGen = struct {...@@ -9181,19 +9236,20 @@ pub const FuncGen = struct {
91819236
9182 fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9237 fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9183 const o = self.dg.object;9238 const o = self.dg.object;
9184 const mod = o.module;9239 const pt = o.pt;
9240 const mod = pt.zcu;
9185 const atomic_load = self.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;9241 const atomic_load = self.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;
9186 const ptr = try self.resolveInst(atomic_load.ptr);9242 const ptr = try self.resolveInst(atomic_load.ptr);
9187 const ptr_ty = self.typeOf(atomic_load.ptr);9243 const ptr_ty = self.typeOf(atomic_load.ptr);
9188 const info = ptr_ty.ptrInfo(mod);9244 const info = ptr_ty.ptrInfo(mod);
9189 const elem_ty = Type.fromInterned(info.child);9245 const elem_ty = Type.fromInterned(info.child);
9190 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;9246 if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) return .none;
9191 const ordering = toLlvmAtomicOrdering(atomic_load.order);9247 const ordering = toLlvmAtomicOrdering(atomic_load.order);
9192 const llvm_abi_ty = try o.getAtomicAbiType(elem_ty, false);9248 const llvm_abi_ty = try o.getAtomicAbiType(elem_ty, false);
9193 const ptr_alignment = (if (info.flags.alignment != .none)9249 const ptr_alignment = (if (info.flags.alignment != .none)
9194 @as(InternPool.Alignment, info.flags.alignment)9250 @as(InternPool.Alignment, info.flags.alignment)
9195 else9251 else
9196 Type.fromInterned(info.child).abiAlignment(mod)).toLlvm();9252 Type.fromInterned(info.child).abiAlignment(pt)).toLlvm();
9197 const access_kind: Builder.MemoryAccessKind =9253 const access_kind: Builder.MemoryAccessKind =
9198 if (info.flags.is_volatile) .@"volatile" else .normal;9254 if (info.flags.is_volatile) .@"volatile" else .normal;
9199 const elem_llvm_ty = try o.lowerType(elem_ty);9255 const elem_llvm_ty = try o.lowerType(elem_ty);
...@@ -9228,11 +9284,12 @@ pub const FuncGen = struct {...@@ -9228,11 +9284,12 @@ pub const FuncGen = struct {
9228 ordering: Builder.AtomicOrdering,9284 ordering: Builder.AtomicOrdering,
9229 ) !Builder.Value {9285 ) !Builder.Value {
9230 const o = self.dg.object;9286 const o = self.dg.object;
9231 const mod = o.module;9287 const pt = o.pt;
9288 const mod = pt.zcu;
9232 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;9289 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
9233 const ptr_ty = self.typeOf(bin_op.lhs);9290 const ptr_ty = self.typeOf(bin_op.lhs);
9234 const operand_ty = ptr_ty.childType(mod);9291 const operand_ty = ptr_ty.childType(mod);
9235 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return .none;9292 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) return .none;
9236 const ptr = try self.resolveInst(bin_op.lhs);9293 const ptr = try self.resolveInst(bin_op.lhs);
9237 var element = try self.resolveInst(bin_op.rhs);9294 var element = try self.resolveInst(bin_op.rhs);
9238 const llvm_abi_ty = try o.getAtomicAbiType(operand_ty, false);9295 const llvm_abi_ty = try o.getAtomicAbiType(operand_ty, false);
...@@ -9252,12 +9309,13 @@ pub const FuncGen = struct {...@@ -9252,12 +9309,13 @@ pub const FuncGen = struct {
92529309
9253 fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {9310 fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {
9254 const o = self.dg.object;9311 const o = self.dg.object;
9255 const mod = o.module;9312 const pt = o.pt;
9313 const mod = pt.zcu;
9256 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;9314 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
9257 const dest_slice = try self.resolveInst(bin_op.lhs);9315 const dest_slice = try self.resolveInst(bin_op.lhs);
9258 const ptr_ty = self.typeOf(bin_op.lhs);9316 const ptr_ty = self.typeOf(bin_op.lhs);
9259 const elem_ty = self.typeOf(bin_op.rhs);9317 const elem_ty = self.typeOf(bin_op.rhs);
9260 const dest_ptr_align = ptr_ty.ptrAlignment(mod).toLlvm();9318 const dest_ptr_align = ptr_ty.ptrAlignment(pt).toLlvm();
9261 const dest_ptr = try self.sliceOrArrayPtr(dest_slice, ptr_ty);9319 const dest_ptr = try self.sliceOrArrayPtr(dest_slice, ptr_ty);
9262 const access_kind: Builder.MemoryAccessKind =9320 const access_kind: Builder.MemoryAccessKind =
9263 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal;9321 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal;
...@@ -9270,7 +9328,7 @@ pub const FuncGen = struct {...@@ -9270,7 +9328,7 @@ pub const FuncGen = struct {
9270 ptr_ty.isSlice(mod) and9328 ptr_ty.isSlice(mod) and
9271 std.Target.wasm.featureSetHas(o.target.cpu.features, .bulk_memory);9329 std.Target.wasm.featureSetHas(o.target.cpu.features, .bulk_memory);
92729330
9273 if (try self.air.value(bin_op.rhs, mod)) |elem_val| {9331 if (try self.air.value(bin_op.rhs, pt)) |elem_val| {
9274 if (elem_val.isUndefDeep(mod)) {9332 if (elem_val.isUndefDeep(mod)) {
9275 // Even if safety is disabled, we still emit a memset to undefined since it conveys9333 // 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 using9334 // extra information to LLVM. However, safety makes the difference between using
...@@ -9296,7 +9354,7 @@ pub const FuncGen = struct {...@@ -9296,7 +9354,7 @@ pub const FuncGen = struct {
9296 // repeating byte pattern, for example, `@as(u64, 0)` has a9354 // repeating byte pattern, for example, `@as(u64, 0)` has a
9297 // repeating byte pattern of 0 bytes. In such case, the memset9355 // repeating byte pattern of 0 bytes. In such case, the memset
9298 // intrinsic can be used.9356 // intrinsic can be used.
9299 if (try elem_val.hasRepeatedByteRepr(elem_ty, mod)) |byte_val| {9357 if (try elem_val.hasRepeatedByteRepr(elem_ty, pt)) |byte_val| {
9300 const fill_byte = try o.builder.intValue(.i8, byte_val);9358 const fill_byte = try o.builder.intValue(.i8, byte_val);
9301 const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);9359 const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
9302 if (intrinsic_len0_traps) {9360 if (intrinsic_len0_traps) {
...@@ -9309,7 +9367,7 @@ pub const FuncGen = struct {...@@ -9309,7 +9367,7 @@ pub const FuncGen = struct {
9309 }9367 }
93109368
9311 const value = try self.resolveInst(bin_op.rhs);9369 const value = try self.resolveInst(bin_op.rhs);
9312 const elem_abi_size = elem_ty.abiSize(mod);9370 const elem_abi_size = elem_ty.abiSize(pt);
93139371
9314 if (elem_abi_size == 1) {9372 if (elem_abi_size == 1) {
9315 // In this case we can take advantage of LLVM's intrinsic.9373 // In this case we can take advantage of LLVM's intrinsic.
...@@ -9361,9 +9419,9 @@ pub const FuncGen = struct {...@@ -9361,9 +9419,9 @@ pub const FuncGen = struct {
9361 _ = try self.wip.brCond(end, body_block, end_block);9419 _ = try self.wip.brCond(end, body_block, end_block);
93629420
9363 self.wip.cursor = .{ .block = body_block };9421 self.wip.cursor = .{ .block = body_block };
9364 const elem_abi_align = elem_ty.abiAlignment(mod);9422 const elem_abi_align = elem_ty.abiAlignment(pt);
9365 const it_ptr_align = InternPool.Alignment.fromLlvm(dest_ptr_align).min(elem_abi_align).toLlvm();9423 const it_ptr_align = InternPool.Alignment.fromLlvm(dest_ptr_align).min(elem_abi_align).toLlvm();
9366 if (isByRef(elem_ty, mod)) {9424 if (isByRef(elem_ty, pt)) {
9367 _ = try self.wip.callMemCpy(9425 _ = try self.wip.callMemCpy(
9368 it_ptr.toValue(),9426 it_ptr.toValue(),
9369 it_ptr_align,9427 it_ptr_align,
...@@ -9405,7 +9463,8 @@ pub const FuncGen = struct {...@@ -9405,7 +9463,8 @@ pub const FuncGen = struct {
94059463
9406 fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9464 fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9407 const o = self.dg.object;9465 const o = self.dg.object;
9408 const mod = o.module;9466 const pt = o.pt;
9467 const mod = pt.zcu;
9409 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;9468 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
9410 const dest_slice = try self.resolveInst(bin_op.lhs);9469 const dest_slice = try self.resolveInst(bin_op.lhs);
9411 const dest_ptr_ty = self.typeOf(bin_op.lhs);9470 const dest_ptr_ty = self.typeOf(bin_op.lhs);
...@@ -9434,9 +9493,9 @@ pub const FuncGen = struct {...@@ -9434,9 +9493,9 @@ pub const FuncGen = struct {
9434 self.wip.cursor = .{ .block = memcpy_block };9493 self.wip.cursor = .{ .block = memcpy_block };
9435 _ = try self.wip.callMemCpy(9494 _ = try self.wip.callMemCpy(
9436 dest_ptr,9495 dest_ptr,
9437 dest_ptr_ty.ptrAlignment(mod).toLlvm(),9496 dest_ptr_ty.ptrAlignment(pt).toLlvm(),
9438 src_ptr,9497 src_ptr,
9439 src_ptr_ty.ptrAlignment(mod).toLlvm(),9498 src_ptr_ty.ptrAlignment(pt).toLlvm(),
9440 len,9499 len,
9441 access_kind,9500 access_kind,
9442 );9501 );
...@@ -9447,9 +9506,9 @@ pub const FuncGen = struct {...@@ -9447,9 +9506,9 @@ pub const FuncGen = struct {
94479506
9448 _ = try self.wip.callMemCpy(9507 _ = try self.wip.callMemCpy(
9449 dest_ptr,9508 dest_ptr,
9450 dest_ptr_ty.ptrAlignment(mod).toLlvm(),9509 dest_ptr_ty.ptrAlignment(pt).toLlvm(),
9451 src_ptr,9510 src_ptr,
9452 src_ptr_ty.ptrAlignment(mod).toLlvm(),9511 src_ptr_ty.ptrAlignment(pt).toLlvm(),
9453 len,9512 len,
9454 access_kind,9513 access_kind,
9455 );9514 );
...@@ -9458,10 +9517,11 @@ pub const FuncGen = struct {...@@ -9458,10 +9517,11 @@ pub const FuncGen = struct {
94589517
9459 fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9518 fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9460 const o = self.dg.object;9519 const o = self.dg.object;
9461 const mod = o.module;9520 const pt = o.pt;
9521 const mod = pt.zcu;
9462 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;9522 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
9463 const un_ty = self.typeOf(bin_op.lhs).childType(mod);9523 const un_ty = self.typeOf(bin_op.lhs).childType(mod);
9464 const layout = un_ty.unionGetLayout(mod);9524 const layout = un_ty.unionGetLayout(pt);
9465 if (layout.tag_size == 0) return .none;9525 if (layout.tag_size == 0) return .none;
9466 const union_ptr = try self.resolveInst(bin_op.lhs);9526 const union_ptr = try self.resolveInst(bin_op.lhs);
9467 const new_tag = try self.resolveInst(bin_op.rhs);9527 const new_tag = try self.resolveInst(bin_op.rhs);
...@@ -9479,13 +9539,13 @@ pub const FuncGen = struct {...@@ -9479,13 +9539,13 @@ pub const FuncGen = struct {
94799539
9480 fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9540 fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9481 const o = self.dg.object;9541 const o = self.dg.object;
9482 const mod = o.module;9542 const pt = o.pt;
9483 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;9543 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
9484 const un_ty = self.typeOf(ty_op.operand);9544 const un_ty = self.typeOf(ty_op.operand);
9485 const layout = un_ty.unionGetLayout(mod);9545 const layout = un_ty.unionGetLayout(pt);
9486 if (layout.tag_size == 0) return .none;9546 if (layout.tag_size == 0) return .none;
9487 const union_handle = try self.resolveInst(ty_op.operand);9547 const union_handle = try self.resolveInst(ty_op.operand);
9488 if (isByRef(un_ty, mod)) {9548 if (isByRef(un_ty, pt)) {
9489 const llvm_un_ty = try o.lowerType(un_ty);9549 const llvm_un_ty = try o.lowerType(un_ty);
9490 if (layout.payload_size == 0)9550 if (layout.payload_size == 0)
9491 return self.wip.load(.normal, llvm_un_ty, union_handle, .default, "");9551 return self.wip.load(.normal, llvm_un_ty, union_handle, .default, "");
...@@ -9554,7 +9614,7 @@ pub const FuncGen = struct {...@@ -9554,7 +9614,7 @@ pub const FuncGen = struct {
95549614
9555 fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9615 fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9556 const o = self.dg.object;9616 const o = self.dg.object;
9557 const mod = o.module;9617 const mod = o.pt.zcu;
9558 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;9618 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
9559 const operand_ty = self.typeOf(ty_op.operand);9619 const operand_ty = self.typeOf(ty_op.operand);
9560 var bits = operand_ty.intInfo(mod).bits;9620 var bits = operand_ty.intInfo(mod).bits;
...@@ -9588,7 +9648,7 @@ pub const FuncGen = struct {...@@ -9588,7 +9648,7 @@ pub const FuncGen = struct {
95889648
9589 fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9649 fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9590 const o = self.dg.object;9650 const o = self.dg.object;
9591 const mod = o.module;9651 const mod = o.pt.zcu;
9592 const ip = &mod.intern_pool;9652 const ip = &mod.intern_pool;
9593 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;9653 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
9594 const operand = try self.resolveInst(ty_op.operand);9654 const operand = try self.resolveInst(ty_op.operand);
...@@ -9638,7 +9698,8 @@ pub const FuncGen = struct {...@@ -9638,7 +9698,8 @@ pub const FuncGen = struct {
96389698
9639 fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !Builder.Function.Index {9699 fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !Builder.Function.Index {
9640 const o = self.dg.object;9700 const o = self.dg.object;
9641 const zcu = o.module;9701 const pt = o.pt;
9702 const zcu = pt.zcu;
9642 const enum_type = zcu.intern_pool.loadEnumType(enum_ty.toIntern());9703 const enum_type = zcu.intern_pool.loadEnumType(enum_ty.toIntern());
96439704
9644 // TODO: detect when the type changes and re-emit this function.9705 // TODO: detect when the type changes and re-emit this function.
...@@ -9678,7 +9739,7 @@ pub const FuncGen = struct {...@@ -9678,7 +9739,7 @@ pub const FuncGen = struct {
96789739
9679 for (0..enum_type.names.len) |field_index| {9740 for (0..enum_type.names.len) |field_index| {
9680 const this_tag_int_value = try o.lowerValue(9741 const this_tag_int_value = try o.lowerValue(
9681 (try zcu.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(),9742 (try pt.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(),
9682 );9743 );
9683 try wip_switch.addCase(this_tag_int_value, named_block, &wip);9744 try wip_switch.addCase(this_tag_int_value, named_block, &wip);
9684 }9745 }
...@@ -9745,7 +9806,8 @@ pub const FuncGen = struct {...@@ -9745,7 +9806,8 @@ pub const FuncGen = struct {
97459806
9746 fn airShuffle(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9807 fn airShuffle(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9747 const o = self.dg.object;9808 const o = self.dg.object;
9748 const mod = o.module;9809 const pt = o.pt;
9810 const mod = pt.zcu;
9749 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;9811 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
9750 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;9812 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;
9751 const a = try self.resolveInst(extra.a);9813 const a = try self.resolveInst(extra.a);
...@@ -9763,11 +9825,11 @@ pub const FuncGen = struct {...@@ -9763,11 +9825,11 @@ pub const FuncGen = struct {
9763 defer self.gpa.free(values);9825 defer self.gpa.free(values);
97649826
9765 for (values, 0..) |*val, i| {9827 for (values, 0..) |*val, i| {
9766 const elem = try mask.elemValue(mod, i);9828 const elem = try mask.elemValue(pt, i);
9767 if (elem.isUndef(mod)) {9829 if (elem.isUndef(mod)) {
9768 val.* = try o.builder.undefConst(.i32);9830 val.* = try o.builder.undefConst(.i32);
9769 } else {9831 } else {
9770 const int = elem.toSignedInt(mod);9832 const int = elem.toSignedInt(pt);
9771 const unsigned: u32 = @intCast(if (int >= 0) int else ~int + a_len);9833 const unsigned: u32 = @intCast(if (int >= 0) int else ~int + a_len);
9772 val.* = try o.builder.intConst(.i32, unsigned);9834 val.* = try o.builder.intConst(.i32, unsigned);
9773 }9835 }
...@@ -9854,7 +9916,7 @@ pub const FuncGen = struct {...@@ -9854,7 +9916,7 @@ pub const FuncGen = struct {
98549916
9855 fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {9917 fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
9856 const o = self.dg.object;9918 const o = self.dg.object;
9857 const mod = o.module;9919 const mod = o.pt.zcu;
9858 const target = mod.getTarget();9920 const target = mod.getTarget();
98599921
9860 const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce;9922 const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
...@@ -9964,7 +10026,8 @@ pub const FuncGen = struct {...@@ -9964,7 +10026,8 @@ pub const FuncGen = struct {
996410026
9965 fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {10027 fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9966 const o = self.dg.object;10028 const o = self.dg.object;
9967 const mod = o.module;10029 const pt = o.pt;
10030 const mod = pt.zcu;
9968 const ip = &mod.intern_pool;10031 const ip = &mod.intern_pool;
9969 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;10032 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
9970 const result_ty = self.typeOfIndex(inst);10033 const result_ty = self.typeOfIndex(inst);
...@@ -9986,16 +10049,16 @@ pub const FuncGen = struct {...@@ -9986,16 +10049,16 @@ pub const FuncGen = struct {
9986 if (mod.typeToPackedStruct(result_ty)) |struct_type| {10049 if (mod.typeToPackedStruct(result_ty)) |struct_type| {
9987 const backing_int_ty = struct_type.backingIntType(ip).*;10050 const backing_int_ty = struct_type.backingIntType(ip).*;
9988 assert(backing_int_ty != .none);10051 assert(backing_int_ty != .none);
9989 const big_bits = Type.fromInterned(backing_int_ty).bitSize(mod);10052 const big_bits = Type.fromInterned(backing_int_ty).bitSize(pt);
9990 const int_ty = try o.builder.intType(@intCast(big_bits));10053 const int_ty = try o.builder.intType(@intCast(big_bits));
9991 comptime assert(Type.packed_struct_layout_version == 2);10054 comptime assert(Type.packed_struct_layout_version == 2);
9992 var running_int = try o.builder.intValue(int_ty, 0);10055 var running_int = try o.builder.intValue(int_ty, 0);
9993 var running_bits: u16 = 0;10056 var running_bits: u16 = 0;
9994 for (elements, struct_type.field_types.get(ip)) |elem, field_ty| {10057 for (elements, struct_type.field_types.get(ip)) |elem, field_ty| {
9995 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) continue;10058 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue;
999610059
9997 const non_int_val = try self.resolveInst(elem);10060 const non_int_val = try self.resolveInst(elem);
9998 const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(mod));10061 const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(pt));
9999 const small_int_ty = try o.builder.intType(ty_bit_size);10062 const small_int_ty = try o.builder.intType(ty_bit_size);
10000 const small_int_val = if (Type.fromInterned(field_ty).isPtrAtRuntime(mod))10063 const small_int_val = if (Type.fromInterned(field_ty).isPtrAtRuntime(mod))
10001 try self.wip.cast(.ptrtoint, non_int_val, small_int_ty, "")10064 try self.wip.cast(.ptrtoint, non_int_val, small_int_ty, "")
...@@ -10013,23 +10076,23 @@ pub const FuncGen = struct {...@@ -10013,23 +10076,23 @@ pub const FuncGen = struct {
1001310076
10014 assert(result_ty.containerLayout(mod) != .@"packed");10077 assert(result_ty.containerLayout(mod) != .@"packed");
1001510078
10016 if (isByRef(result_ty, mod)) {10079 if (isByRef(result_ty, pt)) {
10017 // TODO in debug builds init to undef so that the padding will be 0xaa10080 // TODO in debug builds init to undef so that the padding will be 0xaa
10018 // even if we fully populate the fields.10081 // even if we fully populate the fields.
10019 const alignment = result_ty.abiAlignment(mod).toLlvm();10082 const alignment = result_ty.abiAlignment(pt).toLlvm();
10020 const alloca_inst = try self.buildAllocaWorkaround(result_ty, alignment);10083 const alloca_inst = try self.buildAllocaWorkaround(result_ty, alignment);
1002110084
10022 for (elements, 0..) |elem, i| {10085 for (elements, 0..) |elem, i| {
10023 if ((try result_ty.structFieldValueComptime(mod, i)) != null) continue;10086 if ((try result_ty.structFieldValueComptime(pt, i)) != null) continue;
1002410087
10025 const llvm_elem = try self.resolveInst(elem);10088 const llvm_elem = try self.resolveInst(elem);
10026 const llvm_i = o.llvmFieldIndex(result_ty, i).?;10089 const llvm_i = o.llvmFieldIndex(result_ty, i).?;
10027 const field_ptr =10090 const field_ptr =
10028 try self.wip.gepStruct(llvm_result_ty, alloca_inst, llvm_i, "");10091 try self.wip.gepStruct(llvm_result_ty, alloca_inst, llvm_i, "");
10029 const field_ptr_ty = try mod.ptrType(.{10092 const field_ptr_ty = try pt.ptrType(.{
10030 .child = self.typeOf(elem).toIntern(),10093 .child = self.typeOf(elem).toIntern(),
10031 .flags = .{10094 .flags = .{
10032 .alignment = result_ty.structFieldAlign(i, mod),10095 .alignment = result_ty.structFieldAlign(i, pt),
10033 },10096 },
10034 });10097 });
10035 try self.store(field_ptr, field_ptr_ty, llvm_elem, .none);10098 try self.store(field_ptr, field_ptr_ty, llvm_elem, .none);
...@@ -10039,7 +10102,7 @@ pub const FuncGen = struct {...@@ -10039,7 +10102,7 @@ pub const FuncGen = struct {
10039 } else {10102 } else {
10040 var result = try o.builder.poisonValue(llvm_result_ty);10103 var result = try o.builder.poisonValue(llvm_result_ty);
10041 for (elements, 0..) |elem, i| {10104 for (elements, 0..) |elem, i| {
10042 if ((try result_ty.structFieldValueComptime(mod, i)) != null) continue;10105 if ((try result_ty.structFieldValueComptime(pt, i)) != null) continue;
1004310106
10044 const llvm_elem = try self.resolveInst(elem);10107 const llvm_elem = try self.resolveInst(elem);
10045 const llvm_i = o.llvmFieldIndex(result_ty, i).?;10108 const llvm_i = o.llvmFieldIndex(result_ty, i).?;
...@@ -10049,15 +10112,15 @@ pub const FuncGen = struct {...@@ -10049,15 +10112,15 @@ pub const FuncGen = struct {
10049 }10112 }
10050 },10113 },
10051 .Array => {10114 .Array => {
10052 assert(isByRef(result_ty, mod));10115 assert(isByRef(result_ty, pt));
1005310116
10054 const llvm_usize = try o.lowerType(Type.usize);10117 const llvm_usize = try o.lowerType(Type.usize);
10055 const usize_zero = try o.builder.intValue(llvm_usize, 0);10118 const usize_zero = try o.builder.intValue(llvm_usize, 0);
10056 const alignment = result_ty.abiAlignment(mod).toLlvm();10119 const alignment = result_ty.abiAlignment(pt).toLlvm();
10057 const alloca_inst = try self.buildAllocaWorkaround(result_ty, alignment);10120 const alloca_inst = try self.buildAllocaWorkaround(result_ty, alignment);
1005810121
10059 const array_info = result_ty.arrayInfo(mod);10122 const array_info = result_ty.arrayInfo(mod);
10060 const elem_ptr_ty = try mod.ptrType(.{10123 const elem_ptr_ty = try pt.ptrType(.{
10061 .child = array_info.elem_type.toIntern(),10124 .child = array_info.elem_type.toIntern(),
10062 });10125 });
1006310126
...@@ -10084,21 +10147,22 @@ pub const FuncGen = struct {...@@ -10084,21 +10147,22 @@ pub const FuncGen = struct {
1008410147
10085 fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {10148 fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10086 const o = self.dg.object;10149 const o = self.dg.object;
10087 const mod = o.module;10150 const pt = o.pt;
10151 const mod = pt.zcu;
10088 const ip = &mod.intern_pool;10152 const ip = &mod.intern_pool;
10089 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;10153 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
10090 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;10154 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
10091 const union_ty = self.typeOfIndex(inst);10155 const union_ty = self.typeOfIndex(inst);
10092 const union_llvm_ty = try o.lowerType(union_ty);10156 const union_llvm_ty = try o.lowerType(union_ty);
10093 const layout = union_ty.unionGetLayout(mod);10157 const layout = union_ty.unionGetLayout(pt);
10094 const union_obj = mod.typeToUnion(union_ty).?;10158 const union_obj = mod.typeToUnion(union_ty).?;
1009510159
10096 if (union_obj.getLayout(ip) == .@"packed") {10160 if (union_obj.getLayout(ip) == .@"packed") {
10097 const big_bits = union_ty.bitSize(mod);10161 const big_bits = union_ty.bitSize(pt);
10098 const int_llvm_ty = try o.builder.intType(@intCast(big_bits));10162 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]);10163 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);
10100 const non_int_val = try self.resolveInst(extra.init);10164 const non_int_val = try self.resolveInst(extra.init);
10101 const small_int_ty = try o.builder.intType(@intCast(field_ty.bitSize(mod)));10165 const small_int_ty = try o.builder.intType(@intCast(field_ty.bitSize(pt)));
10102 const small_int_val = if (field_ty.isPtrAtRuntime(mod))10166 const small_int_val = if (field_ty.isPtrAtRuntime(mod))
10103 try self.wip.cast(.ptrtoint, non_int_val, small_int_ty, "")10167 try self.wip.cast(.ptrtoint, non_int_val, small_int_ty, "")
10104 else10168 else
...@@ -10110,19 +10174,19 @@ pub const FuncGen = struct {...@@ -10110,19 +10174,19 @@ pub const FuncGen = struct {
10110 const tag_ty = union_ty.unionTagTypeHypothetical(mod);10174 const tag_ty = union_ty.unionTagTypeHypothetical(mod);
10111 const union_field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index];10175 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).?;10176 const enum_field_index = tag_ty.enumFieldIndex(union_field_name, mod).?;
10113 const tag_val = try mod.enumValueFieldIndex(tag_ty, enum_field_index);10177 const tag_val = try pt.enumValueFieldIndex(tag_ty, enum_field_index);
10114 break :blk try tag_val.intFromEnum(tag_ty, mod);10178 break :blk try tag_val.intFromEnum(tag_ty, pt);
10115 };10179 };
10116 if (layout.payload_size == 0) {10180 if (layout.payload_size == 0) {
10117 if (layout.tag_size == 0) {10181 if (layout.tag_size == 0) {
10118 return .none;10182 return .none;
10119 }10183 }
10120 assert(!isByRef(union_ty, mod));10184 assert(!isByRef(union_ty, pt));
10121 var big_int_space: Value.BigIntSpace = undefined;10185 var big_int_space: Value.BigIntSpace = undefined;
10122 const tag_big_int = tag_int_val.toBigInt(&big_int_space, mod);10186 const tag_big_int = tag_int_val.toBigInt(&big_int_space, pt);
10123 return try o.builder.bigIntValue(union_llvm_ty, tag_big_int);10187 return try o.builder.bigIntValue(union_llvm_ty, tag_big_int);
10124 }10188 }
10125 assert(isByRef(union_ty, mod));10189 assert(isByRef(union_ty, pt));
10126 // The llvm type of the alloca will be the named LLVM union type, and will not10190 // 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.10191 // 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 set10192 // We must construct the correct unnamed struct type here, in order to then set
...@@ -10132,14 +10196,14 @@ pub const FuncGen = struct {...@@ -10132,14 +10196,14 @@ pub const FuncGen = struct {
10132 const llvm_payload = try self.resolveInst(extra.init);10196 const llvm_payload = try self.resolveInst(extra.init);
10133 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);10197 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);
10134 const field_llvm_ty = try o.lowerType(field_ty);10198 const field_llvm_ty = try o.lowerType(field_ty);
10135 const field_size = field_ty.abiSize(mod);10199 const field_size = field_ty.abiSize(pt);
10136 const field_align = mod.unionFieldNormalAlignment(union_obj, extra.field_index);10200 const field_align = pt.unionFieldNormalAlignment(union_obj, extra.field_index);
10137 const llvm_usize = try o.lowerType(Type.usize);10201 const llvm_usize = try o.lowerType(Type.usize);
10138 const usize_zero = try o.builder.intValue(llvm_usize, 0);10202 const usize_zero = try o.builder.intValue(llvm_usize, 0);
1013910203
10140 const llvm_union_ty = t: {10204 const llvm_union_ty = t: {
10141 const payload_ty = p: {10205 const payload_ty = p: {
10142 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {10206 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) {
10143 const padding_len = layout.payload_size;10207 const padding_len = layout.payload_size;
10144 break :p try o.builder.arrayType(padding_len, .i8);10208 break :p try o.builder.arrayType(padding_len, .i8);
10145 }10209 }
...@@ -10169,7 +10233,7 @@ pub const FuncGen = struct {...@@ -10169,7 +10233,7 @@ pub const FuncGen = struct {
1016910233
10170 // Now we follow the layout as expressed above with GEP instructions to set the10234 // Now we follow the layout as expressed above with GEP instructions to set the
10171 // tag and the payload.10235 // tag and the payload.
10172 const field_ptr_ty = try mod.ptrType(.{10236 const field_ptr_ty = try pt.ptrType(.{
10173 .child = field_ty.toIntern(),10237 .child = field_ty.toIntern(),
10174 .flags = .{ .alignment = field_align },10238 .flags = .{ .alignment = field_align },
10175 });10239 });
...@@ -10195,9 +10259,9 @@ pub const FuncGen = struct {...@@ -10195,9 +10259,9 @@ pub const FuncGen = struct {
10195 const field_ptr = try self.wip.gep(.inbounds, llvm_union_ty, result_ptr, &indices, "");10259 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));10260 const tag_ty = try o.lowerType(Type.fromInterned(union_obj.enum_tag_ty));
10197 var big_int_space: Value.BigIntSpace = undefined;10261 var big_int_space: Value.BigIntSpace = undefined;
10198 const tag_big_int = tag_int_val.toBigInt(&big_int_space, mod);10262 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);10263 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();10264 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);10265 _ = try self.wip.store(.normal, llvm_tag, field_ptr, tag_alignment);
10202 }10266 }
1020310267
...@@ -10223,7 +10287,7 @@ pub const FuncGen = struct {...@@ -10223,7 +10287,7 @@ pub const FuncGen = struct {
10223 // by the target.10287 // by the target.
10224 // To work around this, don't emit llvm.prefetch in this case.10288 // To work around this, don't emit llvm.prefetch in this case.
10225 // See https://bugs.llvm.org/show_bug.cgi?id=2103710289 // See https://bugs.llvm.org/show_bug.cgi?id=21037
10226 const mod = o.module;10290 const mod = o.pt.zcu;
10227 const target = mod.getTarget();10291 const target = mod.getTarget();
10228 switch (prefetch.cache) {10292 switch (prefetch.cache) {
10229 .instruction => switch (target.cpu.arch) {10293 .instruction => switch (target.cpu.arch) {
...@@ -10279,7 +10343,7 @@ pub const FuncGen = struct {...@@ -10279,7 +10343,7 @@ pub const FuncGen = struct {
1027910343
10280 fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {10344 fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10281 const o = self.dg.object;10345 const o = self.dg.object;
10282 const target = o.module.getTarget();10346 const target = o.pt.zcu.getTarget();
10283 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures10347 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures
1028410348
10285 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;10349 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
...@@ -10289,7 +10353,7 @@ pub const FuncGen = struct {...@@ -10289,7 +10353,7 @@ pub const FuncGen = struct {
1028910353
10290 fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {10354 fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10291 const o = self.dg.object;10355 const o = self.dg.object;
10292 const target = o.module.getTarget();10356 const target = o.pt.zcu.getTarget();
10293 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures10357 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures
1029410358
10295 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;10359 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
...@@ -10312,7 +10376,7 @@ pub const FuncGen = struct {...@@ -10312,7 +10376,7 @@ pub const FuncGen = struct {
1031210376
10313 fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {10377 fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10314 const o = self.dg.object;10378 const o = self.dg.object;
10315 const target = o.module.getTarget();10379 const target = o.pt.zcu.getTarget();
10316 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures10380 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures
1031710381
10318 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;10382 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
...@@ -10322,7 +10386,7 @@ pub const FuncGen = struct {...@@ -10322,7 +10386,7 @@ pub const FuncGen = struct {
1032210386
10323 fn getErrorNameTable(self: *FuncGen) Allocator.Error!Builder.Variable.Index {10387 fn getErrorNameTable(self: *FuncGen) Allocator.Error!Builder.Variable.Index {
10324 const o = self.dg.object;10388 const o = self.dg.object;
10325 const mod = o.module;10389 const pt = o.pt;
1032610390
10327 const table = o.error_name_table;10391 const table = o.error_name_table;
10328 if (table != .none) return table;10392 if (table != .none) return table;
...@@ -10334,7 +10398,7 @@ pub const FuncGen = struct {...@@ -10334,7 +10398,7 @@ pub const FuncGen = struct {
10334 variable_index.setMutability(.constant, &o.builder);10398 variable_index.setMutability(.constant, &o.builder);
10335 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);10399 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
10336 variable_index.setAlignment(10400 variable_index.setAlignment(
10337 Type.slice_const_u8_sentinel_0.abiAlignment(mod).toLlvm(),10401 Type.slice_const_u8_sentinel_0.abiAlignment(pt).toLlvm(),
10338 &o.builder,10402 &o.builder,
10339 );10403 );
1034010404
...@@ -10372,15 +10436,16 @@ pub const FuncGen = struct {...@@ -10372,15 +10436,16 @@ pub const FuncGen = struct {
10372 can_elide_load: bool,10436 can_elide_load: bool,
10373 ) !Builder.Value {10437 ) !Builder.Value {
10374 const o = fg.dg.object;10438 const o = fg.dg.object;
10375 const mod = o.module;10439 const pt = o.pt;
10440 const mod = pt.zcu;
10376 const payload_ty = opt_ty.optionalChild(mod);10441 const payload_ty = opt_ty.optionalChild(mod);
1037710442
10378 if (isByRef(opt_ty, mod)) {10443 if (isByRef(opt_ty, pt)) {
10379 // We have a pointer and we need to return a pointer to the first field.10444 // 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, "");10445 const payload_ptr = try fg.wip.gepStruct(opt_llvm_ty, opt_handle, 0, "");
1038110446
10382 const payload_alignment = payload_ty.abiAlignment(mod).toLlvm();10447 const payload_alignment = payload_ty.abiAlignment(pt).toLlvm();
10383 if (isByRef(payload_ty, mod)) {10448 if (isByRef(payload_ty, pt)) {
10384 if (can_elide_load)10449 if (can_elide_load)
10385 return payload_ptr;10450 return payload_ptr;
1038610451
...@@ -10389,7 +10454,7 @@ pub const FuncGen = struct {...@@ -10389,7 +10454,7 @@ pub const FuncGen = struct {
10389 return fg.loadTruncate(.normal, payload_ty, payload_ptr, payload_alignment);10454 return fg.loadTruncate(.normal, payload_ty, payload_ptr, payload_alignment);
10390 }10455 }
1039110456
10392 assert(!isByRef(payload_ty, mod));10457 assert(!isByRef(payload_ty, pt));
10393 return fg.wip.extractValue(opt_handle, &.{0}, "");10458 return fg.wip.extractValue(opt_handle, &.{0}, "");
10394 }10459 }
1039510460
...@@ -10400,12 +10465,12 @@ pub const FuncGen = struct {...@@ -10400,12 +10465,12 @@ pub const FuncGen = struct {
10400 non_null_bit: Builder.Value,10465 non_null_bit: Builder.Value,
10401 ) !Builder.Value {10466 ) !Builder.Value {
10402 const o = self.dg.object;10467 const o = self.dg.object;
10468 const pt = o.pt;
10403 const optional_llvm_ty = try o.lowerType(optional_ty);10469 const optional_llvm_ty = try o.lowerType(optional_ty);
10404 const non_null_field = try self.wip.cast(.zext, non_null_bit, .i8, "");10470 const non_null_field = try self.wip.cast(.zext, non_null_bit, .i8, "");
10405 const mod = o.module;
1040610471
10407 if (isByRef(optional_ty, mod)) {10472 if (isByRef(optional_ty, pt)) {
10408 const payload_alignment = optional_ty.abiAlignment(mod).toLlvm();10473 const payload_alignment = optional_ty.abiAlignment(pt).toLlvm();
10409 const alloca_inst = try self.buildAllocaWorkaround(optional_ty, payload_alignment);10474 const alloca_inst = try self.buildAllocaWorkaround(optional_ty, payload_alignment);
1041010475
10411 {10476 {
...@@ -10432,7 +10497,8 @@ pub const FuncGen = struct {...@@ -10432,7 +10497,8 @@ pub const FuncGen = struct {
10432 field_index: u32,10497 field_index: u32,
10433 ) !Builder.Value {10498 ) !Builder.Value {
10434 const o = self.dg.object;10499 const o = self.dg.object;
10435 const mod = o.module;10500 const pt = o.pt;
10501 const mod = pt.zcu;
10436 const struct_ty = struct_ptr_ty.childType(mod);10502 const struct_ty = struct_ptr_ty.childType(mod);
10437 switch (struct_ty.zigTypeTag(mod)) {10503 switch (struct_ty.zigTypeTag(mod)) {
10438 .Struct => switch (struct_ty.containerLayout(mod)) {10504 .Struct => switch (struct_ty.containerLayout(mod)) {
...@@ -10452,7 +10518,7 @@ pub const FuncGen = struct {...@@ -10452,7 +10518,7 @@ pub const FuncGen = struct {
1045210518
10453 // We have a pointer to a packed struct field that happens to be byte-aligned.10519 // 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.10520 // 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);10521 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;10522 if (byte_offset == 0) return struct_ptr;
10457 const usize_ty = try o.lowerType(Type.usize);10523 const usize_ty = try o.lowerType(Type.usize);
10458 const llvm_index = try o.builder.intValue(usize_ty, byte_offset);10524 const llvm_index = try o.builder.intValue(usize_ty, byte_offset);
...@@ -10470,14 +10536,14 @@ pub const FuncGen = struct {...@@ -10470,14 +10536,14 @@ pub const FuncGen = struct {
10470 // the struct.10536 // the struct.
10471 const llvm_index = try o.builder.intValue(10537 const llvm_index = try o.builder.intValue(
10472 try o.lowerType(Type.usize),10538 try o.lowerType(Type.usize),
10473 @intFromBool(struct_ty.hasRuntimeBitsIgnoreComptime(mod)),10539 @intFromBool(struct_ty.hasRuntimeBitsIgnoreComptime(pt)),
10474 );10540 );
10475 return self.wip.gep(.inbounds, struct_llvm_ty, struct_ptr, &.{llvm_index}, "");10541 return self.wip.gep(.inbounds, struct_llvm_ty, struct_ptr, &.{llvm_index}, "");
10476 }10542 }
10477 },10543 },
10478 },10544 },
10479 .Union => {10545 .Union => {
10480 const layout = struct_ty.unionGetLayout(mod);10546 const layout = struct_ty.unionGetLayout(pt);
10481 if (layout.payload_size == 0 or struct_ty.containerLayout(mod) == .@"packed") return struct_ptr;10547 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));10548 const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align));
10483 const union_llvm_ty = try o.lowerType(struct_ty);10549 const union_llvm_ty = try o.lowerType(struct_ty);
...@@ -10500,9 +10566,10 @@ pub const FuncGen = struct {...@@ -10500,9 +10566,10 @@ pub const FuncGen = struct {
10500 // => so load the byte aligned value and trunc the unwanted bits.10566 // => so load the byte aligned value and trunc the unwanted bits.
1050110567
10502 const o = fg.dg.object;10568 const o = fg.dg.object;
10503 const mod = o.module;10569 const pt = o.pt;
10570 const mod = pt.zcu;
10504 const payload_llvm_ty = try o.lowerType(payload_ty);10571 const payload_llvm_ty = try o.lowerType(payload_ty);
10505 const abi_size = payload_ty.abiSize(mod);10572 const abi_size = payload_ty.abiSize(pt);
1050610573
10507 // llvm bug workarounds:10574 // llvm bug workarounds:
10508 const workaround_explicit_mask = o.target.cpu.arch == .powerpc and abi_size >= 4;10575 const workaround_explicit_mask = o.target.cpu.arch == .powerpc and abi_size >= 4;
...@@ -10522,7 +10589,7 @@ pub const FuncGen = struct {...@@ -10522,7 +10589,7 @@ pub const FuncGen = struct {
10522 const shifted = if (payload_llvm_ty != load_llvm_ty and o.target.cpu.arch.endian() == .big)10589 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(10590 try fg.wip.bin(.lshr, loaded, try o.builder.intValue(
10524 load_llvm_ty,10591 load_llvm_ty,
10525 (payload_ty.abiSize(mod) - (std.math.divCeil(u64, payload_ty.bitSize(mod), 8) catch unreachable)) * 8,10592 (payload_ty.abiSize(pt) - (std.math.divCeil(u64, payload_ty.bitSize(pt), 8) catch unreachable)) * 8,
10526 ), "")10593 ), "")
10527 else10594 else
10528 loaded;10595 loaded;
...@@ -10546,11 +10613,11 @@ pub const FuncGen = struct {...@@ -10546,11 +10613,11 @@ pub const FuncGen = struct {
10546 access_kind: Builder.MemoryAccessKind,10613 access_kind: Builder.MemoryAccessKind,
10547 ) !Builder.Value {10614 ) !Builder.Value {
10548 const o = fg.dg.object;10615 const o = fg.dg.object;
10549 const mod = o.module;10616 const pt = o.pt;
10550 //const pointee_llvm_ty = try o.lowerType(pointee_type);10617 //const pointee_llvm_ty = try o.lowerType(pointee_type);
10551 const result_align = InternPool.Alignment.fromLlvm(ptr_alignment).max(pointee_type.abiAlignment(mod)).toLlvm();10618 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);10619 const result_ptr = try fg.buildAllocaWorkaround(pointee_type, result_align);
10553 const size_bytes = pointee_type.abiSize(mod);10620 const size_bytes = pointee_type.abiSize(pt);
10554 _ = try fg.wip.callMemCpy(10621 _ = try fg.wip.callMemCpy(
10555 result_ptr,10622 result_ptr,
10556 result_align,10623 result_align,
...@@ -10567,15 +10634,16 @@ pub const FuncGen = struct {...@@ -10567,15 +10634,16 @@ pub const FuncGen = struct {
10567 /// For isByRef=false types, it creates a load instruction and returns it.10634 /// 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 {10635 fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) !Builder.Value {
10569 const o = self.dg.object;10636 const o = self.dg.object;
10570 const mod = o.module;10637 const pt = o.pt;
10638 const mod = pt.zcu;
10571 const info = ptr_ty.ptrInfo(mod);10639 const info = ptr_ty.ptrInfo(mod);
10572 const elem_ty = Type.fromInterned(info.child);10640 const elem_ty = Type.fromInterned(info.child);
10573 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;10641 if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) return .none;
1057410642
10575 const ptr_alignment = (if (info.flags.alignment != .none)10643 const ptr_alignment = (if (info.flags.alignment != .none)
10576 @as(InternPool.Alignment, info.flags.alignment)10644 @as(InternPool.Alignment, info.flags.alignment)
10577 else10645 else
10578 elem_ty.abiAlignment(mod)).toLlvm();10646 elem_ty.abiAlignment(pt)).toLlvm();
1057910647
10580 const access_kind: Builder.MemoryAccessKind =10648 const access_kind: Builder.MemoryAccessKind =
10581 if (info.flags.is_volatile) .@"volatile" else .normal;10649 if (info.flags.is_volatile) .@"volatile" else .normal;
...@@ -10591,7 +10659,7 @@ pub const FuncGen = struct {...@@ -10591,7 +10659,7 @@ pub const FuncGen = struct {
10591 }10659 }
1059210660
10593 if (info.packed_offset.host_size == 0) {10661 if (info.packed_offset.host_size == 0) {
10594 if (isByRef(elem_ty, mod)) {10662 if (isByRef(elem_ty, pt)) {
10595 return self.loadByRef(ptr, elem_ty, ptr_alignment, access_kind);10663 return self.loadByRef(ptr, elem_ty, ptr_alignment, access_kind);
10596 }10664 }
10597 return self.loadTruncate(access_kind, elem_ty, ptr, ptr_alignment);10665 return self.loadTruncate(access_kind, elem_ty, ptr, ptr_alignment);
...@@ -10601,13 +10669,13 @@ pub const FuncGen = struct {...@@ -10601,13 +10669,13 @@ pub const FuncGen = struct {
10601 const containing_int =10669 const containing_int =
10602 try self.wip.load(access_kind, containing_int_ty, ptr, ptr_alignment, "");10670 try self.wip.load(access_kind, containing_int_ty, ptr, ptr_alignment, "");
1060310671
10604 const elem_bits = ptr_ty.childType(mod).bitSize(mod);10672 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);10673 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, "");10674 const shifted_value = try self.wip.bin(.lshr, containing_int, shift_amt, "");
10607 const elem_llvm_ty = try o.lowerType(elem_ty);10675 const elem_llvm_ty = try o.lowerType(elem_ty);
1060810676
10609 if (isByRef(elem_ty, mod)) {10677 if (isByRef(elem_ty, pt)) {
10610 const result_align = elem_ty.abiAlignment(mod).toLlvm();10678 const result_align = elem_ty.abiAlignment(pt).toLlvm();
10611 const result_ptr = try self.buildAllocaWorkaround(elem_ty, result_align);10679 const result_ptr = try self.buildAllocaWorkaround(elem_ty, result_align);
1061210680
10613 const same_size_int = try o.builder.intType(@intCast(elem_bits));10681 const same_size_int = try o.builder.intType(@intCast(elem_bits));
...@@ -10639,13 +10707,14 @@ pub const FuncGen = struct {...@@ -10639,13 +10707,14 @@ pub const FuncGen = struct {
10639 ordering: Builder.AtomicOrdering,10707 ordering: Builder.AtomicOrdering,
10640 ) !void {10708 ) !void {
10641 const o = self.dg.object;10709 const o = self.dg.object;
10642 const mod = o.module;10710 const pt = o.pt;
10711 const mod = pt.zcu;
10643 const info = ptr_ty.ptrInfo(mod);10712 const info = ptr_ty.ptrInfo(mod);
10644 const elem_ty = Type.fromInterned(info.child);10713 const elem_ty = Type.fromInterned(info.child);
10645 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {10714 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) {
10646 return;10715 return;
10647 }10716 }
10648 const ptr_alignment = ptr_ty.ptrAlignment(mod).toLlvm();10717 const ptr_alignment = ptr_ty.ptrAlignment(pt).toLlvm();
10649 const access_kind: Builder.MemoryAccessKind =10718 const access_kind: Builder.MemoryAccessKind =
10650 if (info.flags.is_volatile) .@"volatile" else .normal;10719 if (info.flags.is_volatile) .@"volatile" else .normal;
1065110720
...@@ -10669,7 +10738,7 @@ pub const FuncGen = struct {...@@ -10669,7 +10738,7 @@ pub const FuncGen = struct {
10669 assert(ordering == .none);10738 assert(ordering == .none);
10670 const containing_int =10739 const containing_int =
10671 try self.wip.load(access_kind, containing_int_ty, ptr, ptr_alignment, "");10740 try self.wip.load(access_kind, containing_int_ty, ptr, ptr_alignment, "");
10672 const elem_bits = ptr_ty.childType(mod).bitSize(mod);10741 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);10742 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 bit10743 // Convert to equally-sized integer type in order to perform the bit
10675 // operations on the value to store10744 // operations on the value to store
...@@ -10704,7 +10773,7 @@ pub const FuncGen = struct {...@@ -10704,7 +10773,7 @@ pub const FuncGen = struct {
10704 _ = try self.wip.store(access_kind, ored_value, ptr, ptr_alignment);10773 _ = try self.wip.store(access_kind, ored_value, ptr, ptr_alignment);
10705 return;10774 return;
10706 }10775 }
10707 if (!isByRef(elem_ty, mod)) {10776 if (!isByRef(elem_ty, pt)) {
10708 _ = try self.wip.storeAtomic(10777 _ = try self.wip.storeAtomic(
10709 access_kind,10778 access_kind,
10710 elem,10779 elem,
...@@ -10720,8 +10789,8 @@ pub const FuncGen = struct {...@@ -10720,8 +10789,8 @@ pub const FuncGen = struct {
10720 ptr,10789 ptr,
10721 ptr_alignment,10790 ptr_alignment,
10722 elem,10791 elem,
10723 elem_ty.abiAlignment(mod).toLlvm(),10792 elem_ty.abiAlignment(pt).toLlvm(),
10724 try o.builder.intValue(try o.lowerType(Type.usize), elem_ty.abiSize(mod)),10793 try o.builder.intValue(try o.lowerType(Type.usize), elem_ty.abiSize(pt)),
10725 access_kind,10794 access_kind,
10726 );10795 );
10727 }10796 }
...@@ -10747,12 +10816,13 @@ pub const FuncGen = struct {...@@ -10747,12 +10816,13 @@ pub const FuncGen = struct {
10747 a5: Builder.Value,10816 a5: Builder.Value,
10748 ) Allocator.Error!Builder.Value {10817 ) Allocator.Error!Builder.Value {
10749 const o = fg.dg.object;10818 const o = fg.dg.object;
10750 const mod = o.module;10819 const pt = o.pt;
10820 const mod = pt.zcu;
10751 const target = mod.getTarget();10821 const target = mod.getTarget();
10752 if (!target_util.hasValgrindSupport(target)) return default_value;10822 if (!target_util.hasValgrindSupport(target)) return default_value;
1075310823
10754 const llvm_usize = try o.lowerType(Type.usize);10824 const llvm_usize = try o.lowerType(Type.usize);
10755 const usize_alignment = Type.usize.abiAlignment(mod).toLlvm();10825 const usize_alignment = Type.usize.abiAlignment(pt).toLlvm();
1075610826
10757 const array_llvm_ty = try o.builder.arrayType(6, llvm_usize);10827 const array_llvm_ty = try o.builder.arrayType(6, llvm_usize);
10758 const array_ptr = if (fg.valgrind_client_request_array == .none) a: {10828 const array_ptr = if (fg.valgrind_client_request_array == .none) a: {
...@@ -10813,13 +10883,13 @@ pub const FuncGen = struct {...@@ -10813,13 +10883,13 @@ pub const FuncGen = struct {
1081310883
10814 fn typeOf(fg: *FuncGen, inst: Air.Inst.Ref) Type {10884 fn typeOf(fg: *FuncGen, inst: Air.Inst.Ref) Type {
10815 const o = fg.dg.object;10885 const o = fg.dg.object;
10816 const mod = o.module;10886 const mod = o.pt.zcu;
10817 return fg.air.typeOf(inst, &mod.intern_pool);10887 return fg.air.typeOf(inst, &mod.intern_pool);
10818 }10888 }
1081910889
10820 fn typeOfIndex(fg: *FuncGen, inst: Air.Inst.Index) Type {10890 fn typeOfIndex(fg: *FuncGen, inst: Air.Inst.Index) Type {
10821 const o = fg.dg.object;10891 const o = fg.dg.object;
10822 const mod = o.module;10892 const mod = o.pt.zcu;
10823 return fg.air.typeOfIndex(inst, &mod.intern_pool);10893 return fg.air.typeOfIndex(inst, &mod.intern_pool);
10824 }10894 }
10825};10895};
...@@ -10990,12 +11060,12 @@ fn toLlvmGlobalAddressSpace(wanted_address_space: std.builtin.AddressSpace, targ...@@ -10990,12 +11060,12 @@ fn toLlvmGlobalAddressSpace(wanted_address_space: std.builtin.AddressSpace, targ
10990 };11060 };
10991}11061}
1099211062
10993fn returnTypeByRef(zcu: *Zcu, target: std.Target, ty: Type) bool {11063fn returnTypeByRef(pt: Zcu.PerThread, target: std.Target, ty: Type) bool {
10994 if (isByRef(ty, zcu)) {11064 if (isByRef(ty, pt)) {
10995 return true;11065 return true;
10996 } else if (target.cpu.arch.isX86() and11066 } else if (target.cpu.arch.isX86() and
10997 !std.Target.x86.featureSetHas(target.cpu.features, .evex512) and11067 !std.Target.x86.featureSetHas(target.cpu.features, .evex512) and
10998 ty.totalVectorBits(zcu) >= 512)11068 ty.totalVectorBits(pt) >= 512)
10999 {11069 {
11000 // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns11070 // 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"11071 // "512-bit vector arguments require 'evex512' for AVX512"
...@@ -11005,38 +11075,38 @@ fn returnTypeByRef(zcu: *Zcu, target: std.Target, ty: Type) bool {...@@ -11005,38 +11075,38 @@ fn returnTypeByRef(zcu: *Zcu, target: std.Target, ty: Type) bool {
11005 }11075 }
11006}11076}
1100711077
11008fn firstParamSRet(fn_info: InternPool.Key.FuncType, zcu: *Zcu, target: std.Target) bool {11078fn firstParamSRet(fn_info: InternPool.Key.FuncType, pt: Zcu.PerThread, target: std.Target) bool {
11009 const return_type = Type.fromInterned(fn_info.return_type);11079 const return_type = Type.fromInterned(fn_info.return_type);
11010 if (!return_type.hasRuntimeBitsIgnoreComptime(zcu)) return false;11080 if (!return_type.hasRuntimeBitsIgnoreComptime(pt)) return false;
1101111081
11012 return switch (fn_info.cc) {11082 return switch (fn_info.cc) {
11013 .Unspecified, .Inline => returnTypeByRef(zcu, target, return_type),11083 .Unspecified, .Inline => returnTypeByRef(pt, target, return_type),
11014 .C => switch (target.cpu.arch) {11084 .C => switch (target.cpu.arch) {
11015 .mips, .mipsel => false,11085 .mips, .mipsel => false,
11016 .x86 => isByRef(return_type, zcu),11086 .x86 => isByRef(return_type, pt),
11017 .x86_64 => switch (target.os.tag) {11087 .x86_64 => switch (target.os.tag) {
11018 .windows => x86_64_abi.classifyWindows(return_type, zcu) == .memory,11088 .windows => x86_64_abi.classifyWindows(return_type, pt) == .memory,
11019 else => firstParamSRetSystemV(return_type, zcu, target),11089 else => firstParamSRetSystemV(return_type, pt, target),
11020 },11090 },
11021 .wasm32 => wasm_c_abi.classifyType(return_type, zcu)[0] == .indirect,11091 .wasm32 => wasm_c_abi.classifyType(return_type, pt)[0] == .indirect,
11022 .aarch64, .aarch64_be => aarch64_c_abi.classifyType(return_type, zcu) == .memory,11092 .aarch64, .aarch64_be => aarch64_c_abi.classifyType(return_type, pt) == .memory,
11023 .arm, .armeb => switch (arm_c_abi.classifyType(return_type, zcu, .ret)) {11093 .arm, .armeb => switch (arm_c_abi.classifyType(return_type, pt, .ret)) {
11024 .memory, .i64_array => true,11094 .memory, .i64_array => true,
11025 .i32_array => |size| size != 1,11095 .i32_array => |size| size != 1,
11026 .byval => false,11096 .byval => false,
11027 },11097 },
11028 .riscv32, .riscv64 => riscv_c_abi.classifyType(return_type, zcu) == .memory,11098 .riscv32, .riscv64 => riscv_c_abi.classifyType(return_type, pt) == .memory,
11029 else => false, // TODO investigate C ABI for other architectures11099 else => false, // TODO investigate C ABI for other architectures
11030 },11100 },
11031 .SysV => firstParamSRetSystemV(return_type, zcu, target),11101 .SysV => firstParamSRetSystemV(return_type, pt, target),
11032 .Win64 => x86_64_abi.classifyWindows(return_type, zcu) == .memory,11102 .Win64 => x86_64_abi.classifyWindows(return_type, pt) == .memory,
11033 .Stdcall => !isScalar(zcu, return_type),11103 .Stdcall => !isScalar(pt.zcu, return_type),
11034 else => false,11104 else => false,
11035 };11105 };
11036}11106}
1103711107
11038fn firstParamSRetSystemV(ty: Type, zcu: *Zcu, target: std.Target) bool {11108fn firstParamSRetSystemV(ty: Type, pt: Zcu.PerThread, target: std.Target) bool {
11039 const class = x86_64_abi.classifySystemV(ty, zcu, target, .ret);11109 const class = x86_64_abi.classifySystemV(ty, pt, target, .ret);
11040 if (class[0] == .memory) return true;11110 if (class[0] == .memory) return true;
11041 if (class[0] == .x87 and class[2] != .none) return true;11111 if (class[0] == .x87 and class[2] != .none) return true;
11042 return false;11112 return false;
...@@ -11046,9 +11116,10 @@ fn firstParamSRetSystemV(ty: Type, zcu: *Zcu, target: std.Target) bool {...@@ -11046,9 +11116,10 @@ fn firstParamSRetSystemV(ty: Type, zcu: *Zcu, target: std.Target) bool {
11046/// completely differently in the function prototype to honor the C ABI, and then11116/// completely differently in the function prototype to honor the C ABI, and then
11047/// be effectively bitcasted to the actual return type.11117/// be effectively bitcasted to the actual return type.
11048fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {11118fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {
11049 const mod = o.module;11119 const pt = o.pt;
11120 const mod = pt.zcu;
11050 const return_type = Type.fromInterned(fn_info.return_type);11121 const return_type = Type.fromInterned(fn_info.return_type);
11051 if (!return_type.hasRuntimeBitsIgnoreComptime(mod)) {11122 if (!return_type.hasRuntimeBitsIgnoreComptime(pt)) {
11052 // If the return type is an error set or an error union, then we make this11123 // 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 function11124 // anyerror return type instead, so that it can be coerced into a function
11054 // pointer type which has anyerror as the return type.11125 // pointer type which has anyerror as the return type.
...@@ -11058,12 +11129,12 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu...@@ -11058,12 +11129,12 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu
11058 switch (fn_info.cc) {11129 switch (fn_info.cc) {
11059 .Unspecified,11130 .Unspecified,
11060 .Inline,11131 .Inline,
11061 => return if (returnTypeByRef(mod, target, return_type)) .void else o.lowerType(return_type),11132 => return if (returnTypeByRef(pt, target, return_type)) .void else o.lowerType(return_type),
1106211133
11063 .C => {11134 .C => {
11064 switch (target.cpu.arch) {11135 switch (target.cpu.arch) {
11065 .mips, .mipsel => return o.lowerType(return_type),11136 .mips, .mipsel => return o.lowerType(return_type),
11066 .x86 => return if (isByRef(return_type, mod)) .void else o.lowerType(return_type),11137 .x86 => return if (isByRef(return_type, pt)) .void else o.lowerType(return_type),
11067 .x86_64 => switch (target.os.tag) {11138 .x86_64 => switch (target.os.tag) {
11068 .windows => return lowerWin64FnRetTy(o, fn_info),11139 .windows => return lowerWin64FnRetTy(o, fn_info),
11069 else => return lowerSystemVFnRetTy(o, fn_info),11140 else => return lowerSystemVFnRetTy(o, fn_info),
...@@ -11072,36 +11143,36 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu...@@ -11072,36 +11143,36 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu
11072 if (isScalar(mod, return_type)) {11143 if (isScalar(mod, return_type)) {
11073 return o.lowerType(return_type);11144 return o.lowerType(return_type);
11074 }11145 }
11075 const classes = wasm_c_abi.classifyType(return_type, mod);11146 const classes = wasm_c_abi.classifyType(return_type, pt);
11076 if (classes[0] == .indirect or classes[0] == .none) {11147 if (classes[0] == .indirect or classes[0] == .none) {
11077 return .void;11148 return .void;
11078 }11149 }
1107911150
11080 assert(classes[0] == .direct and classes[1] == .none);11151 assert(classes[0] == .direct and classes[1] == .none);
11081 const scalar_type = wasm_c_abi.scalarType(return_type, mod);11152 const scalar_type = wasm_c_abi.scalarType(return_type, pt);
11082 return o.builder.intType(@intCast(scalar_type.abiSize(mod) * 8));11153 return o.builder.intType(@intCast(scalar_type.abiSize(pt) * 8));
11083 },11154 },
11084 .aarch64, .aarch64_be => {11155 .aarch64, .aarch64_be => {
11085 switch (aarch64_c_abi.classifyType(return_type, mod)) {11156 switch (aarch64_c_abi.classifyType(return_type, pt)) {
11086 .memory => return .void,11157 .memory => return .void,
11087 .float_array => return o.lowerType(return_type),11158 .float_array => return o.lowerType(return_type),
11088 .byval => return o.lowerType(return_type),11159 .byval => return o.lowerType(return_type),
11089 .integer => return o.builder.intType(@intCast(return_type.bitSize(mod))),11160 .integer => return o.builder.intType(@intCast(return_type.bitSize(pt))),
11090 .double_integer => return o.builder.arrayType(2, .i64),11161 .double_integer => return o.builder.arrayType(2, .i64),
11091 }11162 }
11092 },11163 },
11093 .arm, .armeb => {11164 .arm, .armeb => {
11094 switch (arm_c_abi.classifyType(return_type, mod, .ret)) {11165 switch (arm_c_abi.classifyType(return_type, pt, .ret)) {
11095 .memory, .i64_array => return .void,11166 .memory, .i64_array => return .void,
11096 .i32_array => |len| return if (len == 1) .i32 else .void,11167 .i32_array => |len| return if (len == 1) .i32 else .void,
11097 .byval => return o.lowerType(return_type),11168 .byval => return o.lowerType(return_type),
11098 }11169 }
11099 },11170 },
11100 .riscv32, .riscv64 => {11171 .riscv32, .riscv64 => {
11101 switch (riscv_c_abi.classifyType(return_type, mod)) {11172 switch (riscv_c_abi.classifyType(return_type, pt)) {
11102 .memory => return .void,11173 .memory => return .void,
11103 .integer => {11174 .integer => {
11104 return o.builder.intType(@intCast(return_type.bitSize(mod)));11175 return o.builder.intType(@intCast(return_type.bitSize(pt)));
11105 },11176 },
11106 .double_integer => {11177 .double_integer => {
11107 return o.builder.structType(.normal, &.{ .i64, .i64 });11178 return o.builder.structType(.normal, &.{ .i64, .i64 });
...@@ -11112,7 +11183,7 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu...@@ -11112,7 +11183,7 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu
11112 var types: [8]Builder.Type = undefined;11183 var types: [8]Builder.Type = undefined;
11113 for (0..return_type.structFieldCount(mod)) |field_index| {11184 for (0..return_type.structFieldCount(mod)) |field_index| {
11114 const field_ty = return_type.structFieldType(field_index, mod);11185 const field_ty = return_type.structFieldType(field_index, mod);
11115 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;11186 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
11116 types[types_len] = try o.lowerType(field_ty);11187 types[types_len] = try o.lowerType(field_ty);
11117 types_len += 1;11188 types_len += 1;
11118 }11189 }
...@@ -11132,14 +11203,14 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu...@@ -11132,14 +11203,14 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu
11132}11203}
1113311204
11134fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {11205fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {
11135 const mod = o.module;11206 const pt = o.pt;
11136 const return_type = Type.fromInterned(fn_info.return_type);11207 const return_type = Type.fromInterned(fn_info.return_type);
11137 switch (x86_64_abi.classifyWindows(return_type, mod)) {11208 switch (x86_64_abi.classifyWindows(return_type, pt)) {
11138 .integer => {11209 .integer => {
11139 if (isScalar(mod, return_type)) {11210 if (isScalar(pt.zcu, return_type)) {
11140 return o.lowerType(return_type);11211 return o.lowerType(return_type);
11141 } else {11212 } else {
11142 return o.builder.intType(@intCast(return_type.abiSize(mod) * 8));11213 return o.builder.intType(@intCast(return_type.abiSize(pt) * 8));
11143 }11214 }
11144 },11215 },
11145 .win_i128 => return o.builder.vectorType(.normal, 2, .i64),11216 .win_i128 => return o.builder.vectorType(.normal, 2, .i64),
...@@ -11150,14 +11221,15 @@ fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Err...@@ -11150,14 +11221,15 @@ fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Err
11150}11221}
1115111222
11152fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {11223fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {
11153 const mod = o.module;11224 const pt = o.pt;
11225 const mod = pt.zcu;
11154 const ip = &mod.intern_pool;11226 const ip = &mod.intern_pool;
11155 const return_type = Type.fromInterned(fn_info.return_type);11227 const return_type = Type.fromInterned(fn_info.return_type);
11156 if (isScalar(mod, return_type)) {11228 if (isScalar(mod, return_type)) {
11157 return o.lowerType(return_type);11229 return o.lowerType(return_type);
11158 }11230 }
11159 const target = mod.getTarget();11231 const target = mod.getTarget();
11160 const classes = x86_64_abi.classifySystemV(return_type, mod, target, .ret);11232 const classes = x86_64_abi.classifySystemV(return_type, pt, target, .ret);
11161 if (classes[0] == .memory) return .void;11233 if (classes[0] == .memory) return .void;
11162 var types_index: u32 = 0;11234 var types_index: u32 = 0;
11163 var types_buffer: [8]Builder.Type = undefined;11235 var types_buffer: [8]Builder.Type = undefined;
...@@ -11249,8 +11321,7 @@ const ParamTypeIterator = struct {...@@ -11249,8 +11321,7 @@ const ParamTypeIterator = struct {
1124911321
11250 pub fn next(it: *ParamTypeIterator) Allocator.Error!?Lowering {11322 pub fn next(it: *ParamTypeIterator) Allocator.Error!?Lowering {
11251 if (it.zig_index >= it.fn_info.param_types.len) return null;11323 if (it.zig_index >= it.fn_info.param_types.len) return null;
11252 const zcu = it.object.module;11324 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];11325 const ty = it.fn_info.param_types.get(ip)[it.zig_index];
11255 it.byval_attr = false;11326 it.byval_attr = false;
11256 return nextInner(it, Type.fromInterned(ty));11327 return nextInner(it, Type.fromInterned(ty));
...@@ -11258,8 +11329,7 @@ const ParamTypeIterator = struct {...@@ -11258,8 +11329,7 @@ const ParamTypeIterator = struct {
1125811329
11259 /// `airCall` uses this instead of `next` so that it can take into account variadic functions.11330 /// `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 {11331 pub fn nextCall(it: *ParamTypeIterator, fg: *FuncGen, args: []const Air.Inst.Ref) Allocator.Error!?Lowering {
11261 const zcu = it.object.module;11332 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) {11333 if (it.zig_index >= it.fn_info.param_types.len) {
11264 if (it.zig_index >= args.len) {11334 if (it.zig_index >= args.len) {
11265 return null;11335 return null;
...@@ -11272,10 +11342,11 @@ const ParamTypeIterator = struct {...@@ -11272,10 +11342,11 @@ const ParamTypeIterator = struct {
11272 }11342 }
1127311343
11274 fn nextInner(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering {11344 fn nextInner(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering {
11275 const zcu = it.object.module;11345 const pt = it.object.pt;
11346 const zcu = pt.zcu;
11276 const target = zcu.getTarget();11347 const target = zcu.getTarget();
1127711348
11278 if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) {11349 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
11279 it.zig_index += 1;11350 it.zig_index += 1;
11280 return .no_bits;11351 return .no_bits;
11281 }11352 }
...@@ -11288,11 +11359,11 @@ const ParamTypeIterator = struct {...@@ -11288,11 +11359,11 @@ const ParamTypeIterator = struct {
11288 {11359 {
11289 it.llvm_index += 1;11360 it.llvm_index += 1;
11290 return .slice;11361 return .slice;
11291 } else if (isByRef(ty, zcu)) {11362 } else if (isByRef(ty, pt)) {
11292 return .byref;11363 return .byref;
11293 } else if (target.cpu.arch.isX86() and11364 } else if (target.cpu.arch.isX86() and
11294 !std.Target.x86.featureSetHas(target.cpu.features, .evex512) and11365 !std.Target.x86.featureSetHas(target.cpu.features, .evex512) and
11295 ty.totalVectorBits(zcu) >= 512)11366 ty.totalVectorBits(pt) >= 512)
11296 {11367 {
11297 // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns11368 // 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"11369 // "512-bit vector arguments require 'evex512' for AVX512"
...@@ -11320,7 +11391,7 @@ const ParamTypeIterator = struct {...@@ -11320,7 +11391,7 @@ const ParamTypeIterator = struct {
11320 if (isScalar(zcu, ty)) {11391 if (isScalar(zcu, ty)) {
11321 return .byval;11392 return .byval;
11322 }11393 }
11323 const classes = wasm_c_abi.classifyType(ty, zcu);11394 const classes = wasm_c_abi.classifyType(ty, pt);
11324 if (classes[0] == .indirect) {11395 if (classes[0] == .indirect) {
11325 return .byref;11396 return .byref;
11326 }11397 }
...@@ -11329,7 +11400,7 @@ const ParamTypeIterator = struct {...@@ -11329,7 +11400,7 @@ const ParamTypeIterator = struct {
11329 .aarch64, .aarch64_be => {11400 .aarch64, .aarch64_be => {
11330 it.zig_index += 1;11401 it.zig_index += 1;
11331 it.llvm_index += 1;11402 it.llvm_index += 1;
11332 switch (aarch64_c_abi.classifyType(ty, zcu)) {11403 switch (aarch64_c_abi.classifyType(ty, pt)) {
11333 .memory => return .byref_mut,11404 .memory => return .byref_mut,
11334 .float_array => |len| return Lowering{ .float_array = len },11405 .float_array => |len| return Lowering{ .float_array = len },
11335 .byval => return .byval,11406 .byval => return .byval,
...@@ -11344,7 +11415,7 @@ const ParamTypeIterator = struct {...@@ -11344,7 +11415,7 @@ const ParamTypeIterator = struct {
11344 .arm, .armeb => {11415 .arm, .armeb => {
11345 it.zig_index += 1;11416 it.zig_index += 1;
11346 it.llvm_index += 1;11417 it.llvm_index += 1;
11347 switch (arm_c_abi.classifyType(ty, zcu, .arg)) {11418 switch (arm_c_abi.classifyType(ty, pt, .arg)) {
11348 .memory => {11419 .memory => {
11349 it.byval_attr = true;11420 it.byval_attr = true;
11350 return .byref;11421 return .byref;
...@@ -11359,7 +11430,7 @@ const ParamTypeIterator = struct {...@@ -11359,7 +11430,7 @@ const ParamTypeIterator = struct {
11359 it.llvm_index += 1;11430 it.llvm_index += 1;
11360 if (ty.toIntern() == .f16_type and11431 if (ty.toIntern() == .f16_type and
11361 !std.Target.riscv.featureSetHas(target.cpu.features, .d)) return .as_u16;11432 !std.Target.riscv.featureSetHas(target.cpu.features, .d)) return .as_u16;
11362 switch (riscv_c_abi.classifyType(ty, zcu)) {11433 switch (riscv_c_abi.classifyType(ty, pt)) {
11363 .memory => return .byref_mut,11434 .memory => return .byref_mut,
11364 .byval => return .byval,11435 .byval => return .byval,
11365 .integer => return .abi_sized_int,11436 .integer => return .abi_sized_int,
...@@ -11368,7 +11439,7 @@ const ParamTypeIterator = struct {...@@ -11368,7 +11439,7 @@ const ParamTypeIterator = struct {
11368 it.types_len = 0;11439 it.types_len = 0;
11369 for (0..ty.structFieldCount(zcu)) |field_index| {11440 for (0..ty.structFieldCount(zcu)) |field_index| {
11370 const field_ty = ty.structFieldType(field_index, zcu);11441 const field_ty = ty.structFieldType(field_index, zcu);
11371 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;11442 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
11372 it.types_buffer[it.types_len] = try it.object.lowerType(field_ty);11443 it.types_buffer[it.types_len] = try it.object.lowerType(field_ty);
11373 it.types_len += 1;11444 it.types_len += 1;
11374 }11445 }
...@@ -11406,10 +11477,10 @@ const ParamTypeIterator = struct {...@@ -11406,10 +11477,10 @@ const ParamTypeIterator = struct {
11406 }11477 }
1140711478
11408 fn nextWin64(it: *ParamTypeIterator, ty: Type) ?Lowering {11479 fn nextWin64(it: *ParamTypeIterator, ty: Type) ?Lowering {
11409 const zcu = it.object.module;11480 const pt = it.object.pt;
11410 switch (x86_64_abi.classifyWindows(ty, zcu)) {11481 switch (x86_64_abi.classifyWindows(ty, pt)) {
11411 .integer => {11482 .integer => {
11412 if (isScalar(zcu, ty)) {11483 if (isScalar(pt.zcu, ty)) {
11413 it.zig_index += 1;11484 it.zig_index += 1;
11414 it.llvm_index += 1;11485 it.llvm_index += 1;
11415 return .byval;11486 return .byval;
...@@ -11439,17 +11510,17 @@ const ParamTypeIterator = struct {...@@ -11439,17 +11510,17 @@ const ParamTypeIterator = struct {
11439 }11510 }
1144011511
11441 fn nextSystemV(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering {11512 fn nextSystemV(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering {
11442 const zcu = it.object.module;11513 const pt = it.object.pt;
11443 const ip = &zcu.intern_pool;11514 const ip = &pt.zcu.intern_pool;
11444 const target = zcu.getTarget();11515 const target = pt.zcu.getTarget();
11445 const classes = x86_64_abi.classifySystemV(ty, zcu, target, .arg);11516 const classes = x86_64_abi.classifySystemV(ty, pt, target, .arg);
11446 if (classes[0] == .memory) {11517 if (classes[0] == .memory) {
11447 it.zig_index += 1;11518 it.zig_index += 1;
11448 it.llvm_index += 1;11519 it.llvm_index += 1;
11449 it.byval_attr = true;11520 it.byval_attr = true;
11450 return .byref;11521 return .byref;
11451 }11522 }
11452 if (isScalar(zcu, ty)) {11523 if (isScalar(pt.zcu, ty)) {
11453 it.zig_index += 1;11524 it.zig_index += 1;
11454 it.llvm_index += 1;11525 it.llvm_index += 1;
11455 return .byval;11526 return .byval;
...@@ -11550,7 +11621,7 @@ fn iterateParamTypes(object: *Object, fn_info: InternPool.Key.FuncType) ParamTyp...@@ -11550,7 +11621,7 @@ fn iterateParamTypes(object: *Object, fn_info: InternPool.Key.FuncType) ParamTyp
1155011621
11551fn ccAbiPromoteInt(11622fn ccAbiPromoteInt(
11552 cc: std.builtin.CallingConvention,11623 cc: std.builtin.CallingConvention,
11553 mod: *Module,11624 mod: *Zcu,
11554 ty: Type,11625 ty: Type,
11555) ?std.builtin.Signedness {11626) ?std.builtin.Signedness {
11556 const target = mod.getTarget();11627 const target = mod.getTarget();
...@@ -11598,13 +11669,13 @@ fn ccAbiPromoteInt(...@@ -11598,13 +11669,13 @@ fn ccAbiPromoteInt(
1159811669
11599/// This is the one source of truth for whether a type is passed around as an LLVM pointer,11670/// This is the one source of truth for whether a type is passed around as an LLVM pointer,
11600/// or as an LLVM value.11671/// or as an LLVM value.
11601fn isByRef(ty: Type, mod: *Module) bool {11672fn isByRef(ty: Type, pt: Zcu.PerThread) bool {
11602 // For tuples and structs, if there are more than this many non-void11673 // For tuples and structs, if there are more than this many non-void
11603 // fields, then we make it byref, otherwise byval.11674 // fields, then we make it byref, otherwise byval.
11604 const max_fields_byval = 0;11675 const max_fields_byval = 0;
11605 const ip = &mod.intern_pool;11676 const ip = &pt.zcu.intern_pool;
1160611677
11607 switch (ty.zigTypeTag(mod)) {11678 switch (ty.zigTypeTag(pt.zcu)) {
11608 .Type,11679 .Type,
11609 .ComptimeInt,11680 .ComptimeInt,
11610 .ComptimeFloat,11681 .ComptimeFloat,
...@@ -11627,17 +11698,17 @@ fn isByRef(ty: Type, mod: *Module) bool {...@@ -11627,17 +11698,17 @@ fn isByRef(ty: Type, mod: *Module) bool {
11627 .AnyFrame,11698 .AnyFrame,
11628 => return false,11699 => return false,
1162911700
11630 .Array, .Frame => return ty.hasRuntimeBits(mod),11701 .Array, .Frame => return ty.hasRuntimeBits(pt),
11631 .Struct => {11702 .Struct => {
11632 const struct_type = switch (ip.indexToKey(ty.toIntern())) {11703 const struct_type = switch (ip.indexToKey(ty.toIntern())) {
11633 .anon_struct_type => |tuple| {11704 .anon_struct_type => |tuple| {
11634 var count: usize = 0;11705 var count: usize = 0;
11635 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| {11706 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;11707 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue;
1163711708
11638 count += 1;11709 count += 1;
11639 if (count > max_fields_byval) return true;11710 if (count > max_fields_byval) return true;
11640 if (isByRef(Type.fromInterned(field_ty), mod)) return true;11711 if (isByRef(Type.fromInterned(field_ty), pt)) return true;
11641 }11712 }
11642 return false;11713 return false;
11643 },11714 },
...@@ -11655,27 +11726,27 @@ fn isByRef(ty: Type, mod: *Module) bool {...@@ -11655,27 +11726,27 @@ fn isByRef(ty: Type, mod: *Module) bool {
11655 count += 1;11726 count += 1;
11656 if (count > max_fields_byval) return true;11727 if (count > max_fields_byval) return true;
11657 const field_ty = Type.fromInterned(field_types[field_index]);11728 const field_ty = Type.fromInterned(field_types[field_index]);
11658 if (isByRef(field_ty, mod)) return true;11729 if (isByRef(field_ty, pt)) return true;
11659 }11730 }
11660 return false;11731 return false;
11661 },11732 },
11662 .Union => switch (ty.containerLayout(mod)) {11733 .Union => switch (ty.containerLayout(pt.zcu)) {
11663 .@"packed" => return false,11734 .@"packed" => return false,
11664 else => return ty.hasRuntimeBits(mod),11735 else => return ty.hasRuntimeBits(pt),
11665 },11736 },
11666 .ErrorUnion => {11737 .ErrorUnion => {
11667 const payload_ty = ty.errorUnionPayload(mod);11738 const payload_ty = ty.errorUnionPayload(pt.zcu);
11668 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {11739 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
11669 return false;11740 return false;
11670 }11741 }
11671 return true;11742 return true;
11672 },11743 },
11673 .Optional => {11744 .Optional => {
11674 const payload_ty = ty.optionalChild(mod);11745 const payload_ty = ty.optionalChild(pt.zcu);
11675 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {11746 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
11676 return false;11747 return false;
11677 }11748 }
11678 if (ty.optionalReprIsPayload(mod)) {11749 if (ty.optionalReprIsPayload(pt.zcu)) {
11679 return false;11750 return false;
11680 }11751 }
11681 return true;11752 return true;
...@@ -11683,7 +11754,7 @@ fn isByRef(ty: Type, mod: *Module) bool {...@@ -11683,7 +11754,7 @@ fn isByRef(ty: Type, mod: *Module) bool {
11683 }11754 }
11684}11755}
1168511756
11686fn isScalar(mod: *Module, ty: Type) bool {11757fn isScalar(mod: *Zcu, ty: Type) bool {
11687 return switch (ty.zigTypeTag(mod)) {11758 return switch (ty.zigTypeTag(mod)) {
11688 .Void,11759 .Void,
11689 .Bool,11760 .Bool,
...@@ -11774,7 +11845,7 @@ const lt_errors_fn_name = "__zig_lt_errors_len";...@@ -11774,7 +11845,7 @@ const lt_errors_fn_name = "__zig_lt_errors_len";
11774/// Without this workaround, LLVM crashes with "unknown codeview register H1"11845/// Without this workaround, LLVM crashes with "unknown codeview register H1"
11775/// https://github.com/llvm/llvm-project/issues/5648411846/// https://github.com/llvm/llvm-project/issues/56484
11776fn needDbgVarWorkaround(o: *Object) bool {11847fn needDbgVarWorkaround(o: *Object) bool {
11777 const target = o.module.getTarget();11848 const target = o.pt.zcu.getTarget();
11778 if (target.os.tag == .windows and target.cpu.arch == .aarch64) {11849 if (target.os.tag == .windows and target.cpu.arch == .aarch64) {
11779 return true;11850 return true;
11780 }11851 }
...@@ -11817,14 +11888,14 @@ fn buildAllocaInner(...@@ -11817,14 +11888,14 @@ fn buildAllocaInner(
11817 return wip.conv(.unneeded, alloca, .ptr, "");11888 return wip.conv(.unneeded, alloca, .ptr, "");
11818}11889}
1181911890
11820fn errUnionPayloadOffset(payload_ty: Type, mod: *Module) !u1 {11891fn errUnionPayloadOffset(payload_ty: Type, pt: Zcu.PerThread) !u1 {
11821 const err_int_ty = try mod.errorIntType();11892 const err_int_ty = try pt.errorIntType();
11822 return @intFromBool(err_int_ty.abiAlignment(mod).compare(.gt, payload_ty.abiAlignment(mod)));11893 return @intFromBool(err_int_ty.abiAlignment(pt).compare(.gt, payload_ty.abiAlignment(pt)));
11823}11894}
1182411895
11825fn errUnionErrorOffset(payload_ty: Type, mod: *Module) !u1 {11896fn errUnionErrorOffset(payload_ty: Type, pt: Zcu.PerThread) !u1 {
11826 const err_int_ty = try mod.errorIntType();11897 const err_int_ty = try pt.errorIntType();
11827 return @intFromBool(err_int_ty.abiAlignment(mod).compare(.lte, payload_ty.abiAlignment(mod)));11898 return @intFromBool(err_int_ty.abiAlignment(pt).compare(.lte, payload_ty.abiAlignment(pt)));
11828}11899}
1182911900
11830/// Returns true for asm constraint (e.g. "=*m", "=r") if it accepts a memory location11901/// Returns true for asm constraint (e.g. "=*m", "=r") if it accepts a memory location
src/codegen/spirv.zig+239-211
...@@ -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,7 +1747,7 @@ const DeclGen = struct {...@@ -1742,7 +1747,7 @@ 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 }
...@@ -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.zcu);
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.zcu);
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.zcu);
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+24-25
...@@ -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,12 +419,12 @@ pub const File = struct {...@@ -421,12 +419,12 @@ 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, module: *Zcu, decl_index: InternPool.DeclIndex) UpdateDeclError!void {
430 const decl = module.declPtr(decl_index);428 const decl = module.declPtr(decl_index);
431 assert(decl.has_tv);429 assert(decl.has_tv);
432 switch (base.tag) {430 switch (base.tag) {
...@@ -537,7 +535,7 @@ pub const File = struct {...@@ -537,7 +535,7 @@ 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, prog_node);
...@@ -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 }
...@@ -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+31-28
...@@ -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 },
...@@ -390,8 +391,8 @@ pub fn updateDeclLineNumber(self: *C, zcu: *Zcu, decl_index: InternPool.DeclInde...@@ -390,8 +391,8 @@ pub fn updateDeclLineNumber(self: *C, zcu: *Zcu, decl_index: InternPool.DeclInde
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+53-32
...@@ -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,14 +1162,14 @@ pub fn updateFunc(self: *Coff, mod: *Module, func_index: InternPool.Index, air:...@@ -1160,14 +1162,14 @@ 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) {
...@@ -1179,7 +1181,7 @@ pub fn lowerUnnamedConst(self: *Coff, val: Value, decl_index: InternPool.DeclInd...@@ -1179,7 +1181,7 @@ pub fn lowerUnnamedConst(self: *Coff, val: Value, decl_index: InternPool.DeclInd
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(mod);
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) {
...@@ -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,
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.zcu);
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+20-19
...@@ -550,11 +550,12 @@ pub fn getDeclVAddr(self: *Elf, decl_index: InternPool.DeclIndex, reloc_info: li...@@ -550,11 +550,12 @@ pub fn getDeclVAddr(self: *Elf, decl_index: InternPool.DeclIndex, reloc_info: li
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,41 +2984,41 @@ pub fn freeDecl(self: *Elf, decl_index: InternPool.DeclIndex) void {...@@ -2983,41 +2984,41 @@ 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, mod: *Module, decl_index: InternPool.DeclIndex) !void {
src/link/Elf/ZigObject.zig+60-55
...@@ -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(mod);
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(mod);
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 {
...@@ -1291,9 +1293,10 @@ pub fn lowerUnnamedConst(...@@ -1291,9 +1293,10 @@ pub fn lowerUnnamedConst(
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| {
src/link/MachO.zig+17-16
...@@ -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,24 +3178,24 @@ pub fn writeCodeSignature(self: *MachO, code_sig: *CodeSignature) !void {...@@ -3178,24 +3178,24 @@ 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, module: *Module, decl_index: InternPool.DeclIndex) !void {
...@@ -3205,15 +3205,15 @@ pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl_index: InternPoo...@@ -3205,15 +3205,15 @@ pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl_index: InternPoo
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(
...@@ -3237,11 +3237,12 @@ pub fn getDeclVAddr(self: *MachO, decl_index: InternPool.DeclIndex, reloc_info:...@@ -3237,11 +3237,12 @@ pub fn getDeclVAddr(self: *MachO, decl_index: InternPool.DeclIndex, reloc_info:
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+49-33
...@@ -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(mod);
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,20 @@ fn updateDeclCode(...@@ -879,19 +887,20 @@ 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 mod = pt.zcu;
888 const decl = mod.declPtr(decl_index);897 const decl = mod.declPtr(decl_index);
889 const decl_name = try decl.fullyQualifiedName(mod);898 const decl_name = try decl.fullyQualifiedName(mod);
890899
891 log.debug("updateTlv {} ({*})", .{ decl_name.fmt(&mod.intern_pool), decl });900 log.debug("updateTlv {} ({*})", .{ decl_name.fmt(&mod.intern_pool), decl });
892901
893 const decl_name_slice = decl_name.toSlice(&mod.intern_pool);902 const decl_name_slice = decl_name.toSlice(&mod.intern_pool);
894 const required_alignment = decl.getAlignment(mod);903 const required_alignment = decl.getAlignment(pt);
895904
896 // 1. Lower TLV initializer905 // 1. Lower TLV initializer
897 const init_sym_index = try self.createTlvInitializer(906 const init_sym_index = try self.createTlvInitializer(
...@@ -1079,11 +1088,12 @@ fn getDeclOutputSection(...@@ -1079,11 +1088,12 @@ fn getDeclOutputSection(
1079pub fn lowerUnnamedConst(1088pub fn lowerUnnamedConst(
1080 self: *ZigObject,1089 self: *ZigObject,
1081 macho_file: *MachO,1090 macho_file: *MachO,
1091 pt: Zcu.PerThread,
1082 val: Value,1092 val: Value,
1083 decl_index: InternPool.DeclIndex,1093 decl_index: InternPool.DeclIndex,
1084) !u32 {1094) !u32 {
1085 const gpa = macho_file.base.comp.gpa;1095 const mod = pt.zcu;
1086 const mod = macho_file.base.comp.module.?;1096 const gpa = mod.gpa;
1087 const gop = try self.unnamed_consts.getOrPut(gpa, decl_index);1097 const gop = try self.unnamed_consts.getOrPut(gpa, decl_index);
1088 if (!gop.found_existing) {1098 if (!gop.found_existing) {
1089 gop.value_ptr.* = .{};1099 gop.value_ptr.* = .{};
...@@ -1096,9 +1106,10 @@ pub fn lowerUnnamedConst(...@@ -1096,9 +1106,10 @@ pub fn lowerUnnamedConst(
1096 defer gpa.free(name);1106 defer gpa.free(name);
1097 const sym_index = switch (try self.lowerConst(1107 const sym_index = switch (try self.lowerConst(
1098 macho_file,1108 macho_file,
1109 pt,
1099 name,1110 name,
1100 val,1111 val,
1101 val.typeOf(mod).abiAlignment(mod),1112 val.typeOf(mod).abiAlignment(pt),
1102 macho_file.zig_const_sect_index.?,1113 macho_file.zig_const_sect_index.?,
1103 decl.navSrcLoc(mod),1114 decl.navSrcLoc(mod),
1104 )) {1115 )) {
...@@ -1123,6 +1134,7 @@ const LowerConstResult = union(enum) {...@@ -1123,6 +1134,7 @@ const LowerConstResult = union(enum) {
1123fn lowerConst(1134fn lowerConst(
1124 self: *ZigObject,1135 self: *ZigObject,
1125 macho_file: *MachO,1136 macho_file: *MachO,
1137 pt: Zcu.PerThread,
1126 name: []const u8,1138 name: []const u8,
1127 val: Value,1139 val: Value,
1128 required_alignment: Atom.Alignment,1140 required_alignment: Atom.Alignment,
...@@ -1136,7 +1148,7 @@ fn lowerConst(...@@ -1136,7 +1148,7 @@ fn lowerConst(
11361148
1137 const sym_index = try self.addAtom(macho_file);1149 const sym_index = try self.addAtom(macho_file);
11381150
1139 const res = try codegen.generateSymbol(&macho_file.base, src_loc, val, &code_buffer, .{1151 const res = try codegen.generateSymbol(&macho_file.base, pt, src_loc, val, &code_buffer, .{
1140 .none = {},1152 .none = {},
1141 }, .{1153 }, .{
1142 .parent_atom_index = sym_index,1154 .parent_atom_index = sym_index,
...@@ -1181,13 +1193,14 @@ fn lowerConst(...@@ -1181,13 +1193,14 @@ fn lowerConst(
1181pub fn updateExports(1193pub fn updateExports(
1182 self: *ZigObject,1194 self: *ZigObject,
1183 macho_file: *MachO,1195 macho_file: *MachO,
1184 mod: *Module,1196 pt: Zcu.PerThread,
1185 exported: Module.Exported,1197 exported: Module.Exported,
1186 export_indices: []const u32,1198 export_indices: []const u32,
1187) link.File.UpdateExportsError!void {1199) link.File.UpdateExportsError!void {
1188 const tracy = trace(@src());1200 const tracy = trace(@src());
1189 defer tracy.end();1201 defer tracy.end();
11901202
1203 const mod = pt.zcu;
1191 const gpa = macho_file.base.comp.gpa;1204 const gpa = macho_file.base.comp.gpa;
1192 const metadata = switch (exported) {1205 const metadata = switch (exported) {
1193 .decl_index => |decl_index| blk: {1206 .decl_index => |decl_index| blk: {
...@@ -1196,7 +1209,7 @@ pub fn updateExports(...@@ -1196,7 +1209,7 @@ pub fn updateExports(
1196 },1209 },
1197 .value => |value| self.anon_decls.getPtr(value) orelse blk: {1210 .value => |value| self.anon_decls.getPtr(value) orelse blk: {
1198 const first_exp = mod.all_exports.items[export_indices[0]];1211 const first_exp = mod.all_exports.items[export_indices[0]];
1199 const res = try self.lowerAnonDecl(macho_file, value, .none, first_exp.src);1212 const res = try self.lowerAnonDecl(macho_file, pt, value, .none, first_exp.src);
1200 switch (res) {1213 switch (res) {
1201 .ok => {},1214 .ok => {},
1202 .fail => |em| {1215 .fail => |em| {
...@@ -1272,6 +1285,7 @@ pub fn updateExports(...@@ -1272,6 +1285,7 @@ pub fn updateExports(
1272fn updateLazySymbol(1285fn updateLazySymbol(
1273 self: *ZigObject,1286 self: *ZigObject,
1274 macho_file: *MachO,1287 macho_file: *MachO,
1288 pt: Zcu.PerThread,
1275 lazy_sym: link.File.LazySymbol,1289 lazy_sym: link.File.LazySymbol,
1276 symbol_index: Symbol.Index,1290 symbol_index: Symbol.Index,
1277) !void {1291) !void {
...@@ -1285,7 +1299,7 @@ fn updateLazySymbol(...@@ -1285,7 +1299,7 @@ fn updateLazySymbol(
1285 const name_str_index = blk: {1299 const name_str_index = blk: {
1286 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{1300 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
1287 @tagName(lazy_sym.kind),1301 @tagName(lazy_sym.kind),
1288 lazy_sym.ty.fmt(mod),1302 lazy_sym.ty.fmt(pt),
1289 });1303 });
1290 defer gpa.free(name);1304 defer gpa.free(name);
1291 break :blk try self.strtab.insert(gpa, name);1305 break :blk try self.strtab.insert(gpa, name);
...@@ -1294,6 +1308,7 @@ fn updateLazySymbol(...@@ -1294,6 +1308,7 @@ fn updateLazySymbol(
1294 const src = lazy_sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded;1308 const src = lazy_sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded;
1295 const res = try codegen.generateLazySymbol(1309 const res = try codegen.generateLazySymbol(
1296 &macho_file.base,1310 &macho_file.base,
1311 pt,
1297 src,1312 src,
1298 lazy_sym,1313 lazy_sym,
1299 &required_alignment,1314 &required_alignment,
...@@ -1431,10 +1446,11 @@ pub fn getOrCreateMetadataForDecl(...@@ -1431,10 +1446,11 @@ pub fn getOrCreateMetadataForDecl(
1431pub fn getOrCreateMetadataForLazySymbol(1446pub fn getOrCreateMetadataForLazySymbol(
1432 self: *ZigObject,1447 self: *ZigObject,
1433 macho_file: *MachO,1448 macho_file: *MachO,
1449 pt: Zcu.PerThread,
1434 lazy_sym: link.File.LazySymbol,1450 lazy_sym: link.File.LazySymbol,
1435) !Symbol.Index {1451) !Symbol.Index {
1436 const gpa = macho_file.base.comp.gpa;1452 const mod = pt.zcu;
1437 const mod = macho_file.base.comp.module.?;1453 const gpa = mod.gpa;
1438 const gop = try self.lazy_syms.getOrPut(gpa, lazy_sym.getDecl(mod));1454 const gop = try self.lazy_syms.getOrPut(gpa, lazy_sym.getDecl(mod));
1439 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();1455 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
1440 if (!gop.found_existing) gop.value_ptr.* = .{};1456 if (!gop.found_existing) gop.value_ptr.* = .{};
...@@ -1464,7 +1480,7 @@ pub fn getOrCreateMetadataForLazySymbol(...@@ -1464,7 +1480,7 @@ pub fn getOrCreateMetadataForLazySymbol(
1464 metadata.state.* = .pending_flush;1480 metadata.state.* = .pending_flush;
1465 const symbol_index = metadata.symbol_index.*;1481 const symbol_index = metadata.symbol_index.*;
1466 // anyerror needs to be deferred until flushModule1482 // anyerror needs to be deferred until flushModule
1467 if (lazy_sym.getDecl(mod) != .none) try self.updateLazySymbol(macho_file, lazy_sym, symbol_index);1483 if (lazy_sym.getDecl(mod) != .none) try self.updateLazySymbol(macho_file, pt, lazy_sym, symbol_index);
1468 return symbol_index;1484 return symbol_index;
1469}1485}
14701486
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+47-40
...@@ -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);
...@@ -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,7 +1496,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {...@@ -1490,7 +1496,7 @@ 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, mod: *Zcu, decl_index: InternPool.DeclIndex) !void {
1494 _ = self;1500 _ = self;
1495 _ = mod;1501 _ = mod;
1496 _ = decl_index;1502 _ = decl_index;
...@@ -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+25-26
...@@ -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,25 +1439,25 @@ pub fn deinit(wasm: *Wasm) void {...@@ -1441,25 +1439,25 @@ 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, mod: *Zcu, 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(mod, decl_index);
1465}1463}
...@@ -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,
...@@ -1531,11 +1529,12 @@ pub fn getDeclVAddr(...@@ -1531,11 +1529,12 @@ pub fn getDeclVAddr(
15311529
1532pub fn lowerAnonDecl(1530pub fn lowerAnonDecl(
1533 wasm: *Wasm,1531 wasm: *Wasm,
1532 pt: Zcu.PerThread,
1534 decl_val: InternPool.Index,1533 decl_val: InternPool.Index,
1535 explicit_alignment: Alignment,1534 explicit_alignment: Alignment,
1536 src_loc: Module.LazySrcLoc,1535 src_loc: Zcu.LazySrcLoc,
1537) !codegen.Result {1536) !codegen.Result {
1538 return wasm.zigObjectPtr().?.lowerAnonDecl(wasm, decl_val, explicit_alignment, src_loc);1537 return wasm.zigObjectPtr().?.lowerAnonDecl(wasm, pt, decl_val, explicit_alignment, src_loc);
1539}1538}
15401539
1541pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {1540pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
...@@ -1553,15 +1552,15 @@ pub fn deleteExport(...@@ -1553,15 +1552,15 @@ pub fn deleteExport(
15531552
1554pub fn updateExports(1553pub fn updateExports(
1555 wasm: *Wasm,1554 wasm: *Wasm,
1556 mod: *Module,1555 pt: Zcu.PerThread,
1557 exported: Module.Exported,1556 exported: Zcu.Exported,
1558 export_indices: []const u32,1557 export_indices: []const u32,
1559) !void {1558) !void {
1560 if (build_options.skip_non_native and builtin.object_format != .wasm) {1559 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");1560 @panic("Attempted to compile for object format that was disabled by build configuration");
1562 }1561 }
1563 if (wasm.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, export_indices);1562 if (wasm.llvm_object) |llvm_object| return llvm_object.updateExports(pt, exported, export_indices);
1564 return wasm.zigObjectPtr().?.updateExports(wasm, mod, exported, export_indices);1563 return wasm.zigObjectPtr().?.updateExports(wasm, pt, exported, export_indices);
1565}1564}
15661565
1567pub fn freeDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) void {1566pub fn freeDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) void {
...@@ -2466,18 +2465,18 @@ fn appendDummySegment(wasm: *Wasm) !void {...@@ -2466,18 +2465,18 @@ fn appendDummySegment(wasm: *Wasm) !void {
2466 });2465 });
2467}2466}
24682467
2469pub fn flush(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void {2468pub 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;2469 const comp = wasm.base.comp;
2471 const use_lld = build_options.have_llvm and comp.config.use_lld;2470 const use_lld = build_options.have_llvm and comp.config.use_lld;
24722471
2473 if (use_lld) {2472 if (use_lld) {
2474 return wasm.linkWithLLD(arena, prog_node);2473 return wasm.linkWithLLD(arena, tid, prog_node);
2475 }2474 }
2476 return wasm.flushModule(arena, prog_node);2475 return wasm.flushModule(arena, tid, prog_node);
2477}2476}
24782477
2479/// Uses the in-house linker to link one or multiple object -and archive files into a WebAssembly binary.2478/// 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 {2479pub fn flushModule(wasm: *Wasm, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
2481 const tracy = trace(@src());2480 const tracy = trace(@src());
2482 defer tracy.end();2481 defer tracy.end();
24832482
...@@ -2513,7 +2512,7 @@ pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node)...@@ -2513,7 +2512,7 @@ pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node)
2513 const wasi_exec_model = comp.config.wasi_exec_model;2512 const wasi_exec_model = comp.config.wasi_exec_model;
25142513
2515 if (wasm.zigObjectPtr()) |zig_object| {2514 if (wasm.zigObjectPtr()) |zig_object| {
2516 try zig_object.flushModule(wasm);2515 try zig_object.flushModule(wasm, tid);
2517 }2516 }
25182517
2519 // When the target os is WASI, we allow linking with WASI-LIBC2518 // When the target os is WASI, we allow linking with WASI-LIBC
...@@ -3324,7 +3323,7 @@ fn emitImport(wasm: *Wasm, writer: anytype, import: types.Import) !void {...@@ -3324,7 +3323,7 @@ fn emitImport(wasm: *Wasm, writer: anytype, import: types.Import) !void {
3324 }3323 }
3325}3324}
33263325
3327fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node) !void {3326fn linkWithLLD(wasm: *Wasm, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void {
3328 const tracy = trace(@src());3327 const tracy = trace(@src());
3329 defer tracy.end();3328 defer tracy.end();
33303329
...@@ -3342,7 +3341,7 @@ fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node) !voi...@@ -3342,7 +3341,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 it3341 // 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.3342 // will not be part of the linker line anyway.
3344 const module_obj_path: ?[]const u8 = if (comp.module != null) blk: {3343 const module_obj_path: ?[]const u8 = if (comp.module != null) blk: {
3345 try wasm.flushModule(arena, prog_node);3344 try wasm.flushModule(arena, tid, prog_node);
33463345
3347 if (fs.path.dirname(full_out_path)) |dirname| {3346 if (fs.path.dirname(full_out_path)) |dirname| {
3348 break :blk try fs.path.join(arena, &.{ dirname, wasm.base.zcu_object_sub_path.? });3347 break :blk try fs.path.join(arena, &.{ dirname, wasm.base.zcu_object_sub_path.? });
...@@ -4009,8 +4008,8 @@ pub fn storeDeclType(wasm: *Wasm, decl_index: InternPool.DeclIndex, func_type: s...@@ -4009,8 +4008,8 @@ pub fn storeDeclType(wasm: *Wasm, decl_index: InternPool.DeclIndex, func_type: s
4009/// Returns the symbol index of the error name table.4008/// Returns the symbol index of the error name table.
4010///4009///
4011/// When the symbol does not yet exist, it will create a new one instead.4010/// When the symbol does not yet exist, it will create a new one instead.
4012pub fn getErrorTableSymbol(wasm_file: *Wasm) !u32 {4011pub fn getErrorTableSymbol(wasm_file: *Wasm, pt: Zcu.PerThread) !u32 {
4013 const sym_index = try wasm_file.zigObjectPtr().?.getErrorTableSymbol(wasm_file);4012 const sym_index = try wasm_file.zigObjectPtr().?.getErrorTableSymbol(wasm_file, pt);
4014 return @intFromEnum(sym_index);4013 return @intFromEnum(sym_index);
4015}4014}
40164015
src/link/Wasm/ZigObject.zig+59-41
...@@ -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;
...@@ -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,21 +287,21 @@ pub fn updateDecl(...@@ -285,21 +287,21 @@ 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, decl_index);
304 const atom = wasm_file.getAtomPtr(atom_index);306 const atom = wasm_file.getAtomPtr(atom_index);
305 atom.clear();307 atom.clear();
...@@ -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(zcu);
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.
...@@ -437,9 +442,10 @@ pub fn getOrCreateAtomForDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_ind...@@ -437,9 +442,10 @@ pub fn getOrCreateAtomForDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_ind
437pub fn lowerAnonDecl(442pub fn lowerAnonDecl(
438 zig_object: *ZigObject,443 zig_object: *ZigObject,
439 wasm_file: *Wasm,444 wasm_file: *Wasm,
445 pt: Zcu.PerThread,
440 decl_val: InternPool.Index,446 decl_val: InternPool.Index,
441 explicit_alignment: InternPool.Alignment,447 explicit_alignment: InternPool.Alignment,
442 src_loc: Module.LazySrcLoc,448 src_loc: Zcu.LazySrcLoc,
443) !codegen.Result {449) !codegen.Result {
444 const gpa = wasm_file.base.comp.gpa;450 const gpa = wasm_file.base.comp.gpa;
445 const gop = try zig_object.anon_decls.getOrPut(gpa, decl_val);451 const gop = try zig_object.anon_decls.getOrPut(gpa, decl_val);
...@@ -449,7 +455,7 @@ pub fn lowerAnonDecl(...@@ -449,7 +455,7 @@ pub fn lowerAnonDecl(
449 @intFromEnum(decl_val),455 @intFromEnum(decl_val),
450 }) catch unreachable;456 }) catch unreachable;
451457
452 switch (try zig_object.lowerConst(wasm_file, name, Value.fromInterned(decl_val), src_loc)) {458 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,459 .ok => |atom_index| zig_object.anon_decls.values()[gop.index] = atom_index,
454 .fail => |em| return .{ .fail = em },460 .fail => |em| return .{ .fail = em },
455 }461 }
...@@ -469,9 +475,15 @@ pub fn lowerAnonDecl(...@@ -469,9 +475,15 @@ pub fn lowerAnonDecl(
469/// Lowers a constant typed value to a local symbol and atom.475/// Lowers a constant typed value to a local symbol and atom.
470/// Returns the symbol index of the local476/// Returns the symbol index of the local
471/// The given `decl` is the parent decl whom owns the constant.477/// 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 {478pub fn lowerUnnamedConst(
473 const gpa = wasm_file.base.comp.gpa;479 zig_object: *ZigObject,
474 const mod = wasm_file.base.comp.module.?;480 wasm_file: *Wasm,
481 pt: Zcu.PerThread,
482 val: Value,
483 decl_index: InternPool.DeclIndex,
484) !u32 {
485 const mod = pt.zcu;
486 const gpa = mod.gpa;
475 std.debug.assert(val.typeOf(mod).zigTypeTag(mod) != .Fn); // cannot create local symbols for functions487 std.debug.assert(val.typeOf(mod).zigTypeTag(mod) != .Fn); // cannot create local symbols for functions
476 const decl = mod.declPtr(decl_index);488 const decl = mod.declPtr(decl_index);
477489
...@@ -494,7 +506,7 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, val: Value, d...@@ -494,7 +506,7 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, val: Value, d
494 else506 else
495 decl.navSrcLoc(mod);507 decl.navSrcLoc(mod);
496508
497 switch (try zig_object.lowerConst(wasm_file, name, val, decl_src)) {509 switch (try zig_object.lowerConst(wasm_file, pt, name, val, decl_src)) {
498 .ok => |atom_index| {510 .ok => |atom_index| {
499 try wasm_file.getAtomPtr(parent_atom_index).locals.append(gpa, atom_index);511 try wasm_file.getAtomPtr(parent_atom_index).locals.append(gpa, atom_index);
500 return @intFromEnum(wasm_file.getAtom(atom_index).sym_index);512 return @intFromEnum(wasm_file.getAtom(atom_index).sym_index);
...@@ -509,10 +521,17 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, val: Value, d...@@ -509,10 +521,17 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, val: Value, d
509521
510const LowerConstResult = union(enum) {522const LowerConstResult = union(enum) {
511 ok: Atom.Index,523 ok: Atom.Index,
512 fail: *Module.ErrorMsg,524 fail: *Zcu.ErrorMsg,
513};525};
514526
515fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: Value, src_loc: Module.LazySrcLoc) !LowerConstResult {527fn lowerConst(
528 zig_object: *ZigObject,
529 wasm_file: *Wasm,
530 pt: Zcu.PerThread,
531 name: []const u8,
532 val: Value,
533 src_loc: Zcu.LazySrcLoc,
534) !LowerConstResult {
516 const gpa = wasm_file.base.comp.gpa;535 const gpa = wasm_file.base.comp.gpa;
517 const mod = wasm_file.base.comp.module.?;536 const mod = wasm_file.base.comp.module.?;
518537
...@@ -526,7 +545,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: V...@@ -526,7 +545,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: V
526545
527 const code = code: {546 const code = code: {
528 const atom = wasm_file.getAtomPtr(atom_index);547 const atom = wasm_file.getAtomPtr(atom_index);
529 atom.alignment = ty.abiAlignment(mod);548 atom.alignment = ty.abiAlignment(pt);
530 const segment_name = try std.mem.concat(gpa, u8, &.{ ".rodata.", name });549 const segment_name = try std.mem.concat(gpa, u8, &.{ ".rodata.", name });
531 errdefer gpa.free(segment_name);550 errdefer gpa.free(segment_name);
532 zig_object.symbol(sym_index).* = .{551 zig_object.symbol(sym_index).* = .{
...@@ -536,13 +555,14 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: V...@@ -536,13 +555,14 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: V
536 .index = try zig_object.createDataSegment(555 .index = try zig_object.createDataSegment(
537 gpa,556 gpa,
538 segment_name,557 segment_name,
539 ty.abiAlignment(mod),558 ty.abiAlignment(pt),
540 ),559 ),
541 .virtual_address = undefined,560 .virtual_address = undefined,
542 };561 };
543562
544 const result = try codegen.generateSymbol(563 const result = try codegen.generateSymbol(
545 &wasm_file.base,564 &wasm_file.base,
565 pt,
546 src_loc,566 src_loc,
547 val,567 val,
548 &value_bytes,568 &value_bytes,
...@@ -568,7 +588,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: V...@@ -568,7 +588,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: V
568/// Returns the symbol index of the error name table.588/// Returns the symbol index of the error name table.
569///589///
570/// When the symbol does not yet exist, it will create a new one instead.590/// 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 {591pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm, pt: Zcu.PerThread) !Symbol.Index {
572 if (zig_object.error_table_symbol != .null) {592 if (zig_object.error_table_symbol != .null) {
573 return zig_object.error_table_symbol;593 return zig_object.error_table_symbol;
574 }594 }
...@@ -581,8 +601,7 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !Symbol.Ind...@@ -581,8 +601,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);601 const atom_index = try wasm_file.createAtom(sym_index, zig_object.index);
582 const atom = wasm_file.getAtomPtr(atom_index);602 const atom = wasm_file.getAtomPtr(atom_index);
583 const slice_ty = Type.slice_const_u8_sentinel_0;603 const slice_ty = Type.slice_const_u8_sentinel_0;
584 const mod = wasm_file.base.comp.module.?;604 atom.alignment = slice_ty.abiAlignment(pt);
585 atom.alignment = slice_ty.abiAlignment(mod);
586605
587 const sym_name = try zig_object.string_table.insert(gpa, "__zig_err_name_table");606 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");607 const segment_name = try gpa.dupe(u8, ".rodata.__zig_err_name_table");
...@@ -604,7 +623,7 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !Symbol.Ind...@@ -604,7 +623,7 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !Symbol.Ind
604///623///
605/// This creates a table that consists of pointers and length to each error name.624/// 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.625/// The table is what is being pointed to within the runtime bodies that are generated.
607fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {626fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm, tid: Zcu.PerThread.Id) !void {
608 if (zig_object.error_table_symbol == .null) return;627 if (zig_object.error_table_symbol == .null) return;
609 const gpa = wasm_file.base.comp.gpa;628 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 }).?;629 const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = zig_object.error_table_symbol }).?;
...@@ -631,11 +650,11 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {...@@ -631,11 +650,11 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {
631650
632 // Addend for each relocation to the table651 // Addend for each relocation to the table
633 var addend: u32 = 0;652 var addend: u32 = 0;
634 const mod = wasm_file.base.comp.module.?;653 const pt: Zcu.PerThread = .{ .zcu = wasm_file.base.comp.module.?, .tid = tid };
635 for (mod.global_error_set.keys()) |error_name| {654 for (pt.zcu.global_error_set.keys()) |error_name| {
636 const atom = wasm_file.getAtomPtr(atom_index);655 const atom = wasm_file.getAtomPtr(atom_index);
637656
638 const error_name_slice = error_name.toSlice(&mod.intern_pool);657 const error_name_slice = error_name.toSlice(&pt.zcu.intern_pool);
639 const len: u32 = @intCast(error_name_slice.len + 1); // names are 0-terminated658 const len: u32 = @intCast(error_name_slice.len + 1); // names are 0-terminated
640659
641 const slice_ty = Type.slice_const_u8_sentinel_0;660 const slice_ty = Type.slice_const_u8_sentinel_0;
...@@ -650,14 +669,14 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {...@@ -650,14 +669,14 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {
650 .offset = offset,669 .offset = offset,
651 .addend = @intCast(addend),670 .addend = @intCast(addend),
652 });671 });
653 atom.size += @intCast(slice_ty.abiSize(mod));672 atom.size += @intCast(slice_ty.abiSize(pt));
654 addend += len;673 addend += len;
655674
656 // as we updated the error name table, we now store the actual name within the names atom675 // 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);676 try names_atom.code.ensureUnusedCapacity(gpa, len);
658 names_atom.code.appendSliceAssumeCapacity(error_name_slice[0..len]);677 names_atom.code.appendSliceAssumeCapacity(error_name_slice[0..len]);
659678
660 log.debug("Populated error name: '{}'", .{error_name.fmt(&mod.intern_pool)});679 log.debug("Populated error name: '{}'", .{error_name.fmt(&pt.zcu.intern_pool)});
661 }680 }
662 names_atom.size = addend;681 names_atom.size = addend;
663 zig_object.error_names_atom = names_atom_index;682 zig_object.error_names_atom = names_atom_index;
...@@ -858,10 +877,11 @@ pub fn deleteExport(...@@ -858,10 +877,11 @@ pub fn deleteExport(
858pub fn updateExports(877pub fn updateExports(
859 zig_object: *ZigObject,878 zig_object: *ZigObject,
860 wasm_file: *Wasm,879 wasm_file: *Wasm,
861 mod: *Module,880 pt: Zcu.PerThread,
862 exported: Module.Exported,881 exported: Zcu.Exported,
863 export_indices: []const u32,882 export_indices: []const u32,
864) !void {883) !void {
884 const mod = pt.zcu;
865 const decl_index = switch (exported) {885 const decl_index = switch (exported) {
866 .decl_index => |i| i,886 .decl_index => |i| i,
867 .value => |val| {887 .value => |val| {
...@@ -880,7 +900,7 @@ pub fn updateExports(...@@ -880,7 +900,7 @@ pub fn updateExports(
880 for (export_indices) |export_idx| {900 for (export_indices) |export_idx| {
881 const exp = mod.all_exports.items[export_idx];901 const exp = mod.all_exports.items[export_idx];
882 if (exp.opts.section.toSlice(&mod.intern_pool)) |section| {902 if (exp.opts.section.toSlice(&mod.intern_pool)) |section| {
883 try mod.failed_exports.putNoClobber(gpa, export_idx, try Module.ErrorMsg.create(903 try mod.failed_exports.putNoClobber(gpa, export_idx, try Zcu.ErrorMsg.create(
884 gpa,904 gpa,
885 decl.navSrcLoc(mod),905 decl.navSrcLoc(mod),
886 "Unimplemented: ExportOptions.section '{s}'",906 "Unimplemented: ExportOptions.section '{s}'",
...@@ -913,7 +933,7 @@ pub fn updateExports(...@@ -913,7 +933,7 @@ pub fn updateExports(
913 },933 },
914 .strong => {}, // symbols are strong by default934 .strong => {}, // symbols are strong by default
915 .link_once => {935 .link_once => {
916 try mod.failed_exports.putNoClobber(gpa, export_idx, try Module.ErrorMsg.create(936 try mod.failed_exports.putNoClobber(gpa, export_idx, try Zcu.ErrorMsg.create(
917 gpa,937 gpa,
918 decl.navSrcLoc(mod),938 decl.navSrcLoc(mod),
919 "Unimplemented: LinkOnce",939 "Unimplemented: LinkOnce",
...@@ -1096,7 +1116,7 @@ pub fn createDebugSectionForIndex(zig_object: *ZigObject, wasm_file: *Wasm, inde...@@ -1096,7 +1116,7 @@ pub fn createDebugSectionForIndex(zig_object: *ZigObject, wasm_file: *Wasm, inde
1096 return atom_index;1116 return atom_index;
1097}1117}
10981118
1099pub fn updateDeclLineNumber(zig_object: *ZigObject, mod: *Module, decl_index: InternPool.DeclIndex) !void {1119pub fn updateDeclLineNumber(zig_object: *ZigObject, mod: *Zcu, decl_index: InternPool.DeclIndex) !void {
1100 if (zig_object.dwarf) |*dw| {1120 if (zig_object.dwarf) |*dw| {
1101 const decl = mod.declPtr(decl_index);1121 const decl = mod.declPtr(decl_index);
1102 const decl_name = try decl.fullyQualifiedName(mod);1122 const decl_name = try decl.fullyQualifiedName(mod);
...@@ -1228,8 +1248,8 @@ fn appendFunction(zig_object: *ZigObject, gpa: std.mem.Allocator, func: std.wasm...@@ -1228,8 +1248,8 @@ fn appendFunction(zig_object: *ZigObject, gpa: std.mem.Allocator, func: std.wasm
1228 return index;1248 return index;
1229}1249}
12301250
1231pub fn flushModule(zig_object: *ZigObject, wasm_file: *Wasm) !void {1251pub fn flushModule(zig_object: *ZigObject, wasm_file: *Wasm, tid: Zcu.PerThread.Id) !void {
1232 try zig_object.populateErrorNameTable(wasm_file);1252 try zig_object.populateErrorNameTable(wasm_file, tid);
1233 try zig_object.setupErrorsLen(wasm_file);1253 try zig_object.setupErrorsLen(wasm_file);
1234}1254}
12351255
...@@ -1248,8 +1268,6 @@ const File = @import("file.zig").File;...@@ -1248,8 +1268,6 @@ const File = @import("file.zig").File;
1248const InternPool = @import("../../InternPool.zig");1268const InternPool = @import("../../InternPool.zig");
1249const Liveness = @import("../../Liveness.zig");1269const Liveness = @import("../../Liveness.zig");
1250const Zcu = @import("../../Zcu.zig");1270const Zcu = @import("../../Zcu.zig");
1251/// Deprecated.
1252const Module = Zcu;
1253const StringTable = @import("../StringTable.zig");1271const StringTable = @import("../StringTable.zig");
1254const Symbol = @import("Symbol.zig");1272const Symbol = @import("Symbol.zig");
1255const Type = @import("../../Type.zig");1273const Type = @import("../../Type.zig");
src/main.zig+4-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;
...@@ -3092,7 +3092,7 @@ fn buildOutputType(...@@ -3092,7 +3092,7 @@ fn buildOutputType(
3092 defer emit_implib_resolved.deinit();3092 defer emit_implib_resolved.deinit();
30933093
3094 var thread_pool: ThreadPool = undefined;3094 var thread_pool: ThreadPool = undefined;
3095 try thread_pool.init(.{ .allocator = gpa });3095 try thread_pool.init(.{ .allocator = gpa, .track_ids = true });
3096 defer thread_pool.deinit();3096 defer thread_pool.deinit();
30973097
3098 var cleanup_local_cache_dir: ?fs.Dir = null;3098 var cleanup_local_cache_dir: ?fs.Dir = null;
...@@ -4895,7 +4895,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -4895,7 +4895,7 @@ 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;4895 child_argv.items[argv_index_cache_dir] = local_cache_directory.path orelse cwd_path;
48964896
4897 var thread_pool: ThreadPool = undefined;4897 var thread_pool: ThreadPool = undefined;
4898 try thread_pool.init(.{ .allocator = gpa });4898 try thread_pool.init(.{ .allocator = gpa, .track_ids = true });
4899 defer thread_pool.deinit();4899 defer thread_pool.deinit();
49004900
4901 // Dummy http client that is not actually used when only_core_functionality is enabled.4901 // Dummy http client that is not actually used when only_core_functionality is enabled.
...@@ -5329,7 +5329,7 @@ fn jitCmd(...@@ -5329,7 +5329,7 @@ fn jitCmd(
5329 defer global_cache_directory.handle.close();5329 defer global_cache_directory.handle.close();
53305330
5331 var thread_pool: ThreadPool = undefined;5331 var thread_pool: ThreadPool = undefined;
5332 try thread_pool.init(.{ .allocator = gpa });5332 try thread_pool.init(.{ .allocator = gpa, .track_ids = true });
5333 defer thread_pool.deinit();5333 defer thread_pool.deinit();
53345334
5335 var child_argv: std.ArrayListUnmanaged([]const u8) = .{};5335 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, 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;