Some peephole loop optimizations

This commit is contained in:
drmortalwombat 2024-05-12 21:06:50 +02:00
parent ba1bc29b1a
commit 04d1abd803
2 changed files with 118 additions and 9 deletions

View File

@ -7097,7 +7097,6 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void)
if (!mVisited)
{
mVisited = true;
#if 1
int sz = mInstructions.Size();
if (sz >= 2 && mInstructions[sz - 1]->mCode == IC_BRANCH && mInstructions[sz - 2]->mCode == IC_RELATIONAL_OPERATOR && mInstructions[sz - 2]->mDst.mTemp == mInstructions[sz - 1]->mSrc[0].mTemp)
@ -7138,7 +7137,7 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void)
{
constFalse = true;
}
else if (cins->mSrc[1].IsUnsigned() && cins->mSrc[0].IsUnsigned())
else if (cins->mSrc[1].IsPositive() && cins->mSrc[0].IsPositive())
{
if (cins->mSrc[1].mRange.mMaxValue < cins->mSrc[0].mRange.mMinValue)
constTrue = true;
@ -7153,7 +7152,7 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void)
constFalse = true;
break;
case IA_CMPLEU:
if (cins->mSrc[1].IsUnsigned() && cins->mSrc[0].IsUnsigned())
if (cins->mSrc[1].IsPositive() && cins->mSrc[0].IsPositive())
{
if (cins->mSrc[1].mRange.mMaxValue <= cins->mSrc[0].mRange.mMinValue)
constTrue = true;
@ -7172,11 +7171,11 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void)
{
constFalse = true;
}
else if (cins->mSrc[1].IsUnsigned() && cins->mSrc[1].mRange.mMaxValue == 0)
else if (cins->mSrc[1].IsPositive() && cins->mSrc[1].mRange.mMaxValue == 0)
{
constFalse = true;
}
else if (cins->mSrc[1].IsUnsigned() && cins->mSrc[0].IsUnsigned())
else if (cins->mSrc[1].IsPositive() && cins->mSrc[0].IsPositive())
{
if (cins->mSrc[1].mRange.mMinValue > cins->mSrc[0].mRange.mMaxValue)
constTrue = true;
@ -7191,7 +7190,7 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void)
constFalse = true;
break;
case IA_CMPGEU:
if (cins->mSrc[1].IsUnsigned() && cins->mSrc[0].IsUnsigned())
if (cins->mSrc[1].IsPositive() && cins->mSrc[0].IsPositive())
{
if (cins->mSrc[1].mRange.mMinValue >= cins->mSrc[0].mRange.mMaxValue)
constTrue = true;
@ -20634,7 +20633,7 @@ void InterCodeProcedure::Close(void)
{
GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "ffill");
CheckFunc = !strcmp(mIdent->mString, "window_mask3");
CheckCase = false;
mEntryBlock = mBlocks[0];
@ -22398,7 +22397,7 @@ void InterCodeProcedure::Disassemble(FILE* file)
void InterCodeProcedure::Disassemble(const char* name, bool dumpSets)
{
#if 1
#if 0
#ifdef _WIN32
FILE* file;
static bool initial = true;

View File

@ -22390,6 +22390,10 @@ void NativeCodeBasicBlock::MarkLiveBlockChain(int index, NativeCodeBasicBlock* b
bool NativeCodeBasicBlock::CanJoinEntryLoadStoreZP(int saddr, int daddr)
{
// Avoid moving code into loops
if (mLoopHead && (mTrueJump == this || mFalseJump == this))
return false;
if (mFalseJump && mExitRequiredRegs[daddr])
return false;
@ -34026,6 +34030,50 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
}
}
}
if (mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE)
{
int a0 = mIns[i + 0].mAddress, a1 = mIns[i + 1].mAddress;
if (!mEntryRequiredRegs[a0] && !ReferencesZeroPage(a0, i + 2) && !ChangesZeroPage(a1, i + 2))
{
if (!exitBlock)
return OptimizeSimpleLoopInvariant(proc, full);
if (exitBlock->mNumEntries == 1 && !exitBlock->mEntryRequiredRegs[CPU_REG_Z])
{
if (!exitBlock->mEntryRequiredRegs[CPU_REG_A])
{
mExitRequiredRegs += a1;
exitBlock->mEntryRequiredRegs += a1;
exitBlock->mIns.Insert(0, NativeCodeInstruction(mIns[i + 0].mIns, ASMIT_LDA, mIns[i + 1]));
exitBlock->mIns.Insert(1, NativeCodeInstruction(mIns[i + 0].mIns, ASMIT_STA, mIns[i + 0]));
mIns.Remove(i + 0);
sz--;
changed = true;
}
}
}
else if (!mEntryRequiredRegs[a1] && !ReferencesZeroPage(a1, i + 2) && !ChangesZeroPage(a0, i + 2))
{
if (!exitBlock)
return OptimizeSimpleLoopInvariant(proc, full);
if (exitBlock->mNumEntries == 1 && !exitBlock->mEntryRequiredRegs[CPU_REG_Z])
{
if (!exitBlock->mEntryRequiredRegs[CPU_REG_A])
{
mExitRequiredRegs += a0;
exitBlock->mEntryRequiredRegs += a0;
exitBlock->mIns.Insert(0, NativeCodeInstruction(mIns[i + 1].mIns, ASMIT_LDA, mIns[i + 0]));
exitBlock->mIns.Insert(1, NativeCodeInstruction(mIns[i + 1].mIns, ASMIT_STA, mIns[i + 1]));
mIns.Remove(i + 1);
sz--;
changed = true;
}
}
}
}
}
if (sz >= 3 && mIns[0].mType == ASMIT_LDA && mIns[sz - 2].mType == ASMIT_LDA && mIns[0].SameEffectiveAddress(mIns[sz - 2]) && mIns[sz - 1].mType == ASMIT_CMP)
@ -35302,6 +35350,38 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
}
if (sz >= 3 &&
mIns[0].mType == ASMIT_TAY &&
mIns[sz - 1].mType == ASMIT_CPX && mIns[sz - 2].mType == ASMIT_TXA && mIns[sz - 3].mType == ASMIT_INX &&
!mExitRequiredRegs[CPU_REG_Y] &&
!ChangesXReg(0, sz - 3) && !ChangesYReg(1, sz - 3))
{
bool canX = true, canY = false;
for (int i = 0; i < sz - 3; i++)
{
if (mIns[i].mMode == ASMIM_ABSOLUTE_X && !HasAsmInstructionMode(mIns[i].mType, ASMIM_ABSOLUTE_Y))
canY = false;
else if (mIns[i].mMode == ASMIM_ABSOLUTE_Y && !HasAsmInstructionMode(mIns[i].mType, ASMIM_ABSOLUTE_X))
canX = false;
else if (mIns[i].mMode == ASMIM_INDIRECT_Y)
canX = false;
else if (mIns[i].mMode == ASMIM_INDIRECT_X)
canY = false;
}
if (canX)
{
for (int i = 0; i < sz - 3; i++)
{
mIns[i].mLive |= LIVE_CPU_REG_X;
if (mIns[i].mMode == ASMIM_ABSOLUTE_Y)
mIns[i].mMode = ASMIM_ABSOLUTE_X;
}
return true;
}
}
CheckLive();
return changed;
@ -42972,6 +43052,36 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_LDX, mIns[i + 0].mMode) &&
mIns[i + 1].mType == ASMIT_CMP && HasAsmInstructionMode(ASMIT_CPX, mIns[i + 1].mMode) &&
mIns[i + 2].mType == ASMIT_TAX && !(mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)))
{
mIns[i + 0].mType = ASMIT_LDX; mIns[i + 0].mLive |= LIVE_CPU_REG_X;
mIns[i + 1].mType = ASMIT_CPX; mIns[i + 1].mLive |= LIVE_CPU_REG_X;
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_LDY, mIns[i + 0].mMode) &&
mIns[i + 1].mType == ASMIT_CMP && HasAsmInstructionMode(ASMIT_CPY, mIns[i + 1].mMode) &&
mIns[i + 2].mType == ASMIT_TAX && !(mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)))
{
mIns[i + 0].mType = ASMIT_LDY; mIns[i + 0].mLive |= LIVE_CPU_REG_Y;
mIns[i + 1].mType = ASMIT_CPY; mIns[i + 1].mLive |= LIVE_CPU_REG_Y;
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_STX && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 1].mType == ASMIT_LDA && !(mIns[i + 1].ReferencesYReg()) &&
mIns[i + 2].mType == ASMIT_LDY && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress == mIns[i + 0].mAddress && !(mIns[i + 2].mLive & LIVE_MEM))
{
mIns[i + 2] = mIns[i + 1];
mIns[i + 0].mType = ASMIT_TXA; mIns[i + 0].mMode = ASMIM_IMPLIED; mIns[i + 0].mLive |= LIVE_CPU_REG_A;
mIns[i + 1].mType = ASMIT_TAY; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 1].mLive |= LIVE_CPU_REG_Y;
progress = true;
}
if (
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress <= 1 &&
@ -47506,7 +47616,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{
mInterProc = proc;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "story_messages");
CheckFunc = !strcmp(mInterProc->mIdent->mString, "window_mask3");
int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks];