mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
stage2: add dbg_block_{begin,end} instruction
This commit is contained in:
parent
ad5770eba4
commit
a8520fbd0f
14 changed files with 119 additions and 1 deletions
|
|
@ -326,6 +326,10 @@ pub const Inst = struct {
|
|||
/// Result type is always void.
|
||||
/// Uses the `dbg_stmt` field.
|
||||
dbg_stmt,
|
||||
/// Marks the beginning of a semantic scope for debug info variables.
|
||||
dbg_block_begin,
|
||||
/// Marks the end of a semantic scope for debug info variables.
|
||||
dbg_block_end,
|
||||
/// Marks the start of an inline call.
|
||||
/// Uses `ty_pl` with the payload being the index of a Value.Function in air.values.
|
||||
dbg_inline_begin,
|
||||
|
|
@ -990,6 +994,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
|
|||
.dbg_stmt,
|
||||
.dbg_inline_begin,
|
||||
.dbg_inline_end,
|
||||
.dbg_block_begin,
|
||||
.dbg_block_end,
|
||||
.dbg_var_ptr,
|
||||
.dbg_var_val,
|
||||
.store,
|
||||
|
|
|
|||
|
|
@ -2052,6 +2052,12 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod
|
|||
const tree = astgen.tree;
|
||||
const node_tags = tree.nodes.items(.tag);
|
||||
|
||||
_ = try gz.add(.{ .tag = .extended, .data = .{ .extended = .{
|
||||
.opcode = .dbg_block_begin,
|
||||
.small = undefined,
|
||||
.operand = undefined
|
||||
} } });
|
||||
|
||||
var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa);
|
||||
defer block_arena.deinit();
|
||||
const block_arena_allocator = block_arena.allocator();
|
||||
|
|
@ -2105,6 +2111,12 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod
|
|||
}
|
||||
}
|
||||
|
||||
_ = try gz.add(.{ .tag = .extended, .data = .{ .extended = .{
|
||||
.opcode = .dbg_block_end,
|
||||
.small = undefined,
|
||||
.operand = undefined
|
||||
} } });
|
||||
|
||||
try genDefers(gz, parent_scope, scope, .normal_only);
|
||||
try checkUsed(gz, parent_scope, scope);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -316,6 +316,8 @@ fn analyzeInst(
|
|||
.dbg_stmt,
|
||||
.dbg_inline_begin,
|
||||
.dbg_inline_end,
|
||||
.dbg_block_begin,
|
||||
.dbg_block_end,
|
||||
.unreach,
|
||||
.fence,
|
||||
.ret_addr,
|
||||
|
|
|
|||
26
src/Sema.zig
26
src/Sema.zig
|
|
@ -1216,6 +1216,8 @@ fn zirExtended(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
|||
.wasm_memory_size => return sema.zirWasmMemorySize( block, extended),
|
||||
.wasm_memory_grow => return sema.zirWasmMemoryGrow( block, extended),
|
||||
.prefetch => return sema.zirPrefetch( block, extended),
|
||||
.dbg_block_begin => return sema.zirDbgBlockBegin( block),
|
||||
.dbg_block_end => return sema.zirDbgBlockEnd( block),
|
||||
// zig fmt: on
|
||||
}
|
||||
}
|
||||
|
|
@ -4215,6 +4217,26 @@ fn zirDbgStmt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
|
|||
});
|
||||
}
|
||||
|
||||
fn zirDbgBlockBegin(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
|
||||
if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return .void_value;
|
||||
|
||||
_ = try block.addInst(.{
|
||||
.tag = .dbg_block_begin,
|
||||
.data = undefined,
|
||||
});
|
||||
return .void_value;
|
||||
}
|
||||
|
||||
fn zirDbgBlockEnd(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
|
||||
if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return .void_value;
|
||||
|
||||
_ = try block.addInst(.{
|
||||
.tag = .dbg_block_end,
|
||||
.data = undefined,
|
||||
});
|
||||
return .void_value;
|
||||
}
|
||||
|
||||
fn zirDbgVar(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
|
|
@ -5224,7 +5246,9 @@ fn emitDbgInline(
|
|||
new_func_ty: Type,
|
||||
tag: Air.Inst.Tag,
|
||||
) CompileError!void {
|
||||
// No change of file; no dbg_inline needed.
|
||||
if (sema.mod.comp.bin_file.options.strip) return;
|
||||
|
||||
// Recursive inline call; no dbg_inline needed.
|
||||
if (old_func == new_func) return;
|
||||
|
||||
try sema.air_values.append(sema.gpa, try Value.Tag.function.create(sema.arena, new_func));
|
||||
|
|
|
|||
|
|
@ -1646,6 +1646,10 @@ pub const Inst = struct {
|
|||
/// The `@prefetch` builtin.
|
||||
/// `operand` is payload index to `BinNode`.
|
||||
prefetch,
|
||||
/// Marks the beginning of a semantic scope for debug info variables.
|
||||
dbg_block_begin,
|
||||
/// Marks the end of a semantic scope for debug info variables.
|
||||
dbg_block_end,
|
||||
|
||||
pub const InstData = struct {
|
||||
opcode: Extended,
|
||||
|
|
|
|||
|
|
@ -654,6 +654,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
|||
.dbg_inline_end,
|
||||
=> try self.airDbgInline(inst),
|
||||
|
||||
.dbg_block_begin,
|
||||
.dbg_block_end,
|
||||
=> try self.airDbgBlock(inst),
|
||||
|
||||
.call => try self.airCall(inst, .auto),
|
||||
.call_always_tail => try self.airCall(inst, .always_tail),
|
||||
.call_never_tail => try self.airCall(inst, .never_tail),
|
||||
|
|
@ -2731,6 +2735,11 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
|
|||
return self.finishAir(inst, .dead, .{ .none, .none, .none });
|
||||
}
|
||||
|
||||
fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {
|
||||
// TODO emit debug info lexical block
|
||||
return self.finishAir(inst, .dead, .{ .none, .none, .none });
|
||||
}
|
||||
|
||||
fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
|
||||
const name = self.air.nullTerminatedString(pl_op.payload);
|
||||
|
|
|
|||
|
|
@ -644,6 +644,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
|||
.dbg_inline_end,
|
||||
=> try self.airDbgInline(inst),
|
||||
|
||||
.dbg_block_begin,
|
||||
.dbg_block_end,
|
||||
=> try self.airDbgBlock(inst),
|
||||
|
||||
.call => try self.airCall(inst, .auto),
|
||||
.call_always_tail => try self.airCall(inst, .always_tail),
|
||||
.call_never_tail => try self.airCall(inst, .never_tail),
|
||||
|
|
@ -2948,6 +2952,11 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
|
|||
return self.finishAir(inst, .dead, .{ .none, .none, .none });
|
||||
}
|
||||
|
||||
fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {
|
||||
// TODO emit debug info lexical block
|
||||
return self.finishAir(inst, .dead, .{ .none, .none, .none });
|
||||
}
|
||||
|
||||
fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
|
||||
const name = self.air.nullTerminatedString(pl_op.payload);
|
||||
|
|
|
|||
|
|
@ -618,6 +618,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
|||
.dbg_inline_end,
|
||||
=> try self.airDbgInline(inst),
|
||||
|
||||
.dbg_block_begin,
|
||||
.dbg_block_end,
|
||||
=> try self.airDbgBlock(inst),
|
||||
|
||||
.call => try self.airCall(inst, .auto),
|
||||
.call_always_tail => try self.airCall(inst, .always_tail),
|
||||
.call_never_tail => try self.airCall(inst, .never_tail),
|
||||
|
|
@ -1653,6 +1657,11 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
|
|||
return self.finishAir(inst, .dead, .{ .none, .none, .none });
|
||||
}
|
||||
|
||||
fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {
|
||||
// TODO emit debug info lexical block
|
||||
return self.finishAir(inst, .dead, .{ .none, .none, .none });
|
||||
}
|
||||
|
||||
fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
|
||||
const name = self.air.nullTerminatedString(pl_op.payload);
|
||||
|
|
|
|||
|
|
@ -1330,6 +1330,8 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
|
|||
.dbg_stmt,
|
||||
.dbg_inline_begin,
|
||||
.dbg_inline_end,
|
||||
.dbg_block_begin,
|
||||
.dbg_block_end,
|
||||
.dbg_var_ptr,
|
||||
.dbg_var_val,
|
||||
=> WValue.none,
|
||||
|
|
|
|||
|
|
@ -735,6 +735,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
|||
.dbg_inline_end,
|
||||
=> try self.airDbgInline(inst),
|
||||
|
||||
.dbg_block_begin,
|
||||
.dbg_block_end,
|
||||
=> try self.airDbgBlock(inst),
|
||||
|
||||
.call => try self.airCall(inst, .auto),
|
||||
.call_always_tail => try self.airCall(inst, .always_tail),
|
||||
.call_never_tail => try self.airCall(inst, .never_tail),
|
||||
|
|
@ -3683,6 +3687,11 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
|
|||
return self.finishAir(inst, .dead, .{ .none, .none, .none });
|
||||
}
|
||||
|
||||
fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {
|
||||
// TODO emit debug info lexical block
|
||||
return self.finishAir(inst, .dead, .{ .none, .none, .none });
|
||||
}
|
||||
|
||||
fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
|
||||
const name = self.air.nullTerminatedString(pl_op.payload);
|
||||
|
|
|
|||
|
|
@ -1786,6 +1786,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
|
|||
.dbg_inline_end,
|
||||
=> try airDbgInline(f, inst),
|
||||
|
||||
.dbg_block_begin,
|
||||
.dbg_block_end,
|
||||
=> CValue{ .none = {} },
|
||||
|
||||
.call => try airCall(f, inst, .auto),
|
||||
.call_always_tail => try airCall(f, inst, .always_tail),
|
||||
.call_never_tail => try airCall(f, inst, .never_tail),
|
||||
|
|
|
|||
|
|
@ -3220,6 +3220,10 @@ pub const FuncGen = struct {
|
|||
/// Stack of locations where a call was inlined.
|
||||
dbg_inlined: std.ArrayListUnmanaged(DbgState) = .{},
|
||||
|
||||
/// Stack of `DILexicalBlock`s. dbg_block instructions cannot happend accross
|
||||
/// dbg_inline instructions so no special handling there is required.
|
||||
dbg_block_stack: std.ArrayListUnmanaged(*llvm.DIScope) = .{},
|
||||
|
||||
/// This stores the LLVM values used in a function, such that they can be referred to
|
||||
/// in other instructions. This table is cleared before every function is generated.
|
||||
func_inst_table: std.AutoHashMapUnmanaged(Air.Inst.Ref, *const llvm.Value),
|
||||
|
|
@ -3254,6 +3258,7 @@ pub const FuncGen = struct {
|
|||
fn deinit(self: *FuncGen) void {
|
||||
self.builder.dispose();
|
||||
self.dbg_inlined.deinit(self.gpa);
|
||||
self.dbg_block_stack.deinit(self.gpa);
|
||||
self.func_inst_table.deinit(self.gpa);
|
||||
self.blocks.deinit(self.gpa);
|
||||
}
|
||||
|
|
@ -3475,6 +3480,8 @@ pub const FuncGen = struct {
|
|||
.dbg_stmt => self.airDbgStmt(inst),
|
||||
.dbg_inline_begin => try self.airDbgInlineBegin(inst),
|
||||
.dbg_inline_end => try self.airDbgInlineEnd(inst),
|
||||
.dbg_block_begin => try self.airDbgBlockBegin(),
|
||||
.dbg_block_end => try self.airDbgBlockEnd(),
|
||||
.dbg_var_ptr => try self.airDbgVarPtr(inst),
|
||||
.dbg_var_val => try self.airDbgVarVal(inst),
|
||||
// zig fmt: on
|
||||
|
|
@ -4256,6 +4263,21 @@ pub const FuncGen = struct {
|
|||
return null;
|
||||
}
|
||||
|
||||
fn airDbgBlockBegin(self: *FuncGen) !?*const llvm.Value {
|
||||
const dib = self.dg.object.di_builder orelse return null;
|
||||
const old_scope = self.di_scope.?;
|
||||
try self.dbg_block_stack.append(self.gpa, old_scope);
|
||||
const lexical_block = dib.createLexicalBlock(old_scope, self.di_file.?, self.prev_dbg_line, self.prev_dbg_column);
|
||||
self.di_scope = lexical_block.toScope();
|
||||
return null;
|
||||
}
|
||||
|
||||
fn airDbgBlockEnd(self: *FuncGen) !?*const llvm.Value {
|
||||
if (self.dg.object.di_builder == null) return null;
|
||||
self.di_scope = self.dbg_block_stack.pop();
|
||||
return null;
|
||||
}
|
||||
|
||||
fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
|
||||
const dib = self.dg.object.di_builder orelse return null;
|
||||
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
|
||||
|
|
|
|||
|
|
@ -272,6 +272,8 @@ const Writer = struct {
|
|||
.mul_with_overflow,
|
||||
.shl_with_overflow,
|
||||
=> try w.writeOverflow(s, inst),
|
||||
|
||||
.dbg_block_begin, .dbg_block_end => {},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -463,6 +463,10 @@ const Writer = struct {
|
|||
.builtin_src,
|
||||
=> try self.writeExtNode(stream, extended),
|
||||
|
||||
.dbg_block_begin,
|
||||
.dbg_block_end,
|
||||
=> try stream.writeAll("))"),
|
||||
|
||||
.@"asm" => try self.writeAsm(stream, extended),
|
||||
.func => try self.writeFuncExtended(stream, extended),
|
||||
.variable => try self.writeVarExtended(stream, extended),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue