Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/arch/wasm/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const abi = @import("abi.zig");
const Alignment = InternPool.Alignment;
const errUnionPayloadOffset = codegen.errUnionPayloadOffset;
const errUnionErrorOffset = codegen.errUnionErrorOffset;
const crash_report = @import("../../crash_report.zig");

/// Wasm Value, created when generating an instruction
const WValue = union(enum) {
Expand Down Expand Up @@ -2079,7 +2080,12 @@ fn genBody(func: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
const zcu = pt.zcu;
const ip = &zcu.intern_pool;

for (body) |inst| {
var crash_info = crash_report.prepCodeGenState(pt, body, func.air, func.liveness, func.owner_nav);
crash_info.push();
defer crash_info.pop();

for (body, 0..) |inst, i| {
crash_info.setBodyIndex(i);
if (func.liveness.isUnused(inst) and !func.air.mustLower(inst, ip)) {
continue;
}
Expand Down
8 changes: 7 additions & 1 deletion src/arch/x86_64/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const wip_mir_log = std.log.scoped(.wip_mir);
const math = std.math;
const mem = std.mem;
const trace = @import("../../tracy.zig").trace;
const crash_report = @import("../../crash_report.zig");

const Air = @import("../../Air.zig");
const Allocator = mem.Allocator;
Expand Down Expand Up @@ -2277,10 +2278,15 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
else => break,
};

var crash_info = crash_report.prepCodeGenState(pt, body, self.air, self.liveness, if (self.owner == .nav_index) self.owner.nav_index else null);
crash_info.push();
defer crash_info.pop();

if (self.arg_index == 0) try self.airDbgVarArgs();
self.arg_index = 0;
for (body) |inst| {
for (body, 0..) |inst, i| {
if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip)) continue;
crash_info.setBodyIndex(i);
wip_mir_log.debug("{}", .{self.fmtAir(inst)});
verbose_tracking_log.debug("{}", .{self.fmtTracking()});

Expand Down
7 changes: 7 additions & 0 deletions src/codegen/llvm.zig
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const arm_c_abi = @import("../arch/arm/abi.zig");
const riscv_c_abi = @import("../arch/riscv64/abi.zig");
const mips_c_abi = @import("../arch/mips/abi.zig");
const dev = @import("../dev.zig");
const crash_report = @import("../crash_report.zig");

const target_util = @import("../target.zig");
const libcFloatPrefix = target_util.libcFloatPrefix;
Expand Down Expand Up @@ -5071,8 +5072,14 @@ pub const FuncGen = struct {
try fuzz.pcs.append(gpa, pc);
},
}

var crash_info = crash_report.prepCodeGenState(o.pt, body, self.air, self.liveness, self.ng.nav_index);
crash_info.push();
defer crash_info.pop();

for (body, 0..) |inst, i| {
if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip)) continue;
crash_info.setBodyIndex(i);

const val: Builder.Value = switch (air_tags[@intFromEnum(inst)]) {
// zig fmt: off
Expand Down
71 changes: 70 additions & 1 deletion src/crash_report.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ const build_options = @import("build_options");
const debug = std.debug;
const io = std.io;
const print_zir = @import("print_zir.zig");
const print_air = @import("print_air.zig");
const windows = std.os.windows;
const posix = std.posix;
const native_os = builtin.os.tag;

const Air = @import("Air.zig");
const Liveness = @import("Liveness.zig");
const Zcu = @import("Zcu.zig");
const Sema = @import("Sema.zig");
const InternPool = @import("InternPool.zig");
const Zir = std.zig.Zir;
const Decl = Zcu.Decl;
const dev = @import("dev.zig");

/// To use these crash report diagnostics, publish this panic in your main file
Expand Down Expand Up @@ -150,6 +152,69 @@ fn dumpStatusReport() !void {
try stderr.writeAll("\n");
}

pub const CodeGenState = if (build_options.enable_debug_extensions) struct {
parent: ?*CodeGenState,
pt: Zcu.PerThread,
air: Air,
liveness: Liveness,
nav_index: ?InternPool.Nav.Index,
body: []const Air.Inst.Index,
body_index: usize,

pub fn push(self: *CodeGenState) void {
debug.assert(self.parent == null);
self.parent = codegen_state;
codegen_state = if (self.nav_index == null) null else self;
}

pub fn pop(self: *CodeGenState) void {
debug.assert(self.nav_index == null or codegen_state == self);
codegen_state = self.parent;
}

pub fn setBodyIndex(self: *CodeGenState, index: usize) void {
self.body_index = index;
}
} else struct {
pub inline fn push(_: CodeGenState) void {}
pub inline fn pop(_: CodeGenState) void {}
pub inline fn setBodyIndex(_: CodeGenState, _: usize) void {}
};

threadlocal var codegen_state: ?*CodeGenState = if (build_options.enable_debug_extensions) null else @compileError("Cannot use codegen_state without debug extensions.");

pub inline fn prepCodeGenState(pt: Zcu.PerThread, body: []const Air.Inst.Index, air: Air, liveness: Liveness, nav_index: ?InternPool.Nav.Index) CodeGenState {
return if (build_options.enable_debug_extensions) .{
.parent = null,
.pt = pt,
.air = air,
.liveness = liveness,
.nav_index = nav_index,
.body = body,
.body_index = 0,
} else .{};
}

fn dumpCodeGenReport() !void {
const state = codegen_state orelse return;
const stderr = io.getStdErr().writer();
const file = state.pt.zcu.navFileScope(state.nav_index.?);

try stderr.writeAll("CodeGen ");
try writeFilePath(file, stderr);
try stderr.writeAll("\n");

try print_air.writeContext(
stderr,
state.pt,
state.body,
state.body_index,
state.air,
state.liveness,
);
try stderr.writeAll(" For full context, use the --verbose-air flag\n\n");
}

var crash_heap: [16 * 4096]u8 = undefined;

fn writeFilePath(file: *Zcu.File, writer: anytype) !void {
Expand Down Expand Up @@ -415,6 +480,10 @@ const PanicSwitch = struct {
stderr.print("\nIntercepted error.{} while dumping current state. Continuing...\n", .{err}) catch {};
};

dumpCodeGenReport() catch |err| {
stderr.print("\nIntercepted error.{} while dumping CodeGen state. Continuing...\n", .{err}) catch {};
};

goTo(reportStack, .{state});
}

Expand Down
28 changes: 28 additions & 0 deletions src/print_air.zig
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,34 @@ pub fn write(stream: anytype, pt: Zcu.PerThread, air: Air, liveness: ?Liveness)
writer.writeBody(stream, air.getMainBody()) catch return;
}

pub fn writeContext(
stream: anytype,
pt: Zcu.PerThread,
block: []const Air.Inst.Index,
block_index: usize,
air: Air,
liveness: ?Liveness,
) !void {
var writer: Writer = .{
.pt = pt,
.gpa = pt.zcu.gpa,
.air = air,
.liveness = liveness,
.indent = 6,
.skip_body = false,
};

try writer.writeBody(stream, block[0..block_index]);
try stream.writeAll(" > ");
writer.indent = 0;
try writer.writeInst(stream, block[block_index]);
writer.indent = 6;
try stream.writeByte('\n');
if (block_index + 1 < block.len) {
try writer.writeBody(stream, block[block_index + 1 ..]);
}
}

pub fn writeInst(
stream: anytype,
inst: Air.Inst.Index,
Expand Down
Loading