Merge pull request #12517 from lioncash/alloc

Jit64/JitRegCache: Simplify GetAllocationOrder()
This commit is contained in:
JosJuice 2024-01-23 19:23:42 +01:00 committed by GitHub
commit 96fda3d126
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
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());
}
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};
*count = sizeof(allocation_order) / sizeof(X64Reg);
return allocation_order;
}

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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;