authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-03-15 18:27:09+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-03-16 10:53:41+02:00
logd83a26f068f42c6f9cafd25b7038b70553a496d8
tree016bc2d9fa343ceac3a1b1f0fd6971dde706a1e4
parent03438118369605df178f4bfdb5b1a8ad6a349be7

stage2 llvm: keep track of inlined functions


14 files changed, 132 insertions(+), 46 deletions(-)

src/Air.zig+7-3
...@@ -326,9 +326,12 @@ pub const Inst = struct {...@@ -326,9 +326,12 @@ pub const Inst = struct {
326 /// Result type is always void.326 /// Result type is always void.
327 /// Uses the `dbg_stmt` field.327 /// Uses the `dbg_stmt` field.
328 dbg_stmt,328 dbg_stmt,
329 /// Marks change of source function. Emitted around an inline call.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.330 /// Uses `ty_pl` with the payload being the index of a Value.Function in air.values.
331 dbg_func,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,
332 /// Marks the beginning of a local variable. The operand is a pointer pointing335 /// Marks the beginning of a local variable. The operand is a pointer pointing
333 /// to the storage for the variable. The local may be a const or a var.336 /// to the storage for the variable. The local may be a const or a var.
334 /// Result type is always void.337 /// Result type is always void.
...@@ -973,7 +976,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {...@@ -973,7 +976,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
973976
974 .breakpoint,977 .breakpoint,
975 .dbg_stmt,978 .dbg_stmt,
976 .dbg_func,979 .dbg_inline_begin,
980 .dbg_inline_end,
977 .dbg_var_ptr,981 .dbg_var_ptr,
978 .dbg_var_val,982 .dbg_var_val,
979 .store,983 .store,
src/Liveness.zig+2-1
...@@ -314,7 +314,8 @@ fn analyzeInst(...@@ -314,7 +314,8 @@ fn analyzeInst(
314 .const_ty,314 .const_ty,
315 .breakpoint,315 .breakpoint,
316 .dbg_stmt,316 .dbg_stmt,
317 .dbg_func,317 .dbg_inline_begin,
318 .dbg_inline_end,
318 .unreach,319 .unreach,
319 .fence,320 .fence,
320 .ret_addr,321 .ret_addr,
src/Sema.zig+10-5
...@@ -4765,7 +4765,9 @@ fn analyzeCall(...@@ -4765,7 +4765,9 @@ fn analyzeCall(
4765 }4765 }
47664766
4767 const new_func_resolved_ty = try Type.Tag.function.create(sema.arena, new_fn_info);4767 const new_func_resolved_ty = try Type.Tag.function.create(sema.arena, new_fn_info);
4768 if (!is_comptime_call) try sema.emitDbgFunc(block, parent_func.?, module_fn, new_func_resolved_ty);4768 if (!is_comptime_call) {
4769 try sema.emitDbgInline(block, parent_func.?, module_fn, new_func_resolved_ty, .dbg_inline_begin);
4770 }
47694771
4770 const result = result: {4772 const result = result: {
4771 sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) {4773 sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) {
...@@ -4781,7 +4783,9 @@ fn analyzeCall(...@@ -4781,7 +4783,9 @@ fn analyzeCall(
4781 break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges);4783 break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges);
4782 };4784 };
47834785
4784 if (!is_comptime_call) try sema.emitDbgFunc(block, module_fn, parent_func.?, parent_func.?.owner_decl.ty);4786 if (!is_comptime_call) {
4787 try sema.emitDbgInline(block, module_fn, parent_func.?, parent_func.?.owner_decl.ty, .dbg_inline_end);
4788 }
47854789
4786 if (should_memoize and is_comptime_call) {4790 if (should_memoize and is_comptime_call) {
4787 const result_val = try sema.resolveConstMaybeUndefVal(block, call_src, result);4791 const result_val = try sema.resolveConstMaybeUndefVal(block, call_src, result);
...@@ -5187,19 +5191,20 @@ fn instantiateGenericCall(...@@ -5187,19 +5191,20 @@ fn instantiateGenericCall(
5187 return func_inst;5191 return func_inst;
5188}5192}
51895193
5190fn emitDbgFunc(5194fn emitDbgInline(
5191 sema: *Sema,5195 sema: *Sema,
5192 block: *Block,5196 block: *Block,
5193 old_func: *Module.Fn,5197 old_func: *Module.Fn,
5194 new_func: *Module.Fn,5198 new_func: *Module.Fn,
5195 new_func_ty: Type,5199 new_func_ty: Type,
5200 tag: Air.Inst.Tag,
5196) CompileError!void {5201) CompileError!void {
5197 // No change of file; no dbg_func needed.5202 // No change of file; no dbg_inline needed.
5198 if (old_func == new_func) return;5203 if (old_func == new_func) return;
51995204
5200 try sema.air_values.append(sema.gpa, try Value.Tag.function.create(sema.arena, new_func));5205 try sema.air_values.append(sema.gpa, try Value.Tag.function.create(sema.arena, new_func));
5201 _ = try block.addInst(.{5206 _ = try block.addInst(.{
5202 .tag = .dbg_func,5207 .tag = tag,
5203 .data = .{ .ty_pl = .{5208 .data = .{ .ty_pl = .{
5204 .ty = try sema.addType(new_func_ty),5209 .ty = try sema.addType(new_func_ty),
5205 .payload = @intCast(u32, sema.air_values.items.len - 1),5210 .payload = @intCast(u32, sema.air_values.items.len - 1),
src/arch/aarch64/CodeGen.zig+5-2
...@@ -598,7 +598,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -598,7 +598,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
598 .fence => try self.airFence(),598 .fence => try self.airFence(),
599 .cond_br => try self.airCondBr(inst),599 .cond_br => try self.airCondBr(inst),
600 .dbg_stmt => try self.airDbgStmt(inst),600 .dbg_stmt => try self.airDbgStmt(inst),
601 .dbg_func => try self.airDbgFunc(inst),
602 .fptrunc => try self.airFptrunc(inst),601 .fptrunc => try self.airFptrunc(inst),
603 .fpext => try self.airFpext(inst),602 .fpext => try self.airFpext(inst),
604 .intcast => try self.airIntCast(inst),603 .intcast => try self.airIntCast(inst),
...@@ -650,6 +649,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -650,6 +649,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
650 .dbg_var_val,649 .dbg_var_val,
651 => try self.airDbgVar(inst),650 => try self.airDbgVar(inst),
652651
652 .dbg_inline_begin,
653 .dbg_inline_end,
654 => try self.airDbgInline(inst),
655
653 .call => try self.airCall(inst, .auto),656 .call => try self.airCall(inst, .auto),
654 .call_always_tail => try self.airCall(inst, .always_tail),657 .call_always_tail => try self.airCall(inst, .always_tail),
655 .call_never_tail => try self.airCall(inst, .never_tail),658 .call_never_tail => try self.airCall(inst, .never_tail),
...@@ -2716,7 +2719,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {...@@ -2716,7 +2719,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
2716 return self.finishAirBookkeeping();2719 return self.finishAirBookkeeping();
2717}2720}
27182721
2719fn airDbgFunc(self: *Self, inst: Air.Inst.Index) !void {2722fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
2720 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2723 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2721 const function = self.air.values[ty_pl.payload].castTag(.function).?.data;2724 const function = self.air.values[ty_pl.payload].castTag(.function).?.data;
2722 // TODO emit debug info for function change2725 // TODO emit debug info for function change
src/arch/arm/CodeGen.zig+5-2
...@@ -595,7 +595,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -595,7 +595,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
595 .fence => try self.airFence(),595 .fence => try self.airFence(),
596 .cond_br => try self.airCondBr(inst),596 .cond_br => try self.airCondBr(inst),
597 .dbg_stmt => try self.airDbgStmt(inst),597 .dbg_stmt => try self.airDbgStmt(inst),
598 .dbg_func => try self.airDbgFunc(inst),
599 .fptrunc => try self.airFptrunc(inst),598 .fptrunc => try self.airFptrunc(inst),
600 .fpext => try self.airFpext(inst),599 .fpext => try self.airFpext(inst),
601 .intcast => try self.airIntCast(inst),600 .intcast => try self.airIntCast(inst),
...@@ -647,6 +646,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -647,6 +646,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
647 .dbg_var_val,646 .dbg_var_val,
648 => try self.airDbgVar(inst),647 => try self.airDbgVar(inst),
649648
649 .dbg_inline_begin,
650 .dbg_inline_end,
651 => try self.airDbgInline(inst),
652
650 .call => try self.airCall(inst, .auto),653 .call => try self.airCall(inst, .auto),
651 .call_always_tail => try self.airCall(inst, .always_tail),654 .call_always_tail => try self.airCall(inst, .always_tail),
652 .call_never_tail => try self.airCall(inst, .never_tail),655 .call_never_tail => try self.airCall(inst, .never_tail),
...@@ -2836,7 +2839,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {...@@ -2836,7 +2839,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
2836 return self.finishAirBookkeeping();2839 return self.finishAirBookkeeping();
2837}2840}
28382841
2839fn airDbgFunc(self: *Self, inst: Air.Inst.Index) !void {2842fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
2840 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2843 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2841 const function = self.air.values[ty_pl.payload].castTag(.function).?.data;2844 const function = self.air.values[ty_pl.payload].castTag(.function).?.data;
2842 // TODO emit debug info for function change2845 // TODO emit debug info for function change
src/arch/riscv64/CodeGen.zig+5-2
...@@ -562,7 +562,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -562,7 +562,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
562 .fence => try self.airFence(),562 .fence => try self.airFence(),
563 .cond_br => try self.airCondBr(inst),563 .cond_br => try self.airCondBr(inst),
564 .dbg_stmt => try self.airDbgStmt(inst),564 .dbg_stmt => try self.airDbgStmt(inst),
565 .dbg_func => try self.airDbgFunc(inst),
566 .fptrunc => try self.airFptrunc(inst),565 .fptrunc => try self.airFptrunc(inst),
567 .fpext => try self.airFpext(inst),566 .fpext => try self.airFpext(inst),
568 .intcast => try self.airIntCast(inst),567 .intcast => try self.airIntCast(inst),
...@@ -614,6 +613,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -614,6 +613,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
614 .dbg_var_val,613 .dbg_var_val,
615 => try self.airDbgVar(inst),614 => try self.airDbgVar(inst),
616615
616 .dbg_inline_begin,
617 .dbg_inline_end,
618 => try self.airDbgInline(inst),
619
617 .call => try self.airCall(inst, .auto),620 .call => try self.airCall(inst, .auto),
618 .call_always_tail => try self.airCall(inst, .always_tail),621 .call_always_tail => try self.airCall(inst, .always_tail),
619 .call_never_tail => try self.airCall(inst, .never_tail),622 .call_never_tail => try self.airCall(inst, .never_tail),
...@@ -1641,7 +1644,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {...@@ -1641,7 +1644,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
1641 return self.finishAirBookkeeping();1644 return self.finishAirBookkeeping();
1642}1645}
16431646
1644fn airDbgFunc(self: *Self, inst: Air.Inst.Index) !void {1647fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
1645 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;1648 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
1646 const function = self.air.values[ty_pl.payload].castTag(.function).?.data;1649 const function = self.air.values[ty_pl.payload].castTag(.function).?.data;
1647 // TODO emit debug info for function change1650 // TODO emit debug info for function change
src/arch/wasm/CodeGen.zig+2-1
...@@ -1227,7 +1227,8 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1227,7 +1227,8 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
12271227
1228 // TODO1228 // TODO
1229 .dbg_stmt,1229 .dbg_stmt,
1230 .dbg_func,1230 .dbg_inline_begin,
1231 .dbg_inline_end,
1231 .dbg_var_ptr,1232 .dbg_var_ptr,
1232 .dbg_var_val,1233 .dbg_var_val,
1233 => WValue.none,1234 => WValue.none,
src/arch/x86_64/CodeGen.zig+5-2
...@@ -679,7 +679,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -679,7 +679,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
679 .fence => try self.airFence(),679 .fence => try self.airFence(),
680 .cond_br => try self.airCondBr(inst),680 .cond_br => try self.airCondBr(inst),
681 .dbg_stmt => try self.airDbgStmt(inst),681 .dbg_stmt => try self.airDbgStmt(inst),
682 .dbg_func => try self.airDbgFunc(inst),
683 .fptrunc => try self.airFptrunc(inst),682 .fptrunc => try self.airFptrunc(inst),
684 .fpext => try self.airFpext(inst),683 .fpext => try self.airFpext(inst),
685 .intcast => try self.airIntCast(inst),684 .intcast => try self.airIntCast(inst),
...@@ -731,6 +730,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -731,6 +730,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
731 .dbg_var_val,730 .dbg_var_val,
732 => try self.airDbgVar(inst),731 => try self.airDbgVar(inst),
733732
733 .dbg_inline_begin,
734 .dbg_inline_end,
735 => try self.airDbgInline(inst),
736
734 .call => try self.airCall(inst, .auto),737 .call => try self.airCall(inst, .auto),
735 .call_always_tail => try self.airCall(inst, .always_tail),738 .call_always_tail => try self.airCall(inst, .always_tail),
736 .call_never_tail => try self.airCall(inst, .never_tail),739 .call_never_tail => try self.airCall(inst, .never_tail),
...@@ -3671,7 +3674,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {...@@ -3671,7 +3674,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
3671 return self.finishAirBookkeeping();3674 return self.finishAirBookkeeping();
3672}3675}
36733676
3674fn airDbgFunc(self: *Self, inst: Air.Inst.Index) !void {3677fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
3675 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;3678 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
3676 const function = self.air.values[ty_pl.payload].castTag(.function).?.data;3679 const function = self.air.values[ty_pl.payload].castTag(.function).?.data;
3677 // TODO emit debug info for function change3680 // TODO emit debug info for function change
src/codegen/c.zig+5-2
...@@ -1687,7 +1687,6 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -1687,7 +1687,6 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
1687 .block => try airBlock(f, inst),1687 .block => try airBlock(f, inst),
1688 .bitcast => try airBitcast(f, inst),1688 .bitcast => try airBitcast(f, inst),
1689 .dbg_stmt => try airDbgStmt(f, inst),1689 .dbg_stmt => try airDbgStmt(f, inst),
1690 .dbg_func => try airDbgFunc(f, inst),
1691 .intcast => try airIntCast(f, inst),1690 .intcast => try airIntCast(f, inst),
1692 .trunc => try airTrunc(f, inst),1691 .trunc => try airTrunc(f, inst),
1693 .bool_to_int => try airBoolToInt(f, inst),1692 .bool_to_int => try airBoolToInt(f, inst),
...@@ -1727,6 +1726,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -1727,6 +1726,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
1727 .dbg_var_val,1726 .dbg_var_val,
1728 => try airDbgVar(f, inst),1727 => try airDbgVar(f, inst),
17291728
1729 .dbg_inline_begin,
1730 .dbg_inline_end,
1731 => try airDbgInline(f, inst),
1732
1730 .call => try airCall(f, inst, .auto),1733 .call => try airCall(f, inst, .auto),
1731 .call_always_tail => try airCall(f, inst, .always_tail),1734 .call_always_tail => try airCall(f, inst, .always_tail),
1732 .call_never_tail => try airCall(f, inst, .never_tail),1735 .call_never_tail => try airCall(f, inst, .never_tail),
...@@ -2661,7 +2664,7 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2661,7 +2664,7 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
2661 return CValue.none;2664 return CValue.none;
2662}2665}
26632666
2664fn airDbgFunc(f: *Function, inst: Air.Inst.Index) !CValue {2667fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue {
2665 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;2668 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
2666 const writer = f.object.writer();2669 const writer = f.object.writer();
2667 const function = f.air.values[ty_pl.payload].castTag(.function).?.data;2670 const function = f.air.values[ty_pl.payload].castTag(.function).?.data;
src/codegen/llvm.zig+58-20
...@@ -620,7 +620,8 @@ pub const Object = struct {...@@ -620,7 +620,8 @@ pub const Object = struct {
620620
621 llvm_func.fnSetSubprogram(subprogram);621 llvm_func.fnSetSubprogram(subprogram);
622622
623 di_scope = subprogram.toScope();623 const lexical_block = dib.createLexicalBlock(subprogram.toScope(), di_file.?, line_number, 1);
624 di_scope = lexical_block.toScope();
624 }625 }
625626
626 var fg: FuncGen = .{627 var fg: FuncGen = .{
...@@ -639,6 +640,7 @@ pub const Object = struct {...@@ -639,6 +640,7 @@ pub const Object = struct {
639 .single_threaded = module.comp.bin_file.options.single_threaded,640 .single_threaded = module.comp.bin_file.options.single_threaded,
640 .di_scope = di_scope,641 .di_scope = di_scope,
641 .di_file = di_file,642 .di_file = di_file,
643 .base_line = dg.decl.src_line,
642 .prev_dbg_line = 0,644 .prev_dbg_line = 0,
643 .prev_dbg_column = 0,645 .prev_dbg_column = 0,
644 };646 };
...@@ -3210,9 +3212,13 @@ pub const FuncGen = struct {...@@ -3210,9 +3212,13 @@ pub const FuncGen = struct {
3210 builder: *const llvm.Builder,3212 builder: *const llvm.Builder,
3211 di_scope: ?*llvm.DIScope,3213 di_scope: ?*llvm.DIScope,
3212 di_file: ?*llvm.DIFile,3214 di_file: ?*llvm.DIFile,
3215 base_line: u32,
3213 prev_dbg_line: c_uint,3216 prev_dbg_line: c_uint,
3214 prev_dbg_column: c_uint,3217 prev_dbg_column: c_uint,
32153218
3219 /// Stack of locations where a call was inlined.
3220 dbg_inlined: std.ArrayListUnmanaged(DbgState) = .{},
3221
3216 /// This stores the LLVM values used in a function, such that they can be referred to3222 /// This stores the LLVM values used in a function, such that they can be referred to
3217 /// in other instructions. This table is cleared before every function is generated.3223 /// in other instructions. This table is cleared before every function is generated.
3218 func_inst_table: std.AutoHashMapUnmanaged(Air.Inst.Ref, *const llvm.Value),3224 func_inst_table: std.AutoHashMapUnmanaged(Air.Inst.Ref, *const llvm.Value),
...@@ -3240,11 +3246,13 @@ pub const FuncGen = struct {...@@ -3240,11 +3246,13 @@ pub const FuncGen = struct {
32403246
3241 single_threaded: bool,3247 single_threaded: bool,
32423248
3249 const DbgState = struct { loc: *llvm.DILocation, scope: *llvm.DIScope, base_line: u32 };
3243 const BreakBasicBlocks = std.ArrayListUnmanaged(*const llvm.BasicBlock);3250 const BreakBasicBlocks = std.ArrayListUnmanaged(*const llvm.BasicBlock);
3244 const BreakValues = std.ArrayListUnmanaged(*const llvm.Value);3251 const BreakValues = std.ArrayListUnmanaged(*const llvm.Value);
32453252
3246 fn deinit(self: *FuncGen) void {3253 fn deinit(self: *FuncGen) void {
3247 self.builder.dispose();3254 self.builder.dispose();
3255 self.dbg_inlined.deinit(self.gpa);
3248 self.func_inst_table.deinit(self.gpa);3256 self.func_inst_table.deinit(self.gpa);
3249 self.blocks.deinit(self.gpa);3257 self.blocks.deinit(self.gpa);
3250 }3258 }
...@@ -3463,7 +3471,8 @@ pub const FuncGen = struct {...@@ -3463,7 +3471,8 @@ pub const FuncGen = struct {
3463 .const_ty => unreachable,3471 .const_ty => unreachable,
3464 .unreach => self.airUnreach(inst),3472 .unreach => self.airUnreach(inst),
3465 .dbg_stmt => self.airDbgStmt(inst),3473 .dbg_stmt => self.airDbgStmt(inst),
3466 .dbg_func => try self.airDbgFunc(inst),3474 .dbg_inline_begin => try self.airDbgInline(inst, true),
3475 .dbg_inline_end => try self.airDbgInline(inst, false),
3467 .dbg_var_ptr => try self.airDbgVarPtr(inst),3476 .dbg_var_ptr => try self.airDbgVarPtr(inst),
3468 .dbg_var_val => try self.airDbgVarVal(inst),3477 .dbg_var_val => try self.airDbgVarVal(inst),
3469 // zig fmt: on3478 // zig fmt: on
...@@ -4179,24 +4188,44 @@ pub const FuncGen = struct {...@@ -4179,24 +4188,44 @@ pub const FuncGen = struct {
4179 fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) ?*const llvm.Value {4188 fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) ?*const llvm.Value {
4180 const di_scope = self.di_scope orelse return null;4189 const di_scope = self.di_scope orelse return null;
4181 const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt;4190 const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt;
4182 self.prev_dbg_line = @intCast(c_uint, self.dg.decl.src_line + dbg_stmt.line + 1);4191 self.prev_dbg_line = @intCast(c_uint, self.base_line + dbg_stmt.line + 1);
4183 self.prev_dbg_column = @intCast(c_uint, dbg_stmt.column + 1);4192 self.prev_dbg_column = @intCast(c_uint, dbg_stmt.column + 1);
4184 self.builder.setCurrentDebugLocation(self.prev_dbg_line, self.prev_dbg_column, di_scope);4193 const inlined_at = if (self.dbg_inlined.items.len > 0)
4194 self.dbg_inlined.items[self.dbg_inlined.items.len - 1].loc
4195 else
4196 null;
4197 self.builder.setCurrentDebugLocation(self.prev_dbg_line, self.prev_dbg_column, di_scope, inlined_at);
4185 return null;4198 return null;
4186 }4199 }
41874200
4188 fn airDbgFunc(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {4201 fn airDbgInline(self: *FuncGen, inst: Air.Inst.Index, start: bool) !?*const llvm.Value {
4189 const dib = self.dg.object.di_builder orelse return null;4202 const dib = self.dg.object.di_builder orelse return null;
4190 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;4203 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
4191 4204
4192 const function = self.air.values[ty_pl.payload].castTag(.function).?.data;4205 const func = self.air.values[ty_pl.payload].castTag(.function).?.data;
4193 const decl = function.owner_decl;4206 const decl = func.owner_decl;
4207 const di_file = try self.dg.object.getDIFile(self.gpa, decl.src_namespace.file_scope);
4208 self.di_file = di_file;
4209 const line_number = decl.src_line + 1;
4210 const cur_debug_location = self.builder.getCurrentDebugLocation2();
4211 if (start) {
4212 try self.dbg_inlined.append(self.gpa, .{
4213 .loc = @ptrCast(*llvm.DILocation, cur_debug_location),
4214 .scope = self.di_scope.?,
4215 .base_line = self.base_line,
4216 });
4217 } else {
4218 const old = self.dbg_inlined.pop();
4219 self.di_scope = old.scope;
4220 self.base_line = old.base_line;
4221 return null;
4222 }
4223
4194 const fn_ty = try self.air.getRefType(ty_pl.ty).copy(self.dg.object.type_map_arena.allocator());4224 const fn_ty = try self.air.getRefType(ty_pl.ty).copy(self.dg.object.type_map_arena.allocator());
4195 const llvm_func = try self.dg.resolveLlvmFunctionExtra(decl, fn_ty);4225 const fqn = try decl.getFullyQualifiedName(self.gpa);
4226 defer self.gpa.free(fqn);
4196 const fn_info = fn_ty.fnInfo();4227 const fn_info = fn_ty.fnInfo();
4197 const di_file = try self.dg.object.getDIFile(self.gpa, decl.src_namespace.file_scope);
41984228
4199 const line_number = decl.src_line + 1;
4200 const is_internal_linkage = !self.dg.module.decl_exports.contains(decl);4229 const is_internal_linkage = !self.dg.module.decl_exports.contains(decl);
4201 const noret_bit: c_uint = if (fn_info.return_type.isNoReturn())4230 const noret_bit: c_uint = if (fn_info.return_type.isNoReturn())
4202 llvm.DIFlags.NoReturn4231 llvm.DIFlags.NoReturn
...@@ -4205,22 +4234,23 @@ pub const FuncGen = struct {...@@ -4205,22 +4234,23 @@ pub const FuncGen = struct {
4205 const subprogram = dib.createFunction(4234 const subprogram = dib.createFunction(
4206 di_file.toScope(),4235 di_file.toScope(),
4207 decl.name,4236 decl.name,
4208 llvm_func.getValueName(),4237 fqn,
4209 di_file,4238 di_file,
4210 line_number,4239 line_number,
4211 try self.dg.lowerDebugType(fn_ty),4240 try self.dg.object.lowerDebugType(fn_ty, .full),
4212 is_internal_linkage,4241 is_internal_linkage,
4213 true, // is definition4242 true, // is definition
4214 line_number + function.lbrace_line, // scope line4243 line_number + func.lbrace_line, // scope line
4215 llvm.DIFlags.StaticMember | noret_bit,4244 llvm.DIFlags.StaticMember | noret_bit,
4216 self.dg.module.comp.bin_file.options.optimize_mode != .Debug,4245 self.dg.module.comp.bin_file.options.optimize_mode != .Debug,
4217 null, // decl_subprogram4246 null, // decl_subprogram
4218 );4247 );
4219 try self.dg.object.di_map.put(self.gpa, decl, subprogram.toNode());
42204248
4221 llvm_func.fnSetSubprogram(subprogram);4249 try self.dg.object.di_map.put(self.gpa, decl, subprogram.toNode());
42224250
4223 self.di_scope = subprogram.toScope();4251 const lexical_block = dib.createLexicalBlock(subprogram.toScope(), di_file, line_number, 1);
4252 self.di_scope = lexical_block.toScope();
4253 self.base_line = decl.src_line;
4224 return null;4254 return null;
4225 }4255 }
42264256
...@@ -4240,7 +4270,11 @@ pub const FuncGen = struct {...@@ -4240,7 +4270,11 @@ pub const FuncGen = struct {
4240 true, // always preserve4270 true, // always preserve
4241 0, // flags4271 0, // flags
4242 );4272 );
4243 const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?);4273 const inlined_at = if (self.dbg_inlined.items.len > 0)
4274 self.dbg_inlined.items[self.dbg_inlined.items.len - 1].loc
4275 else
4276 null;
4277 const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?, inlined_at);
4244 const insert_block = self.builder.getInsertBlock();4278 const insert_block = self.builder.getInsertBlock();
4245 _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block);4279 _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block);
4246 return null;4280 return null;
...@@ -4262,7 +4296,11 @@ pub const FuncGen = struct {...@@ -4262,7 +4296,11 @@ pub const FuncGen = struct {
4262 true, // always preserve4296 true, // always preserve
4263 0, // flags4297 0, // flags
4264 );4298 );
4265 const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?);4299 const inlined_at = if (self.dbg_inlined.items.len > 0)
4300 self.dbg_inlined.items[self.dbg_inlined.items.len - 1].loc
4301 else
4302 null;
4303 const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?, inlined_at);
4266 const insert_block = self.builder.getInsertBlock();4304 const insert_block = self.builder.getInsertBlock();
4267 if (isByRef(operand_ty)) {4305 if (isByRef(operand_ty)) {
4268 _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block);4306 _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block);
...@@ -5524,7 +5562,7 @@ pub const FuncGen = struct {...@@ -5524,7 +5562,7 @@ pub const FuncGen = struct {
5524 self.arg_index, // includes +1 because 0 is return type5562 self.arg_index, // includes +1 because 0 is return type
5525 );5563 );
55265564
5527 const debug_loc = llvm.getDebugLoc(lbrace_line, lbrace_col, self.di_scope.?);5565 const debug_loc = llvm.getDebugLoc(lbrace_line, lbrace_col, self.di_scope.?, null);
5528 const insert_block = self.builder.getInsertBlock();5566 const insert_block = self.builder.getInsertBlock();
5529 if (isByRef(inst_ty)) {5567 if (isByRef(inst_ty)) {
5530 _ = dib.insertDeclareAtEnd(arg_val, di_local_var, debug_loc, insert_block);5568 _ = dib.insertDeclareAtEnd(arg_val, di_local_var, debug_loc, insert_block);
src/codegen/llvm/bindings.zig+4-4
...@@ -839,8 +839,8 @@ pub const Builder = opaque {...@@ -839,8 +839,8 @@ pub const Builder = opaque {
839 pub const buildExactSDiv = LLVMBuildExactSDiv;839 pub const buildExactSDiv = LLVMBuildExactSDiv;
840 extern fn LLVMBuildExactSDiv(*const Builder, LHS: *const Value, RHS: *const Value, Name: [*:0]const u8) *const Value;840 extern fn LLVMBuildExactSDiv(*const Builder, LHS: *const Value, RHS: *const Value, Name: [*:0]const u8) *const Value;
841841
842 pub const setCurrentDebugLocation = ZigLLVMSetCurrentDebugLocation;842 pub const setCurrentDebugLocation = ZigLLVMSetCurrentDebugLocation2;
843 extern fn ZigLLVMSetCurrentDebugLocation(builder: *const Builder, line: c_uint, column: c_uint, scope: *DIScope) void;843 extern fn ZigLLVMSetCurrentDebugLocation2(builder: *const Builder, line: c_uint, column: c_uint, scope: *DIScope, inlined_at: ?*DILocation) void;
844844
845 pub const clearCurrentDebugLocation = ZigLLVMClearCurrentDebugLocation;845 pub const clearCurrentDebugLocation = ZigLLVMClearCurrentDebugLocation;
846 extern fn ZigLLVMClearCurrentDebugLocation(builder: *const Builder) void;846 extern fn ZigLLVMClearCurrentDebugLocation(builder: *const Builder) void;
...@@ -1479,8 +1479,8 @@ pub const DISubprogram = opaque {...@@ -1479,8 +1479,8 @@ pub const DISubprogram = opaque {
1479 extern fn ZigLLVMSubprogramReplaceLinkageName(subprogram: *DISubprogram, linkage_name: *MDString) void;1479 extern fn ZigLLVMSubprogramReplaceLinkageName(subprogram: *DISubprogram, linkage_name: *MDString) void;
1480};1480};
14811481
1482pub const getDebugLoc = ZigLLVMGetDebugLoc;1482pub const getDebugLoc = ZigLLVMGetDebugLoc2;
1483extern fn ZigLLVMGetDebugLoc(line: c_uint, col: c_uint, scope: *DIScope) *DILocation;1483extern fn ZigLLVMGetDebugLoc2(line: c_uint, col: c_uint, scope: *DIScope, inlined_at: ?*DILocation) *DILocation;
14841484
1485pub const DIBuilder = opaque {1485pub const DIBuilder = opaque {
1486 pub const dispose = ZigLLVMDisposeDIBuilder;1486 pub const dispose = ZigLLVMDisposeDIBuilder;
src/print_air.zig+3-2
...@@ -242,7 +242,8 @@ const Writer = struct {...@@ -242,7 +242,8 @@ const Writer = struct {
242 .constant => try w.writeConstant(s, inst),242 .constant => try w.writeConstant(s, inst),
243 .assembly => try w.writeAssembly(s, inst),243 .assembly => try w.writeAssembly(s, inst),
244 .dbg_stmt => try w.writeDbgStmt(s, inst),244 .dbg_stmt => try w.writeDbgStmt(s, inst),
245 .dbg_func => try w.writeDbgFunc(s, inst),245
246 .dbg_inline_begin, .dbg_inline_end => try w.writeDbgInline(s, inst),
246 .aggregate_init => try w.writeAggregateInit(s, inst),247 .aggregate_init => try w.writeAggregateInit(s, inst),
247 .union_init => try w.writeUnionInit(s, inst),248 .union_init => try w.writeUnionInit(s, inst),
248 .br => try w.writeBr(s, inst),249 .br => try w.writeBr(s, inst),
...@@ -553,7 +554,7 @@ const Writer = struct {...@@ -553,7 +554,7 @@ const Writer = struct {
553 try s.print("{d}:{d}", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 });554 try s.print("{d}:{d}", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 });
554 }555 }
555556
556 fn writeDbgFunc(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {557 fn writeDbgInline(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
557 const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;558 const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
558 const function = w.air.values[ty_pl.payload].castTag(.function).?.data;559 const function = w.air.values[ty_pl.payload].castTag(.function).?.data;
559 try s.print("{s}", .{function.owner_decl.name});560 try s.print("{s}", .{function.owner_decl.name});
src/zig_llvm.cpp+17
...@@ -799,6 +799,15 @@ void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder,...@@ -799,6 +799,15 @@ void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder,
799 unwrap(builder)->SetCurrentDebugLocation(debug_loc);799 unwrap(builder)->SetCurrentDebugLocation(debug_loc);
800}800}
801801
802void ZigLLVMSetCurrentDebugLocation2(LLVMBuilderRef builder, unsigned int line,
803 unsigned int column, ZigLLVMDIScope *scope, ZigLLVMDILocation *inlined_at)
804{
805 DIScope* di_scope = reinterpret_cast<DIScope*>(scope);
806 DebugLoc debug_loc = DILocation::get(di_scope->getContext(), line, column, di_scope,
807 reinterpret_cast<DILocation *>(inlined_at), false);
808 unwrap(builder)->SetCurrentDebugLocation(debug_loc);
809}
810
802void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder) {811void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder) {
803 unwrap(builder)->SetCurrentDebugLocation(DebugLoc());812 unwrap(builder)->SetCurrentDebugLocation(DebugLoc());
804}813}
...@@ -1025,6 +1034,14 @@ ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col, ZigLLVMDIScop...@@ -1025,6 +1034,14 @@ ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col, ZigLLVMDIScop
1025 return reinterpret_cast<ZigLLVMDILocation*>(debug_loc.get());1034 return reinterpret_cast<ZigLLVMDILocation*>(debug_loc.get());
1026}1035}
10271036
1037ZigLLVMDILocation *ZigLLVMGetDebugLoc2(unsigned line, unsigned col, ZigLLVMDIScope *scope,
1038 ZigLLVMDILocation *inlined_at) {
1039 DIScope* di_scope = reinterpret_cast<DIScope*>(scope);
1040 DebugLoc debug_loc = DILocation::get(di_scope->getContext(), line, col, di_scope,
1041 reinterpret_cast<DILocation *>(inlined_at), false);
1042 return reinterpret_cast<ZigLLVMDILocation*>(debug_loc.get());
1043}
1044
1028void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state) {1045void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state) {
1029 if (on_state) {1046 if (on_state) {
1030 FastMathFlags fmf;1047 FastMathFlags fmf;
src/zig_llvm.h+4
...@@ -232,6 +232,8 @@ ZIG_EXTERN_C void ZigLLVMSetModuleCodeModel(LLVMModuleRef module, LLVMCodeModel...@@ -232,6 +232,8 @@ ZIG_EXTERN_C void ZigLLVMSetModuleCodeModel(LLVMModuleRef module, LLVMCodeModel
232232
233ZIG_EXTERN_C void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder,233ZIG_EXTERN_C void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder,
234 unsigned int line, unsigned int column, struct ZigLLVMDIScope *scope);234 unsigned int line, unsigned int column, struct ZigLLVMDIScope *scope);
235ZIG_EXTERN_C void ZigLLVMSetCurrentDebugLocation2(LLVMBuilderRef builder, unsigned int line,
236 unsigned int column, ZigLLVMDIScope *scope, ZigLLVMDILocation *inlined_at);
235ZIG_EXTERN_C void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder);237ZIG_EXTERN_C void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder);
236238
237ZIG_EXTERN_C struct ZigLLVMDIScope *ZigLLVMLexicalBlockToScope(struct ZigLLVMDILexicalBlock *lexical_block);239ZIG_EXTERN_C struct ZigLLVMDIScope *ZigLLVMLexicalBlockToScope(struct ZigLLVMDILexicalBlock *lexical_block);
...@@ -290,6 +292,8 @@ ZIG_EXTERN_C void ZigLLVMDIBuilderFinalize(struct ZigLLVMDIBuilder *dibuilder);...@@ -290,6 +292,8 @@ ZIG_EXTERN_C void ZigLLVMDIBuilderFinalize(struct ZigLLVMDIBuilder *dibuilder);
290292
291ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col,293ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col,
292 struct ZigLLVMDIScope *scope);294 struct ZigLLVMDIScope *scope);
295ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc2(unsigned line, unsigned col,
296 ZigLLVMDIScope *scope, ZigLLVMDILocation *inlined_at);
293297
294ZIG_EXTERN_C LLVMValueRef ZigLLVMInsertDeclareAtEnd(struct ZigLLVMDIBuilder *dib,298ZIG_EXTERN_C LLVMValueRef ZigLLVMInsertDeclareAtEnd(struct ZigLLVMDIBuilder *dib,
295 LLVMValueRef storage, struct ZigLLVMDILocalVariable *var_info,299 LLVMValueRef storage, struct ZigLLVMDILocalVariable *var_info,