authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-05-07 13:27:11+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-05-07 13:27:11+02:00
logf57b059e58253af3718c5b17fefc40c47b33e63c
tree33d7a59476490d8f5a02c0e77156f0cb9fc3dd00
parentbf11cdc9d880555aee087a9bc0ecd1424428b63b

regalloc: refactor locking multiple registers at once


4 files changed, 16 insertions(+), 28 deletions(-)

src/arch/aarch64/CodeGen.zig+2-4
...@@ -2627,8 +2627,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo...@@ -2627,8 +2627,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
2627 } else {2627 } else {
2628 // TODO optimize the register allocation2628 // TODO optimize the register allocation
2629 const regs = try self.register_manager.allocRegs(4, .{ null, null, null, null });2629 const regs = try self.register_manager.allocRegs(4, .{ null, null, null, null });
2630 var regs_locks: [4]RegisterLock = undefined;2630 const regs_locks = self.register_manager.lockRegsAssumeUnused(4, regs);
2631 self.register_manager.lockRegsAssumeUnused(4, regs, &regs_locks);
2632 defer for (regs_locks) |reg| {2631 defer for (regs_locks) |reg| {
2633 self.register_manager.unlockReg(reg);2632 self.register_manager.unlockReg(reg);
2634 };2633 };
...@@ -4065,8 +4064,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -4065,8 +4064,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
40654064
4066 // TODO call extern memcpy4065 // TODO call extern memcpy
4067 const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null });4066 const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null });
4068 var regs_locks: [5]RegisterLock = undefined;4067 const regs_locks = self.register_manager.lockRegsAssumeUnused(5, regs);
4069 self.register_manager.lockRegsAssumeUnused(5, regs, &regs_locks);
4070 defer for (regs_locks) |reg| {4068 defer for (regs_locks) |reg| {
4071 self.register_manager.unlockReg(reg);4069 self.register_manager.unlockReg(reg);
4072 };4070 };
src/arch/arm/CodeGen.zig+3-6
...@@ -1548,8 +1548,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1548,8 +1548,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1548 defer if (new_rhs_lock) |reg| self.register_manager.unlockReg(reg);1548 defer if (new_rhs_lock) |reg| self.register_manager.unlockReg(reg);
15491549
1550 const dest_regs = try self.register_manager.allocRegs(2, .{ null, null });1550 const dest_regs = try self.register_manager.allocRegs(2, .{ null, null });
1551 var dest_regs_locks: [2]RegisterLock = undefined;1551 const dest_regs_locks = self.register_manager.lockRegsAssumeUnused(2, dest_regs);
1552 self.register_manager.lockRegsAssumeUnused(2, dest_regs, &dest_regs_locks);
1553 defer for (dest_regs_locks) |reg| {1552 defer for (dest_regs_locks) |reg| {
1554 self.register_manager.unlockReg(reg);1553 self.register_manager.unlockReg(reg);
1555 };1554 };
...@@ -2181,8 +2180,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo...@@ -2181,8 +2180,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
2181 } else {2180 } else {
2182 // TODO optimize the register allocation2181 // TODO optimize the register allocation
2183 const regs = try self.register_manager.allocRegs(4, .{ null, null, null, null });2182 const regs = try self.register_manager.allocRegs(4, .{ null, null, null, null });
2184 var regs_locks: [4]RegisterLock = undefined;2183 const regs_locks = self.register_manager.lockRegsAssumeUnused(4, regs);
2185 self.register_manager.lockRegsAssumeUnused(4, regs, &regs_locks);
2186 defer for (regs_locks) |reg_locked| {2184 defer for (regs_locks) |reg_locked| {
2187 self.register_manager.unlockReg(reg_locked);2185 self.register_manager.unlockReg(reg_locked);
2188 };2186 };
...@@ -2285,8 +2283,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type...@@ -2285,8 +2283,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
2285 try self.store(ptr, .{ .register = tmp_reg }, ptr_ty, value_ty);2283 try self.store(ptr, .{ .register = tmp_reg }, ptr_ty, value_ty);
2286 } else {2284 } else {
2287 const regs = try self.register_manager.allocRegs(4, .{ null, null, null, null });2285 const regs = try self.register_manager.allocRegs(4, .{ null, null, null, null });
2288 var regs_locks: [4]RegisterLock = undefined;2286 const regs_locks = self.register_manager.lockRegsAssumeUnused(4, regs);
2289 self.register_manager.lockRegsAssumeUnused(4, regs, &regs_locks);
2290 defer for (regs_locks) |reg| {2287 defer for (regs_locks) |reg| {
2291 self.register_manager.unlockReg(reg);2288 self.register_manager.unlockReg(reg);
2292 };2289 };
src/arch/x86_64/CodeGen.zig+8-16
...@@ -1377,8 +1377,7 @@ fn airMul(self: *Self, inst: Air.Inst.Index) !void {...@@ -1377,8 +1377,7 @@ fn airMul(self: *Self, inst: Air.Inst.Index) !void {
1377 // Spill .rax and .rdx upfront to ensure we don't spill the operands too late.1377 // Spill .rax and .rdx upfront to ensure we don't spill the operands too late.
1378 try self.register_manager.getReg(.rax, inst);1378 try self.register_manager.getReg(.rax, inst);
1379 try self.register_manager.getReg(.rdx, null);1379 try self.register_manager.getReg(.rdx, null);
1380 var reg_locks: [2]RegisterLock = undefined;1380 const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx });
1381 self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks);
1382 defer for (reg_locks) |reg| {1381 defer for (reg_locks) |reg| {
1383 self.register_manager.unlockReg(reg);1382 self.register_manager.unlockReg(reg);
1384 };1383 };
...@@ -1495,8 +1494,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1495,8 +1494,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1495 // Spill .rax and .rdx upfront to ensure we don't spill the operands too late.1494 // Spill .rax and .rdx upfront to ensure we don't spill the operands too late.
1496 try self.register_manager.getReg(.rax, inst);1495 try self.register_manager.getReg(.rax, inst);
1497 try self.register_manager.getReg(.rdx, null);1496 try self.register_manager.getReg(.rdx, null);
1498 var reg_locks: [2]RegisterLock = undefined;1497 const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx });
1499 self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks);
1500 defer for (reg_locks) |reg| {1498 defer for (reg_locks) |reg| {
1501 self.register_manager.unlockReg(reg);1499 self.register_manager.unlockReg(reg);
1502 };1500 };
...@@ -1556,8 +1554,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1556,8 +1554,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1556 // Spill .rax and .rdx upfront to ensure we don't spill the operands too late.1554 // Spill .rax and .rdx upfront to ensure we don't spill the operands too late.
1557 try self.register_manager.getReg(.rax, null);1555 try self.register_manager.getReg(.rax, null);
1558 try self.register_manager.getReg(.rdx, null);1556 try self.register_manager.getReg(.rdx, null);
1559 var reg_locks: [2]RegisterLock = undefined;1557 const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx });
1560 self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks);
1561 defer for (reg_locks) |reg| {1558 defer for (reg_locks) |reg| {
1562 self.register_manager.unlockReg(reg);1559 self.register_manager.unlockReg(reg);
1563 };1560 };
...@@ -1586,8 +1583,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1586,8 +1583,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1586 };1583 };
15871584
1588 const temp_regs = try self.register_manager.allocRegs(3, .{ null, null, null });1585 const temp_regs = try self.register_manager.allocRegs(3, .{ null, null, null });
1589 var temp_regs_locks: [3]RegisterLock = undefined;1586 const temp_regs_locks = self.register_manager.lockRegsAssumeUnused(3, temp_regs);
1590 self.register_manager.lockRegsAssumeUnused(3, temp_regs, &temp_regs_locks);
1591 defer for (temp_regs_locks) |reg| {1587 defer for (temp_regs_locks) |reg| {
1592 self.register_manager.unlockReg(reg);1588 self.register_manager.unlockReg(reg);
1593 };1589 };
...@@ -1819,8 +1815,7 @@ fn airDiv(self: *Self, inst: Air.Inst.Index) !void {...@@ -1819,8 +1815,7 @@ fn airDiv(self: *Self, inst: Air.Inst.Index) !void {
1819 };1815 };
1820 try self.register_manager.getReg(.rax, track_rax);1816 try self.register_manager.getReg(.rax, track_rax);
1821 try self.register_manager.getReg(.rdx, null);1817 try self.register_manager.getReg(.rdx, null);
1822 var reg_locks: [2]RegisterLock = undefined;1818 const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx });
1823 self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks);
1824 defer for (reg_locks) |reg| {1819 defer for (reg_locks) |reg| {
1825 self.register_manager.unlockReg(reg);1820 self.register_manager.unlockReg(reg);
1826 };1821 };
...@@ -1893,8 +1888,7 @@ fn airRem(self: *Self, inst: Air.Inst.Index) !void {...@@ -1893,8 +1888,7 @@ fn airRem(self: *Self, inst: Air.Inst.Index) !void {
1893 // Spill .rax and .rdx upfront to ensure we don't spill the operands too late.1888 // Spill .rax and .rdx upfront to ensure we don't spill the operands too late.
1894 try self.register_manager.getReg(.rax, null);1889 try self.register_manager.getReg(.rax, null);
1895 try self.register_manager.getReg(.rdx, inst);1890 try self.register_manager.getReg(.rdx, inst);
1896 var reg_locks: [2]RegisterLock = undefined;1891 const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx });
1897 self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks);
1898 defer for (reg_locks) |reg| {1892 defer for (reg_locks) |reg| {
1899 self.register_manager.unlockReg(reg);1893 self.register_manager.unlockReg(reg);
1900 };1894 };
...@@ -1929,8 +1923,7 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void {...@@ -1929,8 +1923,7 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void {
1929 // Spill .rax and .rdx upfront to ensure we don't spill the operands too late.1923 // Spill .rax and .rdx upfront to ensure we don't spill the operands too late.
1930 try self.register_manager.getReg(.rax, null);1924 try self.register_manager.getReg(.rax, null);
1931 try self.register_manager.getReg(.rdx, if (signedness == .unsigned) inst else null);1925 try self.register_manager.getReg(.rdx, if (signedness == .unsigned) inst else null);
1932 var reg_locks: [2]RegisterLock = undefined;1926 const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx });
1933 self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks);
1934 defer for (reg_locks) |reg| {1927 defer for (reg_locks) |reg| {
1935 self.register_manager.unlockReg(reg);1928 self.register_manager.unlockReg(reg);
1936 };1929 };
...@@ -5552,8 +5545,7 @@ fn genInlineMemcpy(...@@ -5552,8 +5545,7 @@ fn genInlineMemcpy(
5552 try self.register_manager.getReg(.rax, null);5545 try self.register_manager.getReg(.rax, null);
5553 try self.register_manager.getReg(.rcx, null);5546 try self.register_manager.getReg(.rcx, null);
55545547
5555 var reg_locks: [2]RegisterLock = undefined;5548 const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rcx });
5556 self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rcx }, &reg_locks);
5557 defer for (reg_locks) |lock| {5549 defer for (reg_locks) |lock| {
5558 self.register_manager.unlockReg(lock);5550 self.register_manager.unlockReg(lock);
5559 };5551 };
src/register_manager.zig+3-2
...@@ -151,11 +151,12 @@ pub fn RegisterManager(...@@ -151,11 +151,12 @@ pub fn RegisterManager(
151 self: *Self,151 self: *Self,
152 comptime count: comptime_int,152 comptime count: comptime_int,
153 regs: [count]Register,153 regs: [count]Register,
154 buf: *[count]RegisterLock,154 ) [count]RegisterLock {
155 ) void {155 var buf: [count]RegisterLock = undefined;
156 for (regs) |reg, i| {156 for (regs) |reg, i| {
157 buf[i] = self.lockRegAssumeUnused(reg);157 buf[i] = self.lockRegAssumeUnused(reg);
158 }158 }
159 return buf;
159 }160 }
160161
161 /// Unlocks the register allowing its re-allocation and re-use.162 /// Unlocks the register allowing its re-allocation and re-use.