More XY register cross block optimizations

This commit is contained in:
drmortalwombat 2023-02-07 16:37:41 +01:00
parent ff26dffada
commit 115b34626e
2 changed files with 94 additions and 43 deletions

View File

@ -13951,6 +13951,21 @@ bool NativeCodeBasicBlock::SimplifyLoopEnd(NativeCodeProcedure* proc)
return changed;
}
bool NativeCodeBasicBlock::CanHoistStore(const NativeCodeInstruction& ains) const
{
for (int i = 0; i < mIns.Size(); i++)
{
if (ains.MayBeSameAddress(mIns[i]))
return false;
if (ains.mType == ASMIT_STY && mIns[i].ChangesYReg() ||
ains.mType == ASMIT_STX && mIns[i].ChangesXReg())
return false;
}
return true;
}
bool NativeCodeBasicBlock::CanBytepassLoad(const NativeCodeInstruction& ains) const
{
for (int i = 0; i < mIns.Size(); i++)
@ -14027,12 +14042,22 @@ bool NativeCodeBasicBlock::SimplifyDiamond(NativeCodeProcedure* proc)
}
}
if (mblock->mIns.Size() > 0 && mblock->mIns[0].mType == ASMIT_STX && !(mblock->mIns[0].mLive & LIVE_CPU_REG_X) &&
!mTrueJump->ChangesXReg() && !mFalseJump->ChangesXReg())
if (mblock->mIns.Size() > 0 && mblock->mIns[0].mType == ASMIT_STX && (mblock->mIns[0].mMode == ASMIM_ZERO_PAGE || mblock->mIns[0].mMode == ASMIM_ABSOLUTE) && !(mblock->mIns[0].mLive & LIVE_CPU_REG_X) &&
mTrueJump->CanHoistStore(mblock->mIns[0]) && mFalseJump->CanHoistStore(mblock->mIns[0]))
{
if (mblock->mIns[0].mMode == ASMIM_ZERO_PAGE)
{
mExitRequiredRegs += mblock->mIns[0].mAddress;
mTrueJump->mEntryRequiredRegs += mblock->mIns[0].mAddress;
mTrueJump->mExitRequiredRegs += mblock->mIns[0].mAddress;
mFalseJump->mEntryRequiredRegs += mblock->mIns[0].mAddress;
mFalseJump->mExitRequiredRegs += mblock->mIns[0].mAddress;
mblock->mEntryRequiredRegs += mblock->mIns[0].mAddress;
}
mIns.Push(mblock->mIns[0]);
mblock->mIns.Remove(0);
mIns[mIns.Size() - 1].mLive |= LIVE_CPU_REG_X;
mIns[mIns.Size() - 1].mLive |= LIVE_CPU_REG_X | LIVE_CPU_REG_C | LIVE_CPU_REG_Z;
changed = true;
}
}
@ -18628,7 +18653,7 @@ bool NativeCodeBasicBlock::CrossBlockXYFlood(NativeCodeProcedure* proc)
if ((mIns[i].mType == ASMIT_STA || mIns[i].mType == ASMIT_STX || mIns[i].mType == ASMIT_STY) && mIns[i].mMode == ASMIM_ZERO_PAGE && !(mIns[i].mLive & LIVE_CPU_REG_Z))
{
proc->ResetPatched();
if (mIns[i].mType != ASMIT_STY && !(mIns[i].mLive & LIVE_CPU_REG_X) &&CheckCrossBlockXFlood(this, mIns[i].mAddress, i + 1))
if (mIns[i].mType != ASMIT_STY && !(mIns[i].mLive & LIVE_CPU_REG_X) && CheckCrossBlockXFlood(this, mIns[i].mAddress, i + 1, false))
{
if (mIns[i].mType == ASMIT_STX)
mIns[i].mType = ASMIT_NOP;
@ -18645,8 +18670,25 @@ bool NativeCodeBasicBlock::CrossBlockXYFlood(NativeCodeProcedure* proc)
}
else
{
#if 1
proc->ResetPatched();
if (mIns[i].mType != ASMIT_STX && !(mIns[i].mLive & LIVE_CPU_REG_Y) && CheckCrossBlockYFlood(this, mIns[i].mAddress, i + 1))
if (mIns[i].mType == ASMIT_STX && CheckCrossBlockXFlood(this, mIns[i].mAddress, i + 1, true))
{
mIns[i].mType = ASMIT_NOP;
mIns[i].mMode = ASMIM_IMPLIED;
mIns[i].mLive |= LIVE_CPU_REG_X;
proc->ResetPatched();
if (PatchCrossBlockXFlood(this, mIns[i].mAddress, i + 1))
{
changed = true;
}
}
else
#endif
{
proc->ResetPatched();
if (mIns[i].mType != ASMIT_STX && !(mIns[i].mLive & LIVE_CPU_REG_Y) && CheckCrossBlockYFlood(this, mIns[i].mAddress, i + 1, false))
{
if (mIns[i].mType == ASMIT_STY)
mIns[i].mType = ASMIT_NOP;
@ -18664,6 +18706,7 @@ bool NativeCodeBasicBlock::CrossBlockXYFlood(NativeCodeProcedure* proc)
}
}
}
}
if (mTrueJump && mTrueJump->CrossBlockXYFlood(proc))
changed = true;
@ -18674,7 +18717,7 @@ bool NativeCodeBasicBlock::CrossBlockXYFlood(NativeCodeProcedure* proc)
return changed;
}
bool NativeCodeBasicBlock::CheckCrossBlockXFlood(const NativeCodeBasicBlock* block, int reg, int at)
bool NativeCodeBasicBlock::CheckCrossBlockXFlood(const NativeCodeBasicBlock* block, int reg, int at, bool rvalid)
{
if (at == 0 && this == block)
return false;
@ -18691,7 +18734,7 @@ bool NativeCodeBasicBlock::CheckCrossBlockXFlood(const NativeCodeBasicBlock* blo
if (mNumEntries > 1)
{
for (int i = 0; i < mEntryBlocks.Size(); i++)
if (!mEntryBlocks[i]->CheckCrossBlockXFloodExit(block, reg))
if (!mEntryBlocks[i]->CheckCrossBlockXFloodExit(block, reg, rvalid))
return false;
}
}
@ -18711,18 +18754,16 @@ bool NativeCodeBasicBlock::CheckCrossBlockXFlood(const NativeCodeBasicBlock* blo
}
else if (ins.mType == ASMIT_INC || ins.mType == ASMIT_DEC)
{
if (rvalid) return false;
}
else if (ins.mType == ASMIT_LDX)
{
return !(ins.mLive & (LIVE_MEM | LIVE_CPU_REG_Z));
}
else if (ins.mType == ASMIT_INC || ins.mType == ASMIT_DEC)
{
}
else
return false;
}
else if (ins.ChangesXReg() || ins.RequiresXReg() || ins.ChangesZeroPage(reg) || ins.ReferencesZeroPage(reg))
else if (ins.ChangesXReg() || (!rvalid && ins.RequiresXReg()) || ins.ChangesZeroPage(reg) || ins.ReferencesZeroPage(reg))
return false;
at++;
@ -18730,9 +18771,9 @@ bool NativeCodeBasicBlock::CheckCrossBlockXFlood(const NativeCodeBasicBlock* blo
mPatchExit = true;
if (mTrueJump && !mTrueJump->CheckCrossBlockXFlood(block, reg, 0))
if (mTrueJump && !mTrueJump->CheckCrossBlockXFlood(block, reg, 0, rvalid))
return false;
if (mFalseJump && !mFalseJump->CheckCrossBlockXFlood(block, reg, 0))
if (mFalseJump && !mFalseJump->CheckCrossBlockXFlood(block, reg, 0, rvalid))
return false;
}
@ -18740,15 +18781,15 @@ bool NativeCodeBasicBlock::CheckCrossBlockXFlood(const NativeCodeBasicBlock* blo
return true;
}
bool NativeCodeBasicBlock::CheckCrossBlockXFloodExit(const NativeCodeBasicBlock* block, int reg)
bool NativeCodeBasicBlock::CheckCrossBlockXFloodExit(const NativeCodeBasicBlock* block, int reg, bool rvalid)
{
if (!mPatchExit)
{
mPatchExit = true;
if (mTrueJump && !mTrueJump->CheckCrossBlockXFlood(block, reg, 0))
if (mTrueJump && !mTrueJump->CheckCrossBlockXFlood(block, reg, 0, rvalid))
return false;
if (mFalseJump && !mFalseJump->CheckCrossBlockXFlood(block, reg, 0))
if (mFalseJump && !mFalseJump->CheckCrossBlockXFlood(block, reg, 0, rvalid))
return false;
int at = mIns.Size() - 1;
@ -18765,6 +18806,7 @@ bool NativeCodeBasicBlock::CheckCrossBlockXFloodExit(const NativeCodeBasicBlock*
}
else if (ins.mType == ASMIT_INC || ins.mType == ASMIT_DEC)
{
if (rvalid) return false;
}
else if (ins.mType == ASMIT_STA || ins.mType == ASMIT_STX)
{
@ -18773,7 +18815,7 @@ bool NativeCodeBasicBlock::CheckCrossBlockXFloodExit(const NativeCodeBasicBlock*
else
return false;
}
else if (ins.ChangesXReg() || ins.RequiresXReg() || ins.ChangesZeroPage(reg) || ins.ReferencesZeroPage(reg))
else if (ins.ChangesXReg() || (!rvalid && ins.RequiresXReg()) || ins.ChangesZeroPage(reg) || ins.ReferencesZeroPage(reg))
return false;
at--;
@ -18782,7 +18824,7 @@ bool NativeCodeBasicBlock::CheckCrossBlockXFloodExit(const NativeCodeBasicBlock*
mPatched = true;
for (int i = 0; i < mEntryBlocks.Size(); i++)
if (!mEntryBlocks[i]->CheckCrossBlockXFloodExit(block, reg))
if (!mEntryBlocks[i]->CheckCrossBlockXFloodExit(block, reg, rvalid))
return false;
}
@ -18932,7 +18974,7 @@ bool NativeCodeBasicBlock::PatchCrossBlockXFlood(const NativeCodeBasicBlock* blo
}
bool NativeCodeBasicBlock::CheckCrossBlockYFlood(const NativeCodeBasicBlock* block, int reg, int at)
bool NativeCodeBasicBlock::CheckCrossBlockYFlood(const NativeCodeBasicBlock* block, int reg, int at, bool rvalid)
{
if (at == 0 && this == block)
return false;
@ -18949,7 +18991,7 @@ bool NativeCodeBasicBlock::CheckCrossBlockYFlood(const NativeCodeBasicBlock* blo
if (mNumEntries > 1)
{
for (int i = 0; i < mEntryBlocks.Size(); i++)
if (!mEntryBlocks[i]->CheckCrossBlockYFloodExit(block, reg))
if (!mEntryBlocks[i]->CheckCrossBlockYFloodExit(block, reg, false))
return false;
}
}
@ -18969,18 +19011,16 @@ bool NativeCodeBasicBlock::CheckCrossBlockYFlood(const NativeCodeBasicBlock* blo
}
else if (ins.mType == ASMIT_INC || ins.mType == ASMIT_DEC)
{
rvalid = false;
}
else if (ins.mType == ASMIT_LDY)
{
return !(ins.mLive & (LIVE_MEM | LIVE_CPU_REG_Z));
}
else if (ins.mType == ASMIT_INC || ins.mType == ASMIT_DEC)
{
}
else
return false;
}
else if (ins.ChangesYReg() || ins.RequiresYReg() || ins.ChangesZeroPage(reg) || ins.ReferencesZeroPage(reg))
else if (ins.ChangesYReg() || (!rvalid && ins.RequiresYReg()) || ins.ChangesZeroPage(reg) || ins.ReferencesZeroPage(reg))
return false;
at++;
@ -18988,9 +19028,9 @@ bool NativeCodeBasicBlock::CheckCrossBlockYFlood(const NativeCodeBasicBlock* blo
mPatchExit = true;
if (mTrueJump && !mTrueJump->CheckCrossBlockYFlood(block, reg, 0))
if (mTrueJump && !mTrueJump->CheckCrossBlockYFlood(block, reg, 0, rvalid))
return false;
if (mFalseJump && !mFalseJump->CheckCrossBlockYFlood(block, reg, 0))
if (mFalseJump && !mFalseJump->CheckCrossBlockYFlood(block, reg, 0, rvalid))
return false;
}
@ -18998,15 +19038,15 @@ bool NativeCodeBasicBlock::CheckCrossBlockYFlood(const NativeCodeBasicBlock* blo
return true;
}
bool NativeCodeBasicBlock::CheckCrossBlockYFloodExit(const NativeCodeBasicBlock* block, int reg)
bool NativeCodeBasicBlock::CheckCrossBlockYFloodExit(const NativeCodeBasicBlock* block, int reg, bool rvalid)
{
if (!mPatchExit)
{
mPatchExit = true;
if (mTrueJump && !mTrueJump->CheckCrossBlockYFlood(block, reg, 0))
if (mTrueJump && !mTrueJump->CheckCrossBlockYFlood(block, reg, 0, false))
return false;
if (mFalseJump && !mFalseJump->CheckCrossBlockYFlood(block, reg, 0))
if (mFalseJump && !mFalseJump->CheckCrossBlockYFlood(block, reg, 0, false))
return false;
int at = mIns.Size() - 1;
@ -19040,7 +19080,7 @@ bool NativeCodeBasicBlock::CheckCrossBlockYFloodExit(const NativeCodeBasicBlock*
mPatched = true;
for (int i = 0; i < mEntryBlocks.Size(); i++)
if (!mEntryBlocks[i]->CheckCrossBlockYFloodExit(block, reg))
if (!mEntryBlocks[i]->CheckCrossBlockYFloodExit(block, reg, false))
return false;
}
@ -22356,7 +22396,7 @@ bool NativeCodeBasicBlock::MoveStoreXUp(int at)
return done;
}
if (mIns[at + n].mLive & LIVE_CPU_REG_Z)
if (n > 0 && mIns[at + n].mLive & LIVE_CPU_REG_Z)
{
if (mIns[at - 1].ChangesZFlag())
return done;
@ -34818,7 +34858,7 @@ void NativeCodeProcedure::RebuildEntry(void)
void NativeCodeProcedure::Optimize(void)
{
CheckFunc = !strcmp(mInterProc->mIdent->mString, "builddop_src");
CheckFunc = !strcmp(mInterProc->mIdent->mString, "malloc");
#if 1
int step = 0;
@ -35303,6 +35343,11 @@ void NativeCodeProcedure::Optimize(void)
changed = true;
}
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
if (step == 7)
{
ResetVisited();
@ -35310,6 +35355,11 @@ void NativeCodeProcedure::Optimize(void)
changed = true;
}
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
#if 1
if (step == 7)
{

View File

@ -462,6 +462,7 @@ public:
bool CrossBlockStoreLoadBypass(NativeCodeProcedure* proc);
bool CanBytepassLoad(const NativeCodeInstruction& ains) const;
bool CanHoistStore(const NativeCodeInstruction& ains) const;
bool MoveAccuTrainUp(int at, int end);
bool MoveAccuTrainsUp(void);
@ -504,13 +505,13 @@ public:
bool CrossBlockXYFlood(NativeCodeProcedure * proc);
bool CheckCrossBlockXFlood(const NativeCodeBasicBlock* block, int reg, int at);
bool CheckCrossBlockXFloodExit(const NativeCodeBasicBlock* block, int reg);
bool CheckCrossBlockXFlood(const NativeCodeBasicBlock* block, int reg, int at, bool rvalid);
bool CheckCrossBlockXFloodExit(const NativeCodeBasicBlock* block, int reg, bool rvalid);
bool PatchCrossBlockXFlood(const NativeCodeBasicBlock* block, int reg, int at);
bool PatchCrossBlockXFloodExit(const NativeCodeBasicBlock* block, int reg);
bool CheckCrossBlockYFlood(const NativeCodeBasicBlock* block, int reg, int at);
bool CheckCrossBlockYFloodExit(const NativeCodeBasicBlock* block, int reg);
bool CheckCrossBlockYFlood(const NativeCodeBasicBlock* block, int reg, int at, bool rvalid);
bool CheckCrossBlockYFloodExit(const NativeCodeBasicBlock* block, int reg, bool rvalid);
bool PatchCrossBlockYFlood(const NativeCodeBasicBlock* block, int reg, int at);
bool PatchCrossBlockYFloodExit(const NativeCodeBasicBlock* block, int reg);