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.
This commit is contained in:
Lioncash 2024-01-23 10:57:14 -05:00
parent d1b4c5482c
commit 9f82efa3e2
6 changed files with 21 additions and 26 deletions

View File

@ -25,11 +25,10 @@ void FPURegCache::LoadRegister(preg_t preg, X64Reg new_loc)
m_emitter->MOVAPD(new_loc, m_regs[preg].Location().value()); 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, static constexpr X64Reg allocation_order[] = {XMM6, XMM7, XMM8, XMM9, XMM10, XMM11, XMM12,
XMM13, XMM14, XMM15, XMM2, XMM3, XMM4, XMM5}; XMM13, XMM14, XMM15, XMM2, XMM3, XMM4, XMM5};
*count = sizeof(allocation_order) / sizeof(X64Reg);
return allocation_order; return allocation_order;
} }

View File

@ -16,7 +16,7 @@ protected:
Gen::OpArg GetDefaultLocation(preg_t preg) const override; Gen::OpArg GetDefaultLocation(preg_t preg) const override;
void StoreRegister(preg_t preg, const Gen::OpArg& newLoc) override; void StoreRegister(preg_t preg, const Gen::OpArg& newLoc) override;
void LoadRegister(preg_t preg, Gen::X64Reg 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 GetRegUtilization() const override;
BitSet32 CountRegsIn(preg_t preg, u32 lookahead) const override; BitSet32 CountRegsIn(preg_t preg, u32 lookahead) const override;
}; };

View File

@ -30,9 +30,9 @@ OpArg GPRRegCache::GetDefaultLocation(preg_t preg) const
return PPCSTATE_GPR(preg); 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 // R12, when used as base register, for example in a LEA, can generate bad code! Need to look into
// this. // this.
#ifdef _WIN32 #ifdef _WIN32
@ -43,7 +43,6 @@ const X64Reg* GPRRegCache::GetAllocationOrder(size_t* count) const
R8, R9, R10, R11, RCX R8, R9, R10, R11, RCX
#endif #endif
}; };
*count = sizeof(allocation_order) / sizeof(X64Reg);
return allocation_order; return allocation_order;
} }

View File

@ -17,7 +17,7 @@ protected:
Gen::OpArg GetDefaultLocation(preg_t preg) const override; Gen::OpArg GetDefaultLocation(preg_t preg) const override;
void StoreRegister(preg_t preg, const Gen::OpArg& new_loc) override; void StoreRegister(preg_t preg, const Gen::OpArg& new_loc) override;
void LoadRegister(preg_t preg, Gen::X64Reg 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 GetRegUtilization() const override;
BitSet32 CountRegsIn(preg_t preg, u32 lookahead) const override; BitSet32 CountRegsIn(preg_t preg, u32 lookahead) const override;
}; };

View File

@ -592,29 +592,25 @@ void RegCache::StoreFromRegister(preg_t i, FlushMode mode)
X64Reg RegCache::GetFreeXReg() X64Reg RegCache::GetFreeXReg()
{ {
size_t aCount; const auto order = GetAllocationOrder();
const X64Reg* aOrder = GetAllocationOrder(&aCount); for (const X64Reg xr : order)
for (size_t i = 0; i < aCount; i++)
{ {
X64Reg xr = aOrder[i];
if (m_xregs[xr].IsFree()) if (m_xregs[xr].IsFree())
{
return xr; return xr;
}
} }
// Okay, not found; run the register allocator heuristic and figure out which register we should // Okay, not found; run the register allocator heuristic and
// clobber. // figure out which register we should clobber.
float min_score = std::numeric_limits<float>::max(); float min_score = std::numeric_limits<float>::max();
X64Reg best_xreg = INVALID_REG; X64Reg best_xreg = INVALID_REG;
size_t best_preg = 0; size_t best_preg = 0;
for (size_t i = 0; i < aCount; i++) for (const X64Reg xreg : order)
{ {
X64Reg xreg = (X64Reg)aOrder[i]; const preg_t preg = m_xregs[xreg].Contents();
preg_t preg = m_xregs[xreg].Contents();
if (m_xregs[xreg].IsLocked() || m_regs[preg].IsLocked()) if (m_xregs[xreg].IsLocked() || m_regs[preg].IsLocked())
continue; continue;
float score = ScoreRegister(xreg);
const float score = ScoreRegister(xreg);
if (score < min_score) if (score < min_score)
{ {
min_score = score; min_score = score;
@ -637,11 +633,11 @@ X64Reg RegCache::GetFreeXReg()
int RegCache::NumFreeRegisters() const int RegCache::NumFreeRegisters() const
{ {
int count = 0; int count = 0;
size_t aCount; for (const X64Reg reg : GetAllocationOrder())
const X64Reg* aOrder = GetAllocationOrder(&aCount); {
for (size_t i = 0; i < aCount; i++) if (m_xregs[reg].IsFree())
if (m_xregs[aOrder[i]].IsFree())
count++; count++;
}
return count; return count;
} }

View File

@ -5,6 +5,7 @@
#include <array> #include <array>
#include <cstddef> #include <cstddef>
#include <span>
#include <type_traits> #include <type_traits>
#include <variant> #include <variant>
@ -187,7 +188,7 @@ protected:
virtual void StoreRegister(preg_t preg, const Gen::OpArg& new_loc) = 0; virtual void StoreRegister(preg_t preg, const Gen::OpArg& new_loc) = 0;
virtual void LoadRegister(preg_t preg, Gen::X64Reg 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 GetRegUtilization() const = 0;
virtual BitSet32 CountRegsIn(preg_t preg, u32 lookahead) const = 0; virtual BitSet32 CountRegsIn(preg_t preg, u32 lookahead) const = 0;