mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
stage2 regalloc: fix tryAllocRegs for specific situations
Previously, tryAllocRegs did not take frozen registers into account when checking if enough registers are available.
This commit is contained in:
parent
f3f5a5d05b
commit
13321c8070
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user