From 0aee40bd13fa72ac4ca41e133440917c0ed94ffb Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 20 Feb 2023 12:19:40 +0100 Subject: riscv64+sparc64: alloc new mcv in bitcast if cannot reuse operand --- src/arch/riscv64/CodeGen.zig | 15 ++++++++++++++- src/arch/sparc64/CodeGen.zig | 16 +++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig index b97ac727c1..afcf4b0bb7 100644 --- a/src/arch/riscv64/CodeGen.zig +++ b/src/arch/riscv64/CodeGen.zig @@ -2338,7 +2338,20 @@ fn airPtrToInt(self: *Self, inst: Air.Inst.Index) !void { fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result = try self.resolveInst(ty_op.operand); + const result = if (self.liveness.isUnused(inst)) .dead else result: { + const operand = try self.resolveInst(ty_op.operand); + if (self.reuseOperand(inst, ty_op.operand, 0, operand)) break :result operand; + + const operand_lock = switch (operand) { + .register => |reg| self.register_manager.lockReg(reg), + else => null, + }; + defer if (operand_lock) |lock| self.register_manager.unlockReg(lock); + + const dest = try self.allocRegOrMem(inst, true); + try self.setRegOrMem(self.air.typeOfIndex(inst), dest, operand); + break :result dest; + }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig index 8344b6e0cc..c8f77fe702 100644 --- a/src/arch/sparc64/CodeGen.zig +++ b/src/arch/sparc64/CodeGen.zig @@ -1091,7 +1091,21 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result = try self.resolveInst(ty_op.operand); + const result = if (self.liveness.isUnused(inst)) .dead else result: { + const operand = try self.resolveInst(ty_op.operand); + if (self.reuseOperand(inst, ty_op.operand, 0, operand)) break :result operand; + + const operand_lock = switch (operand) { + .register => |reg| self.register_manager.lockReg(reg), + .register_with_overflow => |rwo| self.register_manager.lockReg(rwo.reg), + else => null, + }; + defer if (operand_lock) |lock| self.register_manager.unlockReg(lock); + + const dest = try self.allocRegOrMem(inst, true); + try self.setRegOrMem(self.air.typeOfIndex(inst), dest, operand); + break :result dest; + }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } -- cgit v1.2.3