authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-03-02 19:49:20+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-03-02 21:19:34-08:00
logaa688567f556f9d24cae25f087adf90d96f6906f
tree80482843f4312873cc980e02fce787a0db47e45a
parent671c2acf47d17551266f3760698181c83cd96090

Air: replace `.dbg_inline_*` with `.dbg_inline_block`

This prevents the possibility of not emitting a `.dbg_inline_end` instruction and reduces the allocation requirements of the backends. Closes #19093

15 files changed, 414 insertions(+), 345 deletions(-)

src/Air.zig+11-14
...@@ -443,12 +443,9 @@ pub const Inst = struct {...@@ -443,12 +443,9 @@ pub const Inst = struct {
443 /// Result type is always void.443 /// Result type is always void.
444 /// Uses the `dbg_stmt` field.444 /// Uses the `dbg_stmt` field.
445 dbg_stmt,445 dbg_stmt,
446 /// Marks the start of an inline call.446 /// A block that represents an inlined function call.
447 /// Uses the `ty_fn` field.447 /// Uses the `ty_pl` field. Payload is `DbgInlineBlock`.
448 dbg_inline_begin,448 dbg_inline_block,
449 /// Marks the end of an inline call.
450 /// Uses the `ty_fn` field.
451 dbg_inline_end,
452 /// Marks the beginning of a local variable. The operand is a pointer pointing449 /// Marks the beginning of a local variable. The operand is a pointer pointing
453 /// to the storage for the variable. The local may be a const or a var.450 /// to the storage for the variable. The local may be a const or a var.
454 /// Result type is always void.451 /// Result type is always void.
...@@ -1051,10 +1048,6 @@ pub const Inst = struct {...@@ -1051,10 +1048,6 @@ pub const Inst = struct {
1051 // Index into a different array.1048 // Index into a different array.
1052 payload: u32,1049 payload: u32,
1053 },1050 },
1054 ty_fn: struct {
1055 ty: Ref,
1056 func: InternPool.Index,
1057 },
1058 br: struct {1051 br: struct {
1059 block_inst: Index,1052 block_inst: Index,
1060 operand: Ref,1053 operand: Ref,
...@@ -1117,6 +1110,12 @@ pub const Block = struct {...@@ -1117,6 +1110,12 @@ pub const Block = struct {
1117 body_len: u32,1110 body_len: u32,
1118};1111};
11191112
1113/// Trailing is a list of instruction indexes for every `body_len`.
1114pub const DbgInlineBlock = struct {
1115 func: InternPool.Index,
1116 body_len: u32,
1117};
1118
1120/// Trailing is a list of `Inst.Ref` for every `args_len`.1119/// Trailing is a list of `Inst.Ref` for every `args_len`.
1121pub const Call = struct {1120pub const Call = struct {
1122 args_len: u32,1121 args_len: u32,
...@@ -1371,6 +1370,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)...@@ -1371,6 +1370,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)
13711370
1372 .assembly,1371 .assembly,
1373 .block,1372 .block,
1373 .dbg_inline_block,
1374 .struct_field_ptr,1374 .struct_field_ptr,
1375 .struct_field_val,1375 .struct_field_val,
1376 .slice_elem_ptr,1376 .slice_elem_ptr,
...@@ -1448,8 +1448,6 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)...@@ -1448,8 +1448,6 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)
14481448
1449 .breakpoint,1449 .breakpoint,
1450 .dbg_stmt,1450 .dbg_stmt,
1451 .dbg_inline_begin,
1452 .dbg_inline_end,
1453 .dbg_var_ptr,1451 .dbg_var_ptr,
1454 .dbg_var_val,1452 .dbg_var_val,
1455 .store,1453 .store,
...@@ -1606,8 +1604,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool {...@@ -1606,8 +1604,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool {
1606 .@"try",1604 .@"try",
1607 .try_ptr,1605 .try_ptr,
1608 .dbg_stmt,1606 .dbg_stmt,
1609 .dbg_inline_begin,1607 .dbg_inline_block,
1610 .dbg_inline_end,
1611 .dbg_var_ptr,1608 .dbg_var_ptr,
1612 .dbg_var_val,1609 .dbg_var_val,
1613 .ret,1610 .ret,
src/Liveness.zig+25-14
...@@ -327,8 +327,6 @@ pub fn categorizeOperand(...@@ -327,8 +327,6 @@ pub fn categorizeOperand(
327 .trap,327 .trap,
328 .breakpoint,328 .breakpoint,
329 .dbg_stmt,329 .dbg_stmt,
330 .dbg_inline_begin,
331 .dbg_inline_end,
332 .unreach,330 .unreach,
333 .ret_addr,331 .ret_addr,
334 .frame_addr,332 .frame_addr,
...@@ -604,9 +602,19 @@ pub fn categorizeOperand(...@@ -604,9 +602,19 @@ pub fn categorizeOperand(
604 .assembly => {602 .assembly => {
605 return .complex;603 return .complex;
606 },604 },
607 .block => {605 .block, .dbg_inline_block => |tag| {
608 const extra = air.extraData(Air.Block, air_datas[@intFromEnum(inst)].ty_pl.payload);606 const ty_pl = air_datas[@intFromEnum(inst)].ty_pl;
609 const body: []const Air.Inst.Index = @ptrCast(air.extra[extra.end..][0..extra.data.body_len]);607 const body: []const Air.Inst.Index = @ptrCast(switch (tag) {
608 inline .block, .dbg_inline_block => |comptime_tag| body: {
609 const extra = air.extraData(switch (comptime_tag) {
610 .block => Air.Block,
611 .dbg_inline_block => Air.DbgInlineBlock,
612 else => unreachable,
613 }, ty_pl.payload);
614 break :body air.extra[extra.end..][0..extra.data.body_len];
615 },
616 else => unreachable,
617 });
610618
611 if (body.len == 1 and air_tags[@intFromEnum(body[0])] == .cond_br) {619 if (body.len == 1 and air_tags[@intFromEnum(body[0])] == .cond_br) {
612 // Peephole optimization for "panic-like" conditionals, which have620 // Peephole optimization for "panic-like" conditionals, which have
...@@ -963,8 +971,6 @@ fn analyzeInst(...@@ -963,8 +971,6 @@ fn analyzeInst(
963 .ret_ptr,971 .ret_ptr,
964 .breakpoint,972 .breakpoint,
965 .dbg_stmt,973 .dbg_stmt,
966 .dbg_inline_begin,
967 .dbg_inline_end,
968 .fence,974 .fence,
969 .ret_addr,975 .ret_addr,
970 .frame_addr,976 .frame_addr,
...@@ -1235,7 +1241,15 @@ fn analyzeInst(...@@ -1235,7 +1241,15 @@ fn analyzeInst(
1235 return big.finish();1241 return big.finish();
1236 },1242 },
12371243
1238 .block => return analyzeInstBlock(a, pass, data, inst),1244 inline .block, .dbg_inline_block => |comptime_tag| {
1245 const ty_pl = inst_datas[@intFromEnum(inst)].ty_pl;
1246 const extra = a.air.extraData(switch (comptime_tag) {
1247 .block => Air.Block,
1248 .dbg_inline_block => Air.DbgInlineBlock,
1249 else => unreachable,
1250 }, ty_pl.payload);
1251 return analyzeInstBlock(a, pass, data, inst, ty_pl.ty, @ptrCast(a.air.extra[extra.end..][0..extra.data.body_len]));
1252 },
1239 .loop => return analyzeInstLoop(a, pass, data, inst),1253 .loop => return analyzeInstLoop(a, pass, data, inst),
12401254
1241 .@"try" => return analyzeInstCondBr(a, pass, data, inst, .@"try"),1255 .@"try" => return analyzeInstCondBr(a, pass, data, inst, .@"try"),
...@@ -1369,12 +1383,9 @@ fn analyzeInstBlock(...@@ -1369,12 +1383,9 @@ fn analyzeInstBlock(
1369 comptime pass: LivenessPass,1383 comptime pass: LivenessPass,
1370 data: *LivenessPassData(pass),1384 data: *LivenessPassData(pass),
1371 inst: Air.Inst.Index,1385 inst: Air.Inst.Index,
1386 ty: Air.Inst.Ref,
1387 body: []const Air.Inst.Index,
1372) !void {1388) !void {
1373 const inst_datas = a.air.instructions.items(.data);
1374 const ty_pl = inst_datas[@intFromEnum(inst)].ty_pl;
1375 const extra = a.air.extraData(Air.Block, ty_pl.payload);
1376 const body: []const Air.Inst.Index = @ptrCast(a.air.extra[extra.end..][0..extra.data.body_len]);
1377
1378 const gpa = a.gpa;1389 const gpa = a.gpa;
13791390
1380 // We actually want to do `analyzeOperands` *first*, since our result logically doesn't1391 // We actually want to do `analyzeOperands` *first*, since our result logically doesn't
...@@ -1403,7 +1414,7 @@ fn analyzeInstBlock(...@@ -1403,7 +1414,7 @@ fn analyzeInstBlock(
14031414
1404 // If the block is noreturn, block deaths not only aren't useful, they're impossible to1415 // If the block is noreturn, block deaths not only aren't useful, they're impossible to
1405 // find: there could be more stuff alive after the block than before it!1416 // find: there could be more stuff alive after the block than before it!
1406 if (!a.intern_pool.isNoReturn(ty_pl.ty.toType().ip_index)) {1417 if (!a.intern_pool.isNoReturn(ty.toType().toIntern())) {
1407 // The block kills the difference in the live sets1418 // The block kills the difference in the live sets
1408 const block_scope = data.block_scopes.get(inst).?;1419 const block_scope = data.block_scopes.get(inst).?;
1409 const num_deaths = data.live_set.count() - block_scope.live_set.count();1420 const num_deaths = data.live_set.count() - block_scope.live_set.count();
src/Liveness/Verify.zig+14-7
...@@ -29,7 +29,7 @@ const LiveMap = std.AutoHashMapUnmanaged(Air.Inst.Index, void);...@@ -29,7 +29,7 @@ const LiveMap = std.AutoHashMapUnmanaged(Air.Inst.Index, void);
2929
30fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {30fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
31 const ip = self.intern_pool;31 const ip = self.intern_pool;
32 const tag = self.air.instructions.items(.tag);32 const tags = self.air.instructions.items(.tag);
33 const data = self.air.instructions.items(.data);33 const data = self.air.instructions.items(.data);
34 for (body) |inst| {34 for (body) |inst| {
35 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip)) {35 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip)) {
...@@ -37,7 +37,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {...@@ -37,7 +37,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
37 continue;37 continue;
38 }38 }
3939
40 switch (tag[@intFromEnum(inst)]) {40 switch (tags[@intFromEnum(inst)]) {
41 // no operands41 // no operands
42 .arg,42 .arg,
43 .alloc,43 .alloc,
...@@ -46,8 +46,6 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {...@@ -46,8 +46,6 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
46 .ret_ptr,46 .ret_ptr,
47 .breakpoint,47 .breakpoint,
48 .dbg_stmt,48 .dbg_stmt,
49 .dbg_inline_begin,
50 .dbg_inline_end,
51 .fence,49 .fence,
52 .ret_addr,50 .ret_addr,
53 .frame_addr,51 .frame_addr,
...@@ -431,11 +429,20 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {...@@ -431,11 +429,20 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
431 }429 }
432 try self.verifyInst(inst);430 try self.verifyInst(inst);
433 },431 },
434 .block => {432 .block, .dbg_inline_block => |tag| {
435 const ty_pl = data[@intFromEnum(inst)].ty_pl;433 const ty_pl = data[@intFromEnum(inst)].ty_pl;
436 const block_ty = ty_pl.ty.toType();434 const block_ty = ty_pl.ty.toType();
437 const extra = self.air.extraData(Air.Block, ty_pl.payload);435 const block_body: []const Air.Inst.Index = @ptrCast(switch (tag) {
438 const block_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);436 inline .block, .dbg_inline_block => |comptime_tag| body: {
437 const extra = self.air.extraData(switch (comptime_tag) {
438 .block => Air.Block,
439 .dbg_inline_block => Air.DbgInlineBlock,
440 else => unreachable,
441 }, ty_pl.payload);
442 break :body self.air.extra[extra.end..][0..extra.data.body_len];
443 },
444 else => unreachable,
445 });
439 const block_liveness = self.liveness.getBlock(inst);446 const block_liveness = self.liveness.getBlock(inst);
440447
441 var orig_live = try self.live.clone(self.gpa);448 var orig_live = try self.live.clone(self.gpa);
src/Sema.zig+89-66
...@@ -5939,6 +5939,7 @@ fn resolveBlockBody(...@@ -5939,6 +5939,7 @@ fn resolveBlockBody(
5939 if (child_block.is_comptime) {5939 if (child_block.is_comptime) {
5940 return sema.resolveInlineBody(child_block, body, body_inst);5940 return sema.resolveInlineBody(child_block, body, body_inst);
5941 } else {5941 } else {
5942 assert(sema.air_instructions.items(.tag)[@intFromEnum(merges.block_inst)] == .block);
5942 var need_debug_scope = false;5943 var need_debug_scope = false;
5943 child_block.need_debug_scope = &need_debug_scope;5944 child_block.need_debug_scope = &need_debug_scope;
5944 if (sema.analyzeBodyInner(child_block, body)) |_| {5945 if (sema.analyzeBodyInner(child_block, body)) |_| {
...@@ -6002,18 +6003,44 @@ fn resolveAnalyzedBlock(...@@ -6002,18 +6003,44 @@ fn resolveAnalyzedBlock(
6002 assert(child_block.instructions.items.len != 0);6003 assert(child_block.instructions.items.len != 0);
6003 assert(sema.typeOf(child_block.instructions.items[child_block.instructions.items.len - 1].toRef()).isNoReturn(mod));6004 assert(sema.typeOf(child_block.instructions.items[child_block.instructions.items.len - 1].toRef()).isNoReturn(mod));
60046005
6006 const block_tag = sema.air_instructions.items(.tag)[@intFromEnum(merges.block_inst)];
6007 switch (block_tag) {
6008 .block => {},
6009 .dbg_inline_block => assert(need_debug_scope),
6010 else => unreachable,
6011 }
6005 if (merges.results.items.len == 0) {6012 if (merges.results.items.len == 0) {
6006 // No need for a block instruction. We can put the new instructions6013 switch (block_tag) {
6007 // directly into the parent block.6014 .block => {
6008 if (need_debug_scope) {6015 // No need for a block instruction. We can put the new instructions
6009 // The code following this block is unreachable, as the block has no6016 // directly into the parent block.
6010 // merges, so we don't necessarily need to emit this as an AIR block.6017 if (need_debug_scope) {
6011 // However, we need a block *somewhere* to make the scoping correct,6018 // The code following this block is unreachable, as the block has no
6012 // so forward this request to the parent block.6019 // merges, so we don't necessarily need to emit this as an AIR block.
6013 if (parent_block.need_debug_scope) |ptr| ptr.* = true;6020 // However, we need a block *somewhere* to make the scoping correct,
6014 }6021 // so forward this request to the parent block.
6015 try parent_block.instructions.appendSlice(gpa, child_block.instructions.items);6022 if (parent_block.need_debug_scope) |ptr| ptr.* = true;
6016 return child_block.instructions.items[child_block.instructions.items.len - 1].toRef();6023 }
6024 try parent_block.instructions.appendSlice(gpa, child_block.instructions.items);
6025 return child_block.instructions.items[child_block.instructions.items.len - 1].toRef();
6026 },
6027 .dbg_inline_block => {
6028 // Create a block containing all instruction from the body.
6029 try parent_block.instructions.append(gpa, merges.block_inst);
6030 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.DbgInlineBlock).Struct.fields.len +
6031 child_block.instructions.items.len);
6032 sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{
6033 .ty = .noreturn_type,
6034 .payload = sema.addExtraAssumeCapacity(Air.DbgInlineBlock{
6035 .func = child_block.inlining.?.func,
6036 .body_len = @intCast(child_block.instructions.items.len),
6037 }),
6038 } };
6039 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(child_block.instructions.items));
6040 return merges.block_inst.toRef();
6041 },
6042 else => unreachable,
6043 }
6017 }6044 }
6018 if (merges.results.items.len == 1) {6045 if (merges.results.items.len == 1) {
6019 // If the `break` is trailing, we may be able to elide the AIR block here6046 // If the `break` is trailing, we may be able to elide the AIR block here
...@@ -6036,14 +6063,30 @@ fn resolveAnalyzedBlock(...@@ -6036,14 +6063,30 @@ fn resolveAnalyzedBlock(
6036 if (try sema.resolveValue(merges.results.items[0])) |result_val| {6063 if (try sema.resolveValue(merges.results.items[0])) |result_val| {
6037 // Create a block containing all instruction from the body.6064 // Create a block containing all instruction from the body.
6038 try parent_block.instructions.append(gpa, merges.block_inst);6065 try parent_block.instructions.append(gpa, merges.block_inst);
6039 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len +6066 switch (block_tag) {
6040 child_block.instructions.items.len);6067 .block => {
6041 sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{6068 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len +
6042 .ty = .void_type,6069 child_block.instructions.items.len);
6043 .payload = sema.addExtraAssumeCapacity(Air.Block{6070 sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{
6044 .body_len = @intCast(child_block.instructions.items.len),6071 .ty = .void_type,
6045 }),6072 .payload = sema.addExtraAssumeCapacity(Air.Block{
6046 } };6073 .body_len = @intCast(child_block.instructions.items.len),
6074 }),
6075 } };
6076 },
6077 .dbg_inline_block => {
6078 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.DbgInlineBlock).Struct.fields.len +
6079 child_block.instructions.items.len);
6080 sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{
6081 .ty = .void_type,
6082 .payload = sema.addExtraAssumeCapacity(Air.DbgInlineBlock{
6083 .func = child_block.inlining.?.func,
6084 .body_len = @intCast(child_block.instructions.items.len),
6085 }),
6086 } };
6087 },
6088 else => unreachable,
6089 }
6047 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(child_block.instructions.items));6090 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(child_block.instructions.items));
6048 // Rewrite the break to just give value {}; the value is6091 // Rewrite the break to just give value {}; the value is
6049 // comptime-known and will be returned directly.6092 // comptime-known and will be returned directly.
...@@ -6079,14 +6122,30 @@ fn resolveAnalyzedBlock(...@@ -6079,14 +6122,30 @@ fn resolveAnalyzedBlock(
6079 return sema.failWithOwnedErrorMsg(child_block, msg);6122 return sema.failWithOwnedErrorMsg(child_block, msg);
6080 }6123 }
6081 const ty_inst = Air.internedToRef(resolved_ty.toIntern());6124 const ty_inst = Air.internedToRef(resolved_ty.toIntern());
6082 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len +6125 switch (block_tag) {
6083 child_block.instructions.items.len);6126 .block => {
6084 sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{6127 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len +
6085 .ty = ty_inst,6128 child_block.instructions.items.len);
6086 .payload = sema.addExtraAssumeCapacity(Air.Block{6129 sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{
6087 .body_len = @intCast(child_block.instructions.items.len),6130 .ty = ty_inst,
6088 }),6131 .payload = sema.addExtraAssumeCapacity(Air.Block{
6089 } };6132 .body_len = @intCast(child_block.instructions.items.len),
6133 }),
6134 } };
6135 },
6136 .dbg_inline_block => {
6137 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.DbgInlineBlock).Struct.fields.len +
6138 child_block.instructions.items.len);
6139 sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{
6140 .ty = ty_inst,
6141 .payload = sema.addExtraAssumeCapacity(Air.DbgInlineBlock{
6142 .func = child_block.inlining.?.func,
6143 .body_len = @intCast(child_block.instructions.items.len),
6144 }),
6145 } };
6146 },
6147 else => unreachable,
6148 }
6090 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(child_block.instructions.items));6149 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(child_block.instructions.items));
6091 // Now that the block has its type resolved, we need to go back into all the break6150 // Now that the block has its type resolved, we need to go back into all the break
6092 // instructions, and insert type coercion on the operands.6151 // instructions, and insert type coercion on the operands.
...@@ -7379,7 +7438,6 @@ fn analyzeCall(...@@ -7379,7 +7438,6 @@ fn analyzeCall(
7379 .needed_comptime_reason = "function being called at comptime must be comptime-known",7438 .needed_comptime_reason = "function being called at comptime must be comptime-known",
7380 .block_comptime_reason = comptime_reason,7439 .block_comptime_reason = comptime_reason,
7381 });7440 });
7382 const prev_fn_index = sema.func_index;
7383 const module_fn_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) {7441 const module_fn_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) {
7384 .extern_func => return sema.fail(block, call_src, "{s} call of extern function", .{7442 .extern_func => return sema.fail(block, call_src, "{s} call of extern function", .{
7385 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),7443 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),
...@@ -7415,9 +7473,10 @@ fn analyzeCall(...@@ -7415,9 +7473,10 @@ fn analyzeCall(
7415 // set to in the `Block`.7473 // set to in the `Block`.
7416 // This block instruction will be used to capture the return value from the7474 // This block instruction will be used to capture the return value from the
7417 // inlined function.7475 // inlined function.
7476 const need_debug_scope = !is_comptime_call and !block.is_typeof and !block.ownerModule().strip;
7418 const block_inst: Air.Inst.Index = @enumFromInt(sema.air_instructions.len);7477 const block_inst: Air.Inst.Index = @enumFromInt(sema.air_instructions.len);
7419 try sema.air_instructions.append(gpa, .{7478 try sema.air_instructions.append(gpa, .{
7420 .tag = .block,7479 .tag = if (need_debug_scope) .dbg_inline_block else .block,
7421 .data = undefined,7480 .data = undefined,
7422 });7481 });
7423 // This one is shared among sub-blocks within the same callee, but not7482 // This one is shared among sub-blocks within the same callee, but not
...@@ -7584,10 +7643,7 @@ fn analyzeCall(...@@ -7584,10 +7643,7 @@ fn analyzeCall(
7584 }7643 }
75857644
7586 new_fn_info.return_type = sema.fn_ret_ty.toIntern();7645 new_fn_info.return_type = sema.fn_ret_ty.toIntern();
7587 const new_func_resolved_ty = try mod.funcType(new_fn_info);
7588 if (!is_comptime_call and !block.is_typeof) {7646 if (!is_comptime_call and !block.is_typeof) {
7589 try emitDbgInline(block, prev_fn_index, module_fn_index, new_func_resolved_ty, .dbg_inline_begin);
7590
7591 const zir_tags = sema.code.instructions.items(.tag);7647 const zir_tags = sema.code.instructions.items(.tag);
7592 for (fn_info.param_body) |param| switch (zir_tags[@intFromEnum(param)]) {7648 for (fn_info.param_body) |param| switch (zir_tags[@intFromEnum(param)]) {
7593 .param, .param_comptime => {7649 .param, .param_comptime => {
...@@ -7626,21 +7682,9 @@ fn analyzeCall(...@@ -7626,21 +7682,9 @@ fn analyzeCall(
7626 error.ComptimeReturn => break :result inlining.comptime_result,7682 error.ComptimeReturn => break :result inlining.comptime_result,
7627 else => |e| return e,7683 else => |e| return e,
7628 };7684 };
7629 break :result try sema.resolveAnalyzedBlock(block, call_src, &child_block, merges, false);7685 break :result try sema.resolveAnalyzedBlock(block, call_src, &child_block, merges, need_debug_scope);
7630 };7686 };
76317687
7632 if (!is_comptime_call and !block.is_typeof and
7633 sema.typeOf(result).zigTypeTag(mod) != .NoReturn)
7634 {
7635 try emitDbgInline(
7636 block,
7637 module_fn_index,
7638 prev_fn_index,
7639 mod.funcOwnerDeclPtr(sema.func_index).ty,
7640 .dbg_inline_end,
7641 );
7642 }
7643
7644 if (should_memoize and is_comptime_call) {7688 if (should_memoize and is_comptime_call) {
7645 const result_val = try sema.resolveConstValue(block, .unneeded, result, undefined);7689 const result_val = try sema.resolveConstValue(block, .unneeded, result, undefined);
7646 const result_interned = try result_val.intern2(sema.fn_ret_ty, mod);7690 const result_interned = try result_val.intern2(sema.fn_ret_ty, mod);
...@@ -8207,27 +8251,6 @@ fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type)...@@ -8207,27 +8251,6 @@ fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type)
8207 }8251 }
8208}8252}
82098253
8210fn emitDbgInline(
8211 block: *Block,
8212 old_func: InternPool.Index,
8213 new_func: InternPool.Index,
8214 new_func_ty: Type,
8215 tag: Air.Inst.Tag,
8216) CompileError!void {
8217 if (block.ownerModule().strip) return;
8218
8219 // Recursive inline call; no dbg_inline needed.
8220 if (old_func == new_func) return;
8221
8222 _ = try block.addInst(.{
8223 .tag = tag,
8224 .data = .{ .ty_fn = .{
8225 .ty = Air.internedToRef(new_func_ty.toIntern()),
8226 .func = new_func,
8227 } },
8228 });
8229}
8230
8231fn zirIntType(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8254fn zirIntType(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8232 const mod = sema.mod;8255 const mod = sema.mod;
8233 const int_type = sema.code.instructions.items(.data)[@intFromEnum(inst)].int_type;8256 const int_type = sema.code.instructions.items(.data)[@intFromEnum(inst)].int_type;
src/arch/aarch64/CodeGen.zig+13-12
...@@ -747,7 +747,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -747,7 +747,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
747 .frame_addr => try self.airFrameAddress(inst),747 .frame_addr => try self.airFrameAddress(inst),
748 .fence => try self.airFence(),748 .fence => try self.airFence(),
749 .cond_br => try self.airCondBr(inst),749 .cond_br => try self.airCondBr(inst),
750 .dbg_stmt => try self.airDbgStmt(inst),
751 .fptrunc => try self.airFptrunc(inst),750 .fptrunc => try self.airFptrunc(inst),
752 .fpext => try self.airFpext(inst),751 .fpext => try self.airFpext(inst),
753 .intcast => try self.airIntCast(inst),752 .intcast => try self.airIntCast(inst),
...@@ -805,14 +804,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -805,14 +804,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
805 .@"try" => try self.airTry(inst),804 .@"try" => try self.airTry(inst),
806 .try_ptr => try self.airTryPtr(inst),805 .try_ptr => try self.airTryPtr(inst),
807806
807 .dbg_stmt => try self.airDbgStmt(inst),
808 .dbg_inline_block => try self.airDbgInlineBlock(inst),
808 .dbg_var_ptr,809 .dbg_var_ptr,
809 .dbg_var_val,810 .dbg_var_val,
810 => try self.airDbgVar(inst),811 => try self.airDbgVar(inst),
811812
812 .dbg_inline_begin,
813 .dbg_inline_end,
814 => try self.airDbgInline(inst),
815
816 .call => try self.airCall(inst, .auto),813 .call => try self.airCall(inst, .auto),
817 .call_always_tail => try self.airCall(inst, .always_tail),814 .call_always_tail => try self.airCall(inst, .always_tail),
818 .call_never_tail => try self.airCall(inst, .never_tail),815 .call_never_tail => try self.airCall(inst, .never_tail),
...@@ -4621,13 +4618,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {...@@ -4621,13 +4618,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
4621 return self.finishAirBookkeeping();4618 return self.finishAirBookkeeping();
4622}4619}
46234620
4624fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {4621fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void {
4625 const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
4626 const mod = self.bin_file.comp.module.?;4622 const mod = self.bin_file.comp.module.?;
4627 const func = mod.funcInfo(ty_fn.func);4623 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4624 const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
4625 const func = mod.funcInfo(extra.data.func);
4628 // TODO emit debug info for function change4626 // TODO emit debug info for function change
4629 _ = func;4627 _ = func;
4630 return self.finishAir(inst, .dead, .{ .none, .none, .none });4628 try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
4631}4629}
46324630
4633fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {4631fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
...@@ -5042,6 +5040,12 @@ fn jump(self: *Self, inst: Mir.Inst.Index) !void {...@@ -5042,6 +5040,12 @@ fn jump(self: *Self, inst: Mir.Inst.Index) !void {
5042}5040}
50435041
5044fn airBlock(self: *Self, inst: Air.Inst.Index) !void {5042fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
5043 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
5044 const extra = self.air.extraData(Air.Block, ty_pl.payload);
5045 try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
5046}
5047
5048fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !void {
5045 try self.blocks.putNoClobber(self.gpa, inst, .{5049 try self.blocks.putNoClobber(self.gpa, inst, .{
5046 // A block is a setup to be able to jump to the end.5050 // A block is a setup to be able to jump to the end.
5047 .relocs = .{},5051 .relocs = .{},
...@@ -5054,9 +5058,6 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {...@@ -5054,9 +5058,6 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
5054 });5058 });
5055 defer self.blocks.getPtr(inst).?.relocs.deinit(self.gpa);5059 defer self.blocks.getPtr(inst).?.relocs.deinit(self.gpa);
50565060
5057 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
5058 const extra = self.air.extraData(Air.Block, ty_pl.payload);
5059 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
5060 // TODO emit debug info lexical block5061 // TODO emit debug info lexical block
5061 try self.genBody(body);5062 try self.genBody(body);
50625063
src/arch/arm/CodeGen.zig+13-12
...@@ -733,7 +733,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -733,7 +733,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
733 .frame_addr => try self.airFrameAddress(inst),733 .frame_addr => try self.airFrameAddress(inst),
734 .fence => try self.airFence(),734 .fence => try self.airFence(),
735 .cond_br => try self.airCondBr(inst),735 .cond_br => try self.airCondBr(inst),
736 .dbg_stmt => try self.airDbgStmt(inst),
737 .fptrunc => try self.airFptrunc(inst),736 .fptrunc => try self.airFptrunc(inst),
738 .fpext => try self.airFpext(inst),737 .fpext => try self.airFpext(inst),
739 .intcast => try self.airIntCast(inst),738 .intcast => try self.airIntCast(inst),
...@@ -791,14 +790,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -791,14 +790,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
791 .@"try" => try self.airTry(inst),790 .@"try" => try self.airTry(inst),
792 .try_ptr => try self.airTryPtr(inst),791 .try_ptr => try self.airTryPtr(inst),
793792
793 .dbg_stmt => try self.airDbgStmt(inst),
794 .dbg_inline_block => try self.airDbgInlineBlock(inst),
794 .dbg_var_ptr,795 .dbg_var_ptr,
795 .dbg_var_val,796 .dbg_var_val,
796 => try self.airDbgVar(inst),797 => try self.airDbgVar(inst),
797798
798 .dbg_inline_begin,
799 .dbg_inline_end,
800 => try self.airDbgInline(inst),
801
802 .call => try self.airCall(inst, .auto),799 .call => try self.airCall(inst, .auto),
803 .call_always_tail => try self.airCall(inst, .always_tail),800 .call_always_tail => try self.airCall(inst, .always_tail),
804 .call_never_tail => try self.airCall(inst, .never_tail),801 .call_never_tail => try self.airCall(inst, .never_tail),
...@@ -4574,13 +4571,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {...@@ -4574,13 +4571,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
4574 return self.finishAirBookkeeping();4571 return self.finishAirBookkeeping();
4575}4572}
45764573
4577fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {4574fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void {
4578 const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
4579 const mod = self.bin_file.comp.module.?;4575 const mod = self.bin_file.comp.module.?;
4580 const func = mod.funcInfo(ty_fn.func);4576 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4577 const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
4578 const func = mod.funcInfo(extra.data.func);
4581 // TODO emit debug info for function change4579 // TODO emit debug info for function change
4582 _ = func;4580 _ = func;
4583 return self.finishAir(inst, .dead, .{ .none, .none, .none });4581 try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
4584}4582}
45854583
4586fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {4584fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
...@@ -4973,6 +4971,12 @@ fn jump(self: *Self, inst: Mir.Inst.Index) !void {...@@ -4973,6 +4971,12 @@ fn jump(self: *Self, inst: Mir.Inst.Index) !void {
4973}4971}
49744972
4975fn airBlock(self: *Self, inst: Air.Inst.Index) !void {4973fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
4974 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4975 const extra = self.air.extraData(Air.Block, ty_pl.payload);
4976 try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
4977}
4978
4979fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !void {
4976 try self.blocks.putNoClobber(self.gpa, inst, .{4980 try self.blocks.putNoClobber(self.gpa, inst, .{
4977 // A block is a setup to be able to jump to the end.4981 // A block is a setup to be able to jump to the end.
4978 .relocs = .{},4982 .relocs = .{},
...@@ -4985,9 +4989,6 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {...@@ -4985,9 +4989,6 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
4985 });4989 });
4986 defer self.blocks.getPtr(inst).?.relocs.deinit(self.gpa);4990 defer self.blocks.getPtr(inst).?.relocs.deinit(self.gpa);
49874991
4988 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4989 const extra = self.air.extraData(Air.Block, ty_pl.payload);
4990 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
4991 // TODO emit debug info lexical block4992 // TODO emit debug info lexical block
4992 try self.genBody(body);4993 try self.genBody(body);
49934994
src/arch/riscv64/CodeGen.zig+13-13
...@@ -566,7 +566,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -566,7 +566,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
566 .frame_addr => try self.airFrameAddress(inst),566 .frame_addr => try self.airFrameAddress(inst),
567 .fence => try self.airFence(),567 .fence => try self.airFence(),
568 .cond_br => try self.airCondBr(inst),568 .cond_br => try self.airCondBr(inst),
569 .dbg_stmt => try self.airDbgStmt(inst),
570 .fptrunc => try self.airFptrunc(inst),569 .fptrunc => try self.airFptrunc(inst),
571 .fpext => try self.airFpext(inst),570 .fpext => try self.airFpext(inst),
572 .intcast => try self.airIntCast(inst),571 .intcast => try self.airIntCast(inst),
...@@ -624,14 +623,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -624,14 +623,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
624 .@"try" => @panic("TODO"),623 .@"try" => @panic("TODO"),
625 .try_ptr => @panic("TODO"),624 .try_ptr => @panic("TODO"),
626625
626 .dbg_stmt => try self.airDbgStmt(inst),
627 .dbg_inline_block => try self.airDbgInlineBlock(inst),
627 .dbg_var_ptr,628 .dbg_var_ptr,
628 .dbg_var_val,629 .dbg_var_val,
629 => try self.airDbgVar(inst),630 => try self.airDbgVar(inst),
630631
631 .dbg_inline_begin,
632 .dbg_inline_end,
633 => try self.airDbgInline(inst),
634
635 .call => try self.airCall(inst, .auto),632 .call => try self.airCall(inst, .auto),
636 .call_always_tail => try self.airCall(inst, .always_tail),633 .call_always_tail => try self.airCall(inst, .always_tail),
637 .call_never_tail => try self.airCall(inst, .never_tail),634 .call_never_tail => try self.airCall(inst, .never_tail),
...@@ -1881,13 +1878,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {...@@ -1881,13 +1878,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
1881 return self.finishAirBookkeeping();1878 return self.finishAirBookkeeping();
1882}1879}
18831880
1884fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {1881fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void {
1885 const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
1886 const mod = self.bin_file.comp.module.?;1882 const mod = self.bin_file.comp.module.?;
1887 const func = mod.funcInfo(ty_fn.func);1883 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
1884 const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
1885 const func = mod.funcInfo(extra.data.func);
1888 // TODO emit debug info for function change1886 // TODO emit debug info for function change
1889 _ = func;1887 _ = func;
1890 return self.finishAir(inst, .dead, .{ .none, .none, .none });1888 try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
1891}1889}
18921890
1893fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {1891fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
...@@ -2060,6 +2058,12 @@ fn jump(self: *Self, index: usize) !void {...@@ -2060,6 +2058,12 @@ fn jump(self: *Self, index: usize) !void {
2060}2058}
20612059
2062fn airBlock(self: *Self, inst: Air.Inst.Index) !void {2060fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
2061 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
2062 const extra = self.air.extraData(Air.Block, ty_pl.payload);
2063 try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
2064}
2065
2066fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !void {
2063 try self.blocks.putNoClobber(self.gpa, inst, .{2067 try self.blocks.putNoClobber(self.gpa, inst, .{
2064 // A block is a setup to be able to jump to the end.2068 // A block is a setup to be able to jump to the end.
2065 .relocs = .{},2069 .relocs = .{},
...@@ -2071,10 +2075,6 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {...@@ -2071,10 +2075,6 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
2071 .mcv = MCValue{ .none = {} },2075 .mcv = MCValue{ .none = {} },
2072 });2076 });
2073 defer self.blocks.getPtr(inst).?.relocs.deinit(self.gpa);2077 defer self.blocks.getPtr(inst).?.relocs.deinit(self.gpa);
2074
2075 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
2076 const extra = self.air.extraData(Air.Block, ty_pl.payload);
2077 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
2078 // TODO emit debug info lexical block2078 // TODO emit debug info lexical block
2079 try self.genBody(body);2079 try self.genBody(body);
20802080
src/arch/sparc64/CodeGen.zig+13-12
...@@ -579,7 +579,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -579,7 +579,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
579 .frame_addr => @panic("TODO try self.airFrameAddress(inst)"),579 .frame_addr => @panic("TODO try self.airFrameAddress(inst)"),
580 .fence => try self.airFence(inst),580 .fence => try self.airFence(inst),
581 .cond_br => try self.airCondBr(inst),581 .cond_br => try self.airCondBr(inst),
582 .dbg_stmt => try self.airDbgStmt(inst),
583 .fptrunc => @panic("TODO try self.airFptrunc(inst)"),582 .fptrunc => @panic("TODO try self.airFptrunc(inst)"),
584 .fpext => @panic("TODO try self.airFpext(inst)"),583 .fpext => @panic("TODO try self.airFpext(inst)"),
585 .intcast => try self.airIntCast(inst),584 .intcast => try self.airIntCast(inst),
...@@ -637,14 +636,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -637,14 +636,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
637 .@"try" => try self.airTry(inst),636 .@"try" => try self.airTry(inst),
638 .try_ptr => @panic("TODO try self.airTryPtr(inst)"),637 .try_ptr => @panic("TODO try self.airTryPtr(inst)"),
639638
639 .dbg_stmt => try self.airDbgStmt(inst),
640 .dbg_inline_block => try self.airDbgInlineBlock(inst),
640 .dbg_var_ptr,641 .dbg_var_ptr,
641 .dbg_var_val,642 .dbg_var_val,
642 => try self.airDbgVar(inst),643 => try self.airDbgVar(inst),
643644
644 .dbg_inline_begin,
645 .dbg_inline_end,
646 => try self.airDbgInline(inst),
647
648 .call => try self.airCall(inst, .auto),645 .call => try self.airCall(inst, .auto),
649 .call_always_tail => try self.airCall(inst, .always_tail),646 .call_always_tail => try self.airCall(inst, .always_tail),
650 .call_never_tail => try self.airCall(inst, .never_tail),647 .call_never_tail => try self.airCall(inst, .never_tail),
...@@ -1127,6 +1124,12 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {...@@ -1127,6 +1124,12 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
1127}1124}
11281125
1129fn airBlock(self: *Self, inst: Air.Inst.Index) !void {1126fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
1127 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
1128 const extra = self.air.extraData(Air.Block, ty_pl.payload);
1129 try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
1130}
1131
1132fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !void {
1130 try self.blocks.putNoClobber(self.gpa, inst, .{1133 try self.blocks.putNoClobber(self.gpa, inst, .{
1131 // A block is a setup to be able to jump to the end.1134 // A block is a setup to be able to jump to the end.
1132 .relocs = .{},1135 .relocs = .{},
...@@ -1139,9 +1142,6 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {...@@ -1139,9 +1142,6 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
1139 });1142 });
1140 defer self.blocks.getPtr(inst).?.relocs.deinit(self.gpa);1143 defer self.blocks.getPtr(inst).?.relocs.deinit(self.gpa);
11411144
1142 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
1143 const extra = self.air.extraData(Air.Block, ty_pl.payload);
1144 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
1145 // TODO emit debug info lexical block1145 // TODO emit debug info lexical block
1146 try self.genBody(body);1146 try self.genBody(body);
11471147
...@@ -1652,13 +1652,14 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {...@@ -1652,13 +1652,14 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
1652 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1652 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1653}1653}
16541654
1655fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {1655fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void {
1656 const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
1657 const mod = self.bin_file.comp.module.?;1656 const mod = self.bin_file.comp.module.?;
1658 const func = mod.funcInfo(ty_fn.func);1657 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
1658 const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
1659 const func = mod.funcInfo(extra.data.func);
1659 // TODO emit debug info for function change1660 // TODO emit debug info for function change
1660 _ = func;1661 _ = func;
1661 return self.finishAir(inst, .dead, .{ .none, .none, .none });1662 try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
1662}1663}
16631664
1664fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {1665fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
src/arch/wasm/CodeGen.zig+29-25
...@@ -1910,16 +1910,11 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -1910,16 +1910,11 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
1910 .@"try" => func.airTry(inst),1910 .@"try" => func.airTry(inst),
1911 .try_ptr => func.airTryPtr(inst),1911 .try_ptr => func.airTryPtr(inst),
19121912
1913 // TODO1913 .dbg_stmt => func.airDbgStmt(inst),
1914 .dbg_inline_begin,1914 .dbg_inline_block => func.airDbgInlineBlock(inst),
1915 .dbg_inline_end,
1916 => func.finishAir(inst, .none, &.{}),
1917
1918 .dbg_var_ptr => func.airDbgVar(inst, true),1915 .dbg_var_ptr => func.airDbgVar(inst, true),
1919 .dbg_var_val => func.airDbgVar(inst, false),1916 .dbg_var_val => func.airDbgVar(inst, false),
19201917
1921 .dbg_stmt => func.airDbgStmt(inst),
1922
1923 .call => func.airCall(inst, .auto),1918 .call => func.airCall(inst, .auto),
1924 .call_always_tail => func.airCall(inst, .always_tail),1919 .call_always_tail => func.airCall(inst, .always_tail),
1925 .call_never_tail => func.airCall(inst, .never_tail),1920 .call_never_tail => func.airCall(inst, .never_tail),
...@@ -3476,12 +3471,14 @@ fn intStorageAsI32(storage: InternPool.Key.Int.Storage, mod: *Module) i32 {...@@ -3476,12 +3471,14 @@ fn intStorageAsI32(storage: InternPool.Key.Int.Storage, mod: *Module) i32 {
3476}3471}
34773472
3478fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {3473fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3479 const mod = func.bin_file.base.comp.module.?;
3480 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3474 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
3481 const block_ty = ty_pl.ty.toType();
3482 const wasm_block_ty = genBlockType(block_ty, mod);
3483 const extra = func.air.extraData(Air.Block, ty_pl.payload);3475 const extra = func.air.extraData(Air.Block, ty_pl.payload);
3484 const body: []const Air.Inst.Index = @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len]);3476 try func.lowerBlock(inst, ty_pl.ty.toType(), @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len]));
3477}
3478
3479fn lowerBlock(func: *CodeGen, inst: Air.Inst.Index, block_ty: Type, body: []const Air.Inst.Index) InnerError!void {
3480 const mod = func.bin_file.base.comp.module.?;
3481 const wasm_block_ty = genBlockType(block_ty, mod);
34853482
3486 // if wasm_block_ty is non-empty, we create a register to store the temporary value3483 // if wasm_block_ty is non-empty, we create a register to store the temporary value
3487 const block_result: WValue = if (wasm_block_ty != wasm.block_empty) blk: {3484 const block_result: WValue = if (wasm_block_ty != wasm.block_empty) blk: {
...@@ -6472,7 +6469,27 @@ fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6472,7 +6469,27 @@ fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6472 func.finishAir(inst, result, &.{ty_op.operand});6469 func.finishAir(inst, result, &.{ty_op.operand});
6473}6470}
64746471
6475fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) !void {6472fn airDbgStmt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6473 if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{});
6474
6475 const dbg_stmt = func.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
6476 try func.addInst(.{ .tag = .dbg_line, .data = .{
6477 .payload = try func.addExtra(Mir.DbgLineColumn{
6478 .line = dbg_stmt.line,
6479 .column = dbg_stmt.column,
6480 }),
6481 } });
6482 func.finishAir(inst, .none, &.{});
6483}
6484
6485fn airDbgInlineBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6486 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6487 const extra = func.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
6488 // TODO
6489 try func.lowerBlock(inst, ty_pl.ty.toType(), @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len]));
6490}
6491
6492fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void {
6476 if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{});6493 if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{});
64776494
6478 const mod = func.bin_file.base.comp.module.?;6495 const mod = func.bin_file.base.comp.module.?;
...@@ -6497,19 +6514,6 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) !void {...@@ -6497,19 +6514,6 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) !void {
6497 func.finishAir(inst, .none, &.{});6514 func.finishAir(inst, .none, &.{});
6498}6515}
64996516
6500fn airDbgStmt(func: *CodeGen, inst: Air.Inst.Index) !void {
6501 if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{});
6502
6503 const dbg_stmt = func.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
6504 try func.addInst(.{ .tag = .dbg_line, .data = .{
6505 .payload = try func.addExtra(Mir.DbgLineColumn{
6506 .line = dbg_stmt.line,
6507 .column = dbg_stmt.column,
6508 }),
6509 } });
6510 func.finishAir(inst, .none, &.{});
6511}
6512
6513fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {6517fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6514 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6518 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6515 const err_union = try func.resolveInst(pl_op.operand);6519 const err_union = try func.resolveInst(pl_op.operand);
src/arch/x86_64/CodeGen.zig+24-12
...@@ -58,6 +58,7 @@ bin_file: *link.File,...@@ -58,6 +58,7 @@ bin_file: *link.File,
58debug_output: DebugInfoOutput,58debug_output: DebugInfoOutput,
59target: *const std.Target,59target: *const std.Target,
60owner: Owner,60owner: Owner,
61inline_func: InternPool.Index,
61mod: *Package.Module,62mod: *Package.Module,
62err_msg: ?*ErrorMsg,63err_msg: ?*ErrorMsg,
63args: []MCValue,64args: []MCValue,
...@@ -820,6 +821,7 @@ pub fn generate(...@@ -820,6 +821,7 @@ pub fn generate(
820 .bin_file = bin_file,821 .bin_file = bin_file,
821 .debug_output = debug_output,822 .debug_output = debug_output,
822 .owner = .{ .func_index = func_index },823 .owner = .{ .func_index = func_index },
824 .inline_func = func_index,
823 .err_msg = null,825 .err_msg = null,
824 .args = undefined, // populated after `resolveCallingConventionValues`826 .args = undefined, // populated after `resolveCallingConventionValues`
825 .va_info = undefined, // populated after `resolveCallingConventionValues`827 .va_info = undefined, // populated after `resolveCallingConventionValues`
...@@ -987,6 +989,7 @@ pub fn generateLazy(...@@ -987,6 +989,7 @@ pub fn generateLazy(
987 .bin_file = bin_file,989 .bin_file = bin_file,
988 .debug_output = debug_output,990 .debug_output = debug_output,
989 .owner = .{ .lazy_sym = lazy_sym },991 .owner = .{ .lazy_sym = lazy_sym },
992 .inline_func = undefined,
990 .err_msg = null,993 .err_msg = null,
991 .args = undefined,994 .args = undefined,
992 .va_info = undefined,995 .va_info = undefined,
...@@ -2042,7 +2045,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -2042,7 +2045,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
2042 .frame_addr => try self.airFrameAddress(inst),2045 .frame_addr => try self.airFrameAddress(inst),
2043 .fence => try self.airFence(inst),2046 .fence => try self.airFence(inst),
2044 .cond_br => try self.airCondBr(inst),2047 .cond_br => try self.airCondBr(inst),
2045 .dbg_stmt => try self.airDbgStmt(inst),
2046 .fptrunc => try self.airFptrunc(inst),2048 .fptrunc => try self.airFptrunc(inst),
2047 .fpext => try self.airFpext(inst),2049 .fpext => try self.airFpext(inst),
2048 .intcast => try self.airIntCast(inst),2050 .intcast => try self.airIntCast(inst),
...@@ -2098,14 +2100,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -2098,14 +2100,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
2098 .@"try" => try self.airTry(inst),2100 .@"try" => try self.airTry(inst),
2099 .try_ptr => try self.airTryPtr(inst),2101 .try_ptr => try self.airTryPtr(inst),
21002102
2103 .dbg_stmt => try self.airDbgStmt(inst),
2104 .dbg_inline_block => try self.airDbgInlineBlock(inst),
2101 .dbg_var_ptr,2105 .dbg_var_ptr,
2102 .dbg_var_val,2106 .dbg_var_val,
2103 => try self.airDbgVar(inst),2107 => try self.airDbgVar(inst),
21042108
2105 .dbg_inline_begin,
2106 .dbg_inline_end,
2107 => try self.airDbgInline(inst),
2108
2109 .call => try self.airCall(inst, .auto),2109 .call => try self.airCall(inst, .auto),
2110 .call_always_tail => try self.airCall(inst, .always_tail),2110 .call_always_tail => try self.airCall(inst, .always_tail),
2111 .call_never_tail => try self.airCall(inst, .never_tail),2111 .call_never_tail => try self.airCall(inst, .never_tail),
...@@ -12962,14 +12962,23 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {...@@ -12962,14 +12962,23 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
12962 self.finishAirBookkeeping();12962 self.finishAirBookkeeping();
12963}12963}
1296412964
12965fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {12965fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void {
12966 const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;12966 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
12967 const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
12968 const old_inline_func = self.inline_func;
12969 defer self.inline_func = old_inline_func;
12970 self.inline_func = extra.data.func;
12967 _ = try self.addInst(.{12971 _ = try self.addInst(.{
12968 .tag = .pseudo,12972 .tag = .pseudo,
12969 .ops = .pseudo_dbg_inline_func,12973 .ops = .pseudo_dbg_inline_func,
12970 .data = .{ .func = ty_fn.func },12974 .data = .{ .func = extra.data.func },
12975 });
12976 try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
12977 _ = try self.addInst(.{
12978 .tag = .pseudo,
12979 .ops = .pseudo_dbg_inline_func,
12980 .data = .{ .func = old_inline_func },
12971 });12981 });
12972 self.finishAirBookkeeping();
12973}12982}
1297412983
12975fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {12984fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
...@@ -13407,6 +13416,12 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {...@@ -13407,6 +13416,12 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {
13407}13416}
1340813417
13409fn airBlock(self: *Self, inst: Air.Inst.Index) !void {13418fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
13419 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
13420 const extra = self.air.extraData(Air.Block, ty_pl.payload);
13421 try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
13422}
13423
13424fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !void {
13410 // A block is a setup to be able to jump to the end.13425 // A block is a setup to be able to jump to the end.
13411 const inst_tracking_i = self.inst_tracking.count();13426 const inst_tracking_i = self.inst_tracking.count();
13412 self.inst_tracking.putAssumeCapacityNoClobber(inst, InstTracking.init(.unreach));13427 self.inst_tracking.putAssumeCapacityNoClobber(inst, InstTracking.init(.unreach));
...@@ -13415,9 +13430,6 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {...@@ -13415,9 +13430,6 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
13415 try self.blocks.putNoClobber(self.gpa, inst, .{ .state = self.initRetroactiveState() });13430 try self.blocks.putNoClobber(self.gpa, inst, .{ .state = self.initRetroactiveState() });
13416 const liveness = self.liveness.getBlock(inst);13431 const liveness = self.liveness.getBlock(inst);
1341713432
13418 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
13419 const extra = self.air.extraData(Air.Block, ty_pl.payload);
13420 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
13421 // TODO emit debug info lexical block13433 // TODO emit debug info lexical block
13422 try self.genBody(body);13434 try self.genBody(body);
1342313435
src/codegen/c.zig+18-19
...@@ -2554,9 +2554,9 @@ pub fn genTypeDecl(...@@ -2554,9 +2554,9 @@ pub fn genTypeDecl(
2554 .suffix,2554 .suffix,
2555 .{},2555 .{},
2556 );2556 );
2557 try writer.writeAll("; // ");2557 try writer.writeAll("; /* ");
2558 try mod.declPtr(owner_decl).renderFullyQualifiedName(mod, writer);2558 try mod.declPtr(owner_decl).renderFullyQualifiedName(mod, writer);
2559 try writer.writeByte('\n');2559 try writer.writeAll(" */\n");
2560 },2560 },
25612561
2562 .anon_struct,2562 .anon_struct,
...@@ -3215,7 +3215,6 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,...@@ -3215,7 +3215,6 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
3215 .assembly => try airAsm(f, inst),3215 .assembly => try airAsm(f, inst),
3216 .block => try airBlock(f, inst),3216 .block => try airBlock(f, inst),
3217 .bitcast => try airBitcast(f, inst),3217 .bitcast => try airBitcast(f, inst),
3218 .dbg_stmt => try airDbgStmt(f, inst),
3219 .intcast => try airIntCast(f, inst),3218 .intcast => try airIntCast(f, inst),
3220 .trunc => try airTrunc(f, inst),3219 .trunc => try airTrunc(f, inst),
3221 .int_from_bool => try airIntFromBool(f, inst),3220 .int_from_bool => try airIntFromBool(f, inst),
...@@ -3259,13 +3258,9 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,...@@ -3259,13 +3258,9 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
3259 .@"try" => try airTry(f, inst),3258 .@"try" => try airTry(f, inst),
3260 .try_ptr => try airTryPtr(f, inst),3259 .try_ptr => try airTryPtr(f, inst),
32613260
3262 .dbg_var_ptr,3261 .dbg_stmt => try airDbgStmt(f, inst),
3263 .dbg_var_val,3262 .dbg_inline_block => try airDbgInlineBlock(f, inst),
3264 => try airDbgVar(f, inst),3263 .dbg_var_ptr, .dbg_var_val => try airDbgVar(f, inst),
3265
3266 .dbg_inline_begin,
3267 .dbg_inline_end,
3268 => try airDbgInline(f, inst),
32693264
3270 .call => try airCall(f, inst, .auto),3265 .call => try airCall(f, inst, .auto),
3271 .call_always_tail => .none,3266 .call_always_tail => .none,
...@@ -4497,15 +4492,16 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4497,15 +4492,16 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
4497 return .none;4492 return .none;
4498}4493}
44994494
4500fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue {4495fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {
4501 const ty_fn = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
4502 const mod = f.object.dg.module;4496 const mod = f.object.dg.module;
4497 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4498 const extra = f.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
4499 const owner_decl = mod.funcOwnerDeclPtr(extra.data.func);
4503 const writer = f.object.writer();4500 const writer = f.object.writer();
4504 const owner_decl = mod.funcOwnerDeclPtr(ty_fn.func);4501 try writer.writeAll("/* ");
4505 try writer.print("/* dbg func:{s} */\n", .{4502 try owner_decl.renderFullyQualifiedName(mod, writer);
4506 mod.intern_pool.stringToSlice(owner_decl.name),4503 try writer.writeAll(" */ ");
4507 });4504 return lowerBlock(f, inst, @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]));
4508 return .none;
4509}4505}
45104506
4511fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {4507fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
...@@ -4522,10 +4518,13 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4522,10 +4518,13 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
4522}4518}
45234519
4524fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {4520fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {
4525 const mod = f.object.dg.module;
4526 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4521 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4527 const extra = f.air.extraData(Air.Block, ty_pl.payload);4522 const extra = f.air.extraData(Air.Block, ty_pl.payload);
4528 const body: []const Air.Inst.Index = @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]);4523 return lowerBlock(f, inst, @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]));
4524}
4525
4526fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index) !CValue {
4527 const mod = f.object.dg.module;
4529 const liveness_block = f.liveness.getBlock(inst);4528 const liveness_block = f.liveness.getBlock(inst);
45304529
4531 const block_id: usize = f.next_block_index;4530 const block_id: usize = f.next_block_index;
src/codegen/llvm.zig+93-101
...@@ -4762,11 +4762,7 @@ pub const FuncGen = struct {...@@ -4762,11 +4762,7 @@ pub const FuncGen = struct {
4762 file: Builder.Metadata,4762 file: Builder.Metadata,
4763 scope: Builder.Metadata,4763 scope: Builder.Metadata,
47644764
4765 inlined: std.ArrayListUnmanaged(struct {4765 inlined: Builder.DebugLocation = .no_location,
4766 base_line: u32,
4767 location: Builder.DebugLocation,
4768 scope: Builder.Metadata,
4769 }) = .{},
47704766
4771 base_line: u32,4767 base_line: u32,
4772 prev_dbg_line: c_uint,4768 prev_dbg_line: c_uint,
...@@ -4811,7 +4807,6 @@ pub const FuncGen = struct {...@@ -4811,7 +4807,6 @@ pub const FuncGen = struct {
48114807
4812 fn deinit(self: *FuncGen) void {4808 fn deinit(self: *FuncGen) void {
4813 self.wip.deinit();4809 self.wip.deinit();
4814 self.inlined.deinit(self.gpa);
4815 self.func_inst_table.deinit(self.gpa);4810 self.func_inst_table.deinit(self.gpa);
4816 self.blocks.deinit(self.gpa);4811 self.blocks.deinit(self.gpa);
4817 }4812 }
...@@ -5107,8 +5102,7 @@ pub const FuncGen = struct {...@@ -5107,8 +5102,7 @@ pub const FuncGen = struct {
51075102
5108 .unreach => try self.airUnreach(inst),5103 .unreach => try self.airUnreach(inst),
5109 .dbg_stmt => try self.airDbgStmt(inst),5104 .dbg_stmt => try self.airDbgStmt(inst),
5110 .dbg_inline_begin => try self.airDbgInlineBegin(inst),5105 .dbg_inline_block => try self.airDbgInlineBlock(inst),
5111 .dbg_inline_end => try self.airDbgInlineEnd(inst),
5112 .dbg_var_ptr => try self.airDbgVarPtr(inst),5106 .dbg_var_ptr => try self.airDbgVarPtr(inst),
5113 .dbg_var_val => try self.airDbgVarVal(inst),5107 .dbg_var_val => try self.airDbgVarVal(inst),
51145108
...@@ -5126,17 +5120,81 @@ pub const FuncGen = struct {...@@ -5126,17 +5120,81 @@ pub const FuncGen = struct {
5126 }5120 }
5127 }5121 }
51285122
5129 fn genBodyDebugScope(self: *FuncGen, body: []const Air.Inst.Index) Error!void {5123 fn genBodyDebugScope(self: *FuncGen, maybe_inline_func: ?InternPool.Index, body: []const Air.Inst.Index) Error!void {
5130 if (self.wip.strip) return self.genBody(body);5124 if (self.wip.strip) return self.genBody(body);
5125
5126 const old_file = self.file;
5127 const old_inlined = self.inlined;
5128 const old_base_line = self.base_line;
5131 const old_scope = self.scope;5129 const old_scope = self.scope;
5130 defer if (maybe_inline_func) |_| {
5131 self.wip.debug_location = self.inlined;
5132 self.file = old_file;
5133 self.inlined = old_inlined;
5134 self.base_line = old_base_line;
5135 };
5136 defer self.scope = old_scope;
5137
5138 if (maybe_inline_func) |inline_func| {
5139 const o = self.dg.object;
5140 const zcu = o.module;
5141
5142 const func = zcu.funcInfo(inline_func);
5143 const decl_index = func.owner_decl;
5144 const decl = zcu.declPtr(decl_index);
5145 const namespace = zcu.namespacePtr(decl.src_namespace);
5146 const owner_mod = namespace.file_scope.mod;
5147
5148 self.file = try o.getDebugFile(namespace.file_scope);
5149
5150 const line_number = decl.src_line + 1;
5151 self.inlined = self.wip.debug_location;
5152
5153 const fqn = try decl.fullyQualifiedName(zcu);
5154
5155 const is_internal_linkage = !zcu.decl_exports.contains(decl_index);
5156 const fn_ty = try zcu.funcType(.{
5157 .param_types = &.{},
5158 .return_type = .void_type,
5159 });
5160
5161 self.scope = try o.builder.debugSubprogram(
5162 self.file,
5163 try o.builder.metadataString(zcu.intern_pool.stringToSlice(decl.name)),
5164 try o.builder.metadataString(zcu.intern_pool.stringToSlice(fqn)),
5165 line_number,
5166 line_number + func.lbrace_line,
5167 try o.lowerDebugType(fn_ty),
5168 .{
5169 .di_flags = .{ .StaticMember = true },
5170 .sp_flags = .{
5171 .Optimized = owner_mod.optimize_mode != .Debug,
5172 .Definition = true,
5173 .LocalToUnit = is_internal_linkage,
5174 },
5175 },
5176 o.debug_compile_unit,
5177 );
5178
5179 self.base_line = decl.src_line;
5180 const inlined_at_location = try self.wip.debug_location.toMetadata(&o.builder);
5181 self.wip.debug_location = .{
5182 .location = .{
5183 .line = line_number,
5184 .column = 0,
5185 .scope = self.scope,
5186 .inlined_at = inlined_at_location,
5187 },
5188 };
5189 }
5190
5132 self.scope = try self.dg.object.builder.debugLexicalBlock(5191 self.scope = try self.dg.object.builder.debugLexicalBlock(
5133 old_scope,5192 self.scope,
5134 self.file,5193 self.file,
5135 self.prev_dbg_line,5194 self.prev_dbg_line,
5136 self.prev_dbg_column,5195 self.prev_dbg_column,
5137 );5196 );
5138 try self.genBody(body);5197 try self.genBody(body);
5139 self.scope = old_scope;
5140 }5198 }
51415199
5142 pub const CallAttr = enum {5200 pub const CallAttr = enum {
...@@ -5820,15 +5878,23 @@ pub const FuncGen = struct {...@@ -5820,15 +5878,23 @@ pub const FuncGen = struct {
5820 }5878 }
58215879
5822 fn airBlock(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5880 fn airBlock(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5823 const o = self.dg.object;
5824 const mod = o.module;
5825 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5881 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
5826 const extra = self.air.extraData(Air.Block, ty_pl.payload);5882 const extra = self.air.extraData(Air.Block, ty_pl.payload);
5827 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);5883 return self.lowerBlock(inst, null, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
5884 }
5885
5886 fn lowerBlock(
5887 self: *FuncGen,
5888 inst: Air.Inst.Index,
5889 maybe_inline_func: ?InternPool.Index,
5890 body: []const Air.Inst.Index,
5891 ) !Builder.Value {
5892 const o = self.dg.object;
5893 const mod = o.module;
5828 const inst_ty = self.typeOfIndex(inst);5894 const inst_ty = self.typeOfIndex(inst);
58295895
5830 if (inst_ty.isNoReturn(mod)) {5896 if (inst_ty.isNoReturn(mod)) {
5831 try self.genBodyDebugScope(body);5897 try self.genBodyDebugScope(maybe_inline_func, body);
5832 return .none;5898 return .none;
5833 }5899 }
58345900
...@@ -5844,7 +5910,7 @@ pub const FuncGen = struct {...@@ -5844,7 +5910,7 @@ pub const FuncGen = struct {
5844 });5910 });
5845 defer assert(self.blocks.remove(inst));5911 defer assert(self.blocks.remove(inst));
58465912
5847 try self.genBodyDebugScope(body);5913 try self.genBodyDebugScope(maybe_inline_func, body);
58485914
5849 self.wip.cursor = .{ .block = parent_bb };5915 self.wip.cursor = .{ .block = parent_bb };
58505916
...@@ -5903,10 +5969,10 @@ pub const FuncGen = struct {...@@ -5903,10 +5969,10 @@ pub const FuncGen = struct {
5903 _ = try self.wip.brCond(cond, then_block, else_block);5969 _ = try self.wip.brCond(cond, then_block, else_block);
59045970
5905 self.wip.cursor = .{ .block = then_block };5971 self.wip.cursor = .{ .block = then_block };
5906 try self.genBodyDebugScope(then_body);5972 try self.genBodyDebugScope(null, then_body);
59075973
5908 self.wip.cursor = .{ .block = else_block };5974 self.wip.cursor = .{ .block = else_block };
5909 try self.genBodyDebugScope(else_body);5975 try self.genBodyDebugScope(null, else_body);
59105976
5911 // No need to reset the insert cursor since this instruction is noreturn.5977 // No need to reset the insert cursor since this instruction is noreturn.
5912 return .none;5978 return .none;
...@@ -5987,7 +6053,7 @@ pub const FuncGen = struct {...@@ -5987,7 +6053,7 @@ pub const FuncGen = struct {
5987 _ = try fg.wip.brCond(is_err, return_block, continue_block);6053 _ = try fg.wip.brCond(is_err, return_block, continue_block);
59886054
5989 fg.wip.cursor = .{ .block = return_block };6055 fg.wip.cursor = .{ .block = return_block };
5990 try fg.genBodyDebugScope(body);6056 try fg.genBodyDebugScope(null, body);
59916057
5992 fg.wip.cursor = .{ .block = continue_block };6058 fg.wip.cursor = .{ .block = continue_block };
5993 }6059 }
...@@ -6060,13 +6126,13 @@ pub const FuncGen = struct {...@@ -6060,13 +6126,13 @@ pub const FuncGen = struct {
6060 }6126 }
60616127
6062 self.wip.cursor = .{ .block = case_block };6128 self.wip.cursor = .{ .block = case_block };
6063 try self.genBodyDebugScope(case_body);6129 try self.genBodyDebugScope(null, case_body);
6064 }6130 }
60656131
6066 self.wip.cursor = .{ .block = else_block };6132 self.wip.cursor = .{ .block = else_block };
6067 const else_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra_index..][0..switch_br.data.else_body_len]);6133 const else_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra_index..][0..switch_br.data.else_body_len]);
6068 if (else_body.len != 0) {6134 if (else_body.len != 0) {
6069 try self.genBodyDebugScope(else_body);6135 try self.genBodyDebugScope(null, else_body);
6070 } else {6136 } else {
6071 _ = try self.wip.@"unreachable"();6137 _ = try self.wip.@"unreachable"();
6072 }6138 }
...@@ -6085,7 +6151,7 @@ pub const FuncGen = struct {...@@ -6085,7 +6151,7 @@ pub const FuncGen = struct {
6085 _ = try self.wip.br(loop_block);6151 _ = try self.wip.br(loop_block);
60866152
6087 self.wip.cursor = .{ .block = loop_block };6153 self.wip.cursor = .{ .block = loop_block };
6088 try self.genBodyDebugScope(body);6154 try self.genBodyDebugScope(null, body);
60896155
6090 // TODO instead of this logic, change AIR to have the property that6156 // TODO instead of this logic, change AIR to have the property that
6091 // every block is guaranteed to end with a noreturn instruction.6157 // every block is guaranteed to end with a noreturn instruction.
...@@ -6592,96 +6658,22 @@ pub const FuncGen = struct {...@@ -6592,96 +6658,22 @@ pub const FuncGen = struct {
6592 self.prev_dbg_line = @intCast(self.base_line + dbg_stmt.line + 1);6658 self.prev_dbg_line = @intCast(self.base_line + dbg_stmt.line + 1);
6593 self.prev_dbg_column = @intCast(dbg_stmt.column + 1);6659 self.prev_dbg_column = @intCast(dbg_stmt.column + 1);
65946660
6595 const inlined_at_location = if (self.inlined.getLastOrNull()) |inlined|
6596 try inlined.location.toMetadata(self.wip.builder)
6597 else
6598 .none;
6599
6600 self.wip.debug_location = .{6661 self.wip.debug_location = .{
6601 .location = .{6662 .location = .{
6602 .line = self.prev_dbg_line,6663 .line = self.prev_dbg_line,
6603 .column = self.prev_dbg_column,6664 .column = self.prev_dbg_column,
6604 .scope = self.scope,6665 .scope = self.scope,
6605 .inlined_at = inlined_at_location,6666 .inlined_at = try self.inlined.toMetadata(self.wip.builder),
6606 },6667 },
6607 };6668 };
66086669
6609 return .none;6670 return .none;
6610 }6671 }
66116672
6612 fn airDbgInlineBegin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6673 fn airDbgInlineBlock(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6613 const o = self.dg.object;6674 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6614 const zcu = o.module;6675 const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
66156676 return self.lowerBlock(inst, extra.data.func, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
6616 const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
6617 const func = zcu.funcInfo(ty_fn.func);
6618 const decl_index = func.owner_decl;
6619 const decl = zcu.declPtr(decl_index);
6620 const namespace = zcu.namespacePtr(decl.src_namespace);
6621 const owner_mod = namespace.file_scope.mod;
6622
6623 self.file = try o.getDebugFile(namespace.file_scope);
6624
6625 const line_number = decl.src_line + 1;
6626 try self.inlined.append(self.gpa, .{
6627 .location = self.wip.debug_location,
6628 .scope = self.scope,
6629 .base_line = self.base_line,
6630 });
6631
6632 const fqn = try decl.fullyQualifiedName(zcu);
6633
6634 const is_internal_linkage = !zcu.decl_exports.contains(decl_index);
6635 const fn_ty = try zcu.funcType(.{
6636 .param_types = &.{},
6637 .return_type = .void_type,
6638 });
6639
6640 self.scope = try o.builder.debugSubprogram(
6641 self.file,
6642 try o.builder.metadataString(zcu.intern_pool.stringToSlice(decl.name)),
6643 try o.builder.metadataString(zcu.intern_pool.stringToSlice(fqn)),
6644 line_number,
6645 line_number + func.lbrace_line,
6646 try o.lowerDebugType(fn_ty),
6647 .{
6648 .di_flags = .{ .StaticMember = true },
6649 .sp_flags = .{
6650 .Optimized = owner_mod.optimize_mode != .Debug,
6651 .Definition = true,
6652 .LocalToUnit = is_internal_linkage,
6653 },
6654 },
6655 o.debug_compile_unit,
6656 );
6657
6658 self.base_line = decl.src_line;
6659 const inlined_at_location = try self.wip.debug_location.toMetadata(&o.builder);
6660 self.wip.debug_location = .{
6661 .location = .{
6662 .line = line_number,
6663 .column = 0,
6664 .scope = self.scope,
6665 .inlined_at = inlined_at_location,
6666 },
6667 };
6668 return .none;
6669 }
6670
6671 fn airDbgInlineEnd(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
6672 const o = self.dg.object;
6673
6674 const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
6675
6676 const mod = o.module;
6677 const decl = mod.funcOwnerDeclPtr(ty_fn.func);
6678 self.file = try o.getDebugFile(mod.namespacePtr(decl.src_namespace).file_scope);
6679
6680 const old = self.inlined.pop();
6681 self.scope = old.scope;
6682 self.base_line = old.base_line;
6683 self.wip.debug_location = old.location;
6684 return .none;
6685 }6677 }
66866678
6687 fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6679 fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
src/codegen/spirv.zig+19-24
...@@ -208,6 +208,7 @@ pub const Object = struct {...@@ -208,6 +208,7 @@ pub const Object = struct {
208 false => .{ .unstructured = .{} },208 false => .{ .unstructured = .{} },
209 },209 },
210 .current_block_label = undefined,210 .current_block_label = undefined,
211 .base_line = decl.src_line,
211 };212 };
212 defer decl_gen.deinit();213 defer decl_gen.deinit();
213214
...@@ -321,9 +322,8 @@ const DeclGen = struct {...@@ -321,9 +322,8 @@ const DeclGen = struct {
321 /// The code (prologue and body) for the function we are currently generating code for.322 /// The code (prologue and body) for the function we are currently generating code for.
322 func: SpvModule.Fn = .{},323 func: SpvModule.Fn = .{},
323324
324 /// Stack of the base offsets of the current decl, which is what `dbg_stmt` is relative to.325 /// The base offset of the current decl, which is what `dbg_stmt` is relative to.
325 /// This is a stack to keep track of inline functions.326 base_line: u32,
326 base_line_stack: std.ArrayListUnmanaged(u32) = .{},
327327
328 /// If `gen` returned `Error.CodegenFail`, this contains an explanatory message.328 /// If `gen` returned `Error.CodegenFail`, this contains an explanatory message.
329 /// Memory is owned by `module.gpa`.329 /// Memory is owned by `module.gpa`.
...@@ -401,7 +401,6 @@ const DeclGen = struct {...@@ -401,7 +401,6 @@ const DeclGen = struct {
401 self.wip_pointers.deinit(self.gpa);401 self.wip_pointers.deinit(self.gpa);
402 self.control_flow.deinit(self.gpa);402 self.control_flow.deinit(self.gpa);
403 self.func.deinit(self.gpa);403 self.func.deinit(self.gpa);
404 self.base_line_stack.deinit(self.gpa);
405 }404 }
406405
407 /// Return the target which we are currently compiling for.406 /// Return the target which we are currently compiling for.
...@@ -1959,8 +1958,6 @@ const DeclGen = struct {...@@ -1959,8 +1958,6 @@ const DeclGen = struct {
19591958
1960 const decl_id = self.spv.declPtr(spv_decl_index).result_id;1959 const decl_id = self.spv.declPtr(spv_decl_index).result_id;
19611960
1962 try self.base_line_stack.append(self.gpa, decl.src_line);
1963
1964 if (decl.val.getFunction(mod)) |_| {1961 if (decl.val.getFunction(mod)) |_| {
1965 assert(decl.ty.zigTypeTag(mod) == .Fn);1962 assert(decl.ty.zigTypeTag(mod) == .Fn);
1966 const fn_info = mod.typeToFunc(decl.ty).?;1963 const fn_info = mod.typeToFunc(decl.ty).?;
...@@ -2317,8 +2314,7 @@ const DeclGen = struct {...@@ -2317,8 +2314,7 @@ const DeclGen = struct {
2317 .unreach, .trap => return self.airUnreach(),2314 .unreach, .trap => return self.airUnreach(),
23182315
2319 .dbg_stmt => return self.airDbgStmt(inst),2316 .dbg_stmt => return self.airDbgStmt(inst),
2320 .dbg_inline_begin => return self.airDbgInlineBegin(inst),2317 .dbg_inline_block => try self.airDbgInlineBlock(inst),
2321 .dbg_inline_end => return self.airDbgInlineEnd(inst),
2322 .dbg_var_ptr, .dbg_var_val => return self.airDbgVar(inst),2318 .dbg_var_ptr, .dbg_var_val => return self.airDbgVar(inst),
23232319
2324 .unwrap_errunion_err => try self.airErrUnionErr(inst),2320 .unwrap_errunion_err => try self.airErrUnionErr(inst),
...@@ -4311,6 +4307,12 @@ const DeclGen = struct {...@@ -4311,6 +4307,12 @@ const DeclGen = struct {
4311 }4307 }
43124308
4313 fn airBlock(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4309 fn airBlock(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4310 const inst_datas = self.air.instructions.items(.data);
4311 const extra = self.air.extraData(Air.Block, inst_datas[@intFromEnum(inst)].ty_pl.payload);
4312 return self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
4313 }
4314
4315 fn lowerBlock(self: *DeclGen, inst: Air.Inst.Index, body: []const Air.Inst.Index) !?IdRef {
4314 // In AIR, a block doesn't really define an entry point like a block, but4316 // In AIR, a block doesn't really define an entry point like a block, but
4315 // more like a scope that breaks can jump out of and "return" a value from.4317 // more like a scope that breaks can jump out of and "return" a value from.
4316 // This cannot be directly modelled in SPIR-V, so in a block instruction,4318 // This cannot be directly modelled in SPIR-V, so in a block instruction,
...@@ -4320,10 +4322,6 @@ const DeclGen = struct {...@@ -4320,10 +4322,6 @@ const DeclGen = struct {
43204322
4321 const mod = self.module;4323 const mod = self.module;
4322 const ty = self.typeOfIndex(inst);4324 const ty = self.typeOfIndex(inst);
4323 const inst_datas = self.air.instructions.items(.data);
4324 const extra = self.air.extraData(Air.Block, inst_datas[@intFromEnum(inst)].ty_pl.payload);
4325 const body: []const Air.Inst.Index =
4326 @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
4327 const have_block_result = ty.isFnOrHasRuntimeBitsIgnoreComptime(mod);4325 const have_block_result = ty.isFnOrHasRuntimeBitsIgnoreComptime(mod);
43284326
4329 const cf = switch (self.control_flow) {4327 const cf = switch (self.control_flow) {
...@@ -5157,25 +5155,22 @@ const DeclGen = struct {...@@ -5157,25 +5155,22 @@ const DeclGen = struct {
5157 const decl = mod.declPtr(self.decl_index);5155 const decl = mod.declPtr(self.decl_index);
5158 const path = decl.getFileScope(mod).sub_file_path;5156 const path = decl.getFileScope(mod).sub_file_path;
5159 const src_fname_id = try self.spv.resolveSourceFileName(path);5157 const src_fname_id = try self.spv.resolveSourceFileName(path);
5160 const base_line = self.base_line_stack.getLast();
5161 try self.func.body.emit(self.spv.gpa, .OpLine, .{5158 try self.func.body.emit(self.spv.gpa, .OpLine, .{
5162 .file = src_fname_id,5159 .file = src_fname_id,
5163 .line = base_line + dbg_stmt.line + 1,5160 .line = self.base_line + dbg_stmt.line + 1,
5164 .column = dbg_stmt.column + 1,5161 .column = dbg_stmt.column + 1,
5165 });5162 });
5166 }5163 }
51675164
5168 fn airDbgInlineBegin(self: *DeclGen, inst: Air.Inst.Index) !void {5165 fn airDbgInlineBlock(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5169 const mod = self.module;5166 const mod = self.module;
5170 const fn_ty = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;5167 const inst_datas = self.air.instructions.items(.data);
5171 const decl_index = mod.funcInfo(fn_ty.func).owner_decl;5168 const extra = self.air.extraData(Air.DbgInlineBlock, inst_datas[@intFromEnum(inst)].ty_pl.payload);
5172 const decl = mod.declPtr(decl_index);5169 const decl = mod.funcOwnerDeclPtr(extra.data.func);
5173 try self.base_line_stack.append(self.gpa, decl.src_line);5170 const old_base_line = self.base_line;
5174 }5171 defer self.base_line = old_base_line;
51755172 self.base_line = decl.src_line;
5176 fn airDbgInlineEnd(self: *DeclGen, inst: Air.Inst.Index) !void {5173 return self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
5177 _ = inst;
5178 _ = self.base_line_stack.pop();
5179 }5174 }
51805175
5181 fn airDbgVar(self: *DeclGen, inst: Air.Inst.Index) !void {5176 fn airDbgVar(self: *DeclGen, inst: Air.Inst.Index) !void {
src/print_air.zig+23-14
...@@ -260,7 +260,7 @@ const Writer = struct {...@@ -260,7 +260,7 @@ const Writer = struct {
260 .c_va_copy,260 .c_va_copy,
261 => try w.writeTyOp(s, inst),261 => try w.writeTyOp(s, inst),
262262
263 .block => try w.writeBlock(s, inst),263 .block, .dbg_inline_block => try w.writeBlock(s, tag, inst),
264264
265 .loop => try w.writeLoop(s, inst),265 .loop => try w.writeLoop(s, inst),
266266
...@@ -292,7 +292,6 @@ const Writer = struct {...@@ -292,7 +292,6 @@ const Writer = struct {
292 .assembly => try w.writeAssembly(s, inst),292 .assembly => try w.writeAssembly(s, inst),
293 .dbg_stmt => try w.writeDbgStmt(s, inst),293 .dbg_stmt => try w.writeDbgStmt(s, inst),
294294
295 .dbg_inline_begin, .dbg_inline_end => try w.writeDbgInline(s, inst),
296 .aggregate_init => try w.writeAggregateInit(s, inst),295 .aggregate_init => try w.writeAggregateInit(s, inst),
297 .union_init => try w.writeUnionInit(s, inst),296 .union_init => try w.writeUnionInit(s, inst),
298 .br => try w.writeBr(s, inst),297 .br => try w.writeBr(s, inst),
...@@ -367,17 +366,34 @@ const Writer = struct {...@@ -367,17 +366,34 @@ const Writer = struct {
367 try w.writeOperand(s, inst, 0, ty_op.operand);366 try w.writeOperand(s, inst, 0, ty_op.operand);
368 }367 }
369368
370 fn writeBlock(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {369 fn writeBlock(w: *Writer, s: anytype, tag: Air.Inst.Tag, inst: Air.Inst.Index) @TypeOf(s).Error!void {
371 const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;370 const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
372 const extra = w.air.extraData(Air.Block, ty_pl.payload);371 try w.writeType(s, ty_pl.ty.toType());
373 const body: []const Air.Inst.Index = @ptrCast(w.air.extra[extra.end..][0..extra.data.body_len]);372 const body: []const Air.Inst.Index = @ptrCast(switch (tag) {
373 inline .block, .dbg_inline_block => |comptime_tag| body: {
374 const extra = w.air.extraData(switch (comptime_tag) {
375 .block => Air.Block,
376 .dbg_inline_block => Air.DbgInlineBlock,
377 else => unreachable,
378 }, ty_pl.payload);
379 switch (comptime_tag) {
380 .block => {},
381 .dbg_inline_block => {
382 try s.writeAll(", ");
383 try w.writeInstRef(s, Air.internedToRef(extra.data.func), false);
384 },
385 else => unreachable,
386 }
387 break :body w.air.extra[extra.end..][0..extra.data.body_len];
388 },
389 else => unreachable,
390 });
391 if (w.skip_body) return s.writeAll(", ...");
374 const liveness_block = if (w.liveness) |liveness|392 const liveness_block = if (w.liveness) |liveness|
375 liveness.getBlock(inst)393 liveness.getBlock(inst)
376 else394 else
377 Liveness.BlockSlices{ .deaths = &.{} };395 Liveness.BlockSlices{ .deaths = &.{} };
378396
379 try w.writeType(s, ty_pl.ty.toType());
380 if (w.skip_body) return s.writeAll(", ...");
381 try s.writeAll(", {\n");397 try s.writeAll(", {\n");
382 const old_indent = w.indent;398 const old_indent = w.indent;
383 w.indent += 2;399 w.indent += 2;
...@@ -661,13 +677,6 @@ const Writer = struct {...@@ -661,13 +677,6 @@ const Writer = struct {
661 try s.print("{d}:{d}", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 });677 try s.print("{d}:{d}", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 });
662 }678 }
663679
664 fn writeDbgInline(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
665 const ty_fn = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
666 const func_index = ty_fn.func;
667 const owner_decl = w.module.funcOwnerDeclPtr(func_index);
668 try s.print("{}", .{owner_decl.name.fmt(&w.module.intern_pool)});
669 }
670
671 fn writeDbgVar(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {680 fn writeDbgVar(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
672 const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;681 const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
673 try w.writeOperand(s, inst, 0, pl_op.operand);682 try w.writeOperand(s, inst, 0, pl_op.operand);
test/behavior/switch.zig+17
...@@ -913,3 +913,20 @@ test "switch prong captures range" {...@@ -913,3 +913,20 @@ test "switch prong captures range" {
913 S.a(&arr, 5);913 S.a(&arr, 5);
914 try expect(arr[5] == 5);914 try expect(arr[5] == 5);
915}915}
916
917test "prong with inline call to unreachable" {
918 const U = union(enum) {
919 void: void,
920 bool: bool,
921
922 inline fn unreach() noreturn {
923 unreachable;
924 }
925 };
926 var u: U = undefined;
927 u = .{ .bool = true };
928 switch (u) {
929 .void => U.unreach(),
930 .bool => |ok| try expect(ok),
931 }
932}