authorgravatar for timonkruiper@gmail.comTimon Kruiper <timonkruiper@gmail.com> 2021-01-08 12:13:27+01:00
committergravatar for timonkruiper@gmail.comTimon Kruiper <timonkruiper@gmail.com> 2021-01-08 12:13:27+01:00
log3715ed7b54d4382a4495eb041ff3f9ad987bacfb
tree8dde2b6b018a97e2a943006225519d349371d2bb
parent36950815a464c9226783fcdf1190af38950b7405

stage2: implement TZIR printing for `block` and `condbr`

Zig code: ``` fn assert(ok: bool) void { if (!ok) unreachable; } ``` TZIR: ``` Module.Function(name=assert): @0: void = {}; %0: bool = arg(ok) %1: void = dbg_stmt() %2: void = block( %3: bool = not(%0) %4: noreturn = condbr(%3, then: %5: void = breakpoint() %6: noreturn = unreach() else: %7: noreturn = br(%2, @0) ) ) %8: noreturn = retvoid() ```

1 files changed, 76 insertions(+), 16 deletions(-)

src/zir.zig+76-16
......@@ -1915,10 +1915,28 @@ const DumpTzir = struct {
19151915
19161916 const InstTable = std.AutoArrayHashMap(*ir.Inst, usize);
19171917
1918 /// TODO: Improve this code to include a stack of ir.Body and store the instructions
1919 /// in there. Now we are putting all the instructions in a function local table,
1920 /// however instructions that are in a Body can be thown away when the Body ends.
19181921 fn dump(dtz: *DumpTzir, body: ir.Body, writer: std.fs.File.Writer) !void {
19191922 // First pass to pre-populate the table so that we can show even invalid references.
19201923 // Must iterate the same order we iterate the second time.
19211924 // We also look for constants and put them in the const_table.
1925 try dtz.fetchInstsAndResolveConsts(body);
1926
1927 std.debug.print("Module.Function(name={s}):\n", .{dtz.module_fn.owner_decl.name});
1928
1929 for (dtz.const_table.items()) |entry| {
1930 const constant = entry.key.castTag(.constant).?;
1931 try writer.print(" @{d}: {} = {};\n", .{
1932 entry.value, constant.base.ty, constant.val,
1933 });
1934 }
1935
1936 return dtz.dumpBody(body, writer);
1937 }
1938
1939 fn fetchInstsAndResolveConsts(dtz: *DumpTzir, body: ir.Body) error{OutOfMemory}!void {
19221940 for (body.instructions) |inst| {
19231941 try dtz.inst_table.put(inst, dtz.next_index);
19241942 dtz.next_index += 1;
......@@ -1981,11 +1999,21 @@ const DumpTzir = struct {
19811999 try dtz.findConst(&brvoid.block.base);
19822000 },
19832001
2002 .block => {
2003 const block = inst.castTag(.block).?;
2004 try dtz.fetchInstsAndResolveConsts(block.body);
2005 },
2006
2007 .condbr => {
2008 const condbr = inst.castTag(.condbr).?;
2009 try dtz.findConst(condbr.condition);
2010 try dtz.fetchInstsAndResolveConsts(condbr.then_body);
2011 try dtz.fetchInstsAndResolveConsts(condbr.else_body);
2012 },
2013
19842014 // TODO fill out this debug printing
19852015 .assembly,
1986 .block,
19872016 .call,
1988 .condbr,
19892017 .constant,
19902018 .loop,
19912019 .varptr,
......@@ -1993,20 +2021,9 @@ const DumpTzir = struct {
19932021 => {},
19942022 }
19952023 }
1996
1997 std.debug.print("Module.Function(name={s}):\n", .{dtz.module_fn.owner_decl.name});
1998
1999 for (dtz.const_table.items()) |entry| {
2000 const constant = entry.key.castTag(.constant).?;
2001 try writer.print(" @{d}: {} = {};\n", .{
2002 entry.value, constant.base.ty, constant.val,
2003 });
2004 }
2005
2006 return dtz.dumpBody(body, writer);
20072024 }
20082025
2009 fn dumpBody(dtz: *DumpTzir, body: ir.Body, writer: std.fs.File.Writer) !void {
2026 fn dumpBody(dtz: *DumpTzir, body: ir.Body, writer: std.fs.File.Writer) (std.fs.File.WriteError || error{OutOfMemory})!void {
20102027 for (body.instructions) |inst| {
20112028 const my_index = dtz.next_partial_index;
20122029 try dtz.partial_inst_table.put(inst, my_index);
......@@ -2167,11 +2184,54 @@ const DumpTzir = struct {
21672184 }
21682185 },
21692186
2187 .block => {
2188 const block = inst.castTag(.block).?;
2189
2190 try writer.writeAll("\n");
2191
2192 const old_indent = dtz.indent;
2193 dtz.indent += 2;
2194 try dtz.dumpBody(block.body, writer);
2195 dtz.indent = old_indent;
2196
2197 try writer.writeByteNTimes(' ', dtz.indent);
2198 try writer.writeAll(")\n");
2199 },
2200
2201 .condbr => {
2202 const condbr = inst.castTag(.condbr).?;
2203
2204 if (dtz.partial_inst_table.get(condbr.condition)) |operand_index| {
2205 try writer.print("%{d},", .{operand_index});
2206 } else if (dtz.const_table.get(condbr.condition)) |operand_index| {
2207 try writer.print("@{d},", .{operand_index});
2208 } else if (dtz.inst_table.get(condbr.condition)) |operand_index| {
2209 try writer.print("%{d}, // Instruction does not dominate all uses!", .{operand_index});
2210 } else {
2211 try writer.writeAll("!BADREF!,");
2212 }
2213 try writer.writeAll("\n");
2214
2215 try writer.writeByteNTimes(' ', dtz.indent);
2216 try writer.writeAll("then:\n");
2217
2218 const old_indent = dtz.indent;
2219 dtz.indent += 2;
2220 try dtz.dumpBody(condbr.then_body, writer);
2221
2222 try writer.writeByteNTimes(' ', old_indent);
2223 try writer.writeAll("else:\n");
2224
2225 try dtz.dumpBody(condbr.else_body, writer);
2226 dtz.indent = old_indent;
2227
2228 try writer.writeByteNTimes(' ', old_indent);
2229 try writer.writeAll(")\n");
2230 },
2231
21702232 // TODO fill out this debug printing
21712233 .assembly,
2172 .block,
21732234 .call,
2174 .condbr,
21752235 .constant,
21762236 .loop,
21772237 .varptr,