From 13321c8070b52afb24f3c1b57eecbb2aa77fc4ec Mon Sep 17 00:00:00 2001 From: joachimschmidt557 Date: Thu, 17 Mar 2022 21:47:11 +0100 Subject: stage2 regalloc: fix tryAllocRegs for specific situations Previously, tryAllocRegs did not take frozen registers into account when checking if enough registers are available. --- src/arch/aarch64/CodeGen.zig | 11 +++++++---- src/register_manager.zig | 16 +++++++++------- 2 files changed, 16 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 739aaf2d45..3e63c59fe7 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -2648,16 +2648,19 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { if (rhs_should_be_register) { if (!lhs_is_register and !rhs_is_register) { const regs = try self.register_manager.allocRegs(2, .{ - Air.refToIndex(bin_op.rhs).?, Air.refToIndex(bin_op.lhs).?, + Air.refToIndex(bin_op.lhs).?, Air.refToIndex(bin_op.rhs).?, }); lhs_mcv = MCValue{ .register = regs[0] }; rhs_mcv = MCValue{ .register = regs[1] }; } else if (!rhs_is_register) { rhs_mcv = MCValue{ .register = try self.register_manager.allocReg(Air.refToIndex(bin_op.rhs).?) }; + } else if (!lhs_is_register) { + lhs_mcv = MCValue{ .register = try self.register_manager.allocReg(Air.refToIndex(bin_op.lhs).?) }; + } + } else { + if (!lhs_is_register) { + lhs_mcv = MCValue{ .register = try self.register_manager.allocReg(Air.refToIndex(bin_op.lhs).?) }; } - } - if (!lhs_is_register) { - lhs_mcv = MCValue{ .register = try self.register_manager.allocReg(Air.refToIndex(bin_op.lhs).?) }; } // Move the operands to the newly allocated registers diff --git a/src/register_manager.zig b/src/register_manager.zig index 7adf101967..08ac50377b 100644 --- a/src/register_manager.zig +++ b/src/register_manager.zig @@ -148,18 +148,19 @@ pub fn RegisterManager( ) ?[count]Register { comptime assert(count > 0 and count <= tracked_registers.len); - const free_registers = @popCount(FreeRegInt, self.free_registers); - if (free_registers < count) return null; + const free_and_not_frozen_registers = self.free_registers & ~self.frozen_registers; + const free_and_not_frozen_registers_count = @popCount(FreeRegInt, free_and_not_frozen_registers); + if (free_and_not_frozen_registers_count < count) return null; var regs: [count]Register = undefined; var i: usize = 0; for (tracked_registers) |reg| { if (i >= count) break; if (self.isRegFrozen(reg)) continue; - if (self.isRegFree(reg)) { - regs[i] = reg; - i += 1; - } + if (!self.isRegFree(reg)) continue; + + regs[i] = reg; + i += 1; } assert(i == count); @@ -193,7 +194,8 @@ pub fn RegisterManager( insts: [count]?Air.Inst.Index, ) AllocateRegistersError![count]Register { comptime assert(count > 0 and count <= tracked_registers.len); - if (count > tracked_registers.len - @popCount(FreeRegInt, self.frozen_registers)) return error.OutOfRegisters; + const frozen_registers_count = @popCount(FreeRegInt, self.frozen_registers); + if (count > tracked_registers.len - frozen_registers_count) return error.OutOfRegisters; const result = self.tryAllocRegs(count, insts) orelse blk: { // We'll take over the first count registers. Spill -- cgit v1.2.3