| author | |
| committer | |
| log | 13321c8070b52afb24f3c1b57eecbb2aa77fc4ec |
| tree | 8e1993c92445c3ecb25b44d3a94d469c56157126 |
| parent | f3f5a5d05b7056aceb408b701613242d053019ab |
Previously, tryAllocRegs did not take frozen registers into account
when checking if enough registers are available.2 files changed, 16 insertions(+), 11 deletions(-)
src/arch/aarch64/CodeGen.zig+7-4| ... | ... | @@ -2648,16 +2648,19 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 2648 | 2648 | if (rhs_should_be_register) { |
| 2649 | 2649 | if (!lhs_is_register and !rhs_is_register) { |
| 2650 | 2650 | const regs = try self.register_manager.allocRegs(2, .{ |
| 2651 | Air.refToIndex(bin_op.rhs).?, Air.refToIndex(bin_op.lhs).?, | |
| 2651 | Air.refToIndex(bin_op.lhs).?, Air.refToIndex(bin_op.rhs).?, | |
| 2652 | 2652 | }); |
| 2653 | 2653 | lhs_mcv = MCValue{ .register = regs[0] }; |
| 2654 | 2654 | rhs_mcv = MCValue{ .register = regs[1] }; |
| 2655 | 2655 | } else if (!rhs_is_register) { |
| 2656 | 2656 | rhs_mcv = MCValue{ .register = try self.register_manager.allocReg(Air.refToIndex(bin_op.rhs).?) }; |
| 2657 | } else if (!lhs_is_register) { | |
| 2658 | lhs_mcv = MCValue{ .register = try self.register_manager.allocReg(Air.refToIndex(bin_op.lhs).?) }; | |
| 2659 | } | |
| 2660 | } else { | |
| 2661 | if (!lhs_is_register) { | |
| 2662 | lhs_mcv = MCValue{ .register = try self.register_manager.allocReg(Air.refToIndex(bin_op.lhs).?) }; | |
| 2657 | 2663 | } |
| 2658 | } | |
| 2659 | if (!lhs_is_register) { | |
| 2660 | lhs_mcv = MCValue{ .register = try self.register_manager.allocReg(Air.refToIndex(bin_op.lhs).?) }; | |
| 2661 | 2664 | } |
| 2662 | 2665 | |
| 2663 | 2666 | // Move the operands to the newly allocated registers |
src/register_manager.zig+9-7| ... | ... | @@ -148,18 +148,19 @@ pub fn RegisterManager( |
| 148 | 148 | ) ?[count]Register { |
| 149 | 149 | comptime assert(count > 0 and count <= tracked_registers.len); |
| 150 | 150 | |
| 151 | const free_registers = @popCount(FreeRegInt, self.free_registers); | |
| 152 | if (free_registers < count) return null; | |
| 151 | const free_and_not_frozen_registers = self.free_registers & ~self.frozen_registers; | |
| 152 | const free_and_not_frozen_registers_count = @popCount(FreeRegInt, free_and_not_frozen_registers); | |
| 153 | if (free_and_not_frozen_registers_count < count) return null; | |
| 153 | 154 | |
| 154 | 155 | var regs: [count]Register = undefined; |
| 155 | 156 | var i: usize = 0; |
| 156 | 157 | for (tracked_registers) |reg| { |
| 157 | 158 | if (i >= count) break; |
| 158 | 159 | if (self.isRegFrozen(reg)) continue; |
| 159 | if (self.isRegFree(reg)) { | |
| 160 | regs[i] = reg; | |
| 161 | i += 1; | |
| 162 | } | |
| 160 | if (!self.isRegFree(reg)) continue; | |
| 161 | ||
| 162 | regs[i] = reg; | |
| 163 | i += 1; | |
| 163 | 164 | } |
| 164 | 165 | assert(i == count); |
| 165 | 166 | |
| ... | ... | @@ -193,7 +194,8 @@ pub fn RegisterManager( |
| 193 | 194 | insts: [count]?Air.Inst.Index, |
| 194 | 195 | ) AllocateRegistersError![count]Register { |
| 195 | 196 | comptime assert(count > 0 and count <= tracked_registers.len); |
| 196 | if (count > tracked_registers.len - @popCount(FreeRegInt, self.frozen_registers)) return error.OutOfRegisters; | |
| 197 | const frozen_registers_count = @popCount(FreeRegInt, self.frozen_registers); | |
| 198 | if (count > tracked_registers.len - frozen_registers_count) return error.OutOfRegisters; | |
| 197 | 199 | |
| 198 | 200 | const result = self.tryAllocRegs(count, insts) orelse blk: { |
| 199 | 201 | // We'll take over the first count registers. Spill |