Improve zero page register allocator

This commit is contained in:
drmortalwombat 2022-06-19 15:20:53 +02:00
parent 5000d521a1
commit ecfb206d1c
5 changed files with 66 additions and 29 deletions

View File

@ -121,6 +121,8 @@ void Compiler::CompileProcedure(InterCodeProcedure* proc)
for (int i = 0; i < proc->mCalledFunctions.Size(); i++) for (int i = 0; i < proc->mCalledFunctions.Size(); i++)
CompileProcedure(proc->mCalledFunctions[i]); CompileProcedure(proc->mCalledFunctions[i]);
proc->MapCallerSavedTemps();
if (proc->mNativeProcedure) if (proc->mNativeProcedure)
{ {
NativeCodeProcedure* ncproc = new NativeCodeProcedure(mNativeCodeGenerator); NativeCodeProcedure* ncproc = new NativeCodeProcedure(mNativeCodeGenerator);

View File

@ -11934,6 +11934,8 @@ void InterCodeProcedure::Close(void)
BuildTraces(false, false, true); BuildTraces(false, false, true);
DisassembleDebug("Final Merged basic blocks"); DisassembleDebug("Final Merged basic blocks");
MapCallerSavedTemps();
if (mSaveTempsLinkerObject && mTempSize > 16) if (mSaveTempsLinkerObject && mTempSize > 16)
mSaveTempsLinkerObject->AddSpace(mTempSize - 16); mSaveTempsLinkerObject->AddSpace(mTempSize - 16);
} }
@ -12308,9 +12310,11 @@ void InterCodeProcedure::ReduceTemporaries(void)
do { do {
ResetVisited(); ResetVisited();
} while (mEntryBlock->BuildGlobalRequiredTempSet(totalRequired3)); } while (mEntryBlock->BuildGlobalRequiredTempSet(totalRequired3));
}
void InterCodeProcedure::MapCallerSavedTemps(void)
NumberSet callerSaved(numRenamedTemps); {
NumberSet callerSaved(mTemporaries.Size());
ResetVisited(); ResetVisited();
mEntryBlock->BuildCallerSaveTempSet(callerSaved); mEntryBlock->BuildCallerSaveTempSet(callerSaved);

View File

@ -540,6 +540,8 @@ public:
void MarkRelevantStatics(void); void MarkRelevantStatics(void);
void RemoveNonRelevantStatics(void); void RemoveNonRelevantStatics(void);
void MapCallerSavedTemps(void);
void MapVariables(void); void MapVariables(void);
void ReduceTemporaries(void); void ReduceTemporaries(void);
void Disassemble(FILE* file); void Disassemble(FILE* file);

View File

@ -13816,7 +13816,7 @@ bool NativeCodeBasicBlock::PatchSingleUseGlobalLoad(const NativeCodeBasicBlock*
return changed; return changed;
} }
bool NativeCodeBasicBlock::CheckForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, int index, int at, int yval) bool NativeCodeBasicBlock::CheckForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, const NativeCodeInstruction& iins, int at, int yval)
{ {
if (!mPatched) if (!mPatched)
{ {
@ -13858,11 +13858,11 @@ bool NativeCodeBasicBlock::CheckForwardSumYPointer(const NativeCodeBasicBlock* b
yval = (yval - 1) & 255; yval = (yval - 1) & 255;
else if (ins.mType == ASMIT_JSR) else if (ins.mType == ASMIT_JSR)
{ {
if (ins.UsesZeroPage(reg) || ins.UsesZeroPage(reg + 1) || ins.ChangesZeroPage(base) || ins.ChangesZeroPage(base + 1) || ins.ChangesZeroPage(index)) if (ins.UsesZeroPage(reg) || ins.UsesZeroPage(reg + 1) || ins.ChangesZeroPage(base) || ins.ChangesZeroPage(base + 1) || iins.MayBeChangedOnAddress(ins))
return false; return false;
yval = -1; yval = -1;
} }
else if (ins.ChangesZeroPage(base) || ins.ChangesZeroPage(base + 1) || ins.ChangesZeroPage(index)) else if (ins.ChangesZeroPage(base) || ins.ChangesZeroPage(base + 1) || iins.MayBeChangedOnAddress(ins))
return false; return false;
else if (ins.ChangesYReg()) else if (ins.ChangesYReg())
yval = -1; yval = -1;
@ -13870,16 +13870,16 @@ bool NativeCodeBasicBlock::CheckForwardSumYPointer(const NativeCodeBasicBlock* b
at++; at++;
} }
if (mTrueJump && !mTrueJump->CheckForwardSumYPointer(block, reg, base, index, 0, yval)) if (mTrueJump && !mTrueJump->CheckForwardSumYPointer(block, reg, base, iins, 0, yval))
return false; return false;
if (mFalseJump && !mFalseJump->CheckForwardSumYPointer(block, reg, base, index, 0, yval)) if (mFalseJump && !mFalseJump->CheckForwardSumYPointer(block, reg, base, iins, 0, yval))
return false; return false;
} }
return true; return true;
} }
bool NativeCodeBasicBlock::PatchForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, int index, int at, int yval) bool NativeCodeBasicBlock::PatchForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, const NativeCodeInstruction& iins, int at, int yval)
{ {
bool changed = false; bool changed = false;
@ -13906,7 +13906,7 @@ bool NativeCodeBasicBlock::PatchForwardSumYPointer(const NativeCodeBasicBlock* b
if (ins.mLive & LIVE_CPU_REG_Y) if (ins.mLive & LIVE_CPU_REG_Y)
mIns.Insert(at + 1, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, yval)); mIns.Insert(at + 1, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, yval));
mIns.Insert(at, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, index)); mIns.Insert(at, NativeCodeInstruction(ASMIT_LDY, iins));
at++; at++;
for (int i = 0; i < yval; i++) for (int i = 0; i < yval; i++)
{ {
@ -13931,16 +13931,17 @@ bool NativeCodeBasicBlock::PatchForwardSumYPointer(const NativeCodeBasicBlock* b
at++; at++;
} }
if (mTrueJump && mTrueJump->PatchForwardSumYPointer(block, reg, base, index, 0, yval)) if (mTrueJump && mTrueJump->PatchForwardSumYPointer(block, reg, base, iins, 0, yval))
changed = true; changed = true;
if (mFalseJump && mFalseJump->PatchForwardSumYPointer(block, reg, base, index, 0, yval)) if (mFalseJump && mFalseJump->PatchForwardSumYPointer(block, reg, base, iins, 0, yval))
changed = true; changed = true;
if (changed) if (changed)
{ {
mEntryRequiredRegs += base; mEntryRequiredRegs += base;
mEntryRequiredRegs += base + 1; mEntryRequiredRegs += base + 1;
mEntryRequiredRegs += index; if (iins.mMode == ASMIM_ZERO_PAGE)
mEntryRequiredRegs += iins.mAddress;
} }
} }
@ -23335,6 +23336,28 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
} }
} }
} }
else if (
mIns[i + 0].mType == ASMIT_LDX && mIns[i + 0].mMode == ASMIM_ABSOLUTE &&
mIns[i + 1].mType == ASMIT_STX && mIns[i + 1].mMode == ASMIM_ZERO_PAGE)
{
int n = 3;
if (mIns[i + 0].mFlags & NCIF_VOLATILE)
n = 1;
if (mIns[i + 1].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Z))
n--;
if (n > 0)
{
proc->ResetPatched();
if (CheckSingleUseGlobalLoad(this, mIns[i + 1].mAddress, i + 2, mIns[i], n))
{
proc->ResetPatched();
if (PatchSingleUseGlobalLoad(this, mIns[i + 1].mAddress, i + 2, mIns[i]))
progress = true;
CheckLive();
}
}
}
else if ( else if (
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ABSOLUTE) mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ABSOLUTE)
@ -23534,7 +23557,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
if (pass == 0 && if (pass == 0 &&
mIns[i + 0].mType == ASMIT_CLC && mIns[i + 0].mType == ASMIT_CLC &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_IMMEDIATE_ADDRESS && (mIns[i + 1].mFlags & NCIF_LOWER) && mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_IMMEDIATE_ADDRESS && (mIns[i + 1].mFlags & NCIF_LOWER) &&
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mType == ASMIT_ADC &&
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_IMMEDIATE_ADDRESS && (mIns[i + 4].mFlags & NCIF_UPPER) && mIns[i + 4].mLinkerObject == mIns[i + 1].mLinkerObject && mIns[i + 4].mAddress == mIns[i + 1].mAddress && mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_IMMEDIATE_ADDRESS && (mIns[i + 4].mFlags & NCIF_UPPER) && mIns[i + 4].mLinkerObject == mIns[i + 1].mLinkerObject && mIns[i + 4].mAddress == mIns[i + 1].mAddress &&
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 5].mAddress == 0 && mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 5].mAddress == 0 &&
@ -23589,7 +23612,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
#if 1 #if 1
if (mIns[i + 0].mType == ASMIT_CLC && if (mIns[i + 0].mType == ASMIT_CLC &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mType == ASMIT_ADC && (mIns[i + 2].mMode == ASMIM_ZERO_PAGE || mIns[i + 2].mMode == ASMIM_ABSOLUTE) &&
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && /*mIns[i + 3].mAddress != mIns[i + 1].mAddress &&*/ mIns[i + 3].mAddress != mIns[i + 2].mAddress && mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && /*mIns[i + 3].mAddress != mIns[i + 1].mAddress &&*/ mIns[i + 3].mAddress != mIns[i + 2].mAddress &&
mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_ZERO_PAGE && mIns[i + 4].mAddress == mIns[i + 1].mAddress + 1 && mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_ZERO_PAGE && mIns[i + 4].mAddress == mIns[i + 1].mAddress + 1 &&
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 5].mAddress == 0 && mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 5].mAddress == 0 &&
@ -23598,8 +23621,12 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
{ {
int yval = RetrieveYValue(i); int yval = RetrieveYValue(i);
proc->ResetPatched(); proc->ResetPatched();
if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, mIns[i + 2].mAddress, i + 7, yval)) if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, mIns[i + 2], i + 7, yval))
{ {
proc->ResetPatched();
if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, mIns[i + 2], i + 7, yval))
progress = true;
if (mIns[i + 3].mAddress == mIns[i + 1].mAddress) if (mIns[i + 3].mAddress == mIns[i + 1].mAddress)
{ {
for (int j = 0; j < 7; j++) for (int j = 0; j < 7; j++)
@ -23607,16 +23634,12 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + j].mType = ASMIT_NOP; mIns[i + j].mMode = ASMIM_IMPLIED; mIns[i + j].mType = ASMIT_NOP; mIns[i + j].mMode = ASMIM_IMPLIED;
} }
} }
proc->ResetPatched();
if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, mIns[i + 2].mAddress, i + 7, yval))
progress = true;
} }
} }
#endif #endif
#if 1 #if 1
if ( if (
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mType == ASMIT_STA && (mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE) &&
mIns[i + 1].mType == ASMIT_CLC && mIns[i + 1].mType == ASMIT_CLC &&
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress != mIns[i + 0].mAddress && mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress != mIns[i + 0].mAddress &&
@ -23627,8 +23650,12 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
{ {
int yval = RetrieveYValue(i); int yval = RetrieveYValue(i);
proc->ResetPatched(); proc->ResetPatched();
if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 2].mAddress, mIns[i + 0].mAddress, i + 7, yval)) if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 2].mAddress, mIns[i + 0], i + 7, yval))
{ {
proc->ResetPatched();
if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 2].mAddress, mIns[i + 0], i + 7, yval))
progress = true;
if (mIns[i + 3].mAddress == mIns[i + 2].mAddress) if (mIns[i + 3].mAddress == mIns[i + 2].mAddress)
{ {
for (int j = 1; j < 7; j++) for (int j = 1; j < 7; j++)
@ -23636,10 +23663,6 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + j].mType = ASMIT_NOP; mIns[i + j].mMode = ASMIM_IMPLIED; mIns[i + j].mType = ASMIT_NOP; mIns[i + j].mMode = ASMIM_IMPLIED;
} }
} }
proc->ResetPatched();
if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 2].mAddress, mIns[i + 0].mAddress, i + 7, yval))
progress = true;
} }
} }
#if 1 #if 1
@ -24454,7 +24477,7 @@ NativeCodeProcedure::~NativeCodeProcedure(void)
void NativeCodeProcedure::CompressTemporaries(void) void NativeCodeProcedure::CompressTemporaries(void)
{ {
if (mInterProc->mTempSize > 16) if (mInterProc->mTempSize > 0)
{ {
ResetVisited(); ResetVisited();
@ -24505,6 +24528,12 @@ void NativeCodeProcedure::CompressTemporaries(void)
} }
} }
if (tpos < BC_REG_TMP_SAVED)
{
// printf("%s, %d -> %d\n", mInterProc->mIdent->mString, mInterProc->mCallerSavedTemps, tpos - BC_REG_TMP);
mInterProc->mCallerSavedTemps = tpos - BC_REG_TMP;
}
ResetVisited(); ResetVisited();
mEntryBlock->RemapZeroPage(remap); mEntryBlock->RemapZeroPage(remap);

View File

@ -359,8 +359,8 @@ public:
bool CheckSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains, int cycles); bool CheckSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains, int cycles);
bool PatchSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains); bool PatchSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains);
bool CheckForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, int index, int at, int yval); bool CheckForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, const NativeCodeInstruction & iins, int at, int yval);
bool PatchForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, int index, int at, int yval); bool PatchForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, const NativeCodeInstruction & iins, int at, int yval);
bool IsDominatedBy(const NativeCodeBasicBlock* block) const; bool IsDominatedBy(const NativeCodeBasicBlock* block) const;