Some peephole loop optimizations
This commit is contained in:
parent
ba1bc29b1a
commit
04d1abd803
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue