Skip to content

Commit d70853b

Browse files
jacobly0andrewrk
authored andcommitted
main: add debug dump-zir command
1 parent a111130 commit d70853b

File tree

2 files changed

+137
-66
lines changed

2 files changed

+137
-66
lines changed

src/Module.zig

Lines changed: 75 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -3671,74 +3671,13 @@ pub fn astGenFile(mod: *Module, file: *File) !void {
36713671
file.sub_file_path, header.instructions_len,
36723672
});
36733673

3674-
var instructions: std.MultiArrayList(Zir.Inst) = .{};
3675-
defer instructions.deinit(gpa);
3676-
3677-
try instructions.setCapacity(gpa, header.instructions_len);
3678-
instructions.len = header.instructions_len;
3679-
3680-
var zir: Zir = .{
3681-
.instructions = instructions.toOwnedSlice(),
3682-
.string_bytes = &.{},
3683-
.extra = &.{},
3684-
};
3685-
var keep_zir = false;
3686-
defer if (!keep_zir) zir.deinit(gpa);
3687-
3688-
zir.string_bytes = try gpa.alloc(u8, header.string_bytes_len);
3689-
zir.extra = try gpa.alloc(u32, header.extra_len);
3690-
3691-
const safety_buffer = if (data_has_safety_tag)
3692-
try gpa.alloc([8]u8, header.instructions_len)
3693-
else
3694-
undefined;
3695-
defer if (data_has_safety_tag) gpa.free(safety_buffer);
3696-
3697-
const data_ptr = if (data_has_safety_tag)
3698-
@ptrCast([*]u8, safety_buffer.ptr)
3699-
else
3700-
@ptrCast([*]u8, zir.instructions.items(.data).ptr);
3701-
3702-
var iovecs = [_]std.os.iovec{
3703-
.{
3704-
.iov_base = @ptrCast([*]u8, zir.instructions.items(.tag).ptr),
3705-
.iov_len = header.instructions_len,
3706-
},
3707-
.{
3708-
.iov_base = data_ptr,
3709-
.iov_len = header.instructions_len * 8,
3710-
},
3711-
.{
3712-
.iov_base = zir.string_bytes.ptr,
3713-
.iov_len = header.string_bytes_len,
3714-
},
3715-
.{
3716-
.iov_base = @ptrCast([*]u8, zir.extra.ptr),
3717-
.iov_len = header.extra_len * 4,
3674+
file.zir = loadZirCacheBody(gpa, header, cache_file) catch |err| switch (err) {
3675+
error.UnexpectedFileSize => {
3676+
log.warn("unexpected EOF reading cached ZIR for {s}", .{file.sub_file_path});
3677+
break :update;
37183678
},
3679+
else => |e| return e,
37193680
};
3720-
const amt_read = try cache_file.readvAll(&iovecs);
3721-
const amt_expected = zir.instructions.len * 9 +
3722-
zir.string_bytes.len +
3723-
zir.extra.len * 4;
3724-
if (amt_read != amt_expected) {
3725-
log.warn("unexpected EOF reading cached ZIR for {s}", .{file.sub_file_path});
3726-
break :update;
3727-
}
3728-
if (data_has_safety_tag) {
3729-
const tags = zir.instructions.items(.tag);
3730-
for (zir.instructions.items(.data), 0..) |*data, i| {
3731-
const union_tag = Zir.Inst.Tag.data_tags[@enumToInt(tags[i])];
3732-
const as_struct = @ptrCast(*HackDataLayout, data);
3733-
as_struct.* = .{
3734-
.safety_tag = @enumToInt(union_tag),
3735-
.data = safety_buffer[i],
3736-
};
3737-
}
3738-
}
3739-
3740-
keep_zir = true;
3741-
file.zir = zir;
37423681
file.zir_loaded = true;
37433682
file.stat = .{
37443683
.size = header.stat_size,
@@ -3916,6 +3855,76 @@ pub fn astGenFile(mod: *Module, file: *File) !void {
39163855
}
39173856
}
39183857

3858+
pub fn loadZirCache(gpa: Allocator, cache_file: std.fs.File) !Zir {
3859+
return loadZirCacheBody(gpa, try cache_file.reader().readStruct(Zir.Header), cache_file);
3860+
}
3861+
3862+
fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.File) !Zir {
3863+
var instructions: std.MultiArrayList(Zir.Inst) = .{};
3864+
errdefer instructions.deinit(gpa);
3865+
3866+
try instructions.setCapacity(gpa, header.instructions_len);
3867+
instructions.len = header.instructions_len;
3868+
3869+
var zir: Zir = .{
3870+
.instructions = instructions.toOwnedSlice(),
3871+
.string_bytes = &.{},
3872+
.extra = &.{},
3873+
};
3874+
errdefer zir.deinit(gpa);
3875+
3876+
zir.string_bytes = try gpa.alloc(u8, header.string_bytes_len);
3877+
zir.extra = try gpa.alloc(u32, header.extra_len);
3878+
3879+
const safety_buffer = if (data_has_safety_tag)
3880+
try gpa.alloc([8]u8, header.instructions_len)
3881+
else
3882+
undefined;
3883+
defer if (data_has_safety_tag) gpa.free(safety_buffer);
3884+
3885+
const data_ptr = if (data_has_safety_tag)
3886+
@ptrCast([*]u8, safety_buffer.ptr)
3887+
else
3888+
@ptrCast([*]u8, zir.instructions.items(.data).ptr);
3889+
3890+
var iovecs = [_]std.os.iovec{
3891+
.{
3892+
.iov_base = @ptrCast([*]u8, zir.instructions.items(.tag).ptr),
3893+
.iov_len = header.instructions_len,
3894+
},
3895+
.{
3896+
.iov_base = data_ptr,
3897+
.iov_len = header.instructions_len * 8,
3898+
},
3899+
.{
3900+
.iov_base = zir.string_bytes.ptr,
3901+
.iov_len = header.string_bytes_len,
3902+
},
3903+
.{
3904+
.iov_base = @ptrCast([*]u8, zir.extra.ptr),
3905+
.iov_len = header.extra_len * 4,
3906+
},
3907+
};
3908+
const amt_read = try cache_file.readvAll(&iovecs);
3909+
const amt_expected = zir.instructions.len * 9 +
3910+
zir.string_bytes.len +
3911+
zir.extra.len * 4;
3912+
if (amt_read != amt_expected) return error.UnexpectedFileSize;
3913+
if (data_has_safety_tag) {
3914+
const tags = zir.instructions.items(.tag);
3915+
for (zir.instructions.items(.data), 0..) |*data, i| {
3916+
const union_tag = Zir.Inst.Tag.data_tags[@enumToInt(tags[i])];
3917+
const as_struct = @ptrCast(*HackDataLayout, data);
3918+
as_struct.* = .{
3919+
.safety_tag = @enumToInt(union_tag),
3920+
.data = safety_buffer[i],
3921+
};
3922+
}
3923+
}
3924+
3925+
return zir;
3926+
}
3927+
39193928
/// Patch ups:
39203929
/// * Struct.zir_index
39213930
/// * Decl.zir_index

src/main.zig

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ const debug_usage = normal_usage ++
122122
\\Debug Commands:
123123
\\
124124
\\ changelist Compute mappings from old ZIR to new ZIR
125+
\\ dump-zir Dump a file containing cached ZIR
125126
\\
126127
;
127128

@@ -326,6 +327,8 @@ pub fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
326327
return cmdAstCheck(gpa, arena, cmd_args);
327328
} else if (debug_extensions_enabled and mem.eql(u8, cmd, "changelist")) {
328329
return cmdChangelist(gpa, arena, cmd_args);
330+
} else if (debug_extensions_enabled and mem.eql(u8, cmd, "dump-zir")) {
331+
return cmdDumpZir(gpa, arena, cmd_args);
329332
} else {
330333
std.log.info("{s}", .{usage});
331334
fatal("unknown command: {s}", .{args[1]});
@@ -5579,6 +5582,65 @@ pub fn cmdAstCheck(
55795582
return @import("print_zir.zig").renderAsTextToFile(gpa, &file, io.getStdOut());
55805583
}
55815584

5585+
/// This is only enabled for debug builds.
5586+
pub fn cmdDumpZir(
5587+
gpa: Allocator,
5588+
arena: Allocator,
5589+
args: []const []const u8,
5590+
) !void {
5591+
_ = arena;
5592+
const Zir = @import("Zir.zig");
5593+
5594+
const cache_file = args[0];
5595+
5596+
var f = fs.cwd().openFile(cache_file, .{}) catch |err| {
5597+
fatal("unable to open zir cache file for dumping '{s}': {s}", .{ cache_file, @errorName(err) });
5598+
};
5599+
defer f.close();
5600+
5601+
var file: Module.File = .{
5602+
.status = .never_loaded,
5603+
.source_loaded = false,
5604+
.tree_loaded = false,
5605+
.zir_loaded = true,
5606+
.sub_file_path = undefined,
5607+
.source = undefined,
5608+
.stat = undefined,
5609+
.tree = undefined,
5610+
.zir = try Module.loadZirCache(gpa, f),
5611+
.pkg = undefined,
5612+
.root_decl = .none,
5613+
};
5614+
5615+
{
5616+
const instruction_bytes = file.zir.instructions.len *
5617+
// Here we don't use @sizeOf(Zir.Inst.Data) because it would include
5618+
// the debug safety tag but we want to measure release size.
5619+
(@sizeOf(Zir.Inst.Tag) + 8);
5620+
const extra_bytes = file.zir.extra.len * @sizeOf(u32);
5621+
const total_bytes = @sizeOf(Zir) + instruction_bytes + extra_bytes +
5622+
file.zir.string_bytes.len * @sizeOf(u8);
5623+
const stdout = io.getStdOut();
5624+
const fmtIntSizeBin = std.fmt.fmtIntSizeBin;
5625+
// zig fmt: off
5626+
try stdout.writer().print(
5627+
\\# Total ZIR bytes: {}
5628+
\\# Instructions: {d} ({})
5629+
\\# String Table Bytes: {}
5630+
\\# Extra Data Items: {d} ({})
5631+
\\
5632+
, .{
5633+
fmtIntSizeBin(total_bytes),
5634+
file.zir.instructions.len, fmtIntSizeBin(instruction_bytes),
5635+
fmtIntSizeBin(file.zir.string_bytes.len),
5636+
file.zir.extra.len, fmtIntSizeBin(extra_bytes),
5637+
});
5638+
// zig fmt: on
5639+
}
5640+
5641+
return @import("print_zir.zig").renderAsTextToFile(gpa, &file, io.getStdOut());
5642+
}
5643+
55825644
/// This is only enabled for debug builds.
55835645
pub fn cmdChangelist(
55845646
gpa: Allocator,

0 commit comments

Comments
 (0)