| ... | ... | @@ -883,7 +883,8 @@ fn copyToTmpRegister(self: *Self, ty: Type, mcv: MCValue) !Register { |
| 883 | 883 | /// Allocates a new register and copies `mcv` into it. |
| 884 | 884 | /// `reg_owner` is the instruction that gets associated with the register in the register table. |
| 885 | 885 | /// This can have a side effect of spilling instructions to the stack to free up a register. |
| 886 | | fn copyToNewRegister(self: *Self, reg_owner: Air.Inst.Index, ty: Type, mcv: MCValue) !MCValue { |
| 886 | /// WARNING make sure that the allocated register matches the returned MCValue from an instruction! |
| 887 | fn copyToRegisterWithInstTracking(self: *Self, reg_owner: Air.Inst.Index, ty: Type, mcv: MCValue) !MCValue { |
| 887 | 888 | const reg = try self.register_manager.allocReg(reg_owner); |
| 888 | 889 | try self.genSetReg(ty, reg, mcv); |
| 889 | 890 | return MCValue{ .register = reg }; |
| ... | ... | @@ -939,7 +940,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 939 | 940 | operand.freezeIfRegister(&self.register_manager); |
| 940 | 941 | defer operand.unfreezeIfRegister(&self.register_manager); |
| 941 | 942 | |
| 942 | | break :blk try self.copyToNewRegister(inst, dest_ty, operand); |
| 943 | break :blk try self.copyToRegisterWithInstTracking(inst, dest_ty, operand); |
| 943 | 944 | }; |
| 944 | 945 | |
| 945 | 946 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); |
| ... | ... | @@ -970,7 +971,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 970 | 971 | break :blk operand.register.to64(); |
| 971 | 972 | } |
| 972 | 973 | } |
| 973 | | const mcv = try self.copyToNewRegister(inst, src_ty, operand); |
| 974 | const mcv = try self.copyToRegisterWithInstTracking(inst, src_ty, operand); |
| 974 | 975 | break :blk mcv.register.to64(); |
| 975 | 976 | }; |
| 976 | 977 | |
| ... | ... | @@ -1088,7 +1089,7 @@ fn genPtrBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_r |
| 1088 | 1089 | if (self.reuseOperand(inst, op_lhs, 0, ptr)) { |
| 1089 | 1090 | if (ptr.isMemory() or ptr.isRegister()) break :blk ptr; |
| 1090 | 1091 | } |
| 1091 | | break :blk try self.copyToNewRegister(inst, dst_ty, ptr); |
| 1092 | break :blk try self.copyToRegisterWithInstTracking(inst, dst_ty, ptr); |
| 1092 | 1093 | }; |
| 1093 | 1094 | |
| 1094 | 1095 | const offset_mcv = blk: { |
| ... | ... | @@ -1338,7 +1339,7 @@ fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 1338 | 1339 | if (self.reuseOperand(inst, ty_op.operand, 0, operand)) { |
| 1339 | 1340 | break :result operand; |
| 1340 | 1341 | } |
| 1341 | | break :result try self.copyToNewRegister(inst, self.air.typeOfIndex(inst), operand); |
| 1342 | break :result try self.copyToRegisterWithInstTracking(inst, self.air.typeOfIndex(inst), operand); |
| 1342 | 1343 | }; |
| 1343 | 1344 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 1344 | 1345 | } |
| ... | ... | @@ -1666,7 +1667,7 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1666 | 1667 | self.register_manager.freezeRegs(&.{offset_reg}); |
| 1667 | 1668 | defer self.register_manager.unfreezeRegs(&.{offset_reg}); |
| 1668 | 1669 | |
| 1669 | | const dst_mcv = try self.copyToNewRegister(inst, ptr_ty, ptr); |
| 1670 | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ptr_ty, ptr); |
| 1670 | 1671 | try self.genBinMathOpMir(.add, ptr_ty, dst_mcv, .{ .register = offset_reg }); |
| 1671 | 1672 | break :result dst_mcv; |
| 1672 | 1673 | }; |
| ... | ... | @@ -2113,7 +2114,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde |
| 2113 | 2114 | self.register_manager.freezeRegs(&.{offset_reg}); |
| 2114 | 2115 | defer self.register_manager.unfreezeRegs(&.{offset_reg}); |
| 2115 | 2116 | |
| 2116 | | const dst_mcv = try self.copyToNewRegister(inst, ptr_ty, mcv); |
| 2117 | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ptr_ty, mcv); |
| 2117 | 2118 | try self.genBinMathOpMir(.add, ptr_ty, dst_mcv, .{ .register = offset_reg }); |
| 2118 | 2119 | break :result dst_mcv; |
| 2119 | 2120 | }, |
| ... | ... | @@ -2174,7 +2175,9 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2174 | 2175 | if (self.reuseOperand(inst, operand, 0, mcv)) { |
| 2175 | 2176 | break :blk mcv; |
| 2176 | 2177 | } else { |
| 2177 | | const dst_mcv = try self.copyToNewRegister(inst, Type.usize, .{ .register = reg.to64() }); |
| 2178 | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, Type.usize, .{ |
| 2179 | .register = reg.to64(), |
| 2180 | }); |
| 2178 | 2181 | break :blk dst_mcv; |
| 2179 | 2182 | } |
| 2180 | 2183 | }; |
| ... | ... | @@ -2237,7 +2240,7 @@ fn genBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs: |
| 2237 | 2240 | // LHS dies; use it as the destination. |
| 2238 | 2241 | // Both operands cannot be memory. |
| 2239 | 2242 | if (lhs.isMemory() and rhs.isMemory()) { |
| 2240 | | dst_mcv = try self.copyToNewRegister(inst, dst_ty, lhs); |
| 2243 | dst_mcv = try self.copyToRegisterWithInstTracking(inst, dst_ty, lhs); |
| 2241 | 2244 | src_mcv = rhs; |
| 2242 | 2245 | } else { |
| 2243 | 2246 | dst_mcv = lhs; |
| ... | ... | @@ -2247,7 +2250,7 @@ fn genBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs: |
| 2247 | 2250 | // RHS dies; use it as the destination. |
| 2248 | 2251 | // Both operands cannot be memory. |
| 2249 | 2252 | if (lhs.isMemory() and rhs.isMemory()) { |
| 2250 | | dst_mcv = try self.copyToNewRegister(inst, dst_ty, rhs); |
| 2253 | dst_mcv = try self.copyToRegisterWithInstTracking(inst, dst_ty, rhs); |
| 2251 | 2254 | src_mcv = lhs; |
| 2252 | 2255 | } else { |
| 2253 | 2256 | dst_mcv = rhs; |
| ... | ... | @@ -2258,13 +2261,13 @@ fn genBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs: |
| 2258 | 2261 | rhs.freezeIfRegister(&self.register_manager); |
| 2259 | 2262 | defer rhs.unfreezeIfRegister(&self.register_manager); |
| 2260 | 2263 | |
| 2261 | | dst_mcv = try self.copyToNewRegister(inst, dst_ty, lhs); |
| 2264 | dst_mcv = try self.copyToRegisterWithInstTracking(inst, dst_ty, lhs); |
| 2262 | 2265 | src_mcv = rhs; |
| 2263 | 2266 | } else { |
| 2264 | 2267 | lhs.freezeIfRegister(&self.register_manager); |
| 2265 | 2268 | defer lhs.unfreezeIfRegister(&self.register_manager); |
| 2266 | 2269 | |
| 2267 | | dst_mcv = try self.copyToNewRegister(inst, dst_ty, rhs); |
| 2270 | dst_mcv = try self.copyToRegisterWithInstTracking(inst, dst_ty, rhs); |
| 2268 | 2271 | src_mcv = lhs; |
| 2269 | 2272 | } |
| 2270 | 2273 | } |
| ... | ... | @@ -2837,7 +2840,11 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void { |
| 2837 | 2840 | .register => |reg| { |
| 2838 | 2841 | if (Register.allocIndex(reg) == null) { |
| 2839 | 2842 | // Save function return value in a callee saved register |
| 2840 | | break :result try self.copyToNewRegister(inst, self.air.typeOfIndex(inst), info.return_value); |
| 2843 | break :result try self.copyToRegisterWithInstTracking( |
| 2844 | inst, |
| 2845 | self.air.typeOfIndex(inst), |
| 2846 | info.return_value, |
| 2847 | ); |
| 2841 | 2848 | } |
| 2842 | 2849 | }, |
| 2843 | 2850 | else => {}, |