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