From 9f82efa3e262a67bc77849fabdcc0e96193c33de Mon Sep 17 00:00:00 2001
From: Lioncash <mai.iam2048@gmail.com>
Date: Tue, 23 Jan 2024 10:57:14 -0500
Subject: [PATCH] Jit64/JitRegCache: Simplify GetAllocationOrder()

Given we have fixed allocation orders, we can just directly return a
span instead of a pointer and a size via an out parameter.

Makes it a little more convenient, since we get both pieces of info at
once, and also have the ability to iterate directly off the span out of
the box.
---
 .../PowerPC/Jit64/RegCache/FPURegCache.cpp    |  7 ++---
 .../Core/PowerPC/Jit64/RegCache/FPURegCache.h |  2 +-
 .../PowerPC/Jit64/RegCache/GPRRegCache.cpp    |  5 ++--
 .../Core/PowerPC/Jit64/RegCache/GPRRegCache.h |  2 +-
 .../PowerPC/Jit64/RegCache/JitRegCache.cpp    | 28 ++++++++-----------
 .../Core/PowerPC/Jit64/RegCache/JitRegCache.h |  3 +-
 6 files changed, 21 insertions(+), 26 deletions(-)

diff --git a/Source/Core/Core/PowerPC/Jit64/RegCache/FPURegCache.cpp b/Source/Core/Core/PowerPC/Jit64/RegCache/FPURegCache.cpp
index ff47f1c760..df210f80c5 100644
--- a/Source/Core/Core/PowerPC/Jit64/RegCache/FPURegCache.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/RegCache/FPURegCache.cpp
@@ -25,11 +25,10 @@ void FPURegCache::LoadRegister(preg_t preg, X64Reg new_loc)
   m_emitter->MOVAPD(new_loc, m_regs[preg].Location().value());
 }
 
-const X64Reg* FPURegCache::GetAllocationOrder(size_t* count) const
+std::span<const X64Reg> FPURegCache::GetAllocationOrder() const
 {
-  static const X64Reg allocation_order[] = {XMM6,  XMM7,  XMM8,  XMM9, XMM10, XMM11, XMM12,
-                                            XMM13, XMM14, XMM15, XMM2, XMM3,  XMM4,  XMM5};
-  *count = sizeof(allocation_order) / sizeof(X64Reg);
+  static constexpr X64Reg allocation_order[] = {XMM6,  XMM7,  XMM8,  XMM9, XMM10, XMM11, XMM12,
+                                                XMM13, XMM14, XMM15, XMM2, XMM3,  XMM4,  XMM5};
   return allocation_order;
 }
 
diff --git a/Source/Core/Core/PowerPC/Jit64/RegCache/FPURegCache.h b/Source/Core/Core/PowerPC/Jit64/RegCache/FPURegCache.h
index 0f6c8745e1..f7d81663b6 100644
--- a/Source/Core/Core/PowerPC/Jit64/RegCache/FPURegCache.h
+++ b/Source/Core/Core/PowerPC/Jit64/RegCache/FPURegCache.h
@@ -16,7 +16,7 @@ protected:
   Gen::OpArg GetDefaultLocation(preg_t preg) const override;
   void StoreRegister(preg_t preg, const Gen::OpArg& newLoc) override;
   void LoadRegister(preg_t preg, Gen::X64Reg newLoc) override;
-  const Gen::X64Reg* GetAllocationOrder(size_t* count) const override;
+  std::span<const Gen::X64Reg> GetAllocationOrder() const override;
   BitSet32 GetRegUtilization() const override;
   BitSet32 CountRegsIn(preg_t preg, u32 lookahead) const override;
 };
diff --git a/Source/Core/Core/PowerPC/Jit64/RegCache/GPRRegCache.cpp b/Source/Core/Core/PowerPC/Jit64/RegCache/GPRRegCache.cpp
index 6f99d3c21f..e2904516ad 100644
--- a/Source/Core/Core/PowerPC/Jit64/RegCache/GPRRegCache.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/RegCache/GPRRegCache.cpp
@@ -30,9 +30,9 @@ OpArg GPRRegCache::GetDefaultLocation(preg_t preg) const
   return PPCSTATE_GPR(preg);
 }
 
-const X64Reg* GPRRegCache::GetAllocationOrder(size_t* count) const
+std::span<const X64Reg> GPRRegCache::GetAllocationOrder() const
 {
-  static const X64Reg allocation_order[] = {
+  static constexpr X64Reg allocation_order[] = {
 // R12, when used as base register, for example in a LEA, can generate bad code! Need to look into
 // this.
 #ifdef _WIN32
@@ -43,7 +43,6 @@ const X64Reg* GPRRegCache::GetAllocationOrder(size_t* count) const
       R8,  R9,  R10, R11, RCX
 #endif
   };
-  *count = sizeof(allocation_order) / sizeof(X64Reg);
   return allocation_order;
 }
 
diff --git a/Source/Core/Core/PowerPC/Jit64/RegCache/GPRRegCache.h b/Source/Core/Core/PowerPC/Jit64/RegCache/GPRRegCache.h
index 9a5b51e1c3..60985e1960 100644
--- a/Source/Core/Core/PowerPC/Jit64/RegCache/GPRRegCache.h
+++ b/Source/Core/Core/PowerPC/Jit64/RegCache/GPRRegCache.h
@@ -17,7 +17,7 @@ protected:
   Gen::OpArg GetDefaultLocation(preg_t preg) const override;
   void StoreRegister(preg_t preg, const Gen::OpArg& new_loc) override;
   void LoadRegister(preg_t preg, Gen::X64Reg new_loc) override;
-  const Gen::X64Reg* GetAllocationOrder(size_t* count) const override;
+  std::span<const Gen::X64Reg> GetAllocationOrder() const override;
   BitSet32 GetRegUtilization() const override;
   BitSet32 CountRegsIn(preg_t preg, u32 lookahead) const override;
 };
diff --git a/Source/Core/Core/PowerPC/Jit64/RegCache/JitRegCache.cpp b/Source/Core/Core/PowerPC/Jit64/RegCache/JitRegCache.cpp
index 9c6c395a57..86f1d9e15a 100644
--- a/Source/Core/Core/PowerPC/Jit64/RegCache/JitRegCache.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/RegCache/JitRegCache.cpp
@@ -592,29 +592,25 @@ void RegCache::StoreFromRegister(preg_t i, FlushMode mode)
 
 X64Reg RegCache::GetFreeXReg()
 {
-  size_t aCount;
-  const X64Reg* aOrder = GetAllocationOrder(&aCount);
-  for (size_t i = 0; i < aCount; i++)
+  const auto order = GetAllocationOrder();
+  for (const X64Reg xr : order)
   {
-    X64Reg xr = aOrder[i];
     if (m_xregs[xr].IsFree())
-    {
       return xr;
-    }
   }
 
-  // Okay, not found; run the register allocator heuristic and figure out which register we should
-  // clobber.
+  // Okay, not found; run the register allocator heuristic and
+  // figure out which register we should clobber.
   float min_score = std::numeric_limits<float>::max();
   X64Reg best_xreg = INVALID_REG;
   size_t best_preg = 0;
-  for (size_t i = 0; i < aCount; i++)
+  for (const X64Reg xreg : order)
   {
-    X64Reg xreg = (X64Reg)aOrder[i];
-    preg_t preg = m_xregs[xreg].Contents();
+    const preg_t preg = m_xregs[xreg].Contents();
     if (m_xregs[xreg].IsLocked() || m_regs[preg].IsLocked())
       continue;
-    float score = ScoreRegister(xreg);
+
+    const float score = ScoreRegister(xreg);
     if (score < min_score)
     {
       min_score = score;
@@ -637,11 +633,11 @@ X64Reg RegCache::GetFreeXReg()
 int RegCache::NumFreeRegisters() const
 {
   int count = 0;
-  size_t aCount;
-  const X64Reg* aOrder = GetAllocationOrder(&aCount);
-  for (size_t i = 0; i < aCount; i++)
-    if (m_xregs[aOrder[i]].IsFree())
+  for (const X64Reg reg : GetAllocationOrder())
+  {
+    if (m_xregs[reg].IsFree())
       count++;
+  }
   return count;
 }
 
diff --git a/Source/Core/Core/PowerPC/Jit64/RegCache/JitRegCache.h b/Source/Core/Core/PowerPC/Jit64/RegCache/JitRegCache.h
index 7f62befa0a..158c41c02d 100644
--- a/Source/Core/Core/PowerPC/Jit64/RegCache/JitRegCache.h
+++ b/Source/Core/Core/PowerPC/Jit64/RegCache/JitRegCache.h
@@ -5,6 +5,7 @@
 
 #include <array>
 #include <cstddef>
+#include <span>
 #include <type_traits>
 #include <variant>
 
@@ -187,7 +188,7 @@ protected:
   virtual void StoreRegister(preg_t preg, const Gen::OpArg& new_loc) = 0;
   virtual void LoadRegister(preg_t preg, Gen::X64Reg new_loc) = 0;
 
-  virtual const Gen::X64Reg* GetAllocationOrder(size_t* count) const = 0;
+  virtual std::span<const Gen::X64Reg> GetAllocationOrder() const = 0;
 
   virtual BitSet32 GetRegUtilization() const = 0;
   virtual BitSet32 CountRegsIn(preg_t preg, u32 lookahead) const = 0;