feature. See also
. The project being documented here (as the example) is the Zig library itself.
Ir.dumpDecl
fn dumpDecl(ir: *const Ir, decl: *const Decl, gpa: Allocator, name: []const u8, term: std.Io.Terminal) !void
File
Code
fn dumpDecl(ir: *const Ir, decl: *const Decl, gpa: Allocator, name: []const u8, term: std.Io.Terminal) !void {
const tags = decl.instructions.items(.tag);
const data = decl.instructions.items(.data);
const w = term.writer;
var ref_map: RefMap = .empty;
defer ref_map.deinit(gpa);
var label_map: RefMap = .empty;
defer label_map.deinit(gpa);
const ret_inst = decl.body.items[decl.body.items.len - 1];
const ret_operand = data[@backingInt(ret_inst)].un;
const ret_ty = decl.instructions.items(.ty)[@backingInt(ret_operand)];
try ir.writeType(ret_ty, term);
try term.setColor(REF);
try w.print(" @{s}", .{name});
try term.setColor(.reset);
try w.writeAll("(");
var arg_count: u32 = 0;
while (true) : (arg_count += 1) {
const ref = decl.body.items[arg_count];
if (tags[@backingInt(ref)] != .arg) break;
if (arg_count != 0) try w.writeAll(", ");
try ref_map.put(gpa, ref, {});
try ir.writeRef(decl, &ref_map, ref, term);
try term.setColor(.reset);
}
try w.writeAll(") {\n");
for (decl.body.items[arg_count..]) |ref| {
switch (tags[@backingInt(ref)]) {
.label => try label_map.put(gpa, ref, {}),
else => {},
}
}
for (decl.body.items[arg_count..]) |ref| {
const i = @backingInt(ref);
const tag = tags[i];
switch (tag) {
.arg, .constant, .symbol => unreachable,
.label => {
const label_index = label_map.getIndex(ref).?;
try term.setColor(REF);
try w.print("{s}.{d}:\n", .{ data[i].label, label_index });
},
// const un = data[i].un;
// try w.print(" %{d} = label.{d}\n", .{ i, @intFromEnum(un) });
// },
.jmp => {
const un = data[i].un;
try term.setColor(INST);
try w.writeAll(" jmp ");
try writeLabel(decl, &label_map, un, term);
try w.writeByte('\n');
},
.branch => {
const br = data[i].branch;
try term.setColor(INST);
try w.writeAll(" branch ");
try ir.writeRef(decl, &ref_map, br.cond, term);
try term.setColor(.reset);
try w.writeAll(", ");
try writeLabel(decl, &label_map, br.then, term);
try term.setColor(.reset);
try w.writeAll(", ");
try writeLabel(decl, &label_map, br.@"else", term);
try w.writeByte('\n');
},
.select => {
const br = data[i].branch;
try ir.writeNewRef(gpa, decl, &ref_map, ref, term);
try w.writeAll("select ");
try ir.writeRef(decl, &ref_map, br.cond, term);
try term.setColor(.reset);
try w.writeAll(", ");
try ir.writeRef(decl, &ref_map, br.then, term);
try term.setColor(.reset);
try w.writeAll(", ");
try ir.writeRef(decl, &ref_map, br.@"else", term);
try w.writeByte('\n');
},
// const bin = data[i].bin;
// try w.print(" %{s} %{d} label.{d}\n", .{ @tagName(tag), @intFromEnum(bin.lhs), @intFromEnum(bin.rhs) });
// },
.@"switch" => {
const @"switch" = data[i].@"switch";
try term.setColor(INST);
try w.writeAll(" switch ");
try ir.writeRef(decl, &ref_map, @"switch".target, term);
try term.setColor(.reset);
try w.writeAll(" {");
for (@"switch".case_vals[0..@"switch".cases_len], @"switch".case_labels) |val_ref, label_ref| {
try w.writeAll("\n ");
try ir.writeValue(val_ref, term);
try term.setColor(.reset);
try w.writeAll(" => ");
try writeLabel(decl, &label_map, label_ref, term);
try term.setColor(.reset);
}
try term.setColor(LITERAL);
try w.writeAll("\n default ");
try term.setColor(.reset);
try w.writeAll("=> ");
try writeLabel(decl, &label_map, @"switch".default, term);
try term.setColor(.reset);
try w.writeAll("\n }\n");
},
.call => {
const call = data[i].call;
try ir.writeNewRef(gpa, decl, &ref_map, ref, term);
try w.writeAll("call ");
try ir.writeRef(decl, &ref_map, call.func, term);
try term.setColor(.reset);
try w.writeAll("(");
for (call.args(), 0..) |arg, arg_i| {
if (arg_i != 0) try w.writeAll(", ");
try ir.writeRef(decl, &ref_map, arg, term);
try term.setColor(.reset);
}
try w.writeAll(")\n");
},
.alloc => {
const alloc = data[i].alloc;
try ir.writeNewRef(gpa, decl, &ref_map, ref, term);
try w.writeAll("alloc ");
try term.setColor(ATTRIBUTE);
try w.writeAll("size ");
try term.setColor(LITERAL);
try w.print("{d}", .{alloc.size});
try term.setColor(ATTRIBUTE);
try w.writeAll(" align ");
try term.setColor(LITERAL);
try w.print("{d}", .{alloc.@"align"});
try w.writeByte('\n');
},
.phi => {
try ir.writeNewRef(gpa, decl, &ref_map, ref, term);
try w.writeAll("phi");
try term.setColor(.reset);
try w.writeAll(" {");
for (data[i].phi.inputs()) |input| {
try w.writeAll("\n ");
try writeLabel(decl, &label_map, input.label, term);
try term.setColor(.reset);
try w.writeAll(" => ");
try ir.writeRef(decl, &ref_map, input.value, term);
try term.setColor(.reset);
}
try term.setColor(.reset);
try w.writeAll("\n }\n");
},
.store => {
const bin = data[i].bin;
try term.setColor(INST);
try w.writeAll(" store ");
try ir.writeRef(decl, &ref_map, bin.lhs, term);
try term.setColor(.reset);
try w.writeAll(", ");
try ir.writeRef(decl, &ref_map, bin.rhs, term);
try w.writeByte('\n');
},
.ret => {
try term.setColor(INST);
try w.writeAll(" ret ");
if (data[i].un != .none) try ir.writeRef(decl, &ref_map, data[i].un, term);
try w.writeByte('\n');
},
.load => {
try ir.writeNewRef(gpa, decl, &ref_map, ref, term);
try w.writeAll("load ");
try ir.writeRef(decl, &ref_map, data[i].un, term);
try w.writeByte('\n');
},
.bit_or,
.bit_xor,
.bit_and,
.bit_shl,
.bit_shr,
.cmp_eq,
.cmp_ne,
.cmp_lt,
.cmp_lte,
.cmp_gt,
.cmp_gte,
.add,
.sub,
.mul,
.div,
.mod,
=> {
const bin = data[i].bin;
try ir.writeNewRef(gpa, decl, &ref_map, ref, term);
try w.print("{s} ", .{@tagName(tag)});
try ir.writeRef(decl, &ref_map, bin.lhs, term);
try term.setColor(.reset);
try w.writeAll(", ");
try ir.writeRef(decl, &ref_map, bin.rhs, term);
try w.writeByte('\n');
},
.bit_not,
.negate,
.trunc,
.zext,
.sext,
=> {
const un = data[i].un;
try ir.writeNewRef(gpa, decl, &ref_map, ref, term);
try w.print("{s} ", .{@tagName(tag)});
try ir.writeRef(decl, &ref_map, un, term);
try w.writeByte('\n');
},
.label_addr, .jmp_val => {},
}
}
try term.setColor(.reset);
try w.writeAll("}\n\n");
}