x86jit: Automatically flush incompatible regs.
This commit is contained in:
parent
55654f52b2
commit
07fa1ed573
5 changed files with 34 additions and 11 deletions
|
@ -434,6 +434,19 @@ IRNativeReg IRNativeRegCacheBase::FindBestToSpill(MIPSLoc type, MIPSMap flags, b
|
|||
return -1;
|
||||
}
|
||||
|
||||
bool IRNativeRegCacheBase::IsNativeRegCompatible(IRNativeReg nreg, MIPSLoc type, MIPSMap flags) {
|
||||
int allocCount = 0, base = 0;
|
||||
const int *allocOrder = GetAllocationOrder(type, flags, allocCount, base);
|
||||
|
||||
for (int i = 0; i < allocCount; i++) {
|
||||
IRNativeReg allocReg = IRNativeReg(allocOrder[i] - base);
|
||||
if (allocReg == nreg)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void IRNativeRegCacheBase::DiscardNativeReg(IRNativeReg nreg) {
|
||||
_assert_msg_(nreg >= 0 && nreg < config_.totalNativeRegs, "DiscardNativeReg on invalid register %d", nreg);
|
||||
if (nr[nreg].mipsReg != IRREG_INVALID) {
|
||||
|
@ -828,18 +841,24 @@ IRNativeReg IRNativeRegCacheBase::MapNativeReg(MIPSLoc type, IRReg first, int la
|
|||
case MIPSLoc::REG_IMM:
|
||||
case MIPSLoc::REG_AS_PTR:
|
||||
case MIPSLoc::REG:
|
||||
if (type != MIPSLoc::REG)
|
||||
if (type != MIPSLoc::REG) {
|
||||
nreg = AllocateReg(type, flags);
|
||||
} else if (!IsNativeRegCompatible(nreg, type, flags)) {
|
||||
// If it's not compatible, we'll need to reallocate.
|
||||
// TODO: Could do a transfer and avoid memory flush.
|
||||
FlushNativeReg(nreg);
|
||||
nreg = AllocateReg(type, flags);
|
||||
}
|
||||
break;
|
||||
|
||||
case MIPSLoc::FREG:
|
||||
if (type != MIPSLoc::FREG)
|
||||
nreg = AllocateReg(type, flags);
|
||||
break;
|
||||
|
||||
case MIPSLoc::VREG:
|
||||
if (type != MIPSLoc::VREG)
|
||||
if (type != mr[first].loc) {
|
||||
nreg = AllocateReg(type, flags);
|
||||
} else if (!IsNativeRegCompatible(nreg, type, flags)) {
|
||||
FlushNativeReg(nreg);
|
||||
nreg = AllocateReg(type, flags);
|
||||
}
|
||||
break;
|
||||
|
||||
case MIPSLoc::IMM:
|
||||
|
|
|
@ -201,6 +201,7 @@ protected:
|
|||
IRNativeReg AllocateReg(MIPSLoc type, MIPSMap flags);
|
||||
IRNativeReg FindFreeReg(MIPSLoc type, MIPSMap flags) const;
|
||||
IRNativeReg FindBestToSpill(MIPSLoc type, MIPSMap flags, bool unusedOnly, bool *clobbered) const;
|
||||
virtual bool IsNativeRegCompatible(IRNativeReg nreg, MIPSLoc type, MIPSMap flags);
|
||||
virtual void DiscardNativeReg(IRNativeReg nreg);
|
||||
virtual void FlushNativeReg(IRNativeReg nreg);
|
||||
virtual void DiscardReg(IRReg mreg);
|
||||
|
|
|
@ -300,6 +300,13 @@ void RiscVRegCache::AdjustNativeRegAsPtr(IRNativeReg nreg, bool state) {
|
|||
}
|
||||
}
|
||||
|
||||
bool RiscVRegCache::IsNativeRegCompatible(IRNativeReg nreg, MIPSLoc type, MIPSMap flags) {
|
||||
// No special flags except VREG, skip the check for a little speed.
|
||||
if (type != MIPSLoc::VREG)
|
||||
return true;
|
||||
return IRNativeRegCacheBase::IsNativeRegCompatible(nreg, type, flags);
|
||||
}
|
||||
|
||||
void RiscVRegCache::LoadNativeReg(IRNativeReg nreg, IRReg first, int lanes) {
|
||||
RiscVReg r = (RiscVReg)(X0 + nreg);
|
||||
_dbg_assert_(r > X0);
|
||||
|
|
|
@ -76,6 +76,7 @@ protected:
|
|||
const int *GetAllocationOrder(MIPSLoc type, MIPSMap flags, int &count, int &base) const override;
|
||||
void AdjustNativeRegAsPtr(IRNativeReg nreg, bool state) override;
|
||||
|
||||
bool IsNativeRegCompatible(IRNativeReg nreg, MIPSLoc type, MIPSMap flags) override;
|
||||
void LoadNativeReg(IRNativeReg nreg, IRReg first, int lanes) override;
|
||||
void StoreNativeReg(IRNativeReg nreg, IRReg first, int lanes) override;
|
||||
void SetNativeRegValue(IRNativeReg nreg, uint32_t imm) override;
|
||||
|
|
|
@ -172,11 +172,6 @@ X64Reg X64IRRegCache::MapWithFPRTemp(IRInst &inst) {
|
|||
X64Reg X64IRRegCache::MapGPR(IRReg mipsReg, MIPSMap mapFlags) {
|
||||
_dbg_assert_(IsValidGPR(mipsReg));
|
||||
|
||||
if ((mapFlags & X64Map::LOW_SUBREG) == X64Map::LOW_SUBREG && IsGPRMapped(mipsReg) && !HasLowSubregister(RX(mipsReg))) {
|
||||
// Unfortunate. For now, let's flush it. We'll realloc a better one.
|
||||
FlushNativeReg(mr[mipsReg].nReg);
|
||||
}
|
||||
|
||||
// Okay, not mapped, so we need to allocate an RV register.
|
||||
IRNativeReg nreg = MapNativeReg(MIPSLoc::REG, mipsReg, 1, mapFlags);
|
||||
return FromNativeReg(nreg);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue