regalloc: refactor locking multiple registers at once

This commit is contained in:
Jakub Konka 2022-05-07 13:27:11 +02:00
parent bf11cdc9d8
commit f57b059e58
4 changed files with 16 additions and 28 deletions

View File

@ -2627,8 +2627,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
} else {
// TODO optimize the register allocation
const regs = try self.register_manager.allocRegs(4, .{ null, null, null, null });
var regs_locks: [4]RegisterLock = undefined;
self.register_manager.lockRegsAssumeUnused(4, regs, &regs_locks);
const regs_locks = self.register_manager.lockRegsAssumeUnused(4, regs);
defer for (regs_locks) |reg| {
self.register_manager.unlockReg(reg);
};
@ -4065,8 +4064,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
// TODO call extern memcpy
const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null });
var regs_locks: [5]RegisterLock = undefined;
self.register_manager.lockRegsAssumeUnused(5, regs, &regs_locks);
const regs_locks = self.register_manager.lockRegsAssumeUnused(5, regs);
defer for (regs_locks) |reg| {
self.register_manager.unlockReg(reg);
};

View File

@ -1548,8 +1548,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
defer if (new_rhs_lock) |reg| self.register_manager.unlockReg(reg);
const dest_regs = try self.register_manager.allocRegs(2, .{ null, null });
var dest_regs_locks: [2]RegisterLock = undefined;
self.register_manager.lockRegsAssumeUnused(2, dest_regs, &dest_regs_locks);
const dest_regs_locks = self.register_manager.lockRegsAssumeUnused(2, dest_regs);
defer for (dest_regs_locks) |reg| {
self.register_manager.unlockReg(reg);
};
@ -2181,8 +2180,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
} else {
// TODO optimize the register allocation
const regs = try self.register_manager.allocRegs(4, .{ null, null, null, null });
var regs_locks: [4]RegisterLock = undefined;
self.register_manager.lockRegsAssumeUnused(4, regs, &regs_locks);
const regs_locks = self.register_manager.lockRegsAssumeUnused(4, regs);
defer for (regs_locks) |reg_locked| {
self.register_manager.unlockReg(reg_locked);
};
@ -2285,8 +2283,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
try self.store(ptr, .{ .register = tmp_reg }, ptr_ty, value_ty);
} else {
const regs = try self.register_manager.allocRegs(4, .{ null, null, null, null });
var regs_locks: [4]RegisterLock = undefined;
self.register_manager.lockRegsAssumeUnused(4, regs, &regs_locks);
const regs_locks = self.register_manager.lockRegsAssumeUnused(4, regs);
defer for (regs_locks) |reg| {
self.register_manager.unlockReg(reg);
};

View File

@ -1377,8 +1377,7 @@ fn airMul(self: *Self, inst: Air.Inst.Index) !void {
// Spill .rax and .rdx upfront to ensure we don't spill the operands too late.
try self.register_manager.getReg(.rax, inst);
try self.register_manager.getReg(.rdx, null);
var reg_locks: [2]RegisterLock = undefined;
self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks);
const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx });
defer for (reg_locks) |reg| {
self.register_manager.unlockReg(reg);
};
@ -1495,8 +1494,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
// Spill .rax and .rdx upfront to ensure we don't spill the operands too late.
try self.register_manager.getReg(.rax, inst);
try self.register_manager.getReg(.rdx, null);
var reg_locks: [2]RegisterLock = undefined;
self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks);
const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx });
defer for (reg_locks) |reg| {
self.register_manager.unlockReg(reg);
};
@ -1556,8 +1554,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
// Spill .rax and .rdx upfront to ensure we don't spill the operands too late.
try self.register_manager.getReg(.rax, null);
try self.register_manager.getReg(.rdx, null);
var reg_locks: [2]RegisterLock = undefined;
self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks);
const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx });
defer for (reg_locks) |reg| {
self.register_manager.unlockReg(reg);
};
@ -1586,8 +1583,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
};
const temp_regs = try self.register_manager.allocRegs(3, .{ null, null, null });
var temp_regs_locks: [3]RegisterLock = undefined;
self.register_manager.lockRegsAssumeUnused(3, temp_regs, &temp_regs_locks);
const temp_regs_locks = self.register_manager.lockRegsAssumeUnused(3, temp_regs);
defer for (temp_regs_locks) |reg| {
self.register_manager.unlockReg(reg);
};
@ -1819,8 +1815,7 @@ fn airDiv(self: *Self, inst: Air.Inst.Index) !void {
};
try self.register_manager.getReg(.rax, track_rax);
try self.register_manager.getReg(.rdx, null);
var reg_locks: [2]RegisterLock = undefined;
self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks);
const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx });
defer for (reg_locks) |reg| {
self.register_manager.unlockReg(reg);
};
@ -1893,8 +1888,7 @@ fn airRem(self: *Self, inst: Air.Inst.Index) !void {
// Spill .rax and .rdx upfront to ensure we don't spill the operands too late.
try self.register_manager.getReg(.rax, null);
try self.register_manager.getReg(.rdx, inst);
var reg_locks: [2]RegisterLock = undefined;
self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks);
const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx });
defer for (reg_locks) |reg| {
self.register_manager.unlockReg(reg);
};
@ -1929,8 +1923,7 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void {
// Spill .rax and .rdx upfront to ensure we don't spill the operands too late.
try self.register_manager.getReg(.rax, null);
try self.register_manager.getReg(.rdx, if (signedness == .unsigned) inst else null);
var reg_locks: [2]RegisterLock = undefined;
self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks);
const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx });
defer for (reg_locks) |reg| {
self.register_manager.unlockReg(reg);
};
@ -5552,8 +5545,7 @@ fn genInlineMemcpy(
try self.register_manager.getReg(.rax, null);
try self.register_manager.getReg(.rcx, null);
var reg_locks: [2]RegisterLock = undefined;
self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rcx }, &reg_locks);
const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rcx });
defer for (reg_locks) |lock| {
self.register_manager.unlockReg(lock);
};

View File

@ -151,11 +151,12 @@ pub fn RegisterManager(
self: *Self,
comptime count: comptime_int,
regs: [count]Register,
buf: *[count]RegisterLock,
) void {
) [count]RegisterLock {
var buf: [count]RegisterLock = undefined;
for (regs) |reg, i| {
buf[i] = self.lockRegAssumeUnused(reg);
}
return buf;
}
/// Unlocks the register allowing its re-allocation and re-use.