| ... | ... | @@ -585,7 +585,7 @@ const InstTracking = struct { |
| 585 | 585 | tracking_log.debug("%{d} => {} (spilled)", .{ inst, self.* }); |
| 586 | 586 | } |
| 587 | 587 | |
| 588 | | fn verifyMaterialize(self: *InstTracking, target: InstTracking) void { |
| 588 | fn verifyMaterialize(self: InstTracking, target: InstTracking) void { |
| 589 | 589 | switch (self.long) { |
| 590 | 590 | .none, |
| 591 | 591 | .unreach, |
| ... | ... | @@ -634,7 +634,7 @@ const InstTracking = struct { |
| 634 | 634 | } |
| 635 | 635 | |
| 636 | 636 | fn materializeUnsafe( |
| 637 | | self: *InstTracking, |
| 637 | self: InstTracking, |
| 638 | 638 | function: *Self, |
| 639 | 639 | inst: Air.Inst.Index, |
| 640 | 640 | target: InstTracking, |
| ... | ... | @@ -688,7 +688,7 @@ const InstTracking = struct { |
| 688 | 688 | } |
| 689 | 689 | |
| 690 | 690 | fn liveOut(self: *InstTracking, function: *Self, inst: Air.Inst.Index) void { |
| 691 | | for (self.short.getRegs()) |reg| { |
| 691 | for (self.getRegs()) |reg| { |
| 692 | 692 | if (function.register_manager.isRegFree(reg)) { |
| 693 | 693 | tracking_log.debug("%{d} => {} (live-out)", .{ inst, self.* }); |
| 694 | 694 | continue; |
| ... | ... | @@ -701,7 +701,7 @@ const InstTracking = struct { |
| 701 | 701 | // Disable death. |
| 702 | 702 | var found_reg = false; |
| 703 | 703 | var remaining_reg: Register = .none; |
| 704 | | for (tracking.short.getRegs()) |tracked_reg| if (tracked_reg.id() == reg.id()) { |
| 704 | for (tracking.getRegs()) |tracked_reg| if (tracked_reg.id() == reg.id()) { |
| 705 | 705 | assert(!found_reg); |
| 706 | 706 | found_reg = true; |
| 707 | 707 | } else { |
| ... | ... | @@ -10885,12 +10885,12 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 10885 | 10885 | else => unreachable, |
| 10886 | 10886 | } |
| 10887 | 10887 | self.ret_mcv.liveOut(self, inst); |
| 10888 | try self.finishAir(inst, .unreach, .{ un_op, .none, .none }); |
| 10888 | 10889 | |
| 10889 | 10890 | // TODO optimization opportunity: figure out when we can emit this as a 2 byte instruction |
| 10890 | 10891 | // which is available if the jump is 127 bytes or less forward. |
| 10891 | 10892 | const jmp_reloc = try self.asmJmpReloc(undefined); |
| 10892 | 10893 | try self.exitlude_jump_relocs.append(self.gpa, jmp_reloc); |
| 10893 | | return self.finishAir(inst, .unreach, .{ un_op, .none, .none }); |
| 10894 | 10894 | } |
| 10895 | 10895 | |
| 10896 | 10896 | fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| ... | ... | @@ -10905,12 +10905,12 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 10905 | 10905 | else => unreachable, |
| 10906 | 10906 | } |
| 10907 | 10907 | self.ret_mcv.liveOut(self, inst); |
| 10908 | try self.finishAir(inst, .unreach, .{ un_op, .none, .none }); |
| 10908 | 10909 | |
| 10909 | 10910 | // TODO optimization opportunity: figure out when we can emit this as a 2 byte instruction |
| 10910 | 10911 | // which is available if the jump is 127 bytes or less forward. |
| 10911 | 10912 | const jmp_reloc = try self.asmJmpReloc(undefined); |
| 10912 | 10913 | try self.exitlude_jump_relocs.append(self.gpa, jmp_reloc); |
| 10913 | | return self.finishAir(inst, .unreach, .{ un_op, .none, .none }); |
| 10914 | 10914 | } |
| 10915 | 10915 | |
| 10916 | 10916 | fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| ... | ... | @@ -11991,7 +11991,6 @@ fn performReloc(self: *Self, reloc: Mir.Inst.Index) !void { |
| 11991 | 11991 | fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 11992 | 11992 | const mod = self.bin_file.options.module.?; |
| 11993 | 11993 | const br = self.air.instructions.items(.data)[inst].br; |
| 11994 | | const src_mcv = try self.resolveInst(br.operand); |
| 11995 | 11994 | |
| 11996 | 11995 | const block_ty = self.typeOfIndex(br.block_inst); |
| 11997 | 11996 | const block_unused = |
| ... | ... | @@ -12002,15 +12001,17 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 12002 | 12001 | const block_result = result: { |
| 12003 | 12002 | if (block_unused) break :result .none; |
| 12004 | 12003 | |
| 12004 | if (!first_br) try self.getValue(block_tracking.short, null); |
| 12005 | const src_mcv = try self.resolveInst(br.operand); |
| 12006 | |
| 12005 | 12007 | if (self.reuseOperandAdvanced(inst, br.operand, 0, src_mcv, br.block_inst)) { |
| 12006 | 12008 | if (first_br) break :result src_mcv; |
| 12007 | 12009 | |
| 12008 | | for (block_tracking.getRegs()) |block_reg| |
| 12009 | | try self.register_manager.getReg(block_reg, br.block_inst); |
| 12010 | try self.getValue(block_tracking.short, br.block_inst); |
| 12010 | 12011 | // .long = .none to avoid merging operand and block result stack frames. |
| 12011 | | var current_tracking = InstTracking{ .long = .none, .short = src_mcv }; |
| 12012 | const current_tracking: InstTracking = .{ .long = .none, .short = src_mcv }; |
| 12012 | 12013 | try current_tracking.materializeUnsafe(self, br.block_inst, block_tracking.*); |
| 12013 | | for (src_mcv.getRegs()) |src_reg| self.register_manager.freeReg(src_reg); |
| 12014 | for (current_tracking.getRegs()) |src_reg| self.register_manager.freeReg(src_reg); |
| 12014 | 12015 | break :result block_tracking.short; |
| 12015 | 12016 | } |
| 12016 | 12017 | |
| ... | ... | @@ -12018,7 +12019,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 12018 | 12019 | try self.getValue(block_tracking.short, br.block_inst); |
| 12019 | 12020 | break :dst block_tracking.short; |
| 12020 | 12021 | }; |
| 12021 | | try self.genCopy(block_ty, dst_mcv, src_mcv); |
| 12022 | try self.genCopy(block_ty, dst_mcv, try self.resolveInst(br.operand)); |
| 12022 | 12023 | break :result dst_mcv; |
| 12023 | 12024 | }; |
| 12024 | 12025 | |