Skip to content

Commit 49c0bb1

Browse files
authored
Merge pull request #11177 from Vexu/dbg_func
Add debug info for inlined calls
2 parents d4a7a9a + d83a26f commit 49c0bb1

File tree

16 files changed

+277
-12
lines changed

16 files changed

+277
-12
lines changed

src/Air.zig

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ const std = @import("std");
77
const builtin = @import("builtin");
88
const Value = @import("value.zig").Value;
99
const Type = @import("type.zig").Type;
10-
const Module = @import("Module.zig");
1110
const assert = std.debug.assert;
1211
const Air = @This();
1312

@@ -327,6 +326,12 @@ pub const Inst = struct {
327326
/// Result type is always void.
328327
/// Uses the `dbg_stmt` field.
329328
dbg_stmt,
329+
/// Marks the start of an inline call.
330+
/// Uses `ty_pl` with the payload being the index of a Value.Function in air.values.
331+
dbg_inline_begin,
332+
/// Marks the end of an inline call.
333+
/// Uses `ty_pl` with the payload being the index of a Value.Function in air.values.
334+
dbg_inline_end,
330335
/// Marks the beginning of a local variable. The operand is a pointer pointing
331336
/// to the storage for the variable. The local may be a const or a var.
332337
/// Result type is always void.
@@ -971,6 +976,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
971976

972977
.breakpoint,
973978
.dbg_stmt,
979+
.dbg_inline_begin,
980+
.dbg_inline_end,
974981
.dbg_var_ptr,
975982
.dbg_var_val,
976983
.store,

src/AstGen.zig

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5148,6 +5148,7 @@ fn ifExpr(
51485148
else
51495149
false;
51505150

5151+
try emitDbgNode(parent_gz, if_full.ast.cond_expr);
51515152
const cond: struct {
51525153
inst: Zir.Inst.Ref,
51535154
bool_bit: Zir.Inst.Ref,
@@ -5458,6 +5459,7 @@ fn whileExpr(
54585459
else
54595460
false;
54605461

5462+
try emitDbgNode(parent_gz, while_full.ast.cond_expr);
54615463
const cond: struct {
54625464
inst: Zir.Inst.Ref,
54635465
bool_bit: Zir.Inst.Ref,
@@ -5678,6 +5680,8 @@ fn forExpr(
56785680
else
56795681
false;
56805682

5683+
try emitDbgNode(parent_gz, for_full.ast.cond_expr);
5684+
56815685
const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none;
56825686
const array_ptr = try expr(parent_gz, scope, cond_rl, for_full.ast.cond_expr);
56835687
const len = try parent_gz.addUnNode(.indexable_ptr_len, array_ptr, for_full.ast.cond_expr);
@@ -7810,6 +7814,19 @@ fn callExpr(
78107814
break :blk .auto;
78117815
};
78127816

7817+
{
7818+
astgen.advanceSourceCursor(astgen.tree.tokens.items(.start)[call.ast.lparen]);
7819+
const line = astgen.source_line - gz.decl_line;
7820+
const column = astgen.source_column;
7821+
7822+
_ = try gz.add(.{ .tag = .dbg_stmt, .data = .{
7823+
.dbg_stmt = .{
7824+
.line = line,
7825+
.column = column,
7826+
},
7827+
} });
7828+
}
7829+
78137830
assert(callee != .none);
78147831
assert(node != 0);
78157832

src/Liveness.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,8 @@ fn analyzeInst(
314314
.const_ty,
315315
.breakpoint,
316316
.dbg_stmt,
317+
.dbg_inline_begin,
318+
.dbg_inline_end,
317319
.unreach,
318320
.fence,
319321
.ret_addr,

src/Sema.zig

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4639,6 +4639,10 @@ fn analyzeCall(
46394639
// comptime state.
46404640
var should_memoize = true;
46414641

4642+
var new_fn_info = module_fn.owner_decl.ty.fnInfo();
4643+
new_fn_info.param_types = try sema.arena.alloc(Type, new_fn_info.param_types.len);
4644+
new_fn_info.comptime_params = (try sema.arena.alloc(bool, new_fn_info.param_types.len)).ptr;
4645+
46424646
// This will have return instructions analyzed as break instructions to
46434647
// the block_inst above. Here we are performing "comptime/inline semantic analysis"
46444648
// for a function body, which means we must map the parameter ZIR instructions to
@@ -4658,6 +4662,7 @@ fn analyzeCall(
46584662
const param_body = sema.code.extra[extra.end..][0..extra.data.body_len];
46594663
const param_ty_inst = try sema.resolveBody(&child_block, param_body, inst);
46604664
const param_ty = try sema.analyzeAsType(&child_block, param_src, param_ty_inst);
4665+
new_fn_info.param_types[arg_i] = param_ty;
46614666
const arg_src = call_src; // TODO: better source location
46624667
const casted_arg = try sema.coerce(&child_block, param_ty, uncasted_args[arg_i], arg_src);
46634668
try sema.inst_map.putNoClobber(gpa, inst, casted_arg);
@@ -4685,6 +4690,7 @@ fn analyzeCall(
46854690
.param_anytype, .param_anytype_comptime => {
46864691
// No coercion needed.
46874692
const uncasted_arg = uncasted_args[arg_i];
4693+
new_fn_info.param_types[arg_i] = sema.typeOf(uncasted_arg);
46884694
try sema.inst_map.putNoClobber(gpa, inst, uncasted_arg);
46894695

46904696
if (is_comptime_call) {
@@ -4735,6 +4741,7 @@ fn analyzeCall(
47354741
}
47364742
break :blk bare_return_type;
47374743
};
4744+
new_fn_info.return_type = fn_ret_ty;
47384745
const parent_fn_ret_ty = sema.fn_ret_ty;
47394746
sema.fn_ret_ty = fn_ret_ty;
47404747
defer sema.fn_ret_ty = parent_fn_ret_ty;
@@ -4757,6 +4764,11 @@ fn analyzeCall(
47574764
}
47584765
}
47594766

4767+
const new_func_resolved_ty = try Type.Tag.function.create(sema.arena, new_fn_info);
4768+
if (!is_comptime_call) {
4769+
try sema.emitDbgInline(block, parent_func.?, module_fn, new_func_resolved_ty, .dbg_inline_begin);
4770+
}
4771+
47604772
const result = result: {
47614773
sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) {
47624774
error.ComptimeReturn => break :result inlining.comptime_result,
@@ -4771,6 +4783,10 @@ fn analyzeCall(
47714783
break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges);
47724784
};
47734785

4786+
if (!is_comptime_call) {
4787+
try sema.emitDbgInline(block, module_fn, parent_func.?, parent_func.?.owner_decl.ty, .dbg_inline_end);
4788+
}
4789+
47744790
if (should_memoize and is_comptime_call) {
47754791
const result_val = try sema.resolveConstMaybeUndefVal(block, call_src, result);
47764792

@@ -5175,6 +5191,27 @@ fn instantiateGenericCall(
51755191
return func_inst;
51765192
}
51775193

5194+
fn emitDbgInline(
5195+
sema: *Sema,
5196+
block: *Block,
5197+
old_func: *Module.Fn,
5198+
new_func: *Module.Fn,
5199+
new_func_ty: Type,
5200+
tag: Air.Inst.Tag,
5201+
) CompileError!void {
5202+
// No change of file; no dbg_inline needed.
5203+
if (old_func == new_func) return;
5204+
5205+
try sema.air_values.append(sema.gpa, try Value.Tag.function.create(sema.arena, new_func));
5206+
_ = try block.addInst(.{
5207+
.tag = tag,
5208+
.data = .{ .ty_pl = .{
5209+
.ty = try sema.addType(new_func_ty),
5210+
.payload = @intCast(u32, sema.air_values.items.len - 1),
5211+
} },
5212+
});
5213+
}
5214+
51785215
fn zirIntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
51795216
_ = block;
51805217
const tracy = trace(@src());

src/arch/aarch64/CodeGen.zig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
649649
.dbg_var_val,
650650
=> try self.airDbgVar(inst),
651651

652+
.dbg_inline_begin,
653+
.dbg_inline_end,
654+
=> try self.airDbgInline(inst),
655+
652656
.call => try self.airCall(inst, .auto),
653657
.call_always_tail => try self.airCall(inst, .always_tail),
654658
.call_never_tail => try self.airCall(inst, .never_tail),
@@ -2715,6 +2719,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
27152719
return self.finishAirBookkeeping();
27162720
}
27172721

2722+
fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
2723+
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2724+
const function = self.air.values[ty_pl.payload].castTag(.function).?.data;
2725+
// TODO emit debug info for function change
2726+
_ = function;
2727+
return self.finishAir(inst, .dead, .{ .none, .none, .none });
2728+
}
2729+
27182730
fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
27192731
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
27202732
const name = self.air.nullTerminatedString(pl_op.payload);

src/arch/arm/CodeGen.zig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
646646
.dbg_var_val,
647647
=> try self.airDbgVar(inst),
648648

649+
.dbg_inline_begin,
650+
.dbg_inline_end,
651+
=> try self.airDbgInline(inst),
652+
649653
.call => try self.airCall(inst, .auto),
650654
.call_always_tail => try self.airCall(inst, .always_tail),
651655
.call_never_tail => try self.airCall(inst, .never_tail),
@@ -2835,6 +2839,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
28352839
return self.finishAirBookkeeping();
28362840
}
28372841

2842+
fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
2843+
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2844+
const function = self.air.values[ty_pl.payload].castTag(.function).?.data;
2845+
// TODO emit debug info for function change
2846+
_ = function;
2847+
return self.finishAir(inst, .dead, .{ .none, .none, .none });
2848+
}
2849+
28382850
fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
28392851
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
28402852
const name = self.air.nullTerminatedString(pl_op.payload);

src/arch/riscv64/CodeGen.zig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
613613
.dbg_var_val,
614614
=> try self.airDbgVar(inst),
615615

616+
.dbg_inline_begin,
617+
.dbg_inline_end,
618+
=> try self.airDbgInline(inst),
619+
616620
.call => try self.airCall(inst, .auto),
617621
.call_always_tail => try self.airCall(inst, .always_tail),
618622
.call_never_tail => try self.airCall(inst, .never_tail),
@@ -1640,6 +1644,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
16401644
return self.finishAirBookkeeping();
16411645
}
16421646

1647+
fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
1648+
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
1649+
const function = self.air.values[ty_pl.payload].castTag(.function).?.data;
1650+
// TODO emit debug info for function change
1651+
_ = function;
1652+
return self.finishAir(inst, .dead, .{ .none, .none, .none });
1653+
}
1654+
16431655
fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
16441656
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
16451657
const name = self.air.nullTerminatedString(pl_op.payload);

src/arch/wasm/CodeGen.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,6 +1227,8 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
12271227

12281228
// TODO
12291229
.dbg_stmt,
1230+
.dbg_inline_begin,
1231+
.dbg_inline_end,
12301232
.dbg_var_ptr,
12311233
.dbg_var_val,
12321234
=> WValue.none,

src/arch/x86_64/CodeGen.zig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
730730
.dbg_var_val,
731731
=> try self.airDbgVar(inst),
732732

733+
.dbg_inline_begin,
734+
.dbg_inline_end,
735+
=> try self.airDbgInline(inst),
736+
733737
.call => try self.airCall(inst, .auto),
734738
.call_always_tail => try self.airCall(inst, .always_tail),
735739
.call_never_tail => try self.airCall(inst, .never_tail),
@@ -3670,6 +3674,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
36703674
return self.finishAirBookkeeping();
36713675
}
36723676

3677+
fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
3678+
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
3679+
const function = self.air.values[ty_pl.payload].castTag(.function).?.data;
3680+
// TODO emit debug info for function change
3681+
_ = function;
3682+
return self.finishAir(inst, .dead, .{ .none, .none, .none });
3683+
}
3684+
36733685
fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
36743686
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
36753687
const name = self.air.nullTerminatedString(pl_op.payload);

src/codegen/c.zig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1726,6 +1726,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
17261726
.dbg_var_val,
17271727
=> try airDbgVar(f, inst),
17281728

1729+
.dbg_inline_begin,
1730+
.dbg_inline_end,
1731+
=> try airDbgInline(f, inst),
1732+
17291733
.call => try airCall(f, inst, .auto),
17301734
.call_always_tail => try airCall(f, inst, .always_tail),
17311735
.call_never_tail => try airCall(f, inst, .never_tail),
@@ -2660,6 +2664,14 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
26602664
return CValue.none;
26612665
}
26622666

2667+
fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue {
2668+
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
2669+
const writer = f.object.writer();
2670+
const function = f.air.values[ty_pl.payload].castTag(.function).?.data;
2671+
try writer.print("/* dbg func:{s} */\n", .{function.owner_decl.name});
2672+
return CValue.none;
2673+
}
2674+
26632675
fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
26642676
const pl_op = f.air.instructions.items(.data)[inst].pl_op;
26652677
const name = f.air.nullTerminatedString(pl_op.payload);

0 commit comments

Comments
 (0)