Additional register allocation step after late inlining

This commit is contained in:
drmortalwombat 2024-07-21 10:40:37 +02:00
parent efd688320f
commit 3dd23ec789
2 changed files with 146 additions and 6 deletions

View File

@ -15287,6 +15287,15 @@ void InterCodeBasicBlock::EliminateDoubleLoopCounter(void)
lc.mInc = ins; lc.mInc = ins;
} }
} }
#if 1
else if (ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_SUB)
{
if (ins->mDst.mTemp == ins->mSrc[1].mTemp && ins->mSrc[0].mTemp < 0)
{
lc.mInc = ins;
}
}
#endif
else if (ins->mCode == IC_LEA && ins->mDst.mTemp == ins->mSrc[1].mTemp && ins->mSrc[0].mTemp < 0) else if (ins->mCode == IC_LEA && ins->mDst.mTemp == ins->mSrc[1].mTemp && ins->mSrc[0].mTemp < 0)
{ {
lc.mInc = ins; lc.mInc = ins;
@ -15308,7 +15317,8 @@ void InterCodeBasicBlock::EliminateDoubleLoopCounter(void)
InterInstruction* ci = eblock->mInstructions[sz - 2]; InterInstruction* ci = eblock->mInstructions[sz - 2];
if (ci->mOperator == IA_CMPEQ && eblock->mFalseJump == this || if (ci->mOperator == IA_CMPEQ && eblock->mFalseJump == this ||
ci->mOperator == IA_CMPNE && eblock->mTrueJump == this) ci->mOperator == IA_CMPNE && eblock->mTrueJump == this ||
ci->mOperator == IA_CMPGU && eblock->mTrueJump == this && ci->mSrc[0].mTemp < 0 && ci->mSrc[0].mIntConst == 0)
{ {
if (ci->mSrc[0].mTemp < 0) if (ci->mSrc[0].mTemp < 0)
lc.mEnd = ci->mSrc[0].mIntConst; lc.mEnd = ci->mSrc[0].mIntConst;
@ -15364,6 +15374,9 @@ void InterCodeBasicBlock::EliminateDoubleLoopCounter(void)
int64 end = lcs[k].mEnd; int64 end = lcs[k].mEnd;
int64 step = lcs[k].mStep; int64 step = lcs[k].mStep;
if (lcs[k].mInc->mCode == IC_BINARY_OPERATOR && lcs[k].mInc->mOperator == IA_SUB)
step = -step;
if (step > 0 && end > start || step < 0 && end < start) if (step > 0 && end > start || step < 0 && end < start)
loop = (end - start) / step; loop = (end - start) / step;
} }
@ -15397,10 +15410,16 @@ void InterCodeBasicBlock::EliminateDoubleLoopCounter(void)
lcs[k].mCmp->mSrc[ti] = lcs[j].mInc->mDst; lcs[k].mCmp->mSrc[ti] = lcs[j].mInc->mDst;
lcs[k].mCmp->mSrc[ci] = lcs[j].mInit->mConst; lcs[k].mCmp->mSrc[ci] = lcs[j].mInit->mConst;
lcs[k].mCmp->mSrc[ci].mIntConst += loop * lcs[j].mStep; lcs[k].mCmp->mSrc[ci].mIntConst += loop * lcs[j].mStep;
if (lcs[k].mCmp->mOperator == IA_CMPGU)
lcs[k].mCmp->mOperator = IA_CMPNE;
InterInstruction* iins = lcs[k].mInit->Clone();
iins->mConst.mIntConst += loop * lcs[k].mStep;
mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, iins);
lcs[k].mInc->mCode = IC_NONE; lcs[k].mInc->mCode = IC_NONE;
lcs[k].mInc->mNumOperands = 0; lcs[k].mInc->mNumOperands = 0;
lcs[k].mInit->mConst.mIntConst += loop * lcs[k].mStep;
} }
} }
} }

View File

@ -34056,6 +34056,14 @@ bool NativeCodeBasicBlock::IndexXYValueForwarding(int xreg, int xoffset, int xva
else else
xoffset = 0; xoffset = 0;
} }
else if (i + 1 < mIns.Size() && mIns[i].mAddress == yreg && yoffset == 0 &&
mIns[i + 1].mType == ASMIT_LDY && mIns[i + 1].mMode && ASMIM_ABSOLUTE_X && !(mIns[i].mLive & LIVE_CPU_REG_A))
{
mIns[i] = NativeCodeInstruction(mIns[i + 1].mIns, ASMIT_LDA, mIns[i + 1]);
mIns[i].mMode = ASMIM_ABSOLUTE_Y;
mIns[i + 1].mType = ASMIT_TAY; mIns[i + 1].mMode = ASMIM_IMPLIED;
changed = true;
}
else else
{ {
xreg = mIns[i].mAddress; xreg = mIns[i].mAddress;
@ -34099,6 +34107,22 @@ bool NativeCodeBasicBlock::IndexXYValueForwarding(int xreg, int xoffset, int xva
else else
yreg = -1; yreg = -1;
} }
else if (mIns[i].mType == ASMIT_STY && mIns[i].mMode == ASMIM_ZERO_PAGE && yreg == -1)
{
if (xreg >= 0 && mIns[i].ChangesZeroPage(xreg))
xreg = -1;
yreg = mIns[i].mAddress;
yoffset = 0;
yvalue = GlobalValueNumber++;
}
else if (mIns[i].mType == ASMIT_STX && mIns[i].mMode == ASMIM_ZERO_PAGE && xreg == -1)
{
if (yreg >= 0 && mIns[i].ChangesZeroPage(yreg))
yreg = -1;
xreg = mIns[i].mAddress;
xoffset = 0;
xvalue = GlobalValueNumber++;
}
else if (i + 2 < mIns.Size() && else if (i + 2 < mIns.Size() &&
mIns[i].mType == ASMIT_CLC && mIns[i].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 &&
@ -34131,6 +34155,22 @@ bool NativeCodeBasicBlock::IndexXYValueForwarding(int xreg, int xoffset, int xva
i += 3; i += 3;
} }
} }
else if (i + 2 < mIns.Size() &&
mIns[i].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_ADC, mIns[i].mMode) &&
mIns[i + 1].mType == ASMIT_CLC &&
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_ZERO_PAGE)
{
if (yreg == mIns[i + 2].mAddress && yoffset == 0)
{
mIns[i + 2].CopyMode(mIns[i]);
mIns[i].mType = ASMIT_TYA; mIns[i].mMode = ASMIM_IMPLIED;
}
else if (xreg == mIns[i + 2].mAddress && xoffset == 0)
{
mIns[i + 2].CopyMode(mIns[i]);
mIns[i].mType = ASMIT_TXA; mIns[i].mMode = ASMIM_IMPLIED;
}
}
else else
{ {
if (mIns[i].ChangesXReg()) if (mIns[i].ChangesXReg())
@ -35791,6 +35831,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
mExitRequiredRegs += CPU_REG_A; mExitRequiredRegs += CPU_REG_A;
prevBlock->mExitRequiredRegs += CPU_REG_A; prevBlock->mExitRequiredRegs += CPU_REG_A;
prevBlock->CheckLive();
CheckLive(); CheckLive();
return true; return true;
@ -35808,6 +35849,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
mExitRequiredRegs += CPU_REG_A; mExitRequiredRegs += CPU_REG_A;
prevBlock->mExitRequiredRegs += CPU_REG_A; prevBlock->mExitRequiredRegs += CPU_REG_A;
prevBlock->CheckLive();
CheckLive(); CheckLive();
return true; return true;
@ -35829,6 +35871,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
mEntryRequiredRegs += CPU_REG_Y; mEntryRequiredRegs += CPU_REG_Y;
prevBlock->mExitRequiredRegs += CPU_REG_Y; prevBlock->mExitRequiredRegs += CPU_REG_Y;
prevBlock->CheckLive();
CheckLive(); CheckLive();
return true; return true;
@ -35848,6 +35891,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
mEntryRequiredRegs += CPU_REG_Y; mEntryRequiredRegs += CPU_REG_Y;
prevBlock->mExitRequiredRegs += CPU_REG_Y; prevBlock->mExitRequiredRegs += CPU_REG_Y;
prevBlock->CheckLive();
CheckLive(); CheckLive();
return true; return true;
@ -35869,6 +35913,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
mEntryRequiredRegs += CPU_REG_X; mEntryRequiredRegs += CPU_REG_X;
prevBlock->mExitRequiredRegs += CPU_REG_X; prevBlock->mExitRequiredRegs += CPU_REG_X;
prevBlock->CheckLive();
CheckLive(); CheckLive();
return true; return true;
@ -35911,6 +35956,8 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
i++; i++;
} }
if (prevBlock->mExitRequiredRegs[CPU_REG_C])
mIns[si].mLive |= LIVE_CPU_REG_C;
prevBlock->mIns.Push(mIns[si]); prevBlock->mIns.Push(mIns[si]);
mIns.Remove(si); mIns.Remove(si);
@ -35918,6 +35965,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
mExitRequiredRegs += CPU_REG_Y; mExitRequiredRegs += CPU_REG_Y;
CheckLive(); CheckLive();
prevBlock->CheckLive();
return true; return true;
} }
@ -35982,6 +36030,8 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
i++; i++;
} }
if (prevBlock->mExitRequiredRegs[CPU_REG_C])
mIns[si].mLive |= LIVE_CPU_REG_C;
prevBlock->mIns.Push(mIns[si]); prevBlock->mIns.Push(mIns[si]);
mIns.Remove(si); mIns.Remove(si);
@ -35990,6 +36040,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
mExitRequiredRegs += CPU_REG_X; mExitRequiredRegs += CPU_REG_X;
CheckLive(); CheckLive();
prevBlock->CheckLive();
return true; return true;
} }
@ -36045,6 +36096,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
mExitRequiredRegs += CPU_REG_X; mExitRequiredRegs += CPU_REG_X;
CheckLive(); CheckLive();
prevBlock->CheckLive();
return true; return true;
} }
@ -36080,6 +36132,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
mExitRequiredRegs += CPU_REG_X; mExitRequiredRegs += CPU_REG_X;
CheckLive(); CheckLive();
prevBlock->CheckLive();
return true; return true;
} }
@ -36155,6 +36208,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
prevBlock->mExitRequiredRegs += CPU_REG_X; prevBlock->mExitRequiredRegs += CPU_REG_X;
exitBlock->mEntryRequiredRegs += CPU_REG_X; exitBlock->mEntryRequiredRegs += CPU_REG_X;
prevBlock->CheckLive();
CheckLive(); CheckLive();
return true; return true;
} }
@ -36226,6 +36280,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
mExitRequiredRegs += CPU_REG_A; mExitRequiredRegs += CPU_REG_A;
prevBlock->mExitRequiredRegs += CPU_REG_A; prevBlock->mExitRequiredRegs += CPU_REG_A;
prevBlock->CheckLive();
CheckLive(); CheckLive();
return true; return true;
@ -36274,6 +36329,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
mExitRequiredRegs += CPU_REG_A; mExitRequiredRegs += CPU_REG_A;
prevBlock->mExitRequiredRegs += CPU_REG_A; prevBlock->mExitRequiredRegs += CPU_REG_A;
prevBlock->CheckLive();
CheckLive(); CheckLive();
return true; return true;
@ -36331,6 +36387,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
mExitRequiredRegs += CPU_REG_A; mExitRequiredRegs += CPU_REG_A;
prevBlock->mExitRequiredRegs += CPU_REG_A; prevBlock->mExitRequiredRegs += CPU_REG_A;
prevBlock->CheckLive();
CheckLive(); CheckLive();
return true; return true;
@ -36383,6 +36440,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
mEntryRequiredRegs += CPU_REG_Y; mEntryRequiredRegs += CPU_REG_Y;
mExitRequiredRegs += CPU_REG_Y; mExitRequiredRegs += CPU_REG_Y;
prevBlock->CheckLive();
CheckLive(); CheckLive();
return true; return true;
@ -36414,6 +36472,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
mExitRequiredRegs += CPU_REG_X; mExitRequiredRegs += CPU_REG_X;
prevBlock->mExitRequiredRegs += CPU_REG_X; prevBlock->mExitRequiredRegs += CPU_REG_X;
prevBlock->CheckLive();
CheckLive(); CheckLive();
return true; return true;
@ -36463,6 +36522,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
mIns.Remove(i + 1); mIns.Remove(i + 1);
mIns.Remove(0); mIns.Remove(0); mIns.Remove(0); mIns.Remove(0);
prevBlock->CheckLive();
CheckLive(); CheckLive();
return true; return true;
@ -42632,6 +42692,18 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerIterate2(int i, int pass)
mIns[i + 1].mType = ASMIT_LSR; mIns[i + 1].mType = ASMIT_LSR;
return true; return true;
} }
else if (mIns[i].mType == ASMIT_SEC && mIns[i + 1].mType == ASMIT_SBC && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0x80 && !(mIns[i + 1].mLive & LIVE_CPU_REG_C))
{
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
mIns[i + 1].mType = ASMIT_EOR;
return true;
}
else if (mIns[i].mType == ASMIT_CLC && mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0x80 && !(mIns[i + 1].mLive & LIVE_CPU_REG_C))
{
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
mIns[i + 1].mType = ASMIT_EOR;
return true;
}
else if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_IMMEDIATE && mIns[i].mAddress == 0 && mIns[i + 1].mType == ASMIT_LSR && mIns[i + 1].mMode == ASMIM_IMPLIED) else if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_IMMEDIATE && mIns[i].mAddress == 0 && mIns[i + 1].mType == ASMIT_LSR && mIns[i + 1].mMode == ASMIM_IMPLIED)
{ {
mIns[i + 1].mType = ASMIT_CLC; mIns[i + 1].mType = ASMIT_CLC;
@ -47748,6 +47820,55 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerIterateN(int i, int pass)
return true; return true;
} }
if (i + 9 < mIns.Size() &&
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ABSOLUTE_X &&
mIns[i + 1].mType == ASMIT_LSR && mIns[i + 1].mMode == ASMIM_IMPLIED &&
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 3].mType == ASMIT_LDA && mIns[i + 3].mMode == ASMIM_ABSOLUTE_X && !mIns[i + 3].SameEffectiveAddress(mIns[i + 0]) &&
mIns[i + 4].mType == ASMIT_ROR && mIns[i + 4].mMode == ASMIM_IMPLIED &&
mIns[i + 5].mType == ASMIT_LSR && mIns[i + 5].SameEffectiveAddress(mIns[i + 2]) &&
mIns[i + 6].mType == ASMIT_ROR && mIns[i + 4].mMode == ASMIM_IMPLIED &&
mIns[i + 7].mType == ASMIT_STA && mIns[i + 7].SameEffectiveAddress(mIns[i + 3]) &&
mIns[i + 8].mType == ASMIT_LDA && mIns[i + 8].SameEffectiveAddress(mIns[i + 2]) && !(mIns[i + 8].mLive & LIVE_MEM) &&
mIns[i + 9].mType == ASMIT_STA && mIns[i + 9].SameEffectiveAddress(mIns[i + 0]) && !(mIns[i + 9].mLive & LIVE_CPU_REG_A))
{
mIns[i + 0].mType = ASMIT_LSR; mIns[i + 0].mLive |= LIVE_CPU_REG_C;
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
mIns[i + 3].mType = ASMIT_ROR;
mIns[i + 4].mType = ASMIT_NOP; mIns[i + 4].mMode = ASMIM_IMPLIED;
mIns[i + 5].CopyMode(mIns[i + 0]);
mIns[i + 6].mType = ASMIT_NOP; mIns[i + 6].mMode = ASMIM_IMPLIED;
mIns[i + 7].mType = ASMIT_ROR;
mIns[i + 8].mType = ASMIT_NOP; mIns[i + 8].mMode = ASMIM_IMPLIED;
mIns[i + 9].mType = ASMIT_NOP; mIns[i + 9].mMode = ASMIM_IMPLIED;
return true;
}
if (i + 9 < mIns.Size() &&
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ABSOLUTE_X &&
mIns[i + 1].mType == ASMIT_ASL && mIns[i + 1].mMode == ASMIM_IMPLIED &&
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 3].mType == ASMIT_LDA && mIns[i + 3].mMode == ASMIM_ABSOLUTE_X && !mIns[i + 3].SameEffectiveAddress(mIns[i + 0]) &&
mIns[i + 4].mType == ASMIT_ROL && mIns[i + 4].mMode == ASMIM_IMPLIED &&
mIns[i + 5].mType == ASMIT_ASL && mIns[i + 5].SameEffectiveAddress(mIns[i + 2]) &&
mIns[i + 6].mType == ASMIT_ROL && mIns[i + 4].mMode == ASMIM_IMPLIED &&
mIns[i + 7].mType == ASMIT_STA && mIns[i + 7].SameEffectiveAddress(mIns[i + 3]) &&
mIns[i + 8].mType == ASMIT_LDA && mIns[i + 8].SameEffectiveAddress(mIns[i + 2]) && !(mIns[i + 8].mLive & LIVE_MEM) &&
mIns[i + 9].mType == ASMIT_STA && mIns[i + 9].SameEffectiveAddress(mIns[i + 0]) && !(mIns[i + 9].mLive & LIVE_CPU_REG_A))
{
mIns[i + 0].mType = ASMIT_ASL; mIns[i + 0].mLive |= LIVE_CPU_REG_C;
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
mIns[i + 3].mType = ASMIT_ROL;
mIns[i + 4].mType = ASMIT_NOP; mIns[i + 4].mMode = ASMIM_IMPLIED;
mIns[i + 5].CopyMode(mIns[i + 0]);
mIns[i + 6].mType = ASMIT_NOP; mIns[i + 6].mMode = ASMIM_IMPLIED;
mIns[i + 7].mType = ASMIT_ROL;
mIns[i + 8].mType = ASMIT_NOP; mIns[i + 8].mMode = ASMIM_IMPLIED;
mIns[i + 9].mType = ASMIT_NOP; mIns[i + 9].mMode = ASMIM_IMPLIED;
return true;
}
return false; return false;
} }
@ -49897,7 +50018,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
mInterProc = proc; mInterProc = proc;
mInterProc->mLinkerObject->mNativeProc = this; mInterProc->mLinkerObject->mNativeProc = this;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "binlog"); CheckFunc = !strcmp(mInterProc->mIdent->mString, "main");
int nblocks = proc->mBlocks.Size(); int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks]; tblocks = new NativeCodeBasicBlock * [nblocks];
@ -50696,7 +50817,7 @@ void NativeCodeProcedure::Optimize(void)
mEntryBlock->LocalZeroPageValueNumbering(); mEntryBlock->LocalZeroPageValueNumbering();
} }
if (step == 9) if (step == 9 || step == 16)
{ {
ResetVisited(); ResetVisited();
if (mEntryBlock->IndexXYValueForwarding(-1, 0, 0, -1, 0, 0)) if (mEntryBlock->IndexXYValueForwarding(-1, 0, 0, -1, 0, 0))
@ -51074,7 +51195,7 @@ void NativeCodeProcedure::Optimize(void)
} }
#if 1 #if 1
if (!changed && (step == 5 || step == 6)) if (!changed && (step == 5 || step == 6 || step == 19))
{ {
#if 1 #if 1
@ -51597,7 +51718,7 @@ void NativeCodeProcedure::Optimize(void)
} }
#if 1 #if 1
if (!changed && step < 18) if (!changed && step < 19)
{ {
ResetIndexFlipped(); ResetIndexFlipped();