authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-12-31 11:47:56+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-12-31 11:47:56+02:00
logaf197d495478f7a5c33a6550d5525e86d797dc89
treef7ef9ac5dd3131eca188e3e4bbcba4dc16fdd802
parentd86685ac9612c08e33f1d94f7f617d9c0da1b7bd
parentbd711dfd255447883d25f422031592e3824ca296
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #14130 from Vexu/debug-info

Debug info fixes

13 files changed, 86 insertions(+), 45 deletions(-)

src/Air.zig+7-2
...@@ -31,7 +31,7 @@ pub const Inst = struct {...@@ -31,7 +31,7 @@ pub const Inst = struct {
31 /// The first N instructions in the main block must be one arg instruction per31 /// The first N instructions in the main block must be one arg instruction per
32 /// function parameter. This makes function parameters participate in32 /// function parameter. This makes function parameters participate in
33 /// liveness analysis without any special handling.33 /// liveness analysis without any special handling.
34 /// Uses the `ty` field.34 /// Uses the `arg` field.
35 arg,35 arg,
36 /// Float or integer addition. For integers, wrapping is undefined behavior.36 /// Float or integer addition. For integers, wrapping is undefined behavior.
37 /// Both operands are guaranteed to be the same type, and the result type37 /// Both operands are guaranteed to be the same type, and the result type
...@@ -795,6 +795,10 @@ pub const Inst = struct {...@@ -795,6 +795,10 @@ pub const Inst = struct {
795 rhs: Ref,795 rhs: Ref,
796 },796 },
797 ty: Type,797 ty: Type,
798 arg: struct {
799 ty: Ref,
800 src_index: u32,
801 },
798 ty_op: struct {802 ty_op: struct {
799 ty: Ref,803 ty: Ref,
800 operand: Ref,804 operand: Ref,
...@@ -1103,11 +1107,12 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {...@@ -1103,11 +1107,12 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
11031107
1104 .alloc,1108 .alloc,
1105 .ret_ptr,1109 .ret_ptr,
1106 .arg,
1107 .err_return_trace,1110 .err_return_trace,
1108 .c_va_start,1111 .c_va_start,
1109 => return datas[inst].ty,1112 => return datas[inst].ty,
11101113
1114 .arg => return air.getRefType(datas[inst].arg.ty),
1115
1111 .assembly,1116 .assembly,
1112 .block,1117 .block,
1113 .constant,1118 .constant,
src/AstGen.zig+8-2
...@@ -6942,7 +6942,13 @@ fn switchExpr(...@@ -6942,7 +6942,13 @@ fn switchExpr(
6942 // it as the break operand.6942 // it as the break operand.
6943 if (body_len < 2)6943 if (body_len < 2)
6944 break :blk;6944 break :blk;
6945 const store_inst = payloads.items[end_index - 2];6945
6946 var store_index = end_index - 2;
6947 while (true) : (store_index -= 1) switch (zir_tags[payloads.items[store_index]]) {
6948 .dbg_block_end, .dbg_block_begin, .dbg_stmt, .dbg_var_val, .dbg_var_ptr => {},
6949 else => break,
6950 };
6951 const store_inst = payloads.items[store_index];
6946 if (zir_tags[store_inst] != .store_to_block_ptr or6952 if (zir_tags[store_inst] != .store_to_block_ptr or
6947 zir_datas[store_inst].bin.lhs != block_scope.rl_ptr)6953 zir_datas[store_inst].bin.lhs != block_scope.rl_ptr)
6948 break :blk;6954 break :blk;
...@@ -12150,7 +12156,7 @@ const GenZir = struct {...@@ -12150,7 +12156,7 @@ const GenZir = struct {
1215012156
12151 const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);12157 const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
12152 try gz.astgen.instructions.append(gpa, .{ .tag = .dbg_block_end, .data = undefined });12158 try gz.astgen.instructions.append(gpa, .{ .tag = .dbg_block_end, .data = undefined });
12153 try gz.instructions.insert(gpa, gz.instructions.items.len - 1, new_index);12159 try gz.instructions.append(gpa, new_index);
12154 }12160 }
12155};12161};
1215612162
src/Module.zig+5-1
...@@ -5672,11 +5672,15 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {...@@ -5672,11 +5672,15 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {
5672 runtime_param_index += 1;5672 runtime_param_index += 1;
5673 continue;5673 continue;
5674 }5674 }
5675 const air_ty = try sema.addType(param_ty);
5675 const arg_index = @intCast(u32, sema.air_instructions.len);5676 const arg_index = @intCast(u32, sema.air_instructions.len);
5676 inner_block.instructions.appendAssumeCapacity(arg_index);5677 inner_block.instructions.appendAssumeCapacity(arg_index);
5677 sema.air_instructions.appendAssumeCapacity(.{5678 sema.air_instructions.appendAssumeCapacity(.{
5678 .tag = .arg,5679 .tag = .arg,
5679 .data = .{ .ty = param_ty },5680 .data = .{ .arg = .{
5681 .ty = air_ty,
5682 .src_index = @intCast(u32, total_param_index),
5683 } },
5680 });5684 });
5681 sema.inst_map.putAssumeCapacityNoClobber(inst, Air.indexToRef(arg_index));5685 sema.inst_map.putAssumeCapacityNoClobber(inst, Air.indexToRef(arg_index));
5682 total_param_index += 1;5686 total_param_index += 1;
src/Sema.zig+7-8
...@@ -476,13 +476,6 @@ pub const Block = struct {...@@ -476,13 +476,6 @@ pub const Block = struct {
476 });476 });
477 }477 }
478478
479 fn addArg(block: *Block, ty: Type) error{OutOfMemory}!Air.Inst.Ref {
480 return block.addInst(.{
481 .tag = .arg,
482 .data = .{ .ty = ty },
483 });
484 }
485
486 fn addStructFieldPtr(479 fn addStructFieldPtr(
487 block: *Block,480 block: *Block,
488 struct_ptr: Air.Inst.Ref,481 struct_ptr: Air.Inst.Ref,
...@@ -7258,7 +7251,13 @@ fn instantiateGenericCall(...@@ -7258,7 +7251,13 @@ fn instantiateGenericCall(
7258 } else {7251 } else {
7259 // We insert into the map an instruction which is runtime-known7252 // We insert into the map an instruction which is runtime-known
7260 // but has the type of the argument.7253 // but has the type of the argument.
7261 const child_arg = try child_block.addArg(arg_ty);7254 const child_arg = try child_block.addInst(.{
7255 .tag = .arg,
7256 .data = .{ .arg = .{
7257 .ty = try child_sema.addType(arg_ty),
7258 .src_index = @intCast(u32, arg_i),
7259 } },
7260 });
7262 child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);7261 child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);
7263 }7262 }
7264 }7263 }
src/arch/aarch64/CodeGen.zig+2-1
...@@ -4158,7 +4158,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -4158,7 +4158,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
41584158
4159 const ty = self.air.typeOfIndex(inst);4159 const ty = self.air.typeOfIndex(inst);
4160 const result = self.args[arg_index];4160 const result = self.args[arg_index];
4161 const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg_index);4161 const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
4162 const name = self.mod_fn.getParamName(self.bin_file.options.module.?, src_index);
41624163
4163 const mcv = switch (result) {4164 const mcv = switch (result) {
4164 // Copy registers to the stack4165 // Copy registers to the stack
src/arch/arm/CodeGen.zig+3-2
...@@ -4037,8 +4037,9 @@ fn genInlineMemsetCode(...@@ -4037,8 +4037,9 @@ fn genInlineMemsetCode(
40374037
4038fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, arg_index: u32) error{OutOfMemory}!void {4038fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, arg_index: u32) error{OutOfMemory}!void {
4039 const mcv = self.args[arg_index];4039 const mcv = self.args[arg_index];
4040 const ty = self.air.instructions.items(.data)[inst].ty;4040 const arg = self.air.instructions.items(.data)[inst].arg;
4041 const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg_index);4041 const ty = self.air.getRefType(arg.ty);
4042 const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg.src_index);
40424043
4043 switch (self.debug_output) {4044 switch (self.debug_output) {
4044 .dwarf => |dw| {4045 .dwarf => |dw| {
src/arch/riscv64/CodeGen.zig+5-4
...@@ -1608,9 +1608,10 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1608,9 +1608,10 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
1608 return self.fail("TODO implement codegen airFieldParentPtr", .{});1608 return self.fail("TODO implement codegen airFieldParentPtr", .{});
1609}1609}
16101610
1611fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue, arg_index: u32) !void {1611fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
1612 const ty = self.air.instructions.items(.data)[inst].ty;1612 const arg = self.air.instructions.items(.data)[inst].arg;
1613 const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg_index);1613 const ty = self.air.getRefType(arg.ty);
1614 const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg.src_index);
16141615
1615 switch (self.debug_output) {1616 switch (self.debug_output) {
1616 .dwarf => |dw| switch (mcv) {1617 .dwarf => |dw| switch (mcv) {
...@@ -1640,7 +1641,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -1640,7 +1641,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
1640 // TODO support stack-only arguments1641 // TODO support stack-only arguments
1641 // TODO Copy registers to the stack1642 // TODO Copy registers to the stack
1642 const mcv = result;1643 const mcv = result;
1643 try self.genArgDbgInfo(inst, mcv, @intCast(u32, arg_index));1644 try self.genArgDbgInfo(inst, mcv);
16441645
1645 if (self.liveness.isUnused(inst))1646 if (self.liveness.isUnused(inst))
1646 return self.finishAirBookkeeping();1647 return self.finishAirBookkeeping();
src/arch/sparc64/CodeGen.zig+5-4
...@@ -1016,7 +1016,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -1016,7 +1016,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
1016 }1016 }
1017 };1017 };
10181018
1019 try self.genArgDbgInfo(inst, mcv, @intCast(u32, arg_index));1019 try self.genArgDbgInfo(inst, mcv);
10201020
1021 if (self.liveness.isUnused(inst))1021 if (self.liveness.isUnused(inst))
1022 return self.finishAirBookkeeping();1022 return self.finishAirBookkeeping();
...@@ -3407,9 +3407,10 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live...@@ -3407,9 +3407,10 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
3407 self.finishAirBookkeeping();3407 self.finishAirBookkeeping();
3408}3408}
34093409
3410fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue, arg_index: u32) !void {3410fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
3411 const ty = self.air.instructions.items(.data)[inst].ty;3411 const arg = self.air.instructions.items(.data)[inst].arg;
3412 const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg_index);3412 const ty = self.air.getRefType(arg.ty);
3413 const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg.src_index);
34133414
3414 switch (self.debug_output) {3415 switch (self.debug_output) {
3415 .dwarf => |dw| switch (mcv) {3416 .dwarf => |dw| switch (mcv) {
src/arch/wasm/CodeGen.zig+2-2
...@@ -2474,8 +2474,8 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2474,8 +2474,8 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
24742474
2475 switch (func.debug_output) {2475 switch (func.debug_output) {
2476 .dwarf => |dwarf| {2476 .dwarf => |dwarf| {
2477 // TODO: Get the original arg index rather than wasm arg index2477 const src_index = func.air.instructions.items(.data)[inst].arg.src_index;
2478 const name = func.mod_fn.getParamName(func.bin_file.base.options.module.?, arg_index);2478 const name = func.mod_fn.getParamName(func.bin_file.base.options.module.?, src_index);
2479 try dwarf.genArgDbgInfo(name, arg_ty, .wasm, func.mod_fn.owner_decl, .{2479 try dwarf.genArgDbgInfo(name, arg_ty, .wasm, func.mod_fn.owner_decl, .{
2480 .wasm_local = arg.local.value,2480 .wasm_local = arg.local.value,
2481 });2481 });
src/arch/x86_64/CodeGen.zig+2-1
...@@ -3799,7 +3799,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -3799,7 +3799,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
37993799
3800 const ty = self.air.typeOfIndex(inst);3800 const ty = self.air.typeOfIndex(inst);
3801 const mcv = self.args[arg_index];3801 const mcv = self.args[arg_index];
3802 const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg_index);3802 const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
3803 const name = self.mod_fn.getParamName(self.bin_file.options.module.?, src_index);
38033804
3804 if (self.liveness.isUnused(inst))3805 if (self.liveness.isUnused(inst))
3805 return self.finishAirBookkeeping();3806 return self.finishAirBookkeeping();
src/codegen/llvm.zig+31-16
...@@ -1459,7 +1459,8 @@ pub const Object = struct {...@@ -1459,7 +1459,8 @@ pub const Object = struct {
1459 .signed => DW.ATE.signed,1459 .signed => DW.ATE.signed,
1460 .unsigned => DW.ATE.unsigned,1460 .unsigned => DW.ATE.unsigned,
1461 };1461 };
1462 const di_type = dib.createBasicType(name, info.bits, dwarf_encoding);1462 const di_bits = ty.abiSize(target) * 8; // lldb cannot handle non-byte sized types
1463 const di_type = dib.createBasicType(name, di_bits, dwarf_encoding);
1463 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);1464 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
1464 return di_type;1465 return di_type;
1465 },1466 },
...@@ -1550,7 +1551,8 @@ pub const Object = struct {...@@ -1550,7 +1551,8 @@ pub const Object = struct {
1550 return di_type;1551 return di_type;
1551 },1552 },
1552 .Bool => {1553 .Bool => {
1553 const di_type = dib.createBasicType("bool", 1, DW.ATE.boolean);1554 const di_bits = 8; // lldb cannot handle non-byte sized types
1555 const di_type = dib.createBasicType("bool", di_bits, DW.ATE.boolean);
1554 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);1556 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
1555 return di_type;1557 return di_type;
1556 },1558 },
...@@ -1723,10 +1725,31 @@ pub const Object = struct {...@@ -1723,10 +1725,31 @@ pub const Object = struct {
1723 return array_di_ty;1725 return array_di_ty;
1724 },1726 },
1725 .Vector => {1727 .Vector => {
1728 const elem_ty = ty.elemType2();
1729 // Vector elements cannot be padded since that would make
1730 // @bitSizOf(elem) * len > @bitSizOf(vec).
1731 // Neither gdb nor lldb seem to be able to display non-byte sized
1732 // vectors properly.
1733 const elem_di_type = switch (elem_ty.zigTypeTag()) {
1734 .Int => blk: {
1735 const info = elem_ty.intInfo(target);
1736 assert(info.bits != 0);
1737 const name = try ty.nameAlloc(gpa, o.module);
1738 defer gpa.free(name);
1739 const dwarf_encoding: c_uint = switch (info.signedness) {
1740 .signed => DW.ATE.signed,
1741 .unsigned => DW.ATE.unsigned,
1742 };
1743 break :blk dib.createBasicType(name, info.bits, dwarf_encoding);
1744 },
1745 .Bool => dib.createBasicType("bool", 1, DW.ATE.boolean),
1746 else => try o.lowerDebugType(ty.childType(), .full),
1747 };
1748
1726 const vector_di_ty = dib.createVectorType(1749 const vector_di_ty = dib.createVectorType(
1727 ty.abiSize(target) * 8,1750 ty.abiSize(target) * 8,
1728 ty.abiAlignment(target) * 8,1751 ty.abiAlignment(target) * 8,
1729 try o.lowerDebugType(ty.childType(), .full),1752 elem_di_type,
1730 ty.vectorLen(),1753 ty.vectorLen(),
1731 );1754 );
1732 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1755 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
...@@ -1739,7 +1762,8 @@ pub const Object = struct {...@@ -1739,7 +1762,8 @@ pub const Object = struct {
1739 var buf: Type.Payload.ElemType = undefined;1762 var buf: Type.Payload.ElemType = undefined;
1740 const child_ty = ty.optionalChild(&buf);1763 const child_ty = ty.optionalChild(&buf);
1741 if (!child_ty.hasRuntimeBitsIgnoreComptime()) {1764 if (!child_ty.hasRuntimeBitsIgnoreComptime()) {
1742 const di_ty = dib.createBasicType(name, 1, DW.ATE.boolean);1765 const di_bits = 8; // lldb cannot handle non-byte sized types
1766 const di_ty = dib.createBasicType(name, di_bits, DW.ATE.boolean);
1743 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);1767 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
1744 return di_ty;1768 return di_ty;
1745 }1769 }
...@@ -1934,7 +1958,8 @@ pub const Object = struct {...@@ -1934,7 +1958,8 @@ pub const Object = struct {
1934 .signed => DW.ATE.signed,1958 .signed => DW.ATE.signed,
1935 .unsigned => DW.ATE.unsigned,1959 .unsigned => DW.ATE.unsigned,
1936 };1960 };
1937 const di_ty = dib.createBasicType(name, info.bits, dwarf_encoding);1961 const di_bits = ty.abiSize(target) * 8; // lldb cannot handle non-byte sized types
1962 const di_ty = dib.createBasicType(name, di_bits, dwarf_encoding);
1938 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);1963 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
1939 return di_ty;1964 return di_ty;
1940 }1965 }
...@@ -8062,7 +8087,7 @@ pub const FuncGen = struct {...@@ -8062,7 +8087,7 @@ pub const FuncGen = struct {
8062 return arg_val;8087 return arg_val;
8063 }8088 }
80648089
8065 const src_index = self.getSrcArgIndex(self.arg_index - 1);8090 const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
8066 const func = self.dg.decl.getFunction().?;8091 const func = self.dg.decl.getFunction().?;
8067 const lbrace_line = self.dg.module.declPtr(func.owner_decl).src_line + func.lbrace_line + 1;8092 const lbrace_line = self.dg.module.declPtr(func.owner_decl).src_line + func.lbrace_line + 1;
8068 const lbrace_col = func.lbrace_column + 1;8093 const lbrace_col = func.lbrace_column + 1;
...@@ -8095,16 +8120,6 @@ pub const FuncGen = struct {...@@ -8095,16 +8120,6 @@ pub const FuncGen = struct {
8095 return arg_val;8120 return arg_val;
8096 }8121 }
80978122
8098 fn getSrcArgIndex(self: *FuncGen, runtime_index: u32) u32 {
8099 const fn_info = self.dg.decl.ty.fnInfo();
8100 var i: u32 = 0;
8101 for (fn_info.param_types) |param_ty, src_index| {
8102 if (!param_ty.hasRuntimeBitsIgnoreComptime()) continue;
8103 if (i == runtime_index) return @intCast(u32, src_index);
8104 i += 1;
8105 } else unreachable;
8106 }
8107
8108 fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8123 fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8109 if (self.liveness.isUnused(inst)) return null;8124 if (self.liveness.isUnused(inst)) return null;
8110 const ptr_ty = self.air.typeOfIndex(inst);8125 const ptr_ty = self.air.typeOfIndex(inst);
src/link/SpirV.zig+1-1
...@@ -314,7 +314,7 @@ fn cloneAir(air: Air, gpa: Allocator, air_arena: Allocator) !Air {...@@ -314,7 +314,7 @@ fn cloneAir(air: Air, gpa: Allocator, air_arena: Allocator) !Air {
314314
315 for (air_tags) |tag, i| {315 for (air_tags) |tag, i| {
316 switch (tag) {316 switch (tag) {
317 .arg, .alloc, .ret_ptr, .const_ty => air_datas[i].ty = try air_datas[i].ty.copy(air_arena),317 .alloc, .ret_ptr, .const_ty => air_datas[i].ty = try air_datas[i].ty.copy(air_arena),
318 else => {},318 else => {},
319 }319 }
320 }320 }
src/print_air.zig+8-1
...@@ -204,11 +204,12 @@ const Writer = struct {...@@ -204,11 +204,12 @@ const Writer = struct {
204 .const_ty,204 .const_ty,
205 .alloc,205 .alloc,
206 .ret_ptr,206 .ret_ptr,
207 .arg,
208 .err_return_trace,207 .err_return_trace,
209 .c_va_start,208 .c_va_start,
210 => try w.writeTy(s, inst),209 => try w.writeTy(s, inst),
211210
211 .arg => try w.writeArg(s, inst),
212
212 .not,213 .not,
213 .bitcast,214 .bitcast,
214 .load,215 .load,
...@@ -351,6 +352,12 @@ const Writer = struct {...@@ -351,6 +352,12 @@ const Writer = struct {
351 try w.writeType(s, ty);352 try w.writeType(s, ty);
352 }353 }
353354
355 fn writeArg(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
356 const arg = w.air.instructions.items(.data)[inst].arg;
357 try w.writeType(s, w.air.getRefType(arg.ty));
358 try s.print(", {d}", .{arg.src_index});
359 }
360
354 fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {361 fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
355 const ty_op = w.air.instructions.items(.data)[inst].ty_op;362 const ty_op = w.air.instructions.items(.data)[inst].ty_op;
356 try w.writeType(s, w.air.getRefType(ty_op.ty));363 try w.writeType(s, w.air.getRefType(ty_op.ty));