diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 5577756..37f60cc 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -16088,6 +16088,60 @@ bool NativeCodeBasicBlock::Split16BitLoopCount(NativeCodeProcedure* proc) return changed; } +bool NativeCodeBasicBlock::EliminateDeadLoops(void) +{ + bool changed = false; + if (!mVisited) + { + mVisited = true; + + if (mLoopHead && mNumEntries == 2 && mFalseJump) + { + NativeCodeBasicBlock* eblock = nullptr; + if (mTrueJump == this) + eblock = mFalseJump; + else if (mFalseJump == this) + eblock = mTrueJump; + + if (eblock) + { + if (mIns.Size() == 2 && (mIns[0].mType == ASMIT_INX || mIns[0].mType == ASMIT_DEX) && mIns[1].mType == ASMIT_CPX) + { + if (!(eblock->mEntryRequiredRegs[CPU_REG_X])) + { + mLoopHead = false; + mTrueJump = eblock; + mBranch = ASMIT_JMP; + mEntryBlocks.RemoveAll(this); + mNumEntries--; + changed = true; + } + } + else if (mIns.Size() == 2 && (mIns[0].mType == ASMIT_INY || mIns[0].mType == ASMIT_DEY) && mIns[1].mType == ASMIT_CPY) + { + if (!(eblock->mEntryRequiredRegs[CPU_REG_Y])) + { + mLoopHead = false; + mTrueJump = eblock; + mBranch = ASMIT_JMP; + mEntryBlocks.RemoveAll(this); + mNumEntries--; + changed = true; + } + } + } + } + + if (mTrueJump && mTrueJump->EliminateDeadLoops()) + changed = true; + if (mFalseJump && mFalseJump->EliminateDeadLoops()) + changed = true; + } + + return changed; +} + + bool NativeCodeBasicBlock::CrossBlockStoreLoadBypass(NativeCodeProcedure* proc) { bool changed = false; @@ -43115,6 +43169,13 @@ void NativeCodeProcedure::Optimize(void) changed = true; } + if (step >= 9) + { + ResetVisited(); + if (mEntryBlock->EliminateDeadLoops()) + changed = true; + } + #if _DEBUG ResetVisited(); mEntryBlock->CheckBlocks(); diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index fa69c8b..2319579 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -584,6 +584,7 @@ public: bool SimplifyDiamond(NativeCodeProcedure* proc); bool SimplifyLoopEnd(NativeCodeProcedure* proc); bool CrossBlockStoreLoadBypass(NativeCodeProcedure* proc); + bool EliminateDeadLoops(void); bool CanBytepassLoad(const NativeCodeInstruction& ains, int from = 0) const; bool CanHoistStore(const NativeCodeInstruction& ains) const;