mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-10 13:06:24 +02:00
jit: Discard clobbered registers on spill.
If we're spilling anyway, discard rather than saving.
This commit is contained in:
1 parent
f6531a74e1
commit
f817d49dfb
4 files changed
+34
-10
No files matched your search
@@ -193,17 +193,24 @@ void ArmRegCache::MapRegTo(ARMReg reg, MIPSGPReg mipsReg, int mapFlags) {
|
||||
mr[mipsReg].reg = reg;
|
||||
}
|
||||
|
||||
ARMReg ArmRegCache::FindBestToSpill(bool unusedOnly) {
|
||||
ARMReg ArmRegCache::FindBestToSpill(bool unusedOnly, bool *clobbered) {
|
||||
int allocCount;
|
||||
const ARMReg *allocOrder = GetMIPSAllocationOrder(allocCount);
|
||||
|
||||
static const int UNUSED_LOOKAHEAD_OPS = 30;
|
||||
|
||||
*clobbered = false;
|
||||
for (int i = 0; i < allocCount; i++) {
|
||||
ARMReg reg = allocOrder[i];
|
||||
if (ar[reg].mipsReg != MIPS_REG_INVALID && mr[ar[reg].mipsReg].spillLock)
|
||||
continue;
|
||||
|
||||
// Awesome, a clobbered reg. Let's use it.
|
||||
if (MIPSAnalyst::IsRegisterClobbered(ar[reg].mipsReg, compilerPC_, UNUSED_LOOKAHEAD_OPS)) {
|
||||
*clobbered = true;
|
||||
return reg;
|
||||
}
|
||||
|
||||
// Not awesome. A used reg. Let's try to avoid spilling.
|
||||
if (unusedOnly && MIPSAnalyst::IsRegisterUsed(ar[reg].mipsReg, compilerPC_, UNUSED_LOOKAHEAD_OPS)) {
|
||||
continue;
|
||||
@@ -280,14 +287,19 @@ allocate:
|
||||
// Still nothing. Let's spill a reg and goto 10.
|
||||
// TODO: Use age or something to choose which register to spill?
|
||||
// TODO: Spill dirty regs first? or opposite?
|
||||
ARMReg bestToSpill = FindBestToSpill(true);
|
||||
bool clobbered;
|
||||
ARMReg bestToSpill = FindBestToSpill(true, &clobbered);
|
||||
if (bestToSpill == INVALID_REG) {
|
||||
bestToSpill = FindBestToSpill(false);
|
||||
bestToSpill = FindBestToSpill(false, &clobbered);
|
||||
}
|
||||
|
||||
if (bestToSpill != INVALID_REG) {
|
||||
// ERROR_LOG(JIT, "Out of registers at PC %08x - spills register %i.", mips_->pc, bestToSpill);
|
||||
FlushArmReg(bestToSpill);
|
||||
if (clobbered) {
|
||||
DiscardR(ar[bestToSpill].mipsReg);
|
||||
} else {
|
||||
FlushArmReg(bestToSpill);
|
||||
}
|
||||
goto allocate;
|
||||
}
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ private:
|
||||
const ArmGen::ARMReg *GetMIPSAllocationOrder(int &count);
|
||||
void MapRegTo(ArmGen::ARMReg reg, MIPSGPReg mipsReg, int mapFlags);
|
||||
int FlushGetSequential(MIPSGPReg startMipsReg, bool allowFlushImm);
|
||||
ArmGen::ARMReg FindBestToSpill(bool unusedOnly);
|
||||
ArmGen::ARMReg FindBestToSpill(bool unusedOnly, bool *clobbered);
|
||||
|
||||
MIPSState *mips_;
|
||||
ArmGen::ARMXEmitter *emit_;
|
||||
|
||||
@@ -122,12 +122,13 @@ void GPRRegCache::UnlockAllX() {
|
||||
xregs[i].allocLocked = false;
|
||||
}
|
||||
|
||||
X64Reg GPRRegCache::FindBestToSpill(bool unusedOnly) {
|
||||
X64Reg GPRRegCache::FindBestToSpill(bool unusedOnly, bool *clobbered) {
|
||||
int allocCount;
|
||||
const int *allocOrder = GetAllocationOrder(allocCount);
|
||||
|
||||
static const int UNUSED_LOOKAHEAD_OPS = 30;
|
||||
|
||||
*clobbered = false;
|
||||
for (int i = 0; i < allocCount; i++) {
|
||||
X64Reg reg = (X64Reg)allocOrder[i];
|
||||
if (xregs[reg].allocLocked)
|
||||
@@ -135,6 +136,12 @@ X64Reg GPRRegCache::FindBestToSpill(bool unusedOnly) {
|
||||
if (xregs[reg].mipsReg != MIPS_REG_INVALID && regs[xregs[reg].mipsReg].locked)
|
||||
continue;
|
||||
|
||||
// Awesome, a clobbered reg. Let's use it.
|
||||
if (MIPSAnalyst::IsRegisterClobbered(xregs[reg].mipsReg, js_->compilerPC, UNUSED_LOOKAHEAD_OPS)) {
|
||||
*clobbered = true;
|
||||
return reg;
|
||||
}
|
||||
|
||||
// Not awesome. A used reg. Let's try to avoid spilling.
|
||||
if (unusedOnly && MIPSAnalyst::IsRegisterUsed(xregs[reg].mipsReg, js_->compilerPC, UNUSED_LOOKAHEAD_OPS)) {
|
||||
continue;
|
||||
@@ -160,13 +167,18 @@ X64Reg GPRRegCache::GetFreeXReg()
|
||||
}
|
||||
|
||||
//Okay, not found :( Force grab one
|
||||
X64Reg bestToSpill = FindBestToSpill(true);
|
||||
bool clobbered;
|
||||
X64Reg bestToSpill = FindBestToSpill(true, &clobbered);
|
||||
if (bestToSpill == INVALID_REG) {
|
||||
bestToSpill = FindBestToSpill(false);
|
||||
bestToSpill = FindBestToSpill(false, &clobbered);
|
||||
}
|
||||
|
||||
if (bestToSpill != INVALID_REG) {
|
||||
StoreFromRegister(xregs[bestToSpill].mipsReg);
|
||||
if (clobbered) {
|
||||
DiscardRegContentsIfCached(xregs[bestToSpill].mipsReg);
|
||||
} else {
|
||||
StoreFromRegister(xregs[bestToSpill].mipsReg);
|
||||
}
|
||||
return bestToSpill;
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ public:
|
||||
|
||||
private:
|
||||
Gen::X64Reg GetFreeXReg();
|
||||
Gen::X64Reg FindBestToSpill(bool unusedOnly);
|
||||
Gen::X64Reg FindBestToSpill(bool unusedOnly, bool *clobbered);
|
||||
const int *GetAllocationOrder(int &count);
|
||||
|
||||
MIPSCachedReg regs[NUM_MIPS_GPRS];
|
||||
|
||||
Reference in new issue
Block a user