| author | |
| committer | |
| log | 59447e53056d8fb6682b79accccffa176d0b44d1 |
| tree | fef7809520fc67d519150592ea479576c9b289ca |
| parent | 031f23117dadd84b1e7189ee5b0f712eeb23ca1e |
| signature |
This commit eliminates the `dbg_block_{begin,end}` instructions from
both ZIR and AIR. Instead, lexical scoping of `dbg_var_{ptr,val}`
instructions is decided based on the AIR block they exist within. This
is a much more robust system, and also results in a huge drop in ZIR
bytes - around 7% for Sema.zig.
This required some enhancements to Sema to prevent elision of blocks
when they are required for debug variable scoping. This can be observed
by looking at the AIR for the following simple test program with and
without `-fstrip`:
```zig
export fn f() void {
{
var a: u32 = 0;
_ = &a;
}
{
var a: u32 = 0;
_ = &a;
}
}
```
When `-fstrip` is passed, no AIR blocks are generated. When `-fno-strip`
is passed, the ZIR blocks are lowered to true AIR blocks to give correct
lexical scoping to the debug vars.
The changes here incidentally reolve #19060. A corresponding behavior
test has been added.
Resolves: #1906018 files changed, 187 insertions(+), 287 deletions(-)
src/Air.zig-8| ... | @@ -443,10 +443,6 @@ pub const Inst = struct { | ... | @@ -443,10 +443,6 @@ 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 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, | ||
| 450 | /// Marks the start of an inline call. | 446 | /// Marks the start of an inline call. |
| 451 | /// Uses the `ty_fn` field. | 447 | /// Uses the `ty_fn` field. |
| 452 | dbg_inline_begin, | 448 | dbg_inline_begin, |
| ... | @@ -1454,8 +1450,6 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) | ... | @@ -1454,8 +1450,6 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) |
| 1454 | .dbg_stmt, | 1450 | .dbg_stmt, |
| 1455 | .dbg_inline_begin, | 1451 | .dbg_inline_begin, |
| 1456 | .dbg_inline_end, | 1452 | .dbg_inline_end, |
| 1457 | .dbg_block_begin, | ||
| 1458 | .dbg_block_end, | ||
| 1459 | .dbg_var_ptr, | 1453 | .dbg_var_ptr, |
| 1460 | .dbg_var_val, | 1454 | .dbg_var_val, |
| 1461 | .store, | 1455 | .store, |
| ... | @@ -1612,8 +1606,6 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool { | ... | @@ -1612,8 +1606,6 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool { |
| 1612 | .@"try", | 1606 | .@"try", |
| 1613 | .try_ptr, | 1607 | .try_ptr, |
| 1614 | .dbg_stmt, | 1608 | .dbg_stmt, |
| 1615 | .dbg_block_begin, | ||
| 1616 | .dbg_block_end, | ||
| 1617 | .dbg_inline_begin, | 1609 | .dbg_inline_begin, |
| 1618 | .dbg_inline_end, | 1610 | .dbg_inline_end, |
| 1619 | .dbg_var_ptr, | 1611 | .dbg_var_ptr, |
src/AstGen.zig-51| ... | @@ -2445,8 +2445,6 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod | ... | @@ -2445,8 +2445,6 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod |
| 2445 | 2445 | ||
| 2446 | if (statements.len == 0) return; | 2446 | if (statements.len == 0) return; |
| 2447 | 2447 | ||
| 2448 | try gz.addDbgBlockBegin(); | ||
| 2449 | |||
| 2450 | var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa); | 2448 | var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa); |
| 2451 | defer block_arena.deinit(); | 2449 | defer block_arena.deinit(); |
| 2452 | const block_arena_allocator = block_arena.allocator(); | 2450 | const block_arena_allocator = block_arena.allocator(); |
| ... | @@ -2518,8 +2516,6 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod | ... | @@ -2518,8 +2516,6 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod |
| 2518 | } | 2516 | } |
| 2519 | } | 2517 | } |
| 2520 | 2518 | ||
| 2521 | try gz.addDbgBlockEnd(); | ||
| 2522 | |||
| 2523 | try genDefers(gz, parent_scope, scope, .normal_only); | 2519 | try genDefers(gz, parent_scope, scope, .normal_only); |
| 2524 | try checkUsed(gz, parent_scope, scope); | 2520 | try checkUsed(gz, parent_scope, scope); |
| 2525 | } | 2521 | } |
| ... | @@ -2804,8 +2800,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As | ... | @@ -2804,8 +2800,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As |
| 2804 | .dbg_stmt, | 2800 | .dbg_stmt, |
| 2805 | .dbg_var_ptr, | 2801 | .dbg_var_ptr, |
| 2806 | .dbg_var_val, | 2802 | .dbg_var_val, |
| 2807 | .dbg_block_begin, | ||
| 2808 | .dbg_block_end, | ||
| 2809 | .ensure_result_used, | 2803 | .ensure_result_used, |
| 2810 | .ensure_result_non_error, | 2804 | .ensure_result_non_error, |
| 2811 | .ensure_err_union_payload_void, | 2805 | .ensure_err_union_payload_void, |
| ... | @@ -3026,7 +3020,6 @@ fn deferStmt( | ... | @@ -3026,7 +3020,6 @@ fn deferStmt( |
| 3026 | var opt_remapped_err_code: Zir.Inst.OptionalIndex = .none; | 3020 | var opt_remapped_err_code: Zir.Inst.OptionalIndex = .none; |
| 3027 | const have_err_code = scope_tag == .defer_error and payload_token != 0; | 3021 | const have_err_code = scope_tag == .defer_error and payload_token != 0; |
| 3028 | const sub_scope = if (!have_err_code) &defer_gen.base else blk: { | 3022 | const sub_scope = if (!have_err_code) &defer_gen.base else blk: { |
| 3029 | try gz.addDbgBlockBegin(); | ||
| 3030 | const ident_name = try gz.astgen.identAsString(payload_token); | 3023 | const ident_name = try gz.astgen.identAsString(payload_token); |
| 3031 | const remapped_err_code: Zir.Inst.Index = @enumFromInt(gz.astgen.instructions.len); | 3024 | const remapped_err_code: Zir.Inst.Index = @enumFromInt(gz.astgen.instructions.len); |
| 3032 | opt_remapped_err_code = remapped_err_code.toOptional(); | 3025 | opt_remapped_err_code = remapped_err_code.toOptional(); |
| ... | @@ -3052,7 +3045,6 @@ fn deferStmt( | ... | @@ -3052,7 +3045,6 @@ fn deferStmt( |
| 3052 | }; | 3045 | }; |
| 3053 | _ = try unusedResultExpr(&defer_gen, sub_scope, expr_node); | 3046 | _ = try unusedResultExpr(&defer_gen, sub_scope, expr_node); |
| 3054 | try checkUsed(gz, scope, sub_scope); | 3047 | try checkUsed(gz, scope, sub_scope); |
| 3055 | if (have_err_code) try gz.addDbgBlockEnd(); | ||
| 3056 | _ = try defer_gen.addBreak(.break_inline, @enumFromInt(0), .void_value); | 3048 | _ = try defer_gen.addBreak(.break_inline, @enumFromInt(0), .void_value); |
| 3057 | 3049 | ||
| 3058 | // We must handle ref_table for remapped_err_code manually. | 3050 | // We must handle ref_table for remapped_err_code manually. |
| ... | @@ -6245,7 +6237,6 @@ fn ifExpr( | ... | @@ -6245,7 +6237,6 @@ fn ifExpr( |
| 6245 | 6237 | ||
| 6246 | var payload_val_scope: Scope.LocalVal = undefined; | 6238 | var payload_val_scope: Scope.LocalVal = undefined; |
| 6247 | 6239 | ||
| 6248 | try then_scope.addDbgBlockBegin(); | ||
| 6249 | const then_node = if_full.ast.then_expr; | 6240 | const then_node = if_full.ast.then_expr; |
| 6250 | const then_sub_scope = s: { | 6241 | const then_sub_scope = s: { |
| 6251 | if (if_full.error_token != null) { | 6242 | if (if_full.error_token != null) { |
| ... | @@ -6305,7 +6296,6 @@ fn ifExpr( | ... | @@ -6305,7 +6296,6 @@ fn ifExpr( |
| 6305 | const then_result = try expr(&then_scope, then_sub_scope, block_scope.break_result_info, then_node); | 6296 | const then_result = try expr(&then_scope, then_sub_scope, block_scope.break_result_info, then_node); |
| 6306 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); | 6297 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); |
| 6307 | if (!then_scope.endsWithNoReturn()) { | 6298 | if (!then_scope.endsWithNoReturn()) { |
| 6308 | try then_scope.addDbgBlockEnd(); | ||
| 6309 | _ = try then_scope.addBreakWithSrcNode(.@"break", block, then_result, then_node); | 6299 | _ = try then_scope.addBreakWithSrcNode(.@"break", block, then_result, then_node); |
| 6310 | } | 6300 | } |
| 6311 | 6301 | ||
| ... | @@ -6319,7 +6309,6 @@ fn ifExpr( | ... | @@ -6319,7 +6309,6 @@ fn ifExpr( |
| 6319 | 6309 | ||
| 6320 | const else_node = if_full.ast.else_expr; | 6310 | const else_node = if_full.ast.else_expr; |
| 6321 | if (else_node != 0) { | 6311 | if (else_node != 0) { |
| 6322 | try else_scope.addDbgBlockBegin(); | ||
| 6323 | const sub_scope = s: { | 6312 | const sub_scope = s: { |
| 6324 | if (if_full.error_token) |error_token| { | 6313 | if (if_full.error_token) |error_token| { |
| 6325 | const tag: Zir.Inst.Tag = if (payload_is_ref) | 6314 | const tag: Zir.Inst.Tag = if (payload_is_ref) |
| ... | @@ -6347,7 +6336,6 @@ fn ifExpr( | ... | @@ -6347,7 +6336,6 @@ fn ifExpr( |
| 6347 | } | 6336 | } |
| 6348 | }; | 6337 | }; |
| 6349 | const else_result = try expr(&else_scope, sub_scope, block_scope.break_result_info, else_node); | 6338 | const else_result = try expr(&else_scope, sub_scope, block_scope.break_result_info, else_node); |
| 6350 | try else_scope.addDbgBlockEnd(); | ||
| 6351 | if (!else_scope.endsWithNoReturn()) { | 6339 | if (!else_scope.endsWithNoReturn()) { |
| 6352 | // As our last action before the break, "pop" the error trace if needed | 6340 | // As our last action before the break, "pop" the error trace if needed |
| 6353 | if (do_err_trace) | 6341 | if (do_err_trace) |
| ... | @@ -6579,7 +6567,6 @@ fn whileExpr( | ... | @@ -6579,7 +6567,6 @@ fn whileExpr( |
| 6579 | // done adding instructions to loop_scope, can now stack then_scope | 6567 | // done adding instructions to loop_scope, can now stack then_scope |
| 6580 | then_scope.instructions_top = then_scope.instructions.items.len; | 6568 | then_scope.instructions_top = then_scope.instructions.items.len; |
| 6581 | 6569 | ||
| 6582 | try then_scope.addDbgBlockBegin(); | ||
| 6583 | const then_node = while_full.ast.then_expr; | 6570 | const then_node = while_full.ast.then_expr; |
| 6584 | if (opt_payload_inst.unwrap()) |payload_inst| { | 6571 | if (opt_payload_inst.unwrap()) |payload_inst| { |
| 6585 | try then_scope.instructions.append(astgen.gpa, payload_inst); | 6572 | try then_scope.instructions.append(astgen.gpa, payload_inst); |
| ... | @@ -6593,7 +6580,6 @@ fn whileExpr( | ... | @@ -6593,7 +6580,6 @@ fn whileExpr( |
| 6593 | if (while_full.ast.cont_expr != 0) { | 6580 | if (while_full.ast.cont_expr != 0) { |
| 6594 | _ = try unusedResultExpr(&then_scope, then_sub_scope, while_full.ast.cont_expr); | 6581 | _ = try unusedResultExpr(&then_scope, then_sub_scope, while_full.ast.cont_expr); |
| 6595 | } | 6582 | } |
| 6596 | try then_scope.addDbgBlockEnd(); | ||
| 6597 | 6583 | ||
| 6598 | continue_scope.instructions_top = continue_scope.instructions.items.len; | 6584 | continue_scope.instructions_top = continue_scope.instructions.items.len; |
| 6599 | _ = try unusedResultExpr(&continue_scope, &continue_scope.base, then_node); | 6585 | _ = try unusedResultExpr(&continue_scope, &continue_scope.base, then_node); |
| ... | @@ -6610,7 +6596,6 @@ fn whileExpr( | ... | @@ -6610,7 +6596,6 @@ fn whileExpr( |
| 6610 | 6596 | ||
| 6611 | const else_node = while_full.ast.else_expr; | 6597 | const else_node = while_full.ast.else_expr; |
| 6612 | if (else_node != 0) { | 6598 | if (else_node != 0) { |
| 6613 | try else_scope.addDbgBlockBegin(); | ||
| 6614 | const sub_scope = s: { | 6599 | const sub_scope = s: { |
| 6615 | if (while_full.error_token) |error_token| { | 6600 | if (while_full.error_token) |error_token| { |
| 6616 | const tag: Zir.Inst.Tag = if (payload_is_ref) | 6601 | const tag: Zir.Inst.Tag = if (payload_is_ref) |
| ... | @@ -6647,7 +6632,6 @@ fn whileExpr( | ... | @@ -6647,7 +6632,6 @@ fn whileExpr( |
| 6647 | } | 6632 | } |
| 6648 | 6633 | ||
| 6649 | try checkUsed(parent_gz, &else_scope.base, sub_scope); | 6634 | try checkUsed(parent_gz, &else_scope.base, sub_scope); |
| 6650 | try else_scope.addDbgBlockEnd(); | ||
| 6651 | if (!else_scope.endsWithNoReturn()) { | 6635 | if (!else_scope.endsWithNoReturn()) { |
| 6652 | _ = try else_scope.addBreakWithSrcNode(break_tag, loop_block, else_result, else_node); | 6636 | _ = try else_scope.addBreakWithSrcNode(break_tag, loop_block, else_result, else_node); |
| 6653 | } | 6637 | } |
| ... | @@ -6849,8 +6833,6 @@ fn forExpr( | ... | @@ -6849,8 +6833,6 @@ fn forExpr( |
| 6849 | var then_scope = parent_gz.makeSubBlock(&cond_scope.base); | 6833 | var then_scope = parent_gz.makeSubBlock(&cond_scope.base); |
| 6850 | defer then_scope.unstack(); | 6834 | defer then_scope.unstack(); |
| 6851 | 6835 | ||
| 6852 | try then_scope.addDbgBlockBegin(); | ||
| 6853 | |||
| 6854 | const capture_scopes = try gpa.alloc(Scope.LocalVal, for_full.ast.inputs.len); | 6836 | const capture_scopes = try gpa.alloc(Scope.LocalVal, for_full.ast.inputs.len); |
| 6855 | defer gpa.free(capture_scopes); | 6837 | defer gpa.free(capture_scopes); |
| 6856 | 6838 | ||
| ... | @@ -6916,7 +6898,6 @@ fn forExpr( | ... | @@ -6916,7 +6898,6 @@ fn forExpr( |
| 6916 | _ = try addEnsureResult(&then_scope, then_result, then_node); | 6898 | _ = try addEnsureResult(&then_scope, then_result, then_node); |
| 6917 | 6899 | ||
| 6918 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); | 6900 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); |
| 6919 | try then_scope.addDbgBlockEnd(); | ||
| 6920 | 6901 | ||
| 6921 | const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break"; | 6902 | const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break"; |
| 6922 | 6903 | ||
| ... | @@ -7149,8 +7130,6 @@ fn switchExprErrUnion( | ... | @@ -7149,8 +7130,6 @@ fn switchExprErrUnion( |
| 7149 | case_scope.instructions_top = parent_gz.instructions.items.len; | 7130 | case_scope.instructions_top = parent_gz.instructions.items.len; |
| 7150 | defer case_scope.unstack(); | 7131 | defer case_scope.unstack(); |
| 7151 | 7132 | ||
| 7152 | try case_scope.addDbgBlockBegin(); | ||
| 7153 | |||
| 7154 | const unwrap_payload_tag: Zir.Inst.Tag = if (payload_is_ref) | 7133 | const unwrap_payload_tag: Zir.Inst.Tag = if (payload_is_ref) |
| 7155 | .err_union_payload_unsafe_ptr | 7134 | .err_union_payload_unsafe_ptr |
| 7156 | else | 7135 | else |
| ... | @@ -7173,7 +7152,6 @@ fn switchExprErrUnion( | ... | @@ -7173,7 +7152,6 @@ fn switchExprErrUnion( |
| 7173 | catch_or_if_node, | 7152 | catch_or_if_node, |
| 7174 | ), | 7153 | ), |
| 7175 | }; | 7154 | }; |
| 7176 | try case_scope.addDbgBlockEnd(); | ||
| 7177 | _ = try case_scope.addBreakWithSrcNode( | 7155 | _ = try case_scope.addBreakWithSrcNode( |
| 7178 | .@"break", | 7156 | .@"break", |
| 7179 | switch_block, | 7157 | switch_block, |
| ... | @@ -7184,7 +7162,6 @@ fn switchExprErrUnion( | ... | @@ -7184,7 +7162,6 @@ fn switchExprErrUnion( |
| 7184 | .@"if" => { | 7162 | .@"if" => { |
| 7185 | var payload_val_scope: Scope.LocalVal = undefined; | 7163 | var payload_val_scope: Scope.LocalVal = undefined; |
| 7186 | 7164 | ||
| 7187 | try case_scope.addDbgBlockBegin(); | ||
| 7188 | const then_node = if_full.ast.then_expr; | 7165 | const then_node = if_full.ast.then_expr; |
| 7189 | const then_sub_scope = s: { | 7166 | const then_sub_scope = s: { |
| 7190 | assert(if_full.error_token != null); | 7167 | assert(if_full.error_token != null); |
| ... | @@ -7228,7 +7205,6 @@ fn switchExprErrUnion( | ... | @@ -7228,7 +7205,6 @@ fn switchExprErrUnion( |
| 7228 | ); | 7205 | ); |
| 7229 | try checkUsed(parent_gz, &case_scope.base, then_sub_scope); | 7206 | try checkUsed(parent_gz, &case_scope.base, then_sub_scope); |
| 7230 | if (!case_scope.endsWithNoReturn()) { | 7207 | if (!case_scope.endsWithNoReturn()) { |
| 7231 | try case_scope.addDbgBlockEnd(); | ||
| 7232 | _ = try case_scope.addBreakWithSrcNode( | 7208 | _ = try case_scope.addBreakWithSrcNode( |
| 7233 | .@"break", | 7209 | .@"break", |
| 7234 | switch_block, | 7210 | switch_block, |
| ... | @@ -7407,7 +7383,6 @@ fn switchExprErrUnion( | ... | @@ -7407,7 +7383,6 @@ fn switchExprErrUnion( |
| 7407 | if (do_err_trace and nodeMayAppendToErrorTrace(tree, operand_node)) | 7383 | if (do_err_trace and nodeMayAppendToErrorTrace(tree, operand_node)) |
| 7408 | _ = try case_scope.addSaveErrRetIndex(.always); | 7384 | _ = try case_scope.addSaveErrRetIndex(.always); |
| 7409 | 7385 | ||
| 7410 | try case_scope.addDbgBlockBegin(); | ||
| 7411 | if (dbg_var_name != .empty) { | 7386 | if (dbg_var_name != .empty) { |
| 7412 | try case_scope.addDbgVar(.dbg_var_val, dbg_var_name, dbg_var_inst); | 7387 | try case_scope.addDbgVar(.dbg_var_val, dbg_var_name, dbg_var_inst); |
| 7413 | } | 7388 | } |
| ... | @@ -7421,7 +7396,6 @@ fn switchExprErrUnion( | ... | @@ -7421,7 +7396,6 @@ fn switchExprErrUnion( |
| 7421 | try case_scope.addDbgVar(.dbg_var_val, err_name, err_inst.toRef()); | 7396 | try case_scope.addDbgVar(.dbg_var_val, err_name, err_inst.toRef()); |
| 7422 | any_uses_err_capture = true; | 7397 | any_uses_err_capture = true; |
| 7423 | } | 7398 | } |
| 7424 | try case_scope.addDbgBlockEnd(); | ||
| 7425 | 7399 | ||
| 7426 | if (!parent_gz.refIsNoReturn(case_result)) { | 7400 | if (!parent_gz.refIsNoReturn(case_result)) { |
| 7427 | if (do_err_trace) | 7401 | if (do_err_trace) |
| ... | @@ -7868,7 +7842,6 @@ fn switchExpr( | ... | @@ -7868,7 +7842,6 @@ fn switchExpr( |
| 7868 | case_scope.instructions_top = parent_gz.instructions.items.len; | 7842 | case_scope.instructions_top = parent_gz.instructions.items.len; |
| 7869 | defer case_scope.unstack(); | 7843 | defer case_scope.unstack(); |
| 7870 | 7844 | ||
| 7871 | try case_scope.addDbgBlockBegin(); | ||
| 7872 | if (dbg_var_name != .empty) { | 7845 | if (dbg_var_name != .empty) { |
| 7873 | try case_scope.addDbgVar(.dbg_var_val, dbg_var_name, dbg_var_inst); | 7846 | try case_scope.addDbgVar(.dbg_var_val, dbg_var_name, dbg_var_inst); |
| 7874 | } | 7847 | } |
| ... | @@ -7878,7 +7851,6 @@ fn switchExpr( | ... | @@ -7878,7 +7851,6 @@ fn switchExpr( |
| 7878 | const target_expr_node = case.ast.target_expr; | 7851 | const target_expr_node = case.ast.target_expr; |
| 7879 | const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node); | 7852 | const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node); |
| 7880 | try checkUsed(parent_gz, &case_scope.base, sub_scope); | 7853 | try checkUsed(parent_gz, &case_scope.base, sub_scope); |
| 7881 | try case_scope.addDbgBlockEnd(); | ||
| 7882 | if (!parent_gz.refIsNoReturn(case_result)) { | 7854 | if (!parent_gz.refIsNoReturn(case_result)) { |
| 7883 | _ = try case_scope.addBreakWithSrcNode(.@"break", switch_block, case_result, target_expr_node); | 7855 | _ = try case_scope.addBreakWithSrcNode(.@"break", switch_block, case_result, target_expr_node); |
| 7884 | } | 7856 | } |
| ... | @@ -13165,29 +13137,6 @@ const GenZir = struct { | ... | @@ -13165,29 +13137,6 @@ const GenZir = struct { |
| 13165 | }, | 13137 | }, |
| 13166 | } }); | 13138 | } }); |
| 13167 | } | 13139 | } |
| 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 | } | ||
| 13191 | }; | 13140 | }; |
| 13192 | 13141 | ||
| 13193 | /// This can only be for short-lived references; the memory becomes invalidated | 13142 | /// This can only be for short-lived references; the memory becomes invalidated |
src/Liveness.zig-4| ... | @@ -329,8 +329,6 @@ pub fn categorizeOperand( | ... | @@ -329,8 +329,6 @@ pub fn categorizeOperand( |
| 329 | .dbg_stmt, | 329 | .dbg_stmt, |
| 330 | .dbg_inline_begin, | 330 | .dbg_inline_begin, |
| 331 | .dbg_inline_end, | 331 | .dbg_inline_end, |
| 332 | .dbg_block_begin, | ||
| 333 | .dbg_block_end, | ||
| 334 | .unreach, | 332 | .unreach, |
| 335 | .ret_addr, | 333 | .ret_addr, |
| 336 | .frame_addr, | 334 | .frame_addr, |
| ... | @@ -967,8 +965,6 @@ fn analyzeInst( | ... | @@ -967,8 +965,6 @@ fn analyzeInst( |
| 967 | .dbg_stmt, | 965 | .dbg_stmt, |
| 968 | .dbg_inline_begin, | 966 | .dbg_inline_begin, |
| 969 | .dbg_inline_end, | 967 | .dbg_inline_end, |
| 970 | .dbg_block_begin, | ||
| 971 | .dbg_block_end, | ||
| 972 | .fence, | 968 | .fence, |
| 973 | .ret_addr, | 969 | .ret_addr, |
| 974 | .frame_addr, | 970 | .frame_addr, |
src/Liveness/Verify.zig-2| ... | @@ -48,8 +48,6 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { | ... | @@ -48,8 +48,6 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 48 | .dbg_stmt, | 48 | .dbg_stmt, |
| 49 | .dbg_inline_begin, | 49 | .dbg_inline_begin, |
| 50 | .dbg_inline_end, | 50 | .dbg_inline_end, |
| 51 | .dbg_block_begin, | ||
| 52 | .dbg_block_end, | ||
| 53 | .fence, | 51 | .fence, |
| 54 | .ret_addr, | 52 | .ret_addr, |
| 55 | .frame_addr, | 53 | .frame_addr, |
src/Sema.zig+148-124| ... | @@ -364,6 +364,12 @@ pub const Block = struct { | ... | @@ -364,6 +364,12 @@ pub const Block = struct { |
| 364 | 364 | ||
| 365 | c_import_buf: ?*std.ArrayList(u8) = null, | 365 | c_import_buf: ?*std.ArrayList(u8) = null, |
| 366 | 366 | ||
| 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 | |||
| 367 | const ComptimeReason = union(enum) { | 373 | const ComptimeReason = union(enum) { |
| 368 | c_import: struct { | 374 | c_import: struct { |
| 369 | block: *Block, | 375 | block: *Block, |
| ... | @@ -482,6 +488,7 @@ pub const Block = struct { | ... | @@ -482,6 +488,7 @@ pub const Block = struct { |
| 482 | .float_mode = parent.float_mode, | 488 | .float_mode = parent.float_mode, |
| 483 | .c_import_buf = parent.c_import_buf, | 489 | .c_import_buf = parent.c_import_buf, |
| 484 | .error_return_trace_index = parent.error_return_trace_index, | 490 | .error_return_trace_index = parent.error_return_trace_index, |
| 491 | .need_debug_scope = parent.need_debug_scope, | ||
| 485 | }; | 492 | }; |
| 486 | } | 493 | } |
| 487 | 494 | ||
| ... | @@ -986,8 +993,6 @@ fn analyzeBodyInner( | ... | @@ -986,8 +993,6 @@ fn analyzeBodyInner( |
| 986 | crash_info.push(); | 993 | crash_info.push(); |
| 987 | defer crash_info.pop(); | 994 | defer crash_info.pop(); |
| 988 | 995 | ||
| 989 | var dbg_block_begins: u32 = 0; | ||
| 990 | |||
| 991 | // We use a while (true) loop here to avoid a redundant way of breaking out of | 996 | // We use a while (true) loop here to avoid a redundant way of breaking out of |
| 992 | // the loop. The only way to break out of the loop is with a `noreturn` | 997 | // the loop. The only way to break out of the loop is with a `noreturn` |
| 993 | // instruction. | 998 | // instruction. |
| ... | @@ -1332,18 +1337,6 @@ fn analyzeBodyInner( | ... | @@ -1332,18 +1337,6 @@ fn analyzeBodyInner( |
| 1332 | i += 1; | 1337 | i += 1; |
| 1333 | continue; | 1338 | continue; |
| 1334 | }, | 1339 | }, |
| 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 | }, | ||
| 1347 | .ensure_err_union_payload_void => { | 1340 | .ensure_err_union_payload_void => { |
| 1348 | try sema.zirEnsureErrUnionPayloadVoid(block, inst); | 1341 | try sema.zirEnsureErrUnionPayloadVoid(block, inst); |
| 1349 | i += 1; | 1342 | i += 1; |
| ... | @@ -1641,10 +1634,12 @@ fn analyzeBodyInner( | ... | @@ -1641,10 +1634,12 @@ fn analyzeBodyInner( |
| 1641 | const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len); | 1634 | const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len); |
| 1642 | const gpa = sema.gpa; | 1635 | const gpa = sema.gpa; |
| 1643 | 1636 | ||
| 1644 | const opt_break_data = b: { | 1637 | const opt_break_data, const need_debug_scope = b: { |
| 1645 | // Create a temporary child block so that this inline block is properly | 1638 | // Create a temporary child block so that this inline block is properly |
| 1646 | // labeled for any .restore_err_ret_index instructions | 1639 | // labeled for any .restore_err_ret_index instructions |
| 1647 | var child_block = block.makeSubBlock(); | 1640 | var child_block = block.makeSubBlock(); |
| 1641 | var need_debug_scope = false; | ||
| 1642 | child_block.need_debug_scope = &need_debug_scope; | ||
| 1648 | 1643 | ||
| 1649 | // If this block contains a function prototype, we need to reset the | 1644 | // If this block contains a function prototype, we need to reset the |
| 1650 | // current list of parameters and restore it later. | 1645 | // current list of parameters and restore it later. |
| ... | @@ -1665,7 +1660,11 @@ fn analyzeBodyInner( | ... | @@ -1665,7 +1660,11 @@ fn analyzeBodyInner( |
| 1665 | child_block.instructions = block.instructions; | 1660 | child_block.instructions = block.instructions; |
| 1666 | defer block.instructions = child_block.instructions; | 1661 | defer block.instructions = child_block.instructions; |
| 1667 | 1662 | ||
| 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 }; | ||
| 1669 | }; | 1668 | }; |
| 1670 | 1669 | ||
| 1671 | // A runtime conditional branch that needs a post-hoc block to be | 1670 | // A runtime conditional branch that needs a post-hoc block to be |
| ... | @@ -1686,28 +1685,22 @@ fn analyzeBodyInner( | ... | @@ -1686,28 +1685,22 @@ fn analyzeBodyInner( |
| 1686 | // since it crosses a runtime branch. | 1685 | // since it crosses a runtime branch. |
| 1687 | // It may pass through our currently being analyzed block_inline or it | 1686 | // It may pass through our currently being analyzed block_inline or it |
| 1688 | // may point directly to it. In the latter case, this modifies the | 1687 | // 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. |
| 1690 | try sema.addRuntimeBreak(block, break_data); | 1689 | 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. | ||
| 1696 | } | 1690 | } |
| 1697 | 1691 | ||
| 1698 | try labeled_block.block.instructions.appendSlice(gpa, block.instructions.items[block_index..]); | 1692 | try labeled_block.block.instructions.appendSlice(gpa, block.instructions.items[block_index..]); |
| 1699 | block.instructions.items.len = block_index; | 1693 | block.instructions.items.len = block_index; |
| 1700 | 1694 | ||
| 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); |
| 1702 | { | 1696 | { |
| 1703 | // Destroy the ad-hoc block entry so that it does not interfere with | 1697 | // Destroy the ad-hoc block entry so that it does not interfere with |
| 1704 | // the next iteration of comptime control flow, if any. | 1698 | // the next iteration of comptime control flow, if any. |
| 1705 | labeled_block.destroy(gpa); | 1699 | labeled_block.destroy(gpa); |
| 1706 | assert(sema.post_hoc_blocks.remove(new_block_inst)); | 1700 | assert(sema.post_hoc_blocks.remove(new_block_inst)); |
| 1707 | } | 1701 | } |
| 1708 | map.putAssumeCapacity(inst, block_result); | 1702 | |
| 1709 | i += 1; | 1703 | break :blk block_result; |
| 1710 | continue; | ||
| 1711 | } | 1704 | } |
| 1712 | 1705 | ||
| 1713 | const break_data = opt_break_data orelse break always_noreturn; | 1706 | const break_data = opt_break_data orelse break always_noreturn; |
| ... | @@ -1860,19 +1853,6 @@ fn analyzeBodyInner( | ... | @@ -1860,19 +1853,6 @@ fn analyzeBodyInner( |
| 1860 | i += 1; | 1853 | i += 1; |
| 1861 | }; | 1854 | }; |
| 1862 | 1855 | ||
| 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 | |||
| 1876 | // We may have overwritten the capture scope due to a `repeat` instruction where | 1856 | // We may have overwritten the capture scope due to a `repeat` instruction where |
| 1877 | // the body had a capture; restore it now. | 1857 | // the body had a capture; restore it now. |
| 1878 | block.wip_capture_scope = parent_capture_scope; | 1858 | block.wip_capture_scope = parent_capture_scope; |
| ... | @@ -5757,7 +5737,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -5757,7 +5737,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError |
| 5757 | ); | 5737 | ); |
| 5758 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(loop_block.instructions.items)); | 5738 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(loop_block.instructions.items)); |
| 5759 | } | 5739 | } |
| 5760 | return sema.analyzeBlockBody(parent_block, src, &child_block, merges); | 5740 | return sema.analyzeBlockBody(parent_block, src, &child_block, merges, false); |
| 5761 | } | 5741 | } |
| 5762 | 5742 | ||
| 5763 | fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 5743 | fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -5945,13 +5925,31 @@ fn resolveBlockBody( | ... | @@ -5945,13 +5925,31 @@ fn resolveBlockBody( |
| 5945 | if (child_block.is_comptime) { | 5925 | if (child_block.is_comptime) { |
| 5946 | return sema.resolveBody(child_block, body, body_inst); | 5926 | return sema.resolveBody(child_block, body, body_inst); |
| 5947 | } else { | 5927 | } else { |
| 5928 | var need_debug_scope = false; | ||
| 5929 | child_block.need_debug_scope = &need_debug_scope; | ||
| 5948 | if (sema.analyzeBodyInner(child_block, body)) |_| { | 5930 | if (sema.analyzeBodyInner(child_block, body)) |_| { |
| 5949 | return sema.analyzeBlockBody(parent_block, src, child_block, merges); | 5931 | return sema.analyzeBlockBody(parent_block, src, child_block, merges, need_debug_scope); |
| 5950 | } else |err| switch (err) { | 5932 | } else |err| switch (err) { |
| 5951 | error.ComptimeBreak => { | 5933 | error.ComptimeBreak => { |
| 5952 | // Comptime control flow is happening, however child_block may still contain | 5934 | // Comptime control flow is happening, however child_block may still contain |
| 5953 | // runtime instructions which need to be copied to the parent block. | 5935 | // runtime instructions which need to be copied to the parent block. |
| 5954 | try parent_block.instructions.appendSlice(sema.gpa, child_block.instructions.items); | 5936 | if (need_debug_scope and child_block.instructions.items.len > 0) { |
| 5937 | // We need a runtime block for scoping reasons. | ||
| 5938 | _ = try child_block.addBr(merges.block_inst, .void_value); | ||
| 5939 | try parent_block.instructions.append(sema.gpa, merges.block_inst); | ||
| 5940 | try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Block).Struct.fields.len + | ||
| 5941 | child_block.instructions.items.len); | ||
| 5942 | sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{ | ||
| 5943 | .ty = .void_type, | ||
| 5944 | .payload = sema.addExtraAssumeCapacity(Air.Block{ | ||
| 5945 | .body_len = @intCast(child_block.instructions.items.len), | ||
| 5946 | }), | ||
| 5947 | } }; | ||
| 5948 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(child_block.instructions.items)); | ||
| 5949 | } else { | ||
| 5950 | // We can copy instructions directly to the parent block. | ||
| 5951 | try parent_block.instructions.appendSlice(sema.gpa, child_block.instructions.items); | ||
| 5952 | } | ||
| 5955 | 5953 | ||
| 5956 | const break_inst = sema.comptime_break_inst; | 5954 | const break_inst = sema.comptime_break_inst; |
| 5957 | const break_data = sema.code.instructions.items(.data)[@intFromEnum(break_inst)].@"break"; | 5955 | const break_data = sema.code.instructions.items(.data)[@intFromEnum(break_inst)].@"break"; |
| ... | @@ -5973,6 +5971,7 @@ fn analyzeBlockBody( | ... | @@ -5973,6 +5971,7 @@ fn analyzeBlockBody( |
| 5973 | src: LazySrcLoc, | 5971 | src: LazySrcLoc, |
| 5974 | child_block: *Block, | 5972 | child_block: *Block, |
| 5975 | merges: *Block.Merges, | 5973 | merges: *Block.Merges, |
| 5974 | need_debug_scope: bool, | ||
| 5976 | ) CompileError!Air.Inst.Ref { | 5975 | ) CompileError!Air.Inst.Ref { |
| 5977 | const tracy = trace(@src()); | 5976 | const tracy = trace(@src()); |
| 5978 | defer tracy.end(); | 5977 | defer tracy.end(); |
| ... | @@ -5987,25 +5986,57 @@ fn analyzeBlockBody( | ... | @@ -5987,25 +5986,57 @@ fn analyzeBlockBody( |
| 5987 | if (merges.results.items.len == 0) { | 5986 | if (merges.results.items.len == 0) { |
| 5988 | // No need for a block instruction. We can put the new instructions | 5987 | // No need for a block instruction. We can put the new instructions |
| 5989 | // directly into the parent block. | 5988 | // directly into the parent block. |
| 5989 | if (need_debug_scope) { | ||
| 5990 | // The code following this block is unreachable, as the block has no | ||
| 5991 | // merges, so we don't necessarily need to emit this as an AIR block. | ||
| 5992 | // However, we need a block *somewhere* to make the scoping correct, | ||
| 5993 | // so forward this request to the parent block. | ||
| 5994 | if (parent_block.need_debug_scope) |ptr| ptr.* = true; | ||
| 5995 | } | ||
| 5990 | try parent_block.instructions.appendSlice(gpa, child_block.instructions.items); | 5996 | try parent_block.instructions.appendSlice(gpa, child_block.instructions.items); |
| 5991 | return child_block.instructions.items[child_block.instructions.items.len - 1].toRef(); | 5997 | return child_block.instructions.items[child_block.instructions.items.len - 1].toRef(); |
| 5992 | } | 5998 | } |
| 5993 | if (merges.results.items.len == 1) { | 5999 | if (merges.results.items.len == 1) { |
| 5994 | const last_inst_index = child_block.instructions.items.len - 1; | 6000 | // If the `break` is trailing, we may be able to elide the AIR block here |
| 5995 | const last_inst = child_block.instructions.items[last_inst_index]; | 6001 | // by appending the new instructions directly to the parent block. |
| 5996 | if (sema.getBreakBlock(last_inst)) |br_block| { | 6002 | if (!need_debug_scope) { |
| 5997 | if (br_block == merges.block_inst) { | 6003 | const last_inst_index = child_block.instructions.items.len - 1; |
| 5998 | // No need for a block instruction. We can put the new instructions directly | 6004 | const last_inst = child_block.instructions.items[last_inst_index]; |
| 5999 | // into the parent block. Here we omit the break instruction. | 6005 | if (sema.getBreakBlock(last_inst)) |br_block| { |
| 6000 | const without_break = child_block.instructions.items[0..last_inst_index]; | 6006 | if (br_block == merges.block_inst) { |
| 6001 | try parent_block.instructions.appendSlice(gpa, without_break); | 6007 | // Great, the last instruction is the break! Put the instructions |
| 6002 | return merges.results.items[0]; | 6008 | // directly into the parent block. |
| 6003 | } | 6009 | try parent_block.instructions.appendSlice(gpa, child_block.instructions.items[0..last_inst_index]); |
| 6010 | return merges.results.items[0]; | ||
| 6011 | } | ||
| 6012 | } | ||
| 6013 | } | ||
| 6014 | // Okay, we need a runtime block. If the value is comptime-known, the | ||
| 6015 | // block should just return void, and we return the merge result | ||
| 6016 | // directly. Otherwise, we can defer to the logic below. | ||
| 6017 | if (try sema.resolveValue(merges.results.items[0])) |result_val| { | ||
| 6018 | // Create a block containing all instruction from the body. | ||
| 6019 | try parent_block.instructions.append(gpa, merges.block_inst); | ||
| 6020 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + | ||
| 6021 | child_block.instructions.items.len); | ||
| 6022 | sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{ | ||
| 6023 | .ty = .void_type, | ||
| 6024 | .payload = sema.addExtraAssumeCapacity(Air.Block{ | ||
| 6025 | .body_len = @intCast(child_block.instructions.items.len), | ||
| 6026 | }), | ||
| 6027 | } }; | ||
| 6028 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(child_block.instructions.items)); | ||
| 6029 | // Rewrite the break to just give value {}; the value is | ||
| 6030 | // comptime-known and will be returned directly. | ||
| 6031 | sema.air_instructions.items(.data)[@intFromEnum(merges.br_list.items[0])].br.operand = .void_value; | ||
| 6032 | return Air.internedToRef(result_val.toIntern()); | ||
| 6004 | } | 6033 | } |
| 6005 | } | 6034 | } |
| 6006 | // It is impossible to have the number of results be > 1 in a comptime scope. | 6035 | // It is impossible to have the number of results be > 1 in a comptime scope. |
| 6007 | assert(!child_block.is_comptime); // Should already got a compile error in the condbr condition. | 6036 | assert(!child_block.is_comptime); // Should already got a compile error in the condbr condition. |
| 6008 | 6037 | ||
| 6038 | // Note that we'll always create an AIR block here, so `need_debug_scope` is irrelevant. | ||
| 6039 | |||
| 6009 | // Need to set the type and emit the Block instruction. This allows machine code generation | 6040 | // Need to set the type and emit the Block instruction. This allows machine code generation |
| 6010 | // to emit a jump instruction to after the block when it encounters the break. | 6041 | // to emit a jump instruction to after the block when it encounters the break. |
| 6011 | try parent_block.instructions.append(gpa, merges.block_inst); | 6042 | try parent_block.instructions.append(gpa, merges.block_inst); |
| ... | @@ -6383,24 +6414,6 @@ fn zirDbgStmt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi | ... | @@ -6383,24 +6414,6 @@ fn zirDbgStmt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi |
| 6383 | }); | 6414 | }); |
| 6384 | } | 6415 | } |
| 6385 | 6416 | ||
| 6386 | fn zirDbgBlockBegin(block: *Block) CompileError!void { | ||
| 6387 | if (block.is_comptime or block.ownerModule().strip) return; | ||
| 6388 | |||
| 6389 | _ = try block.addInst(.{ | ||
| 6390 | .tag = .dbg_block_begin, | ||
| 6391 | .data = undefined, | ||
| 6392 | }); | ||
| 6393 | } | ||
| 6394 | |||
| 6395 | fn zirDbgBlockEnd(block: *Block) CompileError!void { | ||
| 6396 | if (block.is_comptime or block.ownerModule().strip) return; | ||
| 6397 | |||
| 6398 | _ = try block.addInst(.{ | ||
| 6399 | .tag = .dbg_block_end, | ||
| 6400 | .data = undefined, | ||
| 6401 | }); | ||
| 6402 | } | ||
| 6403 | |||
| 6404 | fn zirDbgVar( | 6417 | fn zirDbgVar( |
| 6405 | sema: *Sema, | 6418 | sema: *Sema, |
| 6406 | block: *Block, | 6419 | block: *Block, |
| ... | @@ -6432,6 +6445,15 @@ fn addDbgVar( | ... | @@ -6432,6 +6445,15 @@ fn addDbgVar( |
| 6432 | if (try sema.typeRequiresComptime(val_ty)) return; | 6445 | if (try sema.typeRequiresComptime(val_ty)) return; |
| 6433 | if (!(try sema.typeHasRuntimeBits(val_ty))) return; | 6446 | if (!(try sema.typeHasRuntimeBits(val_ty))) return; |
| 6434 | 6447 | ||
| 6448 | // To ensure the lexical scoping is known to backends, this alloc must be | ||
| 6449 | // within a real runtime block. We set a flag which communicates information | ||
| 6450 | // to the closest lexically enclosing block: | ||
| 6451 | // * If it is a `block_inline`, communicates to logic in `analyzeBodyInner` | ||
| 6452 | // to create a post-hoc block. | ||
| 6453 | // * Otherwise, communicates to logic in `resolveBlockBody` to create a | ||
| 6454 | // real `block` instruction. | ||
| 6455 | if (block.need_debug_scope) |ptr| ptr.* = true; | ||
| 6456 | |||
| 6435 | try sema.queueFullTypeResolution(operand_ty); | 6457 | try sema.queueFullTypeResolution(operand_ty); |
| 6436 | 6458 | ||
| 6437 | // Add the name to the AIR. | 6459 | // Add the name to the AIR. |
| ... | @@ -7585,7 +7607,7 @@ fn analyzeCall( | ... | @@ -7585,7 +7607,7 @@ fn analyzeCall( |
| 7585 | error.ComptimeReturn => break :result inlining.comptime_result, | 7607 | error.ComptimeReturn => break :result inlining.comptime_result, |
| 7586 | else => |e| return e, | 7608 | else => |e| return e, |
| 7587 | }; | 7609 | }; |
| 7588 | break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges); | 7610 | break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges, false); |
| 7589 | }; | 7611 | }; |
| 7590 | 7612 | ||
| 7591 | if (!is_comptime_call and !block.is_typeof and | 7613 | if (!is_comptime_call and !block.is_typeof and |
| ... | @@ -11528,7 +11550,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp | ... | @@ -11528,7 +11550,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 11528 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(true_instructions)); | 11550 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(true_instructions)); |
| 11529 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(sub_block.instructions.items)); | 11551 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(sub_block.instructions.items)); |
| 11530 | 11552 | ||
| 11531 | return sema.analyzeBlockBody(block, main_src, &child_block, merges); | 11553 | return sema.analyzeBlockBody(block, main_src, &child_block, merges, false); |
| 11532 | } | 11554 | } |
| 11533 | 11555 | ||
| 11534 | fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_ref: bool) CompileError!Air.Inst.Ref { | 11556 | fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_ref: bool) CompileError!Air.Inst.Ref { |
| ... | @@ -12150,7 +12172,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r | ... | @@ -12150,7 +12172,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 12150 | false, | 12172 | false, |
| 12151 | ); | 12173 | ); |
| 12152 | 12174 | ||
| 12153 | return sema.analyzeBlockBody(block, src, &child_block, merges); | 12175 | return sema.analyzeBlockBody(block, src, &child_block, merges, false); |
| 12154 | } | 12176 | } |
| 12155 | 12177 | ||
| 12156 | const SpecialProng = struct { | 12178 | const SpecialProng = struct { |
| ... | @@ -13163,8 +13185,6 @@ fn validateErrSetSwitch( | ... | @@ -13163,8 +13185,6 @@ fn validateErrSetSwitch( |
| 13163 | const tags = sema.code.instructions.items(.tag); | 13185 | const tags = sema.code.instructions.items(.tag); |
| 13164 | const datas = sema.code.instructions.items(.data); | 13186 | const datas = sema.code.instructions.items(.data); |
| 13165 | for (else_case.body) |else_inst| switch (tags[@intFromEnum(else_inst)]) { | 13187 | for (else_case.body) |else_inst| switch (tags[@intFromEnum(else_inst)]) { |
| 13166 | .dbg_block_begin, | ||
| 13167 | .dbg_block_end, | ||
| 13168 | .dbg_stmt, | 13188 | .dbg_stmt, |
| 13169 | .dbg_var_val, | 13189 | .dbg_var_val, |
| 13170 | .ret_type, | 13190 | .ret_type, |
| ... | @@ -13416,8 +13436,6 @@ fn maybeErrorUnwrap( | ... | @@ -13416,8 +13436,6 @@ fn maybeErrorUnwrap( |
| 13416 | .@"unreachable" => if (!block.wantSafety()) return false, | 13436 | .@"unreachable" => if (!block.wantSafety()) return false, |
| 13417 | .err_union_code => if (!allow_err_code_inst) return false, | 13437 | .err_union_code => if (!allow_err_code_inst) return false, |
| 13418 | .save_err_ret_index, | 13438 | .save_err_ret_index, |
| 13419 | .dbg_block_begin, | ||
| 13420 | .dbg_block_end, | ||
| 13421 | .dbg_stmt, | 13439 | .dbg_stmt, |
| 13422 | .str, | 13440 | .str, |
| 13423 | .as_node, | 13441 | .as_node, |
| ... | @@ -13430,10 +13448,7 @@ fn maybeErrorUnwrap( | ... | @@ -13430,10 +13448,7 @@ fn maybeErrorUnwrap( |
| 13430 | 13448 | ||
| 13431 | for (body) |inst| { | 13449 | for (body) |inst| { |
| 13432 | const air_inst = switch (tags[@intFromEnum(inst)]) { | 13450 | const air_inst = switch (tags[@intFromEnum(inst)]) { |
| 13433 | .dbg_block_begin, | 13451 | .err_union_code => continue, |
| 13434 | .dbg_block_end, | ||
| 13435 | .err_union_code, | ||
| 13436 | => continue, | ||
| 13437 | .dbg_stmt => { | 13452 | .dbg_stmt => { |
| 13438 | try sema.zirDbgStmt(block, inst); | 13453 | try sema.zirDbgStmt(block, inst); |
| 13439 | continue; | 13454 | continue; |
| ... | @@ -13499,8 +13514,6 @@ fn maybeErrorUnwrapComptime(sema: *Sema, block: *Block, body: []const Zir.Inst.I | ... | @@ -13499,8 +13514,6 @@ fn maybeErrorUnwrapComptime(sema: *Sema, block: *Block, body: []const Zir.Inst.I |
| 13499 | const tags = sema.code.instructions.items(.tag); | 13514 | const tags = sema.code.instructions.items(.tag); |
| 13500 | const inst = for (body) |inst| { | 13515 | const inst = for (body) |inst| { |
| 13501 | switch (tags[@intFromEnum(inst)]) { | 13516 | switch (tags[@intFromEnum(inst)]) { |
| 13502 | .dbg_block_begin, | ||
| 13503 | .dbg_block_end, | ||
| 13504 | .dbg_stmt, | 13517 | .dbg_stmt, |
| 13505 | .save_err_ret_index, | 13518 | .save_err_ret_index, |
| 13506 | => {}, | 13519 | => {}, |
| ... | @@ -19092,55 +19105,64 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -19092,55 +19105,64 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr |
| 19092 | return try_inst; | 19105 | return try_inst; |
| 19093 | } | 19106 | } |
| 19094 | 19107 | ||
| 19108 | fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*LabeledBlock { | ||
| 19109 | const gop = sema.inst_map.getOrPutAssumeCapacity(dest_block); | ||
| 19110 | if (gop.found_existing) existing: { | ||
| 19111 | // This may be a *result* from an earlier iteration of an inline loop. | ||
| 19112 | // In this case, there will not be a post-hoc block entry, and we can | ||
| 19113 | // continue with the logic below. | ||
| 19114 | const new_block_inst = gop.value_ptr.*.toIndex() orelse break :existing; | ||
| 19115 | return sema.post_hoc_blocks.get(new_block_inst) orelse break :existing; | ||
| 19116 | } | ||
| 19117 | |||
| 19118 | try sema.post_hoc_blocks.ensureUnusedCapacity(sema.gpa, 1); | ||
| 19119 | |||
| 19120 | const new_block_inst: Air.Inst.Index = @enumFromInt(sema.air_instructions.len); | ||
| 19121 | gop.value_ptr.* = new_block_inst.toRef(); | ||
| 19122 | try sema.air_instructions.append(sema.gpa, .{ | ||
| 19123 | .tag = .block, | ||
| 19124 | .data = undefined, | ||
| 19125 | }); | ||
| 19126 | const labeled_block = try sema.gpa.create(LabeledBlock); | ||
| 19127 | labeled_block.* = .{ | ||
| 19128 | .label = .{ | ||
| 19129 | .zir_block = dest_block, | ||
| 19130 | .merges = .{ | ||
| 19131 | .src_locs = .{}, | ||
| 19132 | .results = .{}, | ||
| 19133 | .br_list = .{}, | ||
| 19134 | .block_inst = new_block_inst, | ||
| 19135 | }, | ||
| 19136 | }, | ||
| 19137 | .block = .{ | ||
| 19138 | .parent = block, | ||
| 19139 | .sema = sema, | ||
| 19140 | .src_decl = block.src_decl, | ||
| 19141 | .namespace = block.namespace, | ||
| 19142 | .wip_capture_scope = block.wip_capture_scope, | ||
| 19143 | .instructions = .{}, | ||
| 19144 | .label = &labeled_block.label, | ||
| 19145 | .inlining = block.inlining, | ||
| 19146 | .is_comptime = block.is_comptime, | ||
| 19147 | }, | ||
| 19148 | }; | ||
| 19149 | sema.post_hoc_blocks.putAssumeCapacityNoClobber(new_block_inst, labeled_block); | ||
| 19150 | return labeled_block; | ||
| 19151 | } | ||
| 19152 | |||
| 19095 | // A `break` statement is inside a runtime condition, but trying to | 19153 | // A `break` statement is inside a runtime condition, but trying to |
| 19096 | // break from an inline loop. In such case we must convert it to | 19154 | // break from an inline loop. In such case we must convert it to |
| 19097 | // a runtime break. | 19155 | // a runtime break. |
| 19098 | fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !void { | 19156 | fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !void { |
| 19099 | const gop = sema.inst_map.getOrPutAssumeCapacity(break_data.block_inst); | 19157 | const labeled_block = try sema.ensurePostHoc(child_block, break_data.block_inst); |
| 19100 | const labeled_block = if (!gop.found_existing) blk: { | ||
| 19101 | try sema.post_hoc_blocks.ensureUnusedCapacity(sema.gpa, 1); | ||
| 19102 | |||
| 19103 | const new_block_inst: Air.Inst.Index = @enumFromInt(sema.air_instructions.len); | ||
| 19104 | gop.value_ptr.* = new_block_inst.toRef(); | ||
| 19105 | try sema.air_instructions.append(sema.gpa, .{ | ||
| 19106 | .tag = .block, | ||
| 19107 | .data = undefined, | ||
| 19108 | }); | ||
| 19109 | const labeled_block = try sema.gpa.create(LabeledBlock); | ||
| 19110 | labeled_block.* = .{ | ||
| 19111 | .label = .{ | ||
| 19112 | .zir_block = break_data.block_inst, | ||
| 19113 | .merges = .{ | ||
| 19114 | .src_locs = .{}, | ||
| 19115 | .results = .{}, | ||
| 19116 | .br_list = .{}, | ||
| 19117 | .block_inst = new_block_inst, | ||
| 19118 | }, | ||
| 19119 | }, | ||
| 19120 | .block = .{ | ||
| 19121 | .parent = child_block, | ||
| 19122 | .sema = sema, | ||
| 19123 | .src_decl = child_block.src_decl, | ||
| 19124 | .namespace = child_block.namespace, | ||
| 19125 | .wip_capture_scope = child_block.wip_capture_scope, | ||
| 19126 | .instructions = .{}, | ||
| 19127 | .label = &labeled_block.label, | ||
| 19128 | .inlining = child_block.inlining, | ||
| 19129 | .is_comptime = child_block.is_comptime, | ||
| 19130 | }, | ||
| 19131 | }; | ||
| 19132 | sema.post_hoc_blocks.putAssumeCapacityNoClobber(new_block_inst, labeled_block); | ||
| 19133 | break :blk labeled_block; | ||
| 19134 | } else blk: { | ||
| 19135 | const new_block_inst = gop.value_ptr.*.toIndex().?; | ||
| 19136 | const labeled_block = sema.post_hoc_blocks.get(new_block_inst).?; | ||
| 19137 | break :blk labeled_block; | ||
| 19138 | }; | ||
| 19139 | 19158 | ||
| 19140 | const operand = try sema.resolveInst(break_data.operand); | 19159 | const operand = try sema.resolveInst(break_data.operand); |
| 19141 | const br_ref = try child_block.addBr(labeled_block.label.merges.block_inst, operand); | 19160 | const br_ref = try child_block.addBr(labeled_block.label.merges.block_inst, operand); |
| 19161 | |||
| 19142 | try labeled_block.label.merges.results.append(sema.gpa, operand); | 19162 | try labeled_block.label.merges.results.append(sema.gpa, operand); |
| 19143 | try labeled_block.label.merges.br_list.append(sema.gpa, br_ref.toIndex().?); | 19163 | try labeled_block.label.merges.br_list.append(sema.gpa, br_ref.toIndex().?); |
| 19164 | try labeled_block.label.merges.src_locs.append(sema.gpa, null); | ||
| 19165 | |||
| 19144 | labeled_block.block.runtime_index.increment(); | 19166 | labeled_block.block.runtime_index.increment(); |
| 19145 | if (labeled_block.block.runtime_cond == null and labeled_block.block.runtime_loop == null) { | 19167 | if (labeled_block.block.runtime_cond == null and labeled_block.block.runtime_loop == null) { |
| 19146 | labeled_block.block.runtime_cond = child_block.runtime_cond orelse child_block.runtime_loop; | 19168 | labeled_block.block.runtime_cond = child_block.runtime_cond orelse child_block.runtime_loop; |
| ... | @@ -19481,8 +19503,10 @@ fn analyzeRet( | ... | @@ -19481,8 +19503,10 @@ fn analyzeRet( |
| 19481 | return error.ComptimeReturn; | 19503 | return error.ComptimeReturn; |
| 19482 | } | 19504 | } |
| 19483 | // We are inlining a function call; rewrite the `ret` as a `break`. | 19505 | // We are inlining a function call; rewrite the `ret` as a `break`. |
| 19506 | const br_inst = try block.addBr(inlining.merges.block_inst, operand); | ||
| 19484 | try inlining.merges.results.append(sema.gpa, operand); | 19507 | try inlining.merges.results.append(sema.gpa, operand); |
| 19485 | _ = try block.addBr(inlining.merges.block_inst, operand); | 19508 | try inlining.merges.br_list.append(sema.gpa, br_inst.toIndex().?); |
| 19509 | try inlining.merges.src_locs.append(sema.gpa, operand_src); | ||
| 19486 | return always_noreturn; | 19510 | return always_noreturn; |
| 19487 | } else if (block.is_comptime) { | 19511 | } else if (block.is_comptime) { |
| 19488 | return sema.fail(block, src, "function called at runtime cannot return value at comptime", .{}); | 19512 | 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 { | ... | @@ -392,10 +392,6 @@ pub const Inst = struct { |
| 392 | /// Same as `dbg_var_ptr` but the local is always a const and the operand | 392 | /// Same as `dbg_var_ptr` but the local is always a const and the operand |
| 393 | /// is the local's value. | 393 | /// is the local's value. |
| 394 | dbg_var_val, | 394 | 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, | ||
| 399 | /// Uses a name to identify a Decl and takes a pointer to it. | 395 | /// Uses a name to identify a Decl and takes a pointer to it. |
| 400 | /// Uses the `str_tok` union field. | 396 | /// Uses the `str_tok` union field. |
| 401 | decl_ref, | 397 | decl_ref, |
| ... | @@ -1107,8 +1103,6 @@ pub const Inst = struct { | ... | @@ -1107,8 +1103,6 @@ pub const Inst = struct { |
| 1107 | .dbg_stmt, | 1103 | .dbg_stmt, |
| 1108 | .dbg_var_ptr, | 1104 | .dbg_var_ptr, |
| 1109 | .dbg_var_val, | 1105 | .dbg_var_val, |
| 1110 | .dbg_block_begin, | ||
| 1111 | .dbg_block_end, | ||
| 1112 | .decl_ref, | 1106 | .decl_ref, |
| 1113 | .decl_val, | 1107 | .decl_val, |
| 1114 | .load, | 1108 | .load, |
| ... | @@ -1335,8 +1329,6 @@ pub const Inst = struct { | ... | @@ -1335,8 +1329,6 @@ pub const Inst = struct { |
| 1335 | .dbg_stmt, | 1329 | .dbg_stmt, |
| 1336 | .dbg_var_ptr, | 1330 | .dbg_var_ptr, |
| 1337 | .dbg_var_val, | 1331 | .dbg_var_val, |
| 1338 | .dbg_block_begin, | ||
| 1339 | .dbg_block_end, | ||
| 1340 | .ensure_result_used, | 1332 | .ensure_result_used, |
| 1341 | .ensure_result_non_error, | 1333 | .ensure_result_non_error, |
| 1342 | .ensure_err_union_payload_void, | 1334 | .ensure_err_union_payload_void, |
| ... | @@ -1663,8 +1655,6 @@ pub const Inst = struct { | ... | @@ -1663,8 +1655,6 @@ pub const Inst = struct { |
| 1663 | .dbg_stmt = .dbg_stmt, | 1655 | .dbg_stmt = .dbg_stmt, |
| 1664 | .dbg_var_ptr = .str_op, | 1656 | .dbg_var_ptr = .str_op, |
| 1665 | .dbg_var_val = .str_op, | 1657 | .dbg_var_val = .str_op, |
| 1666 | .dbg_block_begin = .tok, | ||
| 1667 | .dbg_block_end = .tok, | ||
| 1668 | .decl_ref = .str_tok, | 1658 | .decl_ref = .str_tok, |
| 1669 | .decl_val = .str_tok, | 1659 | .decl_val = .str_tok, |
| 1670 | .load = .un_node, | 1660 | .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 { | ... | @@ -813,10 +813,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 813 | .dbg_inline_end, | 813 | .dbg_inline_end, |
| 814 | => try self.airDbgInline(inst), | 814 | => try self.airDbgInline(inst), |
| 815 | 815 | ||
| 816 | .dbg_block_begin, | ||
| 817 | .dbg_block_end, | ||
| 818 | => try self.airDbgBlock(inst), | ||
| 819 | |||
| 820 | .call => try self.airCall(inst, .auto), | 816 | .call => try self.airCall(inst, .auto), |
| 821 | .call_always_tail => try self.airCall(inst, .always_tail), | 817 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 822 | .call_never_tail => try self.airCall(inst, .never_tail), | 818 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | @@ -4634,11 +4630,6 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4634,11 +4630,6 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { |
| 4634 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); | 4630 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); |
| 4635 | } | 4631 | } |
| 4636 | 4632 | ||
| 4637 | fn 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 | |||
| 4642 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { | 4633 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 4643 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 4634 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 4644 | const operand = pl_op.operand; | 4635 | const operand = pl_op.operand; |
| ... | @@ -5066,6 +5057,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5066,6 +5057,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 5066 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 5057 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5067 | const extra = self.air.extraData(Air.Block, ty_pl.payload); | 5058 | const extra = self.air.extraData(Air.Block, ty_pl.payload); |
| 5068 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); | 5059 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); |
| 5060 | // TODO emit debug info lexical block | ||
| 5069 | try self.genBody(body); | 5061 | try self.genBody(body); |
| 5070 | 5062 | ||
| 5071 | // relocations for `br` instructions | 5063 | // 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 { | ... | @@ -799,10 +799,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 799 | .dbg_inline_end, | 799 | .dbg_inline_end, |
| 800 | => try self.airDbgInline(inst), | 800 | => try self.airDbgInline(inst), |
| 801 | 801 | ||
| 802 | .dbg_block_begin, | ||
| 803 | .dbg_block_end, | ||
| 804 | => try self.airDbgBlock(inst), | ||
| 805 | |||
| 806 | .call => try self.airCall(inst, .auto), | 802 | .call => try self.airCall(inst, .auto), |
| 807 | .call_always_tail => try self.airCall(inst, .always_tail), | 803 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 808 | .call_never_tail => try self.airCall(inst, .never_tail), | 804 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | @@ -4587,11 +4583,6 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4587,11 +4583,6 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { |
| 4587 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); | 4583 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); |
| 4588 | } | 4584 | } |
| 4589 | 4585 | ||
| 4590 | fn 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 | |||
| 4595 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { | 4586 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 4596 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 4587 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 4597 | const operand = pl_op.operand; | 4588 | const operand = pl_op.operand; |
| ... | @@ -4997,6 +4988,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4997,6 +4988,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 4997 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 4988 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4998 | const extra = self.air.extraData(Air.Block, ty_pl.payload); | 4989 | const extra = self.air.extraData(Air.Block, ty_pl.payload); |
| 4999 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); | 4990 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); |
| 4991 | // TODO emit debug info lexical block | ||
| 5000 | try self.genBody(body); | 4992 | try self.genBody(body); |
| 5001 | 4993 | ||
| 5002 | // relocations for `br` instructions | 4994 | // 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 { | ... | @@ -632,10 +632,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 632 | .dbg_inline_end, | 632 | .dbg_inline_end, |
| 633 | => try self.airDbgInline(inst), | 633 | => try self.airDbgInline(inst), |
| 634 | 634 | ||
| 635 | .dbg_block_begin, | ||
| 636 | .dbg_block_end, | ||
| 637 | => try self.airDbgBlock(inst), | ||
| 638 | |||
| 639 | .call => try self.airCall(inst, .auto), | 635 | .call => try self.airCall(inst, .auto), |
| 640 | .call_always_tail => try self.airCall(inst, .always_tail), | 636 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 641 | .call_never_tail => try self.airCall(inst, .never_tail), | 637 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | @@ -1894,11 +1890,6 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1894,11 +1890,6 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { |
| 1894 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); | 1890 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); |
| 1895 | } | 1891 | } |
| 1896 | 1892 | ||
| 1897 | fn 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 | |||
| 1902 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { | 1893 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 1903 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 1894 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 1904 | const name = self.air.nullTerminatedString(pl_op.payload); | 1895 | const name = self.air.nullTerminatedString(pl_op.payload); |
| ... | @@ -2084,6 +2075,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2084,6 +2075,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 2084 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 2075 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2085 | const extra = self.air.extraData(Air.Block, ty_pl.payload); | 2076 | const extra = self.air.extraData(Air.Block, ty_pl.payload); |
| 2086 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); | 2077 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); |
| 2078 | // TODO emit debug info lexical block | ||
| 2087 | try self.genBody(body); | 2079 | try self.genBody(body); |
| 2088 | 2080 | ||
| 2089 | for (self.blocks.getPtr(inst).?.relocs.items) |reloc| try self.performReloc(reloc); | 2081 | 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 { | ... | @@ -645,10 +645,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 645 | .dbg_inline_end, | 645 | .dbg_inline_end, |
| 646 | => try self.airDbgInline(inst), | 646 | => try self.airDbgInline(inst), |
| 647 | 647 | ||
| 648 | .dbg_block_begin, | ||
| 649 | .dbg_block_end, | ||
| 650 | => try self.airDbgBlock(inst), | ||
| 651 | |||
| 652 | .call => try self.airCall(inst, .auto), | 648 | .call => try self.airCall(inst, .auto), |
| 653 | .call_always_tail => try self.airCall(inst, .always_tail), | 649 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 654 | .call_never_tail => try self.airCall(inst, .never_tail), | 650 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | @@ -1146,6 +1142,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1146,6 +1142,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 1146 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 1142 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 1147 | const extra = self.air.extraData(Air.Block, ty_pl.payload); | 1143 | const extra = self.air.extraData(Air.Block, ty_pl.payload); |
| 1148 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); | 1144 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); |
| 1145 | // TODO emit debug info lexical block | ||
| 1149 | try self.genBody(body); | 1146 | try self.genBody(body); |
| 1150 | 1147 | ||
| 1151 | // relocations for `bpcc` instructions | 1148 | // relocations for `bpcc` instructions |
| ... | @@ -1655,11 +1652,6 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1655,11 +1652,6 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { |
| 1655 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 1652 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 1656 | } | 1653 | } |
| 1657 | 1654 | ||
| 1658 | fn 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 | |||
| 1663 | fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { | 1655 | fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { |
| 1664 | const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn; | 1656 | const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn; |
| 1665 | const mod = self.bin_file.comp.module.?; | 1657 | 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 { | ... | @@ -1913,8 +1913,6 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1913 | // TODO | 1913 | // TODO |
| 1914 | .dbg_inline_begin, | 1914 | .dbg_inline_begin, |
| 1915 | .dbg_inline_end, | 1915 | .dbg_inline_end, |
| 1916 | .dbg_block_begin, | ||
| 1917 | .dbg_block_end, | ||
| 1918 | => func.finishAir(inst, .none, &.{}), | 1916 | => func.finishAir(inst, .none, &.{}), |
| 1919 | 1917 | ||
| 1920 | .dbg_var_ptr => func.airDbgVar(inst, true), | 1918 | .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 { | ... | @@ -2106,10 +2106,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 2106 | .dbg_inline_end, | 2106 | .dbg_inline_end, |
| 2107 | => try self.airDbgInline(inst), | 2107 | => try self.airDbgInline(inst), |
| 2108 | 2108 | ||
| 2109 | .dbg_block_begin, | ||
| 2110 | .dbg_block_end, | ||
| 2111 | => try self.airDbgBlock(inst), | ||
| 2112 | |||
| 2113 | .call => try self.airCall(inst, .auto), | 2109 | .call => try self.airCall(inst, .auto), |
| 2114 | .call_always_tail => try self.airCall(inst, .always_tail), | 2110 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 2115 | .call_never_tail => try self.airCall(inst, .never_tail), | 2111 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | @@ -12976,12 +12972,6 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -12976,12 +12972,6 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { |
| 12976 | self.finishAirBookkeeping(); | 12972 | self.finishAirBookkeeping(); |
| 12977 | } | 12973 | } |
| 12978 | 12974 | ||
| 12979 | fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void { | ||
| 12980 | _ = inst; | ||
| 12981 | // TODO emit debug info lexical block | ||
| 12982 | self.finishAirBookkeeping(); | ||
| 12983 | } | ||
| 12984 | |||
| 12985 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { | 12975 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 12986 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 12976 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 12987 | const operand = pl_op.operand; | 12977 | const operand = pl_op.operand; |
| ... | @@ -13428,6 +13418,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -13428,6 +13418,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 13428 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 13418 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 13429 | const extra = self.air.extraData(Air.Block, ty_pl.payload); | 13419 | const extra = self.air.extraData(Air.Block, ty_pl.payload); |
| 13430 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); | 13420 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); |
| 13421 | // TODO emit debug info lexical block | ||
| 13431 | try self.genBody(body); | 13422 | try self.genBody(body); |
| 13432 | 13423 | ||
| 13433 | var block_data = self.blocks.fetchRemove(inst).?; | 13424 | 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, | ... | @@ -3268,10 +3268,6 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, |
| 3268 | .dbg_inline_end, | 3268 | .dbg_inline_end, |
| 3269 | => try airDbgInline(f, inst), | 3269 | => try airDbgInline(f, inst), |
| 3270 | 3270 | ||
| 3271 | .dbg_block_begin, | ||
| 3272 | .dbg_block_end, | ||
| 3273 | => .none, | ||
| 3274 | |||
| 3275 | .call => try airCall(f, inst, .auto), | 3271 | .call => try airCall(f, inst, .auto), |
| 3276 | .call_always_tail => .none, | 3272 | .call_always_tail => .none, |
| 3277 | .call_never_tail => try airCall(f, inst, .never_tail), | 3273 | .call_never_tail => try airCall(f, inst, .never_tail), |
src/codegen/llvm.zig+16-28| ... | @@ -4768,8 +4768,6 @@ pub const FuncGen = struct { | ... | @@ -4768,8 +4768,6 @@ pub const FuncGen = struct { |
| 4768 | scope: Builder.Metadata, | 4768 | scope: Builder.Metadata, |
| 4769 | }) = .{}, | 4769 | }) = .{}, |
| 4770 | 4770 | ||
| 4771 | scope_stack: std.ArrayListUnmanaged(Builder.Metadata) = .{}, | ||
| 4772 | |||
| 4773 | base_line: u32, | 4771 | base_line: u32, |
| 4774 | prev_dbg_line: c_uint, | 4772 | prev_dbg_line: c_uint, |
| 4775 | prev_dbg_column: c_uint, | 4773 | prev_dbg_column: c_uint, |
| ... | @@ -4813,7 +4811,6 @@ pub const FuncGen = struct { | ... | @@ -4813,7 +4811,6 @@ pub const FuncGen = struct { |
| 4813 | 4811 | ||
| 4814 | fn deinit(self: *FuncGen) void { | 4812 | fn deinit(self: *FuncGen) void { |
| 4815 | self.wip.deinit(); | 4813 | self.wip.deinit(); |
| 4816 | self.scope_stack.deinit(self.gpa); | ||
| 4817 | self.inlined.deinit(self.gpa); | 4814 | self.inlined.deinit(self.gpa); |
| 4818 | self.func_inst_table.deinit(self.gpa); | 4815 | self.func_inst_table.deinit(self.gpa); |
| 4819 | self.blocks.deinit(self.gpa); | 4816 | self.blocks.deinit(self.gpa); |
| ... | @@ -5112,8 +5109,6 @@ pub const FuncGen = struct { | ... | @@ -5112,8 +5109,6 @@ pub const FuncGen = struct { |
| 5112 | .dbg_stmt => try self.airDbgStmt(inst), | 5109 | .dbg_stmt => try self.airDbgStmt(inst), |
| 5113 | .dbg_inline_begin => try self.airDbgInlineBegin(inst), | 5110 | .dbg_inline_begin => try self.airDbgInlineBegin(inst), |
| 5114 | .dbg_inline_end => try self.airDbgInlineEnd(inst), | 5111 | .dbg_inline_end => try self.airDbgInlineEnd(inst), |
| 5115 | .dbg_block_begin => try self.airDbgBlockBegin(), | ||
| 5116 | .dbg_block_end => try self.airDbgBlockEnd(), | ||
| 5117 | .dbg_var_ptr => try self.airDbgVarPtr(inst), | 5112 | .dbg_var_ptr => try self.airDbgVarPtr(inst), |
| 5118 | .dbg_var_val => try self.airDbgVarVal(inst), | 5113 | .dbg_var_val => try self.airDbgVarVal(inst), |
| 5119 | 5114 | ||
| ... | @@ -5131,6 +5126,19 @@ pub const FuncGen = struct { | ... | @@ -5131,6 +5126,19 @@ pub const FuncGen = struct { |
| 5131 | } | 5126 | } |
| 5132 | } | 5127 | } |
| 5133 | 5128 | ||
| 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 | |||
| 5134 | pub const CallAttr = enum { | 5142 | pub const CallAttr = enum { |
| 5135 | Auto, | 5143 | Auto, |
| 5136 | NeverTail, | 5144 | NeverTail, |
| ... | @@ -5820,7 +5828,7 @@ pub const FuncGen = struct { | ... | @@ -5820,7 +5828,7 @@ pub const FuncGen = struct { |
| 5820 | const inst_ty = self.typeOfIndex(inst); | 5828 | const inst_ty = self.typeOfIndex(inst); |
| 5821 | 5829 | ||
| 5822 | if (inst_ty.isNoReturn(mod)) { | 5830 | if (inst_ty.isNoReturn(mod)) { |
| 5823 | try self.genBody(body); | 5831 | try self.genBodyDebugScope(body); |
| 5824 | return .none; | 5832 | return .none; |
| 5825 | } | 5833 | } |
| 5826 | 5834 | ||
| ... | @@ -5836,7 +5844,7 @@ pub const FuncGen = struct { | ... | @@ -5836,7 +5844,7 @@ pub const FuncGen = struct { |
| 5836 | }); | 5844 | }); |
| 5837 | defer assert(self.blocks.remove(inst)); | 5845 | defer assert(self.blocks.remove(inst)); |
| 5838 | 5846 | ||
| 5839 | try self.genBody(body); | 5847 | try self.genBodyDebugScope(body); |
| 5840 | 5848 | ||
| 5841 | self.wip.cursor = .{ .block = parent_bb }; | 5849 | self.wip.cursor = .{ .block = parent_bb }; |
| 5842 | 5850 | ||
| ... | @@ -6683,26 +6691,6 @@ pub const FuncGen = struct { | ... | @@ -6683,26 +6691,6 @@ pub const FuncGen = struct { |
| 6683 | return .none; | 6691 | return .none; |
| 6684 | } | 6692 | } |
| 6685 | 6693 | ||
| 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 | |||
| 6706 | fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 6694 | fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6707 | const o = self.dg.object; | 6695 | const o = self.dg.object; |
| 6708 | const mod = o.module; | 6696 | const mod = o.module; |
| ... | @@ -7488,7 +7476,7 @@ pub const FuncGen = struct { | ... | @@ -7488,7 +7476,7 @@ pub const FuncGen = struct { |
| 7488 | for (body_tail[1..]) |body_inst| { | 7476 | for (body_tail[1..]) |body_inst| { |
| 7489 | switch (air_tags[@intFromEnum(body_inst)]) { | 7477 | switch (air_tags[@intFromEnum(body_inst)]) { |
| 7490 | .ret => return true, | 7478 | .ret => return true, |
| 7491 | .dbg_stmt, .dbg_block_end => continue, | 7479 | .dbg_stmt => continue, |
| 7492 | else => return false, | 7480 | else => return false, |
| 7493 | } | 7481 | } |
| 7494 | } | 7482 | } |
src/codegen/spirv.zig-2| ... | @@ -2322,8 +2322,6 @@ const DeclGen = struct { | ... | @@ -2322,8 +2322,6 @@ const DeclGen = struct { |
| 2322 | .dbg_inline_begin => return self.airDbgInlineBegin(inst), | 2322 | .dbg_inline_begin => return self.airDbgInlineBegin(inst), |
| 2323 | .dbg_inline_end => return self.airDbgInlineEnd(inst), | 2323 | .dbg_inline_end => return self.airDbgInlineEnd(inst), |
| 2324 | .dbg_var_ptr, .dbg_var_val => return self.airDbgVar(inst), | 2324 | .dbg_var_ptr, .dbg_var_val => return self.airDbgVar(inst), |
| 2325 | .dbg_block_begin => return, | ||
| 2326 | .dbg_block_end => return, | ||
| 2327 | 2325 | ||
| 2328 | .unwrap_errunion_err => try self.airErrUnionErr(inst), | 2326 | .unwrap_errunion_err => try self.airErrUnionErr(inst), |
| 2329 | .unwrap_errunion_payload => try self.airErrUnionPayload(inst), | 2327 | .unwrap_errunion_payload => try self.airErrUnionPayload(inst), |
src/print_air.zig-2| ... | @@ -319,8 +319,6 @@ const Writer = struct { | ... | @@ -319,8 +319,6 @@ const Writer = struct { |
| 319 | .cmp_vector, .cmp_vector_optimized => try w.writeCmpVector(s, inst), | 319 | .cmp_vector, .cmp_vector_optimized => try w.writeCmpVector(s, inst), |
| 320 | .vector_store_elem => try w.writeVectorStoreElem(s, inst), | 320 | .vector_store_elem => try w.writeVectorStoreElem(s, inst), |
| 321 | 321 | ||
| 322 | .dbg_block_begin, .dbg_block_end => {}, | ||
| 323 | |||
| 324 | .work_item_id, | 322 | .work_item_id, |
| 325 | .work_group_size, | 323 | .work_group_size, |
| 326 | .work_group_id, | 324 | .work_group_id, |
src/print_zir.zig-4| ... | @@ -510,10 +510,6 @@ const Writer = struct { | ... | @@ -510,10 +510,6 @@ const Writer = struct { |
| 510 | 510 | ||
| 511 | .dbg_stmt => try self.writeDbgStmt(stream, inst), | 511 | .dbg_stmt => try self.writeDbgStmt(stream, inst), |
| 512 | 512 | ||
| 513 | .dbg_block_begin, | ||
| 514 | .dbg_block_end, | ||
| 515 | => try stream.writeAll(")"), | ||
| 516 | |||
| 517 | .closure_get => try self.writeInstNode(stream, inst), | 513 | .closure_get => try self.writeInstNode(stream, inst), |
| 518 | 514 | ||
| 519 | .@"defer" => try self.writeDefer(stream, inst), | 515 | .@"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" | ... | @@ -1714,3 +1714,21 @@ test "const with specified type initialized with typed array is comptime-known" |
| 1714 | comptime assert(x[1] == 2); | 1714 | comptime assert(x[1] == 2); |
| 1715 | comptime assert(x[2] == 3); | 1715 | comptime assert(x[2] == 3); |
| 1716 | } | 1716 | } |
| 1717 | |||
| 1718 | test "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 | } |