authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-02-27 03:25:04+00:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-02-27 03:25:04+00:00
log8775d8bbcef347640c6ae7e73da02ca6eff1d669
tree3f04f80b042d7baf10074b6f88fabb5693b2b71e
parentf803761e13a65ccbc6a5508f2dc2d7723b010dab
parent59447e53056d8fb6682b79accccffa176d0b44d1
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #19062 from mlugg/dbg-var-blocks

compiler: decide dbg_var scoping based on AIR blocks

18 files changed, 187 insertions(+), 287 deletions(-)

src/Air.zig-8
......@@ -443,10 +443,6 @@ pub const Inst = struct {
443443 /// Result type is always void.
444444 /// Uses the `dbg_stmt` field.
445445 dbg_stmt,
446 /// Marks the beginning of a semantic scope for debug info variables.
447 dbg_block_begin,
448 /// Marks the end of a semantic scope for debug info variables.
449 dbg_block_end,
450446 /// Marks the start of an inline call.
451447 /// Uses the `ty_fn` field.
452448 dbg_inline_begin,
......@@ -1454,8 +1450,6 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)
14541450 .dbg_stmt,
14551451 .dbg_inline_begin,
14561452 .dbg_inline_end,
1457 .dbg_block_begin,
1458 .dbg_block_end,
14591453 .dbg_var_ptr,
14601454 .dbg_var_val,
14611455 .store,
......@@ -1612,8 +1606,6 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool {
16121606 .@"try",
16131607 .try_ptr,
16141608 .dbg_stmt,
1615 .dbg_block_begin,
1616 .dbg_block_end,
16171609 .dbg_inline_begin,
16181610 .dbg_inline_end,
16191611 .dbg_var_ptr,
src/AstGen.zig-51
......@@ -2445,8 +2445,6 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod
24452445
24462446 if (statements.len == 0) return;
24472447
2448 try gz.addDbgBlockBegin();
2449
24502448 var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa);
24512449 defer block_arena.deinit();
24522450 const block_arena_allocator = block_arena.allocator();
......@@ -2518,8 +2516,6 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod
25182516 }
25192517 }
25202518
2521 try gz.addDbgBlockEnd();
2522
25232519 try genDefers(gz, parent_scope, scope, .normal_only);
25242520 try checkUsed(gz, parent_scope, scope);
25252521}
......@@ -2804,8 +2800,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
28042800 .dbg_stmt,
28052801 .dbg_var_ptr,
28062802 .dbg_var_val,
2807 .dbg_block_begin,
2808 .dbg_block_end,
28092803 .ensure_result_used,
28102804 .ensure_result_non_error,
28112805 .ensure_err_union_payload_void,
......@@ -3026,7 +3020,6 @@ fn deferStmt(
30263020 var opt_remapped_err_code: Zir.Inst.OptionalIndex = .none;
30273021 const have_err_code = scope_tag == .defer_error and payload_token != 0;
30283022 const sub_scope = if (!have_err_code) &defer_gen.base else blk: {
3029 try gz.addDbgBlockBegin();
30303023 const ident_name = try gz.astgen.identAsString(payload_token);
30313024 const remapped_err_code: Zir.Inst.Index = @enumFromInt(gz.astgen.instructions.len);
30323025 opt_remapped_err_code = remapped_err_code.toOptional();
......@@ -3052,7 +3045,6 @@ fn deferStmt(
30523045 };
30533046 _ = try unusedResultExpr(&defer_gen, sub_scope, expr_node);
30543047 try checkUsed(gz, scope, sub_scope);
3055 if (have_err_code) try gz.addDbgBlockEnd();
30563048 _ = try defer_gen.addBreak(.break_inline, @enumFromInt(0), .void_value);
30573049
30583050 // We must handle ref_table for remapped_err_code manually.
......@@ -6245,7 +6237,6 @@ fn ifExpr(
62456237
62466238 var payload_val_scope: Scope.LocalVal = undefined;
62476239
6248 try then_scope.addDbgBlockBegin();
62496240 const then_node = if_full.ast.then_expr;
62506241 const then_sub_scope = s: {
62516242 if (if_full.error_token != null) {
......@@ -6305,7 +6296,6 @@ fn ifExpr(
63056296 const then_result = try expr(&then_scope, then_sub_scope, block_scope.break_result_info, then_node);
63066297 try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
63076298 if (!then_scope.endsWithNoReturn()) {
6308 try then_scope.addDbgBlockEnd();
63096299 _ = try then_scope.addBreakWithSrcNode(.@"break", block, then_result, then_node);
63106300 }
63116301
......@@ -6319,7 +6309,6 @@ fn ifExpr(
63196309
63206310 const else_node = if_full.ast.else_expr;
63216311 if (else_node != 0) {
6322 try else_scope.addDbgBlockBegin();
63236312 const sub_scope = s: {
63246313 if (if_full.error_token) |error_token| {
63256314 const tag: Zir.Inst.Tag = if (payload_is_ref)
......@@ -6347,7 +6336,6 @@ fn ifExpr(
63476336 }
63486337 };
63496338 const else_result = try expr(&else_scope, sub_scope, block_scope.break_result_info, else_node);
6350 try else_scope.addDbgBlockEnd();
63516339 if (!else_scope.endsWithNoReturn()) {
63526340 // As our last action before the break, "pop" the error trace if needed
63536341 if (do_err_trace)
......@@ -6579,7 +6567,6 @@ fn whileExpr(
65796567 // done adding instructions to loop_scope, can now stack then_scope
65806568 then_scope.instructions_top = then_scope.instructions.items.len;
65816569
6582 try then_scope.addDbgBlockBegin();
65836570 const then_node = while_full.ast.then_expr;
65846571 if (opt_payload_inst.unwrap()) |payload_inst| {
65856572 try then_scope.instructions.append(astgen.gpa, payload_inst);
......@@ -6593,7 +6580,6 @@ fn whileExpr(
65936580 if (while_full.ast.cont_expr != 0) {
65946581 _ = try unusedResultExpr(&then_scope, then_sub_scope, while_full.ast.cont_expr);
65956582 }
6596 try then_scope.addDbgBlockEnd();
65976583
65986584 continue_scope.instructions_top = continue_scope.instructions.items.len;
65996585 _ = try unusedResultExpr(&continue_scope, &continue_scope.base, then_node);
......@@ -6610,7 +6596,6 @@ fn whileExpr(
66106596
66116597 const else_node = while_full.ast.else_expr;
66126598 if (else_node != 0) {
6613 try else_scope.addDbgBlockBegin();
66146599 const sub_scope = s: {
66156600 if (while_full.error_token) |error_token| {
66166601 const tag: Zir.Inst.Tag = if (payload_is_ref)
......@@ -6647,7 +6632,6 @@ fn whileExpr(
66476632 }
66486633
66496634 try checkUsed(parent_gz, &else_scope.base, sub_scope);
6650 try else_scope.addDbgBlockEnd();
66516635 if (!else_scope.endsWithNoReturn()) {
66526636 _ = try else_scope.addBreakWithSrcNode(break_tag, loop_block, else_result, else_node);
66536637 }
......@@ -6849,8 +6833,6 @@ fn forExpr(
68496833 var then_scope = parent_gz.makeSubBlock(&cond_scope.base);
68506834 defer then_scope.unstack();
68516835
6852 try then_scope.addDbgBlockBegin();
6853
68546836 const capture_scopes = try gpa.alloc(Scope.LocalVal, for_full.ast.inputs.len);
68556837 defer gpa.free(capture_scopes);
68566838
......@@ -6916,7 +6898,6 @@ fn forExpr(
69166898 _ = try addEnsureResult(&then_scope, then_result, then_node);
69176899
69186900 try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
6919 try then_scope.addDbgBlockEnd();
69206901
69216902 const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break";
69226903
......@@ -7149,8 +7130,6 @@ fn switchExprErrUnion(
71497130 case_scope.instructions_top = parent_gz.instructions.items.len;
71507131 defer case_scope.unstack();
71517132
7152 try case_scope.addDbgBlockBegin();
7153
71547133 const unwrap_payload_tag: Zir.Inst.Tag = if (payload_is_ref)
71557134 .err_union_payload_unsafe_ptr
71567135 else
......@@ -7173,7 +7152,6 @@ fn switchExprErrUnion(
71737152 catch_or_if_node,
71747153 ),
71757154 };
7176 try case_scope.addDbgBlockEnd();
71777155 _ = try case_scope.addBreakWithSrcNode(
71787156 .@"break",
71797157 switch_block,
......@@ -7184,7 +7162,6 @@ fn switchExprErrUnion(
71847162 .@"if" => {
71857163 var payload_val_scope: Scope.LocalVal = undefined;
71867164
7187 try case_scope.addDbgBlockBegin();
71887165 const then_node = if_full.ast.then_expr;
71897166 const then_sub_scope = s: {
71907167 assert(if_full.error_token != null);
......@@ -7228,7 +7205,6 @@ fn switchExprErrUnion(
72287205 );
72297206 try checkUsed(parent_gz, &case_scope.base, then_sub_scope);
72307207 if (!case_scope.endsWithNoReturn()) {
7231 try case_scope.addDbgBlockEnd();
72327208 _ = try case_scope.addBreakWithSrcNode(
72337209 .@"break",
72347210 switch_block,
......@@ -7407,7 +7383,6 @@ fn switchExprErrUnion(
74077383 if (do_err_trace and nodeMayAppendToErrorTrace(tree, operand_node))
74087384 _ = try case_scope.addSaveErrRetIndex(.always);
74097385
7410 try case_scope.addDbgBlockBegin();
74117386 if (dbg_var_name != .empty) {
74127387 try case_scope.addDbgVar(.dbg_var_val, dbg_var_name, dbg_var_inst);
74137388 }
......@@ -7421,7 +7396,6 @@ fn switchExprErrUnion(
74217396 try case_scope.addDbgVar(.dbg_var_val, err_name, err_inst.toRef());
74227397 any_uses_err_capture = true;
74237398 }
7424 try case_scope.addDbgBlockEnd();
74257399
74267400 if (!parent_gz.refIsNoReturn(case_result)) {
74277401 if (do_err_trace)
......@@ -7868,7 +7842,6 @@ fn switchExpr(
78687842 case_scope.instructions_top = parent_gz.instructions.items.len;
78697843 defer case_scope.unstack();
78707844
7871 try case_scope.addDbgBlockBegin();
78727845 if (dbg_var_name != .empty) {
78737846 try case_scope.addDbgVar(.dbg_var_val, dbg_var_name, dbg_var_inst);
78747847 }
......@@ -7878,7 +7851,6 @@ fn switchExpr(
78787851 const target_expr_node = case.ast.target_expr;
78797852 const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node);
78807853 try checkUsed(parent_gz, &case_scope.base, sub_scope);
7881 try case_scope.addDbgBlockEnd();
78827854 if (!parent_gz.refIsNoReturn(case_result)) {
78837855 _ = try case_scope.addBreakWithSrcNode(.@"break", switch_block, case_result, target_expr_node);
78847856 }
......@@ -13165,29 +13137,6 @@ const GenZir = struct {
1316513137 },
1316613138 } });
1316713139 }
13168
13169 fn addDbgBlockBegin(gz: *GenZir) !void {
13170 if (gz.is_comptime) return;
13171
13172 _ = try gz.add(.{ .tag = .dbg_block_begin, .data = undefined });
13173 }
13174
13175 fn addDbgBlockEnd(gz: *GenZir) !void {
13176 if (gz.is_comptime) return;
13177 const gpa = gz.astgen.gpa;
13178
13179 const tags = gz.astgen.instructions.items(.tag);
13180 const last_inst = gz.instructions.items[gz.instructions.items.len - 1];
13181 // remove dbg_block_begin immediately followed by dbg_block_end
13182 if (tags[@intFromEnum(last_inst)] == .dbg_block_begin) {
13183 _ = gz.instructions.pop();
13184 return;
13185 }
13186
13187 const new_index: Zir.Inst.Index = @enumFromInt(gz.astgen.instructions.len);
13188 try gz.astgen.instructions.append(gpa, .{ .tag = .dbg_block_end, .data = undefined });
13189 try gz.instructions.append(gpa, new_index);
13190 }
1319113140};
1319213141
1319313142/// This can only be for short-lived references; the memory becomes invalidated
src/Liveness.zig-4
......@@ -329,8 +329,6 @@ pub fn categorizeOperand(
329329 .dbg_stmt,
330330 .dbg_inline_begin,
331331 .dbg_inline_end,
332 .dbg_block_begin,
333 .dbg_block_end,
334332 .unreach,
335333 .ret_addr,
336334 .frame_addr,
......@@ -967,8 +965,6 @@ fn analyzeInst(
967965 .dbg_stmt,
968966 .dbg_inline_begin,
969967 .dbg_inline_end,
970 .dbg_block_begin,
971 .dbg_block_end,
972968 .fence,
973969 .ret_addr,
974970 .frame_addr,
src/Liveness/Verify.zig-2
......@@ -48,8 +48,6 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
4848 .dbg_stmt,
4949 .dbg_inline_begin,
5050 .dbg_inline_end,
51 .dbg_block_begin,
52 .dbg_block_end,
5351 .fence,
5452 .ret_addr,
5553 .frame_addr,
src/Sema.zig+148-124
......@@ -364,6 +364,12 @@ pub const Block = struct {
364364
365365 c_import_buf: ?*std.ArrayList(u8) = null,
366366
367 /// If not `null`, this boolean is set when a `dbg_var_ptr` or `dbg_var_val`
368 /// instruction is emitted. It signals that the innermost lexically
369 /// enclosing `block`/`block_inline` should be translated into a real AIR
370 /// `block` in order for codegen to match lexical scoping for debug vars.
371 need_debug_scope: ?*bool = null,
372
367373 const ComptimeReason = union(enum) {
368374 c_import: struct {
369375 block: *Block,
......@@ -482,6 +488,7 @@ pub const Block = struct {
482488 .float_mode = parent.float_mode,
483489 .c_import_buf = parent.c_import_buf,
484490 .error_return_trace_index = parent.error_return_trace_index,
491 .need_debug_scope = parent.need_debug_scope,
485492 };
486493 }
487494
......@@ -986,8 +993,6 @@ fn analyzeBodyInner(
986993 crash_info.push();
987994 defer crash_info.pop();
988995
989 var dbg_block_begins: u32 = 0;
990
991996 // We use a while (true) loop here to avoid a redundant way of breaking out of
992997 // the loop. The only way to break out of the loop is with a `noreturn`
993998 // instruction.
......@@ -1332,18 +1337,6 @@ fn analyzeBodyInner(
13321337 i += 1;
13331338 continue;
13341339 },
1335 .dbg_block_begin => {
1336 dbg_block_begins += 1;
1337 try zirDbgBlockBegin(block);
1338 i += 1;
1339 continue;
1340 },
1341 .dbg_block_end => {
1342 dbg_block_begins -= 1;
1343 try zirDbgBlockEnd(block);
1344 i += 1;
1345 continue;
1346 },
13471340 .ensure_err_union_payload_void => {
13481341 try sema.zirEnsureErrUnionPayloadVoid(block, inst);
13491342 i += 1;
......@@ -1641,10 +1634,12 @@ fn analyzeBodyInner(
16411634 const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len);
16421635 const gpa = sema.gpa;
16431636
1644 const opt_break_data = b: {
1637 const opt_break_data, const need_debug_scope = b: {
16451638 // Create a temporary child block so that this inline block is properly
16461639 // labeled for any .restore_err_ret_index instructions
16471640 var child_block = block.makeSubBlock();
1641 var need_debug_scope = false;
1642 child_block.need_debug_scope = &need_debug_scope;
16481643
16491644 // If this block contains a function prototype, we need to reset the
16501645 // current list of parameters and restore it later.
......@@ -1665,7 +1660,11 @@ fn analyzeBodyInner(
16651660 child_block.instructions = block.instructions;
16661661 defer block.instructions = child_block.instructions;
16671662
1668 break :b try sema.analyzeBodyBreak(&child_block, inline_body);
1663 const result = try sema.analyzeBodyBreak(&child_block, inline_body);
1664 if (need_debug_scope) {
1665 _ = try sema.ensurePostHoc(block, inst);
1666 }
1667 break :b .{ result, need_debug_scope };
16691668 };
16701669
16711670 // A runtime conditional branch that needs a post-hoc block to be
......@@ -1686,28 +1685,22 @@ fn analyzeBodyInner(
16861685 // since it crosses a runtime branch.
16871686 // It may pass through our currently being analyzed block_inline or it
16881687 // may point directly to it. In the latter case, this modifies the
1689 // block that we are about to look up in the post_hoc_blocks map below.
1688 // block that we looked up in the post_hoc_blocks map above.
16901689 try sema.addRuntimeBreak(block, break_data);
1691 } else {
1692 // Here the comptime control flow ends with noreturn; however
1693 // we have runtime control flow continuing after this block.
1694 // This branch is therefore handled by the `i += 1; continue;`
1695 // logic below.
16961690 }
16971691
16981692 try labeled_block.block.instructions.appendSlice(gpa, block.instructions.items[block_index..]);
16991693 block.instructions.items.len = block_index;
17001694
1701 const block_result = try sema.analyzeBlockBody(block, inst_data.src(), &labeled_block.block, &labeled_block.label.merges);
1695 const block_result = try sema.analyzeBlockBody(block, inst_data.src(), &labeled_block.block, &labeled_block.label.merges, need_debug_scope);
17021696 {
17031697 // Destroy the ad-hoc block entry so that it does not interfere with
17041698 // the next iteration of comptime control flow, if any.
17051699 labeled_block.destroy(gpa);
17061700 assert(sema.post_hoc_blocks.remove(new_block_inst));
17071701 }
1708 map.putAssumeCapacity(inst, block_result);
1709 i += 1;
1710 continue;
1702
1703 break :blk block_result;
17111704 }
17121705
17131706 const break_data = opt_break_data orelse break always_noreturn;
......@@ -1860,19 +1853,6 @@ fn analyzeBodyInner(
18601853 i += 1;
18611854 };
18621855
1863 // balance out dbg_block_begins in case of early noreturn
1864 if (!block.is_comptime and !block.ownerModule().strip) {
1865 const noreturn_inst = block.instructions.popOrNull();
1866 while (dbg_block_begins > 0) {
1867 dbg_block_begins -= 1;
1868 _ = try block.addInst(.{
1869 .tag = .dbg_block_end,
1870 .data = undefined,
1871 });
1872 }
1873 if (noreturn_inst) |some| try block.instructions.append(sema.gpa, some);
1874 }
1875
18761856 // We may have overwritten the capture scope due to a `repeat` instruction where
18771857 // the body had a capture; restore it now.
18781858 block.wip_capture_scope = parent_capture_scope;
......@@ -5762,7 +5742,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
57625742 );
57635743 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(loop_block.instructions.items));
57645744 }
5765 return sema.analyzeBlockBody(parent_block, src, &child_block, merges);
5745 return sema.analyzeBlockBody(parent_block, src, &child_block, merges, false);
57665746}
57675747
57685748fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -5950,13 +5930,31 @@ fn resolveBlockBody(
59505930 if (child_block.is_comptime) {
59515931 return sema.resolveBody(child_block, body, body_inst);
59525932 } else {
5933 var need_debug_scope = false;
5934 child_block.need_debug_scope = &need_debug_scope;
59535935 if (sema.analyzeBodyInner(child_block, body)) |_| {
5954 return sema.analyzeBlockBody(parent_block, src, child_block, merges);
5936 return sema.analyzeBlockBody(parent_block, src, child_block, merges, need_debug_scope);
59555937 } else |err| switch (err) {
59565938 error.ComptimeBreak => {
59575939 // Comptime control flow is happening, however child_block may still contain
59585940 // runtime instructions which need to be copied to the parent block.
5959 try parent_block.instructions.appendSlice(sema.gpa, child_block.instructions.items);
5941 if (need_debug_scope and child_block.instructions.items.len > 0) {
5942 // We need a runtime block for scoping reasons.
5943 _ = try child_block.addBr(merges.block_inst, .void_value);
5944 try parent_block.instructions.append(sema.gpa, merges.block_inst);
5945 try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Block).Struct.fields.len +
5946 child_block.instructions.items.len);
5947 sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{
5948 .ty = .void_type,
5949 .payload = sema.addExtraAssumeCapacity(Air.Block{
5950 .body_len = @intCast(child_block.instructions.items.len),
5951 }),
5952 } };
5953 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(child_block.instructions.items));
5954 } else {
5955 // We can copy instructions directly to the parent block.
5956 try parent_block.instructions.appendSlice(sema.gpa, child_block.instructions.items);
5957 }
59605958
59615959 const break_inst = sema.comptime_break_inst;
59625960 const break_data = sema.code.instructions.items(.data)[@intFromEnum(break_inst)].@"break";
......@@ -5978,6 +5976,7 @@ fn analyzeBlockBody(
59785976 src: LazySrcLoc,
59795977 child_block: *Block,
59805978 merges: *Block.Merges,
5979 need_debug_scope: bool,
59815980) CompileError!Air.Inst.Ref {
59825981 const tracy = trace(@src());
59835982 defer tracy.end();
......@@ -5992,25 +5991,57 @@ fn analyzeBlockBody(
59925991 if (merges.results.items.len == 0) {
59935992 // No need for a block instruction. We can put the new instructions
59945993 // directly into the parent block.
5994 if (need_debug_scope) {
5995 // The code following this block is unreachable, as the block has no
5996 // merges, so we don't necessarily need to emit this as an AIR block.
5997 // However, we need a block *somewhere* to make the scoping correct,
5998 // so forward this request to the parent block.
5999 if (parent_block.need_debug_scope) |ptr| ptr.* = true;
6000 }
59956001 try parent_block.instructions.appendSlice(gpa, child_block.instructions.items);
59966002 return child_block.instructions.items[child_block.instructions.items.len - 1].toRef();
59976003 }
59986004 if (merges.results.items.len == 1) {
5999 const last_inst_index = child_block.instructions.items.len - 1;
6000 const last_inst = child_block.instructions.items[last_inst_index];
6001 if (sema.getBreakBlock(last_inst)) |br_block| {
6002 if (br_block == merges.block_inst) {
6003 // No need for a block instruction. We can put the new instructions directly
6004 // into the parent block. Here we omit the break instruction.
6005 const without_break = child_block.instructions.items[0..last_inst_index];
6006 try parent_block.instructions.appendSlice(gpa, without_break);
6007 return merges.results.items[0];
6008 }
6005 // If the `break` is trailing, we may be able to elide the AIR block here
6006 // by appending the new instructions directly to the parent block.
6007 if (!need_debug_scope) {
6008 const last_inst_index = child_block.instructions.items.len - 1;
6009 const last_inst = child_block.instructions.items[last_inst_index];
6010 if (sema.getBreakBlock(last_inst)) |br_block| {
6011 if (br_block == merges.block_inst) {
6012 // Great, the last instruction is the break! Put the instructions
6013 // directly into the parent block.
6014 try parent_block.instructions.appendSlice(gpa, child_block.instructions.items[0..last_inst_index]);
6015 return merges.results.items[0];
6016 }
6017 }
6018 }
6019 // Okay, we need a runtime block. If the value is comptime-known, the
6020 // block should just return void, and we return the merge result
6021 // directly. Otherwise, we can defer to the logic below.
6022 if (try sema.resolveValue(merges.results.items[0])) |result_val| {
6023 // Create a block containing all instruction from the body.
6024 try parent_block.instructions.append(gpa, merges.block_inst);
6025 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len +
6026 child_block.instructions.items.len);
6027 sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{
6028 .ty = .void_type,
6029 .payload = sema.addExtraAssumeCapacity(Air.Block{
6030 .body_len = @intCast(child_block.instructions.items.len),
6031 }),
6032 } };
6033 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(child_block.instructions.items));
6034 // Rewrite the break to just give value {}; the value is
6035 // comptime-known and will be returned directly.
6036 sema.air_instructions.items(.data)[@intFromEnum(merges.br_list.items[0])].br.operand = .void_value;
6037 return Air.internedToRef(result_val.toIntern());
60096038 }
60106039 }
60116040 // It is impossible to have the number of results be > 1 in a comptime scope.
60126041 assert(!child_block.is_comptime); // Should already got a compile error in the condbr condition.
60136042
6043 // Note that we'll always create an AIR block here, so `need_debug_scope` is irrelevant.
6044
60146045 // Need to set the type and emit the Block instruction. This allows machine code generation
60156046 // to emit a jump instruction to after the block when it encounters the break.
60166047 try parent_block.instructions.append(gpa, merges.block_inst);
......@@ -6388,24 +6419,6 @@ fn zirDbgStmt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
63886419 });
63896420}
63906421
6391fn zirDbgBlockBegin(block: *Block) CompileError!void {
6392 if (block.is_comptime or block.ownerModule().strip) return;
6393
6394 _ = try block.addInst(.{
6395 .tag = .dbg_block_begin,
6396 .data = undefined,
6397 });
6398}
6399
6400fn zirDbgBlockEnd(block: *Block) CompileError!void {
6401 if (block.is_comptime or block.ownerModule().strip) return;
6402
6403 _ = try block.addInst(.{
6404 .tag = .dbg_block_end,
6405 .data = undefined,
6406 });
6407}
6408
64096422fn zirDbgVar(
64106423 sema: *Sema,
64116424 block: *Block,
......@@ -6437,6 +6450,15 @@ fn addDbgVar(
64376450 if (try sema.typeRequiresComptime(val_ty)) return;
64386451 if (!(try sema.typeHasRuntimeBits(val_ty))) return;
64396452
6453 // To ensure the lexical scoping is known to backends, this alloc must be
6454 // within a real runtime block. We set a flag which communicates information
6455 // to the closest lexically enclosing block:
6456 // * If it is a `block_inline`, communicates to logic in `analyzeBodyInner`
6457 // to create a post-hoc block.
6458 // * Otherwise, communicates to logic in `resolveBlockBody` to create a
6459 // real `block` instruction.
6460 if (block.need_debug_scope) |ptr| ptr.* = true;
6461
64406462 try sema.queueFullTypeResolution(operand_ty);
64416463
64426464 // Add the name to the AIR.
......@@ -7590,7 +7612,7 @@ fn analyzeCall(
75907612 error.ComptimeReturn => break :result inlining.comptime_result,
75917613 else => |e| return e,
75927614 };
7593 break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges);
7615 break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges, false);
75947616 };
75957617
75967618 if (!is_comptime_call and !block.is_typeof and
......@@ -11534,7 +11556,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
1153411556 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(true_instructions));
1153511557 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(sub_block.instructions.items));
1153611558
11537 return sema.analyzeBlockBody(block, main_src, &child_block, merges);
11559 return sema.analyzeBlockBody(block, main_src, &child_block, merges, false);
1153811560}
1153911561
1154011562fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_ref: bool) CompileError!Air.Inst.Ref {
......@@ -12156,7 +12178,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
1215612178 false,
1215712179 );
1215812180
12159 return sema.analyzeBlockBody(block, src, &child_block, merges);
12181 return sema.analyzeBlockBody(block, src, &child_block, merges, false);
1216012182}
1216112183
1216212184const SpecialProng = struct {
......@@ -13169,8 +13191,6 @@ fn validateErrSetSwitch(
1316913191 const tags = sema.code.instructions.items(.tag);
1317013192 const datas = sema.code.instructions.items(.data);
1317113193 for (else_case.body) |else_inst| switch (tags[@intFromEnum(else_inst)]) {
13172 .dbg_block_begin,
13173 .dbg_block_end,
1317413194 .dbg_stmt,
1317513195 .dbg_var_val,
1317613196 .ret_type,
......@@ -13422,8 +13442,6 @@ fn maybeErrorUnwrap(
1342213442 .@"unreachable" => if (!block.wantSafety()) return false,
1342313443 .err_union_code => if (!allow_err_code_inst) return false,
1342413444 .save_err_ret_index,
13425 .dbg_block_begin,
13426 .dbg_block_end,
1342713445 .dbg_stmt,
1342813446 .str,
1342913447 .as_node,
......@@ -13436,10 +13454,7 @@ fn maybeErrorUnwrap(
1343613454
1343713455 for (body) |inst| {
1343813456 const air_inst = switch (tags[@intFromEnum(inst)]) {
13439 .dbg_block_begin,
13440 .dbg_block_end,
13441 .err_union_code,
13442 => continue,
13457 .err_union_code => continue,
1344313458 .dbg_stmt => {
1344413459 try sema.zirDbgStmt(block, inst);
1344513460 continue;
......@@ -13505,8 +13520,6 @@ fn maybeErrorUnwrapComptime(sema: *Sema, block: *Block, body: []const Zir.Inst.I
1350513520 const tags = sema.code.instructions.items(.tag);
1350613521 const inst = for (body) |inst| {
1350713522 switch (tags[@intFromEnum(inst)]) {
13508 .dbg_block_begin,
13509 .dbg_block_end,
1351013523 .dbg_stmt,
1351113524 .save_err_ret_index,
1351213525 => {},
......@@ -19098,55 +19111,64 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
1909819111 return try_inst;
1909919112}
1910019113
19114fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*LabeledBlock {
19115 const gop = sema.inst_map.getOrPutAssumeCapacity(dest_block);
19116 if (gop.found_existing) existing: {
19117 // This may be a *result* from an earlier iteration of an inline loop.
19118 // In this case, there will not be a post-hoc block entry, and we can
19119 // continue with the logic below.
19120 const new_block_inst = gop.value_ptr.*.toIndex() orelse break :existing;
19121 return sema.post_hoc_blocks.get(new_block_inst) orelse break :existing;
19122 }
19123
19124 try sema.post_hoc_blocks.ensureUnusedCapacity(sema.gpa, 1);
19125
19126 const new_block_inst: Air.Inst.Index = @enumFromInt(sema.air_instructions.len);
19127 gop.value_ptr.* = new_block_inst.toRef();
19128 try sema.air_instructions.append(sema.gpa, .{
19129 .tag = .block,
19130 .data = undefined,
19131 });
19132 const labeled_block = try sema.gpa.create(LabeledBlock);
19133 labeled_block.* = .{
19134 .label = .{
19135 .zir_block = dest_block,
19136 .merges = .{
19137 .src_locs = .{},
19138 .results = .{},
19139 .br_list = .{},
19140 .block_inst = new_block_inst,
19141 },
19142 },
19143 .block = .{
19144 .parent = block,
19145 .sema = sema,
19146 .src_decl = block.src_decl,
19147 .namespace = block.namespace,
19148 .wip_capture_scope = block.wip_capture_scope,
19149 .instructions = .{},
19150 .label = &labeled_block.label,
19151 .inlining = block.inlining,
19152 .is_comptime = block.is_comptime,
19153 },
19154 };
19155 sema.post_hoc_blocks.putAssumeCapacityNoClobber(new_block_inst, labeled_block);
19156 return labeled_block;
19157}
19158
1910119159// A `break` statement is inside a runtime condition, but trying to
1910219160// break from an inline loop. In such case we must convert it to
1910319161// a runtime break.
1910419162fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !void {
19105 const gop = sema.inst_map.getOrPutAssumeCapacity(break_data.block_inst);
19106 const labeled_block = if (!gop.found_existing) blk: {
19107 try sema.post_hoc_blocks.ensureUnusedCapacity(sema.gpa, 1);
19108
19109 const new_block_inst: Air.Inst.Index = @enumFromInt(sema.air_instructions.len);
19110 gop.value_ptr.* = new_block_inst.toRef();
19111 try sema.air_instructions.append(sema.gpa, .{
19112 .tag = .block,
19113 .data = undefined,
19114 });
19115 const labeled_block = try sema.gpa.create(LabeledBlock);
19116 labeled_block.* = .{
19117 .label = .{
19118 .zir_block = break_data.block_inst,
19119 .merges = .{
19120 .src_locs = .{},
19121 .results = .{},
19122 .br_list = .{},
19123 .block_inst = new_block_inst,
19124 },
19125 },
19126 .block = .{
19127 .parent = child_block,
19128 .sema = sema,
19129 .src_decl = child_block.src_decl,
19130 .namespace = child_block.namespace,
19131 .wip_capture_scope = child_block.wip_capture_scope,
19132 .instructions = .{},
19133 .label = &labeled_block.label,
19134 .inlining = child_block.inlining,
19135 .is_comptime = child_block.is_comptime,
19136 },
19137 };
19138 sema.post_hoc_blocks.putAssumeCapacityNoClobber(new_block_inst, labeled_block);
19139 break :blk labeled_block;
19140 } else blk: {
19141 const new_block_inst = gop.value_ptr.*.toIndex().?;
19142 const labeled_block = sema.post_hoc_blocks.get(new_block_inst).?;
19143 break :blk labeled_block;
19144 };
19163 const labeled_block = try sema.ensurePostHoc(child_block, break_data.block_inst);
1914519164
1914619165 const operand = try sema.resolveInst(break_data.operand);
1914719166 const br_ref = try child_block.addBr(labeled_block.label.merges.block_inst, operand);
19167
1914819168 try labeled_block.label.merges.results.append(sema.gpa, operand);
1914919169 try labeled_block.label.merges.br_list.append(sema.gpa, br_ref.toIndex().?);
19170 try labeled_block.label.merges.src_locs.append(sema.gpa, null);
19171
1915019172 labeled_block.block.runtime_index.increment();
1915119173 if (labeled_block.block.runtime_cond == null and labeled_block.block.runtime_loop == null) {
1915219174 labeled_block.block.runtime_cond = child_block.runtime_cond orelse child_block.runtime_loop;
......@@ -19487,8 +19509,10 @@ fn analyzeRet(
1948719509 return error.ComptimeReturn;
1948819510 }
1948919511 // We are inlining a function call; rewrite the `ret` as a `break`.
19512 const br_inst = try block.addBr(inlining.merges.block_inst, operand);
1949019513 try inlining.merges.results.append(sema.gpa, operand);
19491 _ = try block.addBr(inlining.merges.block_inst, operand);
19514 try inlining.merges.br_list.append(sema.gpa, br_inst.toIndex().?);
19515 try inlining.merges.src_locs.append(sema.gpa, operand_src);
1949219516 return always_noreturn;
1949319517 } else if (block.is_comptime) {
1949419518 return sema.fail(block, src, "function called at runtime cannot return value at comptime", .{});
src/Zir.zig-10
......@@ -392,10 +392,6 @@ pub const Inst = struct {
392392 /// Same as `dbg_var_ptr` but the local is always a const and the operand
393393 /// is the local's value.
394394 dbg_var_val,
395 /// Marks the beginning of a semantic scope for debug info variables.
396 dbg_block_begin,
397 /// Marks the end of a semantic scope for debug info variables.
398 dbg_block_end,
399395 /// Uses a name to identify a Decl and takes a pointer to it.
400396 /// Uses the `str_tok` union field.
401397 decl_ref,
......@@ -1107,8 +1103,6 @@ pub const Inst = struct {
11071103 .dbg_stmt,
11081104 .dbg_var_ptr,
11091105 .dbg_var_val,
1110 .dbg_block_begin,
1111 .dbg_block_end,
11121106 .decl_ref,
11131107 .decl_val,
11141108 .load,
......@@ -1335,8 +1329,6 @@ pub const Inst = struct {
13351329 .dbg_stmt,
13361330 .dbg_var_ptr,
13371331 .dbg_var_val,
1338 .dbg_block_begin,
1339 .dbg_block_end,
13401332 .ensure_result_used,
13411333 .ensure_result_non_error,
13421334 .ensure_err_union_payload_void,
......@@ -1663,8 +1655,6 @@ pub const Inst = struct {
16631655 .dbg_stmt = .dbg_stmt,
16641656 .dbg_var_ptr = .str_op,
16651657 .dbg_var_val = .str_op,
1666 .dbg_block_begin = .tok,
1667 .dbg_block_end = .tok,
16681658 .decl_ref = .str_tok,
16691659 .decl_val = .str_tok,
16701660 .load = .un_node,
src/arch/aarch64/CodeGen.zig+1-9
......@@ -813,10 +813,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
813813 .dbg_inline_end,
814814 => try self.airDbgInline(inst),
815815
816 .dbg_block_begin,
817 .dbg_block_end,
818 => try self.airDbgBlock(inst),
819
820816 .call => try self.airCall(inst, .auto),
821817 .call_always_tail => try self.airCall(inst, .always_tail),
822818 .call_never_tail => try self.airCall(inst, .never_tail),
......@@ -4634,11 +4630,6 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
46344630 return self.finishAir(inst, .dead, .{ .none, .none, .none });
46354631}
46364632
4637fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {
4638 // TODO emit debug info lexical block
4639 return self.finishAir(inst, .dead, .{ .none, .none, .none });
4640}
4641
46424633fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
46434634 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
46444635 const operand = pl_op.operand;
......@@ -5066,6 +5057,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
50665057 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
50675058 const extra = self.air.extraData(Air.Block, ty_pl.payload);
50685059 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
5060 // TODO emit debug info lexical block
50695061 try self.genBody(body);
50705062
50715063 // relocations for `br` instructions
src/arch/arm/CodeGen.zig+1-9
......@@ -799,10 +799,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
799799 .dbg_inline_end,
800800 => try self.airDbgInline(inst),
801801
802 .dbg_block_begin,
803 .dbg_block_end,
804 => try self.airDbgBlock(inst),
805
806802 .call => try self.airCall(inst, .auto),
807803 .call_always_tail => try self.airCall(inst, .always_tail),
808804 .call_never_tail => try self.airCall(inst, .never_tail),
......@@ -4587,11 +4583,6 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
45874583 return self.finishAir(inst, .dead, .{ .none, .none, .none });
45884584}
45894585
4590fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {
4591 // TODO emit debug info lexical block
4592 return self.finishAir(inst, .dead, .{ .none, .none, .none });
4593}
4594
45954586fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
45964587 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
45974588 const operand = pl_op.operand;
......@@ -4997,6 +4988,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
49974988 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
49984989 const extra = self.air.extraData(Air.Block, ty_pl.payload);
49994990 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
4991 // TODO emit debug info lexical block
50004992 try self.genBody(body);
50014993
50024994 // relocations for `br` instructions
src/arch/riscv64/CodeGen.zig+1-9
......@@ -632,10 +632,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
632632 .dbg_inline_end,
633633 => try self.airDbgInline(inst),
634634
635 .dbg_block_begin,
636 .dbg_block_end,
637 => try self.airDbgBlock(inst),
638
639635 .call => try self.airCall(inst, .auto),
640636 .call_always_tail => try self.airCall(inst, .always_tail),
641637 .call_never_tail => try self.airCall(inst, .never_tail),
......@@ -1894,11 +1890,6 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
18941890 return self.finishAir(inst, .dead, .{ .none, .none, .none });
18951891}
18961892
1897fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {
1898 // TODO emit debug info lexical block
1899 return self.finishAir(inst, .dead, .{ .none, .none, .none });
1900}
1901
19021893fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
19031894 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
19041895 const name = self.air.nullTerminatedString(pl_op.payload);
......@@ -2084,6 +2075,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
20842075 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
20852076 const extra = self.air.extraData(Air.Block, ty_pl.payload);
20862077 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
2078 // TODO emit debug info lexical block
20872079 try self.genBody(body);
20882080
20892081 for (self.blocks.getPtr(inst).?.relocs.items) |reloc| try self.performReloc(reloc);
src/arch/sparc64/CodeGen.zig+1-9
......@@ -645,10 +645,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
645645 .dbg_inline_end,
646646 => try self.airDbgInline(inst),
647647
648 .dbg_block_begin,
649 .dbg_block_end,
650 => try self.airDbgBlock(inst),
651
652648 .call => try self.airCall(inst, .auto),
653649 .call_always_tail => try self.airCall(inst, .always_tail),
654650 .call_never_tail => try self.airCall(inst, .never_tail),
......@@ -1146,6 +1142,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
11461142 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
11471143 const extra = self.air.extraData(Air.Block, ty_pl.payload);
11481144 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
1145 // TODO emit debug info lexical block
11491146 try self.genBody(body);
11501147
11511148 // relocations for `bpcc` instructions
......@@ -1655,11 +1652,6 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
16551652 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
16561653}
16571654
1658fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {
1659 // TODO emit debug info lexical block
1660 return self.finishAir(inst, .dead, .{ .none, .none, .none });
1661}
1662
16631655fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
16641656 const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
16651657 const mod = self.bin_file.comp.module.?;
src/arch/wasm/CodeGen.zig-2
......@@ -1913,8 +1913,6 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
19131913 // TODO
19141914 .dbg_inline_begin,
19151915 .dbg_inline_end,
1916 .dbg_block_begin,
1917 .dbg_block_end,
19181916 => func.finishAir(inst, .none, &.{}),
19191917
19201918 .dbg_var_ptr => func.airDbgVar(inst, true),
src/arch/x86_64/CodeGen.zig+1-10
......@@ -2106,10 +2106,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
21062106 .dbg_inline_end,
21072107 => try self.airDbgInline(inst),
21082108
2109 .dbg_block_begin,
2110 .dbg_block_end,
2111 => try self.airDbgBlock(inst),
2112
21132109 .call => try self.airCall(inst, .auto),
21142110 .call_always_tail => try self.airCall(inst, .always_tail),
21152111 .call_never_tail => try self.airCall(inst, .never_tail),
......@@ -12976,12 +12972,6 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
1297612972 self.finishAirBookkeeping();
1297712973}
1297812974
12979fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {
12980 _ = inst;
12981 // TODO emit debug info lexical block
12982 self.finishAirBookkeeping();
12983}
12984
1298512975fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
1298612976 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
1298712977 const operand = pl_op.operand;
......@@ -13428,6 +13418,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
1342813418 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
1342913419 const extra = self.air.extraData(Air.Block, ty_pl.payload);
1343013420 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
13421 // TODO emit debug info lexical block
1343113422 try self.genBody(body);
1343213423
1343313424 var block_data = self.blocks.fetchRemove(inst).?;
src/codegen/c.zig-4
......@@ -3268,10 +3268,6 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
32683268 .dbg_inline_end,
32693269 => try airDbgInline(f, inst),
32703270
3271 .dbg_block_begin,
3272 .dbg_block_end,
3273 => .none,
3274
32753271 .call => try airCall(f, inst, .auto),
32763272 .call_always_tail => .none,
32773273 .call_never_tail => try airCall(f, inst, .never_tail),
src/codegen/llvm.zig+16-28
......@@ -4768,8 +4768,6 @@ pub const FuncGen = struct {
47684768 scope: Builder.Metadata,
47694769 }) = .{},
47704770
4771 scope_stack: std.ArrayListUnmanaged(Builder.Metadata) = .{},
4772
47734771 base_line: u32,
47744772 prev_dbg_line: c_uint,
47754773 prev_dbg_column: c_uint,
......@@ -4813,7 +4811,6 @@ pub const FuncGen = struct {
48134811
48144812 fn deinit(self: *FuncGen) void {
48154813 self.wip.deinit();
4816 self.scope_stack.deinit(self.gpa);
48174814 self.inlined.deinit(self.gpa);
48184815 self.func_inst_table.deinit(self.gpa);
48194816 self.blocks.deinit(self.gpa);
......@@ -5112,8 +5109,6 @@ pub const FuncGen = struct {
51125109 .dbg_stmt => try self.airDbgStmt(inst),
51135110 .dbg_inline_begin => try self.airDbgInlineBegin(inst),
51145111 .dbg_inline_end => try self.airDbgInlineEnd(inst),
5115 .dbg_block_begin => try self.airDbgBlockBegin(),
5116 .dbg_block_end => try self.airDbgBlockEnd(),
51175112 .dbg_var_ptr => try self.airDbgVarPtr(inst),
51185113 .dbg_var_val => try self.airDbgVarVal(inst),
51195114
......@@ -5131,6 +5126,19 @@ pub const FuncGen = struct {
51315126 }
51325127 }
51335128
5129 fn genBodyDebugScope(self: *FuncGen, body: []const Air.Inst.Index) Error!void {
5130 if (self.wip.strip) return self.genBody(body);
5131 const old_scope = self.scope;
5132 self.scope = try self.dg.object.builder.debugLexicalBlock(
5133 old_scope,
5134 self.file,
5135 self.prev_dbg_line,
5136 self.prev_dbg_column,
5137 );
5138 try self.genBody(body);
5139 self.scope = old_scope;
5140 }
5141
51345142 pub const CallAttr = enum {
51355143 Auto,
51365144 NeverTail,
......@@ -5820,7 +5828,7 @@ pub const FuncGen = struct {
58205828 const inst_ty = self.typeOfIndex(inst);
58215829
58225830 if (inst_ty.isNoReturn(mod)) {
5823 try self.genBody(body);
5831 try self.genBodyDebugScope(body);
58245832 return .none;
58255833 }
58265834
......@@ -5836,7 +5844,7 @@ pub const FuncGen = struct {
58365844 });
58375845 defer assert(self.blocks.remove(inst));
58385846
5839 try self.genBody(body);
5847 try self.genBodyDebugScope(body);
58405848
58415849 self.wip.cursor = .{ .block = parent_bb };
58425850
......@@ -6683,26 +6691,6 @@ pub const FuncGen = struct {
66836691 return .none;
66846692 }
66856693
6686 fn airDbgBlockBegin(self: *FuncGen) Allocator.Error!Builder.Value {
6687 const o = self.dg.object;
6688
6689 try self.scope_stack.append(self.gpa, self.scope);
6690
6691 const old = self.scope;
6692 self.scope = try o.builder.debugLexicalBlock(
6693 old,
6694 self.file,
6695 self.prev_dbg_line,
6696 self.prev_dbg_column,
6697 );
6698 return .none;
6699 }
6700
6701 fn airDbgBlockEnd(self: *FuncGen) !Builder.Value {
6702 self.scope = self.scope_stack.pop();
6703 return .none;
6704 }
6705
67066694 fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
67076695 const o = self.dg.object;
67086696 const mod = o.module;
......@@ -7488,7 +7476,7 @@ pub const FuncGen = struct {
74887476 for (body_tail[1..]) |body_inst| {
74897477 switch (air_tags[@intFromEnum(body_inst)]) {
74907478 .ret => return true,
7491 .dbg_stmt, .dbg_block_end => continue,
7479 .dbg_stmt => continue,
74927480 else => return false,
74937481 }
74947482 }
src/codegen/spirv.zig-2
......@@ -2322,8 +2322,6 @@ const DeclGen = struct {
23222322 .dbg_inline_begin => return self.airDbgInlineBegin(inst),
23232323 .dbg_inline_end => return self.airDbgInlineEnd(inst),
23242324 .dbg_var_ptr, .dbg_var_val => return self.airDbgVar(inst),
2325 .dbg_block_begin => return,
2326 .dbg_block_end => return,
23272325
23282326 .unwrap_errunion_err => try self.airErrUnionErr(inst),
23292327 .unwrap_errunion_payload => try self.airErrUnionPayload(inst),
src/print_air.zig-2
......@@ -319,8 +319,6 @@ const Writer = struct {
319319 .cmp_vector, .cmp_vector_optimized => try w.writeCmpVector(s, inst),
320320 .vector_store_elem => try w.writeVectorStoreElem(s, inst),
321321
322 .dbg_block_begin, .dbg_block_end => {},
323
324322 .work_item_id,
325323 .work_group_size,
326324 .work_group_id,
src/print_zir.zig-4
......@@ -510,10 +510,6 @@ const Writer = struct {
510510
511511 .dbg_stmt => try self.writeDbgStmt(stream, inst),
512512
513 .dbg_block_begin,
514 .dbg_block_end,
515 => try stream.writeAll(")"),
516
517513 .closure_get => try self.writeInstNode(stream, inst),
518514
519515 .@"defer" => try self.writeDefer(stream, inst),
test/behavior/eval.zig+18
......@@ -1714,3 +1714,21 @@ test "const with specified type initialized with typed array is comptime-known"
17141714 comptime assert(x[1] == 2);
17151715 comptime assert(x[2] == 3);
17161716}
1717
1718test "block with comptime-known result but possible runtime exit is comptime-known" {
1719 var t: bool = true;
1720 _ = &t;
1721
1722 const a: comptime_int = a: {
1723 if (!t) return error.TestFailed;
1724 break :a 123;
1725 };
1726
1727 const b: comptime_int = b: {
1728 if (t) break :b 456;
1729 return error.TestFailed;
1730 };
1731
1732 comptime assert(a == 123);
1733 comptime assert(b == 456);
1734}