Commit f57b059e58

Jakub Konka <kubkon@jakubkonka.com>
2022-05-07 13:27:11
regalloc: refactor locking multiple registers at once
1 parent bf11cdc
Changed files (4)
src/arch/aarch64/CodeGen.zig
@@ -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);
                 };
src/arch/arm/CodeGen.zig
@@ -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);
                         };
src/arch/x86_64/CodeGen.zig
@@ -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);
     };
src/register_manager.zig
@@ -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.