| ... | ... | @@ -8,16 +8,16 @@ const Type = @import("type.zig").Type; |
| 8 | 8 | const Air = @import("Air.zig"); |
| 9 | 9 | const Liveness = @import("Liveness.zig"); |
| 10 | 10 | |
| 11 | | pub fn write(stream: anytype, module: *Module, air: Air, liveness: Liveness) void { |
| 11 | pub fn write(stream: anytype, module: *Module, air: Air, liveness: ?Liveness) void { |
| 12 | 12 | const instruction_bytes = air.instructions.len * |
| 13 | 13 | // Here we don't use @sizeOf(Air.Inst.Data) because it would include |
| 14 | 14 | // the debug safety tag but we want to measure release size. |
| 15 | 15 | (@sizeOf(Air.Inst.Tag) + 8); |
| 16 | 16 | const extra_bytes = air.extra.len * @sizeOf(u32); |
| 17 | 17 | const values_bytes = air.values.len * @sizeOf(Value); |
| 18 | | const tomb_bytes = liveness.tomb_bits.len * @sizeOf(usize); |
| 19 | | const liveness_extra_bytes = liveness.extra.len * @sizeOf(u32); |
| 20 | | const liveness_special_bytes = liveness.special.count() * 8; |
| 18 | const tomb_bytes = if (liveness) |l| l.tomb_bits.len * @sizeOf(usize) else 0; |
| 19 | const liveness_extra_bytes = if (liveness) |l| l.extra.len * @sizeOf(u32) else 0; |
| 20 | const liveness_special_bytes = if (liveness) |l| l.special.count() * 8 else 0; |
| 21 | 21 | const total_bytes = @sizeOf(Air) + instruction_bytes + extra_bytes + |
| 22 | 22 | values_bytes + @sizeOf(Liveness) + liveness_extra_bytes + |
| 23 | 23 | liveness_special_bytes + tomb_bytes; |
| ... | ... | @@ -38,8 +38,8 @@ pub fn write(stream: anytype, module: *Module, air: Air, liveness: Liveness) voi |
| 38 | 38 | air.extra.len, fmtIntSizeBin(extra_bytes), |
| 39 | 39 | air.values.len, fmtIntSizeBin(values_bytes), |
| 40 | 40 | fmtIntSizeBin(tomb_bytes), |
| 41 | | liveness.extra.len, fmtIntSizeBin(liveness_extra_bytes), |
| 42 | | liveness.special.count(), fmtIntSizeBin(liveness_special_bytes), |
| 41 | if (liveness) |l| l.extra.len else 0, fmtIntSizeBin(liveness_extra_bytes), |
| 42 | if (liveness) |l| l.special.count() else 0, fmtIntSizeBin(liveness_special_bytes), |
| 43 | 43 | }) catch return; |
| 44 | 44 | // zig fmt: on |
| 45 | 45 | |
| ... | ... | @@ -61,7 +61,7 @@ pub fn writeInst( |
| 61 | 61 | inst: Air.Inst.Index, |
| 62 | 62 | module: *Module, |
| 63 | 63 | air: Air, |
| 64 | | liveness: Liveness, |
| 64 | liveness: ?Liveness, |
| 65 | 65 | ) void { |
| 66 | 66 | var writer: Writer = .{ |
| 67 | 67 | .module = module, |
| ... | ... | @@ -74,11 +74,11 @@ pub fn writeInst( |
| 74 | 74 | writer.writeInst(stream, inst) catch return; |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | | pub fn dump(module: *Module, air: Air, liveness: Liveness) void { |
| 77 | pub fn dump(module: *Module, air: Air, liveness: ?Liveness) void { |
| 78 | 78 | write(std.io.getStdErr().writer(), module, air, liveness); |
| 79 | 79 | } |
| 80 | 80 | |
| 81 | | pub fn dumpInst(inst: Air.Inst.Index, module: *Module, air: Air, liveness: Liveness) void { |
| 81 | pub fn dumpInst(inst: Air.Inst.Index, module: *Module, air: Air, liveness: ?Liveness) void { |
| 82 | 82 | writeInst(std.io.getStdErr().writer(), inst, module, air, liveness); |
| 83 | 83 | } |
| 84 | 84 | |
| ... | ... | @@ -86,7 +86,7 @@ const Writer = struct { |
| 86 | 86 | module: *Module, |
| 87 | 87 | gpa: Allocator, |
| 88 | 88 | air: Air, |
| 89 | | liveness: Liveness, |
| 89 | liveness: ?Liveness, |
| 90 | 90 | indent: usize, |
| 91 | 91 | skip_body: bool, |
| 92 | 92 | |
| ... | ... | @@ -109,7 +109,7 @@ const Writer = struct { |
| 109 | 109 | try s.writeByteNTimes(' ', w.indent); |
| 110 | 110 | try s.print("%{d}{c}= {s}(", .{ |
| 111 | 111 | inst, |
| 112 | | @as(u8, if (w.liveness.isUnused(inst)) '!' else ' '), |
| 112 | @as(u8, if (if (w.liveness) |liveness| liveness.isUnused(inst) else false) '!' else ' '), |
| 113 | 113 | @tagName(tag), |
| 114 | 114 | }); |
| 115 | 115 | switch (tag) { |
| ... | ... | @@ -773,7 +773,10 @@ const Writer = struct { |
| 773 | 773 | const extra = w.air.extraData(Air.CondBr, pl_op.payload); |
| 774 | 774 | const then_body = w.air.extra[extra.end..][0..extra.data.then_body_len]; |
| 775 | 775 | const else_body = w.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]; |
| 776 | | const liveness_condbr = w.liveness.getCondBr(inst); |
| 776 | const liveness_condbr = if (w.liveness) |liveness| |
| 777 | liveness.getCondBr(inst) |
| 778 | else |
| 779 | Liveness.CondBrSlices{ .then_deaths = &.{}, .else_deaths = &.{} }; |
| 777 | 780 | |
| 778 | 781 | try w.writeOperand(s, inst, 0, pl_op.operand); |
| 779 | 782 | if (w.skip_body) return s.writeAll(", ..."); |
| ... | ... | @@ -813,8 +816,15 @@ const Writer = struct { |
| 813 | 816 | fn writeSwitchBr(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |
| 814 | 817 | const pl_op = w.air.instructions.items(.data)[inst].pl_op; |
| 815 | 818 | const switch_br = w.air.extraData(Air.SwitchBr, pl_op.payload); |
| 816 | | const liveness = w.liveness.getSwitchBr(w.gpa, inst, switch_br.data.cases_len + 1) catch |
| 817 | | @panic("out of memory"); |
| 819 | const liveness = if (w.liveness) |liveness| |
| 820 | liveness.getSwitchBr(w.gpa, inst, switch_br.data.cases_len + 1) catch |
| 821 | @panic("out of memory") |
| 822 | else blk: { |
| 823 | const slice = w.gpa.alloc([]const Air.Inst.Index, switch_br.data.cases_len + 1) catch |
| 824 | @panic("out of memory"); |
| 825 | std.mem.set([]const Air.Inst.Index, slice, &.{}); |
| 826 | break :blk Liveness.SwitchBrTable{ .deaths = slice }; |
| 827 | }; |
| 818 | 828 | defer w.gpa.free(liveness.deaths); |
| 819 | 829 | var extra_index: usize = switch_br.end; |
| 820 | 830 | var case_i: u32 = 0; |
| ... | ... | @@ -904,13 +914,13 @@ const Writer = struct { |
| 904 | 914 | operand: Air.Inst.Ref, |
| 905 | 915 | ) @TypeOf(s).Error!void { |
| 906 | 916 | const small_tomb_bits = Liveness.bpi - 1; |
| 907 | | const dies = if (op_index < small_tomb_bits) |
| 908 | | w.liveness.operandDies(inst, @intCast(Liveness.OperandInt, op_index)) |
| 909 | | else blk: { |
| 910 | | var extra_index = w.liveness.special.get(inst).?; |
| 917 | const dies = if (w.liveness) |liveness| blk: { |
| 918 | if (op_index < small_tomb_bits) |
| 919 | break :blk liveness.operandDies(inst, @intCast(Liveness.OperandInt, op_index)); |
| 920 | var extra_index = liveness.special.get(inst).?; |
| 911 | 921 | var tomb_op_index: usize = small_tomb_bits; |
| 912 | 922 | while (true) { |
| 913 | | const bits = w.liveness.extra[extra_index]; |
| 923 | const bits = liveness.extra[extra_index]; |
| 914 | 924 | if (op_index < tomb_op_index + 31) { |
| 915 | 925 | break :blk @truncate(u1, bits >> @intCast(u5, op_index - tomb_op_index)) != 0; |
| 916 | 926 | } |
| ... | ... | @@ -918,7 +928,7 @@ const Writer = struct { |
| 918 | 928 | extra_index += 1; |
| 919 | 929 | tomb_op_index += 31; |
| 920 | 930 | } |
| 921 | | }; |
| 931 | } else false; |
| 922 | 932 | return w.writeInstRef(s, operand, dies); |
| 923 | 933 | } |
| 924 | 934 | |