Merge pull request #949 from comex/eviction-policy

Evict registers from the cache based on LRU.
This commit is contained in:
comex 2014-09-03 02:22:45 -04:00
commit 51a5311d6a
2 changed files with 24 additions and 4 deletions

View File

@ -11,7 +11,7 @@
using namespace Gen; using namespace Gen;
using namespace PowerPC; using namespace PowerPC;
RegCache::RegCache() : emit(nullptr) RegCache::RegCache() : emit(nullptr), cur_use_quantum(0)
{ {
} }
@ -29,6 +29,7 @@ void RegCache::Start()
regs[i].location = GetDefaultLocation(i); regs[i].location = GetDefaultLocation(i);
regs[i].away = false; regs[i].away = false;
regs[i].locked = false; regs[i].locked = false;
regs[i].last_used_quantum = 0;
} }
// todo: sort to find the most popular regs // todo: sort to find the most popular regs
@ -110,18 +111,29 @@ X64Reg RegCache::GetFreeXReg()
//Okay, not found :( Force grab one //Okay, not found :( Force grab one
//TODO - add a pass to grab xregs whose ppcreg is not used in the next 3 instructions //TODO - add a pass to grab xregs whose ppcreg is not used in the next 3 instructions
u32 last_used = 0xFFFFFFFF;
X64Reg last_used_xr = INVALID_REG;
size_t last_used_preg = 0;
for (size_t i = 0; i < aCount; i++) for (size_t i = 0; i < aCount; i++)
{ {
X64Reg xr = (X64Reg)aOrder[i]; X64Reg xr = (X64Reg)aOrder[i];
if (xregs[xr].locked) if (xregs[xr].locked)
continue; continue;
size_t preg = xregs[xr].ppcReg; size_t preg = xregs[xr].ppcReg;
if (!regs[preg].locked) if (!regs[preg].locked && regs[preg].last_used_quantum < last_used)
{ {
StoreFromRegister(preg); last_used = regs[preg].last_used_quantum;
return xr; last_used_xr = xr;
last_used_preg = preg;
} }
} }
if (last_used_xr != INVALID_REG)
{
StoreFromRegister(last_used_preg);
return last_used_xr;
}
//Still no dice? Die! //Still no dice? Die!
_assert_msg_(DYNA_REC, 0, "Regcache ran out of regs"); _assert_msg_(DYNA_REC, 0, "Regcache ran out of regs");
return INVALID_REG; return INVALID_REG;
@ -170,6 +182,7 @@ void RegCache::DiscardRegContentsIfCached(size_t preg)
xregs[xr].ppcReg = INVALID_REG; xregs[xr].ppcReg = INVALID_REG;
regs[preg].away = false; regs[preg].away = false;
regs[preg].location = GetDefaultLocation(preg); regs[preg].location = GetDefaultLocation(preg);
regs[preg].last_used_quantum = 0;
} }
} }
@ -251,6 +264,7 @@ void RegCache::BindToRegister(size_t i, bool doLoad, bool makeDirty)
} }
regs[i].away = true; regs[i].away = true;
regs[i].location = ::Gen::R(xr); regs[i].location = ::Gen::R(xr);
regs[i].last_used_quantum = ++cur_use_quantum;
} }
else else
{ {
@ -293,6 +307,7 @@ void RegCache::StoreFromRegister(size_t i, FlushMode mode)
{ {
regs[i].location = newLoc; regs[i].location = newLoc;
regs[i].away = false; regs[i].away = false;
regs[i].last_used_quantum = 0;
} }
} }
} }
@ -348,4 +363,6 @@ void RegCache::Flush(FlushMode mode)
} }
} }
} }
cur_use_quantum = 0;
} }

View File

@ -20,6 +20,7 @@ struct PPCCachedReg
Gen::OpArg location; Gen::OpArg location;
bool away; // value not in source register bool away; // value not in source register
bool locked; bool locked;
u32 last_used_quantum;
}; };
struct X64CachedReg struct X64CachedReg
@ -45,6 +46,8 @@ protected:
Gen::XEmitter *emit; Gen::XEmitter *emit;
u32 cur_use_quantum;
public: public:
RegCache(); RegCache();
virtual ~RegCache() {} virtual ~RegCache() {}