strlen optimization

This commit is contained in:
drmortalwombat 2023-06-27 15:34:13 +02:00
parent 8f39d736d5
commit 63ebf6aa7c
3 changed files with 96 additions and 18 deletions

View File

@ -14196,6 +14196,27 @@ bool InterCodeBasicBlock::PeepholeReplaceOptimization(const GrowingVariableArray
mInstructions[i + 0]->mNumOperands = 0; mInstructions[i + 0]->mNumOperands = 0;
changed = true; changed = true;
} }
else if (
mInstructions[i + 0]->mCode == IC_LEA &&
mInstructions[i + 0]->mSrc[0].mTemp >= 0 && mInstructions[i + 0]->mSrc[1].mTemp >= 0 &&
mInstructions[i + 1]->mCode == IC_LOAD &&
mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[0].mFinal &&
mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 2]->mOperator == IA_ADD &&
mInstructions[i + 2]->mSrc[1].mTemp == mInstructions[i + 2]->mDst.mTemp &&
mInstructions[i + 2]->mSrc[1].mTemp == mInstructions[i + 0]->mSrc[0].mTemp &&
mInstructions[i + 2]->mSrc[0].mTemp < 0 &&
mInstructions[i + 2]->mSrc[0].mIntConst == mInstructions[i + 1]->mSrc[0].mIntConst &&
mInstructions[i + 2]->mSrc[1].mTemp != mInstructions[i + 1]->mDst.mTemp)
{
InterInstruction* iadd = mInstructions[i + 2];
mInstructions[i + 2] = mInstructions[i + 1];
mInstructions[i + 1] = mInstructions[i + 0];
mInstructions[i + 0] = iadd;
mInstructions[i + 2]->mSrc[0].mIntConst = 0;
changed = true;
}
#if 1 #if 1
if (i + 2 < mInstructions.Size() && if (i + 2 < mInstructions.Size() &&

View File

@ -16842,6 +16842,28 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
} }
} }
#if 1
if (mIns.Size() >= 4 && mTrueJump && mFalseJump && mTrueJump->mEntryRequiredRegs.Size() > 0 && mFalseJump->mEntryRequiredRegs.Size() > 0)
{
int sz = mIns.Size();
if (mIns[sz - 4].mType == ASMIT_TYA &&
mIns[sz - 3].mType == ASMIT_CLC &&
mIns[sz - 2].mType == ASMIT_ADC && mIns[sz - 2].mMode == ASMIM_IMMEDIATE && mIns[sz - 2].mAddress == 1 &&
mIns[sz - 1].mType == ASMIT_TAY && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A) &&
(mBranch == ASMIT_BCC || mBranch == ASMIT_BCS) &&
!mTrueJump->mEntryRequiredRegs[CPU_REG_C] && !mFalseJump->mEntryRequiredRegs[CPU_REG_C])
{
mIns[sz - 4].mType = ASMIT_INY; mIns[sz - 4].mLive |= LIVE_CPU_REG_Y | LIVE_CPU_REG_Z;
if (mBranch == ASMIT_BCC)
mBranch = ASMIT_BNE;
else
mBranch = ASMIT_BEQ;
mIns.SetSize(sz - 3);
changed = true;
}
}
#endif
if (mIns.Size() >= 2) if (mIns.Size() >= 2)
{ {
int sz = mIns.Size(); int sz = mIns.Size();
@ -21304,7 +21326,7 @@ bool NativeCodeBasicBlock::PatchForwardLowYPointer(const NativeCodeBasicBlock* b
return changed; return changed;
} }
bool NativeCodeBasicBlock::CheckForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, const NativeCodeInstruction& iins, int at, int yval) bool NativeCodeBasicBlock::CheckForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, const NativeCodeInstruction& iins, int at, int yval, int ymax)
{ {
if (!mPatched) if (!mPatched)
{ {
@ -21346,10 +21368,11 @@ bool NativeCodeBasicBlock::CheckForwardSumYPointer(const NativeCodeBasicBlock* b
{ {
if (iins.mMode == ASMIM_IMMEDIATE && yval + iins.mAddress > 255) if (iins.mMode == ASMIM_IMMEDIATE && yval + iins.mAddress > 255)
return false; return false;
if (yval < 0 || yval > 3) if (yval < 0 || yval > ymax)
return false; return false;
else if (!(ins.mLive & LIVE_MEM)) else if (!(ins.mLive & LIVE_MEM))
return true; return true;
if (yval == 0) ymax = 3;
} }
if (ins.mType == ASMIT_LDY && ins.mMode == ASMIM_IMMEDIATE) if (ins.mType == ASMIT_LDY && ins.mMode == ASMIM_IMMEDIATE)
@ -21377,9 +21400,9 @@ bool NativeCodeBasicBlock::CheckForwardSumYPointer(const NativeCodeBasicBlock* b
at++; at++;
} }
if (mTrueJump && !mTrueJump->CheckForwardSumYPointer(block, reg, base, iins, 0, yval)) if (mTrueJump && !mTrueJump->CheckForwardSumYPointer(block, reg, base, iins, 0, yval, ymax))
return false; return false;
if (mFalseJump && !mFalseJump->CheckForwardSumYPointer(block, reg, base, iins, 0, yval)) if (mFalseJump && !mFalseJump->CheckForwardSumYPointer(block, reg, base, iins, 0, yval, ymax))
return false; return false;
} }
@ -38380,7 +38403,7 @@ 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 + 3].mAddress, mIns[i + 1], i + 7, yval)) if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 1], i + 7, yval, 0))
{ {
proc->ResetPatched(); proc->ResetPatched();
if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 1], i + 7, yval)) if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 1], i + 7, yval))
@ -38411,7 +38434,7 @@ 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 + 3].mAddress, mIns[i + 2], i + 7, yval)) if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 2], i + 7, yval, 0))
{ {
proc->ResetPatched(); proc->ResetPatched();
if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 2], i + 7, yval)) if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 2], i + 7, yval))
@ -38432,15 +38455,30 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
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 + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress != mIns[i + 1].mAddress && mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_ZERO_PAGE && mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_ZERO_PAGE && mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 3].mAddress + 1 && mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 3].mAddress + 1 &&
!(mIns[i + 6].mLive & LIVE_CPU_REG_A)) !(mIns[i + 6].mLive & LIVE_CPU_REG_A))
{ {
int yval = RetrieveYValue(i); int yval = RetrieveYValue(i);
bool subs1 = mIns[i + 3].mAddress != mIns[i + 1].mAddress;
bool subs2 = mIns[i + 3].mAddress != mIns[i + 2].mAddress;
if (subs1 && subs2)
{
if (mLoopHead)
{
if (ChangesZeroPage(mIns[i + 1].mAddress))
subs2 = false;
else if (ChangesZeroPage(mIns[i + 2].mAddress))
subs1 = false;
}
}
proc->ResetPatched(); proc->ResetPatched();
if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 1], i + 7, yval)) if (subs1 && CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 1], i + 7, yval, 0))
{ {
proc->ResetPatched(); proc->ResetPatched();
if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 1], i + 7, yval)) if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 1], i + 7, yval))
@ -38456,6 +38494,25 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
if (mFalseJump) if (mFalseJump)
mFalseJump->CheckLive(); mFalseJump->CheckLive();
} }
else if (subs2)
{
proc->ResetPatched();
if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 2], i + 7, yval, 0))
{
proc->ResetPatched();
if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 2], i + 7, yval))
{
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true;
}
if (mTrueJump)
mTrueJump->CheckLive();
if (mFalseJump)
mFalseJump->CheckLive();
}
}
} }
#endif #endif
#if 1 #if 1
@ -38470,7 +38527,7 @@ 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], i + 7, yval)) if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, mIns[i + 2], i + 7, yval, 3))
{ {
proc->ResetPatched(); proc->ResetPatched();
if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, mIns[i + 2], i + 7, yval)) if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, mIns[i + 2], i + 7, yval))
@ -38504,7 +38561,7 @@ 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], i + 7, yval)) if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 2].mAddress, mIns[i + 0], i + 7, yval, 3))
{ {
proc->ResetPatched(); proc->ResetPatched();
if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 2].mAddress, mIns[i + 0], i + 7, yval)) if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 2].mAddress, mIns[i + 0], i + 7, yval))
@ -38537,7 +38594,7 @@ 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 + 3].mAddress, mIns[i + 2], i + 7, yval)) if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 2], i + 7, yval, 3))
{ {
proc->ResetPatched(); proc->ResetPatched();
if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 2], i + 7, yval)) if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 2], i + 7, yval))
@ -38566,7 +38623,7 @@ 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 + 3].mAddress, mIns[i + 2], i + 7, yval)) if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 2], i + 7, yval, 3))
{ {
proc->ResetPatched(); proc->ResetPatched();
if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 2], i + 7, yval)) if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 2], i + 7, yval))
@ -38595,7 +38652,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
int yval = RetrieveYValue(i); int yval = RetrieveYValue(i);
proc->ResetPatched(); proc->ResetPatched();
if (CheckForwardSumYPointer(this, mIns[i + 2].mAddress, mIns[i + 2].mAddress, mIns[i + 1], i + 7, yval)) if (CheckForwardSumYPointer(this, mIns[i + 2].mAddress, mIns[i + 2].mAddress, mIns[i + 1], i + 7, yval, 3))
{ {
proc->ResetPatched(); proc->ResetPatched();
if (PatchForwardSumYPointer(this, mIns[i + 2].mAddress, mIns[i + 2].mAddress, mIns[i + 1], i + 7, yval)) if (PatchForwardSumYPointer(this, mIns[i + 2].mAddress, mIns[i + 2].mAddress, mIns[i + 1], i + 7, yval))
@ -38622,7 +38679,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
{ {
int yval = RetrieveYValue(i); int yval = RetrieveYValue(i);
proc->ResetPatched(); proc->ResetPatched();
if (CheckForwardSumYPointer(this, mIns[i + 2].mAddress, mIns[i + 1].mAddress, mIns[i + 2], i + 6, yval)) if (CheckForwardSumYPointer(this, mIns[i + 2].mAddress, mIns[i + 1].mAddress, mIns[i + 2], i + 6, yval, 0))
{ {
proc->ResetPatched(); proc->ResetPatched();
if (PatchForwardSumYPointer(this, mIns[i + 2].mAddress, mIns[i + 1].mAddress, mIns[i + 2], i + 6, yval)) if (PatchForwardSumYPointer(this, mIns[i + 2].mAddress, mIns[i + 1].mAddress, mIns[i + 2], i + 6, yval))
@ -38650,7 +38707,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
{ {
int yval = RetrieveYValue(i); int yval = RetrieveYValue(i);
proc->ResetPatched(); proc->ResetPatched();
if (CheckForwardSumYPointer(this, mIns[i + 2].mAddress, mIns[i + 1].mAddress, mIns[i + 2], i + 6, yval)) if (CheckForwardSumYPointer(this, mIns[i + 2].mAddress, mIns[i + 1].mAddress, mIns[i + 2], i + 6, yval, 3))
{ {
proc->ResetPatched(); proc->ResetPatched();
if (PatchForwardSumYPointer(this, mIns[i + 2].mAddress, mIns[i + 1].mAddress, mIns[i + 2], i + 6, yval)) if (PatchForwardSumYPointer(this, mIns[i + 2].mAddress, mIns[i + 1].mAddress, mIns[i + 2], i + 6, yval))
@ -38681,7 +38738,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
NativeCodeInstruction iins(mIns[i + 0].mIns, ASMIT_STA, ASMIM_ZERO_PAGE, reg); NativeCodeInstruction iins(mIns[i + 0].mIns, ASMIT_STA, ASMIM_ZERO_PAGE, reg);
proc->ResetPatched(); proc->ResetPatched();
if (CheckForwardSumYPointer(this, mIns[i + 1].mAddress, mIns[i + 1].mAddress, iins, i + 6, yval)) if (CheckForwardSumYPointer(this, mIns[i + 1].mAddress, mIns[i + 1].mAddress, iins, i + 6, yval, 3))
{ {
mIns[i + 0] = iins; mIns[i + 0] = iins;
for (int j = 1; j < 6; j++) for (int j = 1; j < 6; j++)
@ -40035,7 +40092,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{ {
mInterProc = proc; mInterProc = proc;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "Y::Y"); CheckFunc = !strcmp(mInterProc->mIdent->mString, "strlen");
int nblocks = proc->mBlocks.Size(); int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks]; tblocks = new NativeCodeBasicBlock * [nblocks];

View File

@ -603,7 +603,7 @@ public:
// iins : indexing instruction // iins : indexing instruction
// at : start position in block // at : start position in block
// yval: known y immediate value of -1 if not known // yval: known y immediate value of -1 if not known
bool CheckForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, const NativeCodeInstruction & iins, int at, int yval); bool CheckForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, const NativeCodeInstruction & iins, int at, int yval, int ymax);
bool PatchForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, const NativeCodeInstruction & iins, int at, int yval); bool PatchForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, const NativeCodeInstruction & iins, int at, int yval);
// reg : base register pair to replace LSB with zero // reg : base register pair to replace LSB with zero