Loop MSB optimizations

This commit is contained in:
drmortalwombat 2022-03-22 22:21:59 +01:00
parent 8c77a5d256
commit 5f0e0225e1
6 changed files with 254 additions and 31 deletions

View File

@ -8379,6 +8379,7 @@ void InterCodeBasicBlock::PeepholeOptimization(void)
} }
mInstructions.SetSize(j); mInstructions.SetSize(j);
// shorten lifespan // shorten lifespan
int loopTmp = -1; int loopTmp = -1;
@ -8387,6 +8388,33 @@ void InterCodeBasicBlock::PeepholeOptimization(void)
if (limit >= 0 && mInstructions[limit]->mCode == IC_BRANCH) if (limit >= 0 && mInstructions[limit]->mCode == IC_BRANCH)
{ {
limit--; limit--;
#if 1
// try to move conditional source down
int i = limit;
while (i >= 0 && mInstructions[i]->mDst.mTemp != mInstructions[limit + 1]->mSrc[0].mTemp)
i--;
if (i >= 0 && i != limit)
{
InterInstruction* ins(mInstructions[i]);
if (ins->mCode == IC_BINARY_OPERATOR || ins->mCode == IC_RELATIONAL_OPERATOR)
{
if (ins->mSrc[0].mTemp < 0)
{
int k = i;
while (k < limit && CanBypass(ins, mInstructions[k + 1]))
k++;
if (k == limit)
{
mInstructions.Remove(i);
mInstructions.Insert(limit, ins);
}
}
}
}
#endif
if (limit > 0 && mInstructions[limit]->mCode == IC_RELATIONAL_OPERATOR) if (limit > 0 && mInstructions[limit]->mCode == IC_RELATIONAL_OPERATOR)
{ {
if (mInstructions[limit]->mSrc[1].mTemp) if (mInstructions[limit]->mSrc[1].mTemp)
@ -8417,6 +8445,8 @@ void InterCodeBasicBlock::PeepholeOptimization(void)
limit--; limit--;
} }
} }
else if (limit > 0 && mInstructions[limit]->mDst.mTemp == mInstructions[limit + 1]->mSrc[0].mTemp)
limit--;
} }
else if (limit >= 0 && mInstructions[limit]->mCode == IC_JUMP) else if (limit >= 0 && mInstructions[limit]->mCode == IC_JUMP)
limit --; limit --;

View File

@ -129,7 +129,7 @@ void NativeRegisterDataSet::Intersect(const NativeRegisterDataSet& set)
} }
else if (mRegs[i].mMode == NRDM_ABSOLUTE) else if (mRegs[i].mMode == NRDM_ABSOLUTE)
{ {
if (set.mRegs[i].mMode != NRDM_ABSOLUTE || mRegs[i].mValue != set.mRegs[i].mValue) if (set.mRegs[i].mMode != NRDM_ABSOLUTE || mRegs[i].mValue != set.mRegs[i].mValue || mRegs[i].mLinkerObject != set.mRegs[i].mLinkerObject)
{ {
mRegs[i].Reset(); mRegs[i].Reset();
changed = true; changed = true;
@ -9485,7 +9485,7 @@ bool NativeCodeBasicBlock::ReduceLocalYPressure(void)
return changed; return changed;
} }
bool NativeCodeBasicBlock::ForwardZpYIndex(void) bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
{ {
bool changed = false; bool changed = false;
@ -9588,6 +9588,18 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(void)
mIns[i + 1].mType = ASMIT_STY; mIns[i + 1].mType = ASMIT_STY;
changed = true; changed = true;
} }
else if (i + 2 < mIns.Size() && full &&
mIns[i + 0].mType == ASMIT_INC && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == yreg &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == yreg && yoffset == 0 && !(mIns[i + 1].mLive & LIVE_CPU_REG_Y))
{
for (int j = ypred; j < i; j++)
mIns[j].mLive |= LIVE_CPU_REG_Y;
mIns.Insert(i, NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns[i + 1].mType = ASMIT_STY; mIns[i + 1].mLive |= LIVE_CPU_REG_Y;
mIns[i + 2].mType = ASMIT_TYA; mIns[i + 2].mMode = ASMIM_IMPLIED;
yreg = -1;
changed = true;
}
else if (mIns[i].mType == ASMIT_INY) else if (mIns[i].mType == ASMIT_INY)
{ {
yoffset = (yoffset + 1) & 255; yoffset = (yoffset + 1) & 255;
@ -9621,17 +9633,17 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(void)
} }
} }
if (mTrueJump && mTrueJump->ForwardZpYIndex()) if (mTrueJump && mTrueJump->ForwardZpYIndex(full))
changed = true; changed = true;
if (mFalseJump && mFalseJump->ForwardZpYIndex()) if (mFalseJump && mFalseJump->ForwardZpYIndex(full))
changed = true; changed = true;
} }
return changed; return changed;
} }
bool NativeCodeBasicBlock::ForwardZpXIndex(void) bool NativeCodeBasicBlock::ForwardZpXIndex(bool full)
{ {
bool changed = false; bool changed = false;
@ -9752,10 +9764,10 @@ bool NativeCodeBasicBlock::ForwardZpXIndex(void)
} }
} }
if (mTrueJump && mTrueJump->ForwardZpXIndex()) if (mTrueJump && mTrueJump->ForwardZpXIndex(full))
changed = true; changed = true;
if (mFalseJump && mFalseJump->ForwardZpXIndex()) if (mFalseJump && mFalseJump->ForwardZpXIndex(full))
changed = true; changed = true;
} }
@ -12815,6 +12827,65 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
return lblock->OptimizeSimpleLoopInvariant(proc, this, eblock); return lblock->OptimizeSimpleLoopInvariant(proc, this, eblock);
} }
bool NativeCodeBasicBlock::RemoveSimpleLoopUnusedIndex(void)
{
bool changed = false;
if (!mVisited)
{
mVisited = true;
if (mFalseJump && mTrueJump == this)
{
NumberSet required(mFalseJump->mEntryRequiredRegs);
bool complex = false;
int k = mIns.Size() - 1;
while (k >= 0)
{
if (mIns[k].mType == ASMIT_STA && mIns[k].mMode == ASMIM_ZERO_PAGE && !(mIns[k].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_CPU_REG_Z)) && !required[mIns[k].mAddress])
{
if (k > 2 && mIns[k - 1].mMode == ASMIM_IMMEDIATE && mIns[k - 2].mType == ASMIT_LDA && mIns[k - 2].mMode == ASMIM_ZERO_PAGE && mIns[k - 2].mAddress == mIns[k].mAddress)
k -= 2;
}
else if (mIns[k].mMode == ASMIM_ZERO_PAGE)
required += mIns[k].mAddress;
else if (mIns[k].mMode == ASMIM_INDIRECT_Y)
{
required += mIns[k].mAddress;
required += mIns[k].mAddress + 1;
}
else if (mIns[k].mType == ASMIT_JSR)
complex = true;
k--;
}
if (!complex)
{
for (int i = 0; i < mIns.Size(); i++)
{
if (mIns[i].mType == ASMIT_STA && mIns[i].mMode == ASMIM_ZERO_PAGE && !required[mIns[i].mAddress])
{
mIns[i].mType = ASMIT_NOP;
mIns[i].mMode = ASMIM_IMPLIED;
changed = true;
}
}
}
}
if (mTrueJump && mTrueJump->RemoveSimpleLoopUnusedIndex())
changed = true;
if (mFalseJump && mFalseJump->RemoveSimpleLoopUnusedIndex())
changed = true;
}
return changed;
}
bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock* prevBlock, NativeCodeBasicBlock* exitBlock) bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock* prevBlock, NativeCodeBasicBlock* exitBlock)
{ {
bool changed = false; bool changed = false;
@ -14747,11 +14818,55 @@ void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc)
} }
mIns.SetSize(j); mIns.SetSize(j);
#if 1 #if 1
bool yimm = false, ximm = false; bool yimm = false, ximm = false, aimm = false, afail = false;
int yval = 0, xval = 0; int yval = 0, xval = 0, aval = 0;
for(int i = 0; i < mIns.Size(); i++) for(int i = 0; i < mIns.Size(); i++)
{ {
if (mIns[i].mType == ASMIT_LDY) if (afail)
aimm = false;
if (mIns[i].mType == ASMIT_LDA)
{
if (mIns[i].mMode == ASMIM_IMMEDIATE)
{
if (yimm && mIns[i].mAddress == yval)
{
mIns[i].mType = ASMIT_TYA;
mIns[i].mMode = ASMIM_IMPLIED;
}
else if (ximm && mIns[i].mAddress == xval)
{
mIns[i].mType = ASMIT_TXA;
mIns[i].mMode = ASMIM_IMPLIED;
}
aimm = true;
aval = mIns[i].mAddress;
}
else
aimm = false;
}
else if (mIns[i].mType == ASMIT_TYA)
{
if (yimm)
{
aimm = true;
aval = yval;
}
else
aimm = false;
}
else if (mIns[i].mType == ASMIT_TXA)
{
if (ximm)
{
aimm = true;
aval = xval;
}
else
aimm = false;
}
else if (mIns[i].mType == ASMIT_LDY)
{ {
if (mIns[i].mMode == ASMIM_IMMEDIATE) if (mIns[i].mMode == ASMIM_IMMEDIATE)
{ {
@ -14767,6 +14882,13 @@ void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc)
mIns[i].mType = ASMIT_DEY; mIns[i].mType = ASMIT_DEY;
mIns[i].mMode = ASMIM_IMPLIED; mIns[i].mMode = ASMIM_IMPLIED;
} }
else if (aimm && mIns[i].mAddress == aval)
{
mIns[i].mType = ASMIT_TAY;
mIns[i].mMode = ASMIM_IMPLIED;
yimm = true;
yval = aval;
}
else else
{ {
yimm = true; yimm = true;
@ -14786,7 +14908,15 @@ void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc)
yval = (yval - 1) & 0xff; yval = (yval - 1) & 0xff;
} }
else if (mIns[i].mType == ASMIT_TAY) else if (mIns[i].mType == ASMIT_TAY)
{
if (aimm)
{
yimm = true;
yval = aval;
}
else
yimm = false; yimm = false;
}
else if (mIns[i].mType == ASMIT_LDX) else if (mIns[i].mType == ASMIT_LDX)
{ {
if (mIns[i].mMode == ASMIM_IMMEDIATE) if (mIns[i].mMode == ASMIM_IMMEDIATE)
@ -14803,6 +14933,13 @@ void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc)
mIns[i].mType = ASMIT_DEX; mIns[i].mType = ASMIT_DEX;
mIns[i].mMode = ASMIM_IMPLIED; mIns[i].mMode = ASMIM_IMPLIED;
} }
else if (aimm && mIns[i].mAddress == aval)
{
mIns[i].mType = ASMIT_TAX;
mIns[i].mMode = ASMIM_IMPLIED;
ximm = true;
xval = aval;
}
else else
{ {
ximm = true; ximm = true;
@ -14822,11 +14959,26 @@ void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc)
xval = (xval - 1) & 0xff; xval = (xval - 1) & 0xff;
} }
else if (mIns[i].mType == ASMIT_TAX) else if (mIns[i].mType == ASMIT_TAX)
{
if (aimm)
{
ximm = true;
xval = aval;
}
else
ximm = false; ximm = false;
}
else if (mIns[i].mType == ASMIT_JSR) else if (mIns[i].mType == ASMIT_JSR)
yimm = ximm = false; yimm = ximm = aimm = false;
else if (mIns[i].mMode == ASMIM_RELATIVE && mIns[i].mAddress < 0) else if (mIns[i].mMode == ASMIM_RELATIVE)
yimm = ximm = false; {
if (mIns[i].mAddress < 0)
yimm = ximm = aimm = false;
else
afail = true;
}
else if (mIns[i].ChangesAccu())
aimm = false;
} }
#endif #endif
@ -15617,6 +15769,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
} }
#endif #endif
#if 1
bool progress = false; bool progress = false;
do { do {
progress = false; progress = false;
@ -15674,7 +15827,32 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
changed = true; changed = true;
} }
} }
#if 1
if (sz > 2 &&
mIns[sz - 3].mType == ASMIT_STA &&
mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_IMMEDIATE &&
mIns[sz - 1].mType == ASMIT_CMP && mIns[sz - 1].SameEffectiveAddress(mIns[sz - 3]) && !(mIns[sz - 1].mLive & (LIVE_CPU_REG_Z | LIVE_CPU_REG_A)))
{
if (mBranch == ASMIT_BCC && mIns[sz - 2].mAddress < 0xff)
{
mIns[sz - 3].mLive |= LIVE_CPU_REG_A;
mIns[sz - 1].mMode = ASMIM_IMMEDIATE;
mIns[sz - 1].mAddress = mIns[sz - 2].mAddress + 1;
mIns[sz - 2].mType = ASMIT_NOP; mIns[sz - 2].mMode = ASMIM_IMPLIED;
mBranch = ASMIT_BCS;
changed = true;
}
else if (mBranch == ASMIT_BCS && mIns[sz - 2].mAddress < 0xff)
{
mIns[sz - 3].mLive |= LIVE_CPU_REG_A;
mIns[sz - 1].mMode = ASMIM_IMMEDIATE;
mIns[sz - 1].mAddress = mIns[sz - 2].mAddress + 1;
mIns[sz - 2].mType = ASMIT_NOP; mIns[sz - 2].mMode = ASMIM_IMPLIED;
mBranch = ASMIT_BCC;
changed = true;
}
}
#endif
for (int i = 0; i < mIns.Size(); i++) for (int i = 0; i < mIns.Size(); i++)
{ {
#if 1 #if 1
@ -16537,15 +16715,18 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 2].mType = ASMIT_CLC; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mType = ASMIT_CLC; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true; progress = true;
} }
#if 1
else if ( else if (
mIns[i + 0].ChangesAccuAndFlag() && mIns[i + 0].ChangesAccuAndFlag() &&
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mType == ASMIT_STA &&
mIns[i + 2].mType == ASMIT_ORA && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 0) mIns[i + 2].mType == ASMIT_ORA && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 0)
{ {
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
mIns[i + 0].mLive |= mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z);
mIns[i + 1].mLive |= mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z); mIns[i + 1].mLive |= mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z);
progress = true; progress = true;
} }
#endif
else if ( else if (
mIns[i + 0].ChangesAccuAndFlag() && mIns[i + 0].ChangesAccuAndFlag() &&
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mType == ASMIT_STA &&
@ -17987,6 +18168,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
} }
} }
#endif #endif
#if 1
if (i + 1 < mIns.Size()) if (i + 1 < mIns.Size())
{ {
if ( if (
@ -18014,7 +18196,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
} }
} }
} }
#endif
if (i + 5 < mIns.Size()) if (i + 5 < mIns.Size())
{ {
if ( if (
@ -18404,6 +18586,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
} while (progress); } while (progress);
#endif
if (this->mTrueJump && this->mTrueJump->PeepHoleOptimizer(proc, pass)) if (this->mTrueJump && this->mTrueJump->PeepHoleOptimizer(proc, pass))
changed = true; changed = true;
@ -19431,7 +19614,14 @@ void NativeCodeProcedure::Optimize(void)
{ {
changed = true; changed = true;
} }
#if 1
if (step == 3)
{
ResetVisited();
if (mEntryBlock->RemoveSimpleLoopUnusedIndex())
changed = true;
}
#endif
if (step > 0) if (step > 0)
{ {
ResetVisited(); ResetVisited();
@ -19471,11 +19661,13 @@ void NativeCodeProcedure::Optimize(void)
if (step == 3) if (step == 3)
{ {
ResetVisited(); ResetVisited();
changed = mEntryBlock->OptimizeInnerLoops(this); if (mEntryBlock->OptimizeInnerLoops(this))
changed = true;
ResetVisited(); ResetVisited();
if (mEntryBlock->ReduceLocalYPressure()) if (mEntryBlock->ReduceLocalYPressure())
changed = true; changed = true;
} }
#endif #endif
#if 1 #if 1
@ -19577,11 +19769,11 @@ void NativeCodeProcedure::Optimize(void)
#if 1 #if 1
ResetVisited(); ResetVisited();
if (mEntryBlock->ForwardZpYIndex()) if (mEntryBlock->ForwardZpYIndex(step >= 4))
changed = true; changed = true;
ResetVisited(); ResetVisited();
if (mEntryBlock->ForwardZpXIndex()) if (mEntryBlock->ForwardZpXIndex(step >= 4))
changed = true; changed = true;
#endif #endif
if (!changed && step < 6) if (!changed && step < 6)

View File

@ -164,6 +164,7 @@ public:
bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc); bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc);
bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock * prevBlock, NativeCodeBasicBlock* exitBlock); bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock * prevBlock, NativeCodeBasicBlock* exitBlock);
bool RemoveSimpleLoopUnusedIndex(void);
bool OptimizeSimpleLoop(NativeCodeProcedure* proc); bool OptimizeSimpleLoop(NativeCodeProcedure* proc);
bool SimpleLoopReversal(NativeCodeProcedure* proc); bool SimpleLoopReversal(NativeCodeProcedure* proc);
@ -257,8 +258,8 @@ public:
bool ReplaceYRegWithXReg(int start, int end); bool ReplaceYRegWithXReg(int start, int end);
bool ReplaceXRegWithYReg(int start, int end); bool ReplaceXRegWithYReg(int start, int end);
bool ForwardZpYIndex(void); bool ForwardZpYIndex(bool full);
bool ForwardZpXIndex(void); bool ForwardZpXIndex(bool full);
bool FindImmediateStore(int at, int reg, const NativeCodeInstruction*& ains); bool FindImmediateStore(int at, int reg, const NativeCodeInstruction*& ains);

View File

@ -73,7 +73,7 @@ int main2(int argc, const char** argv)
#else #else
strcpy(strProductName, "oscar64"); strcpy(strProductName, "oscar64");
strcpy(strProductVersion, "1.5.104"); strcpy(strProductVersion, "1.5.105");
#ifdef __APPLE__ #ifdef __APPLE__
uint32_t length = sizeof(basePath); uint32_t length = sizeof(basePath);

View File

@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,5,104,0 FILEVERSION 1,5,105,0
PRODUCTVERSION 1,5,104,0 PRODUCTVERSION 1,5,105,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -43,12 +43,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "oscar64" VALUE "CompanyName", "oscar64"
VALUE "FileDescription", "oscar64 compiler" VALUE "FileDescription", "oscar64 compiler"
VALUE "FileVersion", "1.5.104.0" VALUE "FileVersion", "1.5.105.0"
VALUE "InternalName", "oscar64.exe" VALUE "InternalName", "oscar64.exe"
VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "LegalCopyright", "Copyright (C) 2021"
VALUE "OriginalFilename", "oscar64.exe" VALUE "OriginalFilename", "oscar64.exe"
VALUE "ProductName", "oscar64" VALUE "ProductName", "oscar64"
VALUE "ProductVersion", "1.5.104.0" VALUE "ProductVersion", "1.5.105.0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -3945,15 +3945,15 @@
{ {
"Name" = "8:Microsoft Visual Studio" "Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:oscar64" "ProductName" = "8:oscar64"
"ProductCode" = "8:{459712F2-F0A9-4C4E-94E9-87EDFDD5FBA4}" "ProductCode" = "8:{406BC6F9-178C-4F55-8841-568E49B13E6A}"
"PackageCode" = "8:{36A3B67B-6D78-4E56-A84E-8E9BD9280818}" "PackageCode" = "8:{37C93EF5-4005-4CD6-B3E1-7A1383214775}"
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}" "UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
"AspNetVersion" = "8:2.0.50727.0" "AspNetVersion" = "8:2.0.50727.0"
"RestartWWWService" = "11:FALSE" "RestartWWWService" = "11:FALSE"
"RemovePreviousVersions" = "11:TRUE" "RemovePreviousVersions" = "11:TRUE"
"DetectNewerInstalledVersion" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE"
"InstallAllUsers" = "11:FALSE" "InstallAllUsers" = "11:FALSE"
"ProductVersion" = "8:1.5.104" "ProductVersion" = "8:1.5.105"
"Manufacturer" = "8:oscar64" "Manufacturer" = "8:oscar64"
"ARPHELPTELEPHONE" = "8:" "ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:" "ARPHELPLINK" = "8:"