authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-02-11 21:26:35+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-02-16 11:26:33+00:00
logaba29f9789aff0c1ace2a1d0031818ec2c04070c
tree2ae6a6f39310d6abc61a0c5b707344a0cdb6c0dc
parent2e27967a81d325047e6d82f8c0722a8a654d1ac7
signaturelock-open Commit is signed but in an unrecognized format.

AstGen: fix elision of unnecessary `dbg_stmt` instructions

AstGen has logic to elide leading `dbg_stmt` instructions when multiple are emitted consecutively; however, it only applied in some cases. A simple reshuffle here makes this logic apply universally, saving some bytes in ZIR.

1 files changed, 43 insertions(+), 30 deletions(-)

src/AstGen.zig+43-30
......@@ -3332,31 +3332,11 @@ fn emitDbgNode(gz: *GenZir, node: Ast.Node.Index) !void {
33323332 // If the current block will be evaluated only during semantic analysis
33333333 // then no dbg_stmt ZIR instruction is needed.
33343334 if (gz.is_comptime) return;
3335
33363335 const astgen = gz.astgen;
33373336 astgen.advanceSourceCursorToNode(node);
33383337 const line = astgen.source_line - gz.decl_line;
33393338 const column = astgen.source_column;
3340
3341 if (gz.instructions.items.len > 0) {
3342 const last = gz.instructions.items[gz.instructions.items.len - 1];
3343 const zir_tags = astgen.instructions.items(.tag);
3344 if (zir_tags[@intFromEnum(last)] == .dbg_stmt) {
3345 const zir_datas = astgen.instructions.items(.data);
3346 zir_datas[@intFromEnum(last)].dbg_stmt = .{
3347 .line = line,
3348 .column = column,
3349 };
3350 return;
3351 }
3352 }
3353
3354 _ = try gz.add(.{ .tag = .dbg_stmt, .data = .{
3355 .dbg_stmt = .{
3356 .line = line,
3357 .column = column,
3358 },
3359 } });
3339 try emitDbgStmt(gz, .{ line, column });
33603340}
33613341
33623342fn assign(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerError!void {
......@@ -7143,7 +7123,7 @@ fn switchExprErrUnion(
71437123 block_scope.setBreakResultInfo(block_ri);
71447124
71457125 // Sema expects a dbg_stmt immediately before switch_block_err_union
7146 try emitDbgStmt(parent_gz, operand_lc);
7126 try emitDbgStmtForceCurrentIndex(parent_gz, operand_lc);
71477127 // This gets added to the parent block later, after the item expressions.
71487128 const switch_block = try parent_gz.makeBlockInst(.switch_block_err_union, switch_node);
71497129
......@@ -7723,7 +7703,7 @@ fn switchExpr(
77237703 block_scope.setBreakResultInfo(block_ri);
77247704
77257705 // Sema expects a dbg_stmt immediately before switch_block(_ref)
7726 try emitDbgStmt(parent_gz, operand_lc);
7706 try emitDbgStmtForceCurrentIndex(parent_gz, operand_lc);
77277707 // This gets added to the parent block later, after the item expressions.
77287708 const switch_tag: Zir.Inst.Tag = if (any_payload_is_ref) .switch_block_ref else .switch_block;
77297709 const switch_block = try parent_gz.makeBlockInst(switch_tag, switch_node);
......@@ -9847,13 +9827,8 @@ fn callExpr(
98479827 astgen.advanceSourceCursor(astgen.tree.tokens.items(.start)[call.ast.lparen]);
98489828 const line = astgen.source_line - gz.decl_line;
98499829 const column = astgen.source_column;
9850
9851 _ = try gz.add(.{ .tag = .dbg_stmt, .data = .{
9852 .dbg_stmt = .{
9853 .line = line,
9854 .column = column,
9855 },
9856 } });
9830 // Sema expects a dbg_stmt immediately before call,
9831 try emitDbgStmtForceCurrentIndex(gz, .{ line, column });
98579832 }
98589833
98599834 switch (callee) {
......@@ -13536,6 +13511,44 @@ fn countBodyLenAfterFixups(astgen: *AstGen, body: []const Zir.Inst.Index) u32 {
1353613511
1353713512fn emitDbgStmt(gz: *GenZir, lc: LineColumn) !void {
1353813513 if (gz.is_comptime) return;
13514 if (gz.instructions.items.len > 0) {
13515 const astgen = gz.astgen;
13516 const last = gz.instructions.items[gz.instructions.items.len - 1];
13517 if (astgen.instructions.items(.tag)[@intFromEnum(last)] == .dbg_stmt) {
13518 astgen.instructions.items(.data)[@intFromEnum(last)].dbg_stmt = .{
13519 .line = lc[0],
13520 .column = lc[1],
13521 };
13522 return;
13523 }
13524 }
13525
13526 _ = try gz.add(.{ .tag = .dbg_stmt, .data = .{
13527 .dbg_stmt = .{
13528 .line = lc[0],
13529 .column = lc[1],
13530 },
13531 } });
13532}
13533
13534/// In some cases, Sema expects us to generate a `dbg_stmt` at the instruction
13535/// *index* directly preceding the next instruction (e.g. if a call is %10, it
13536/// expects a dbg_stmt at %9). TODO: this logic may allow redundant dbg_stmt
13537/// instructions; fix up Sema so we don't need it!
13538fn emitDbgStmtForceCurrentIndex(gz: *GenZir, lc: LineColumn) !void {
13539 const astgen = gz.astgen;
13540 if (gz.instructions.items.len > 0 and
13541 @intFromEnum(gz.instructions.items[gz.instructions.items.len - 1]) == astgen.instructions.len - 1)
13542 {
13543 const last = astgen.instructions.len - 1;
13544 if (astgen.instructions.items(.tag)[last] == .dbg_stmt) {
13545 astgen.instructions.items(.data)[last].dbg_stmt = .{
13546 .line = lc[0],
13547 .column = lc[1],
13548 };
13549 return;
13550 }
13551 }
1353913552
1354013553 _ = try gz.add(.{ .tag = .dbg_stmt, .data = .{
1354113554 .dbg_stmt = .{