diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index bb6d1ce..05831fc 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -14056,6 +14056,9 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void) { if (mTrueJump->mNumEntries == 1 && trueExitRequiredTemps[dtemp] && !falseExitRequiredTems[dtemp]) { + if (ins->mDst.mTemp >= 0 && mTrueJump->mEntryValueRange.Size() > ins->mDst.mTemp) + mTrueJump->mEntryValueRange[ins->mDst.mTemp].Reset(); + for (int j = 0; j < ins->mNumOperands; j++) { if (ins->mSrc[j].mTemp >= 0) @@ -14073,6 +14076,9 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void) } else if (mFalseJump->mNumEntries == 1 && !trueExitRequiredTemps[dtemp] && falseExitRequiredTems[dtemp]) { + if (ins->mDst.mTemp >= 0 && mFalseJump->mEntryValueRange.Size() > ins->mDst.mTemp) + mFalseJump->mEntryValueRange[ins->mDst.mTemp].Reset(); + for (int j = 0; j < ins->mNumOperands; j++) { if (ins->mSrc[j].mTemp >= 0) @@ -14116,6 +14122,9 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void) if (ins->mCode != IC_LOAD || j == mFalseJump->mInstructions.Size()) { + if (ins->mDst.mTemp >= 0 && joinedBlock->mEntryValueRange.Size() > ins->mDst.mTemp) + joinedBlock->mEntryValueRange[ins->mDst.mTemp].Reset(); + for (int j = 0; j < ins->mNumOperands; j++) { if (ins->mSrc[j].mTemp >= 0) @@ -19673,6 +19682,7 @@ bool InterCodeBasicBlock::PeepholeReplaceOptimization(const GrowingVariableArray mInstructions[i + 1]->mSrc[0].mIntConst >>= shift; mInstructions[i + 0]->mOperator = IA_AND; mInstructions[i + 0]->mSrc[0].mIntConst = ~((1LL << shift) - 1); + mInstructions[i + 0]->mDst.mRange.Reset(); changed = true; } else if ( @@ -19685,6 +19695,7 @@ bool InterCodeBasicBlock::PeepholeReplaceOptimization(const GrowingVariableArray mInstructions[i + 1]->mSrc[1].mIntConst >>= shift; mInstructions[i + 0]->mOperator = IA_AND; mInstructions[i + 0]->mSrc[0].mIntConst = ~((1LL << shift) - 1); + mInstructions[i + 0]->mDst.mRange.Reset(); changed = true; } else if ( @@ -23216,7 +23227,7 @@ void InterCodeProcedure::Close(void) { GrowingTypeArray tstack(IT_NONE); - CheckFunc = !strcmp(mIdent->mString, "runner_entering"); + CheckFunc = !strcmp(mIdent->mString, "player_move"); CheckCase = false; mEntryBlock = mBlocks[0]; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index f94b515..45c88dd 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -1793,7 +1793,7 @@ bool NativeCodeInstruction::IsSameLS(const NativeCodeInstruction& ins) const return false; } -bool NativeCodeInstruction::MayBeMovedBefore(const NativeCodeInstruction& ins) +bool NativeCodeInstruction::MayBeMovedBefore(const NativeCodeInstruction& ins) const { if ((ChangesAddress() || ins.ChangesAddress()) && MayBeSameAddress(ins)) return false; @@ -19196,6 +19196,83 @@ bool NativeCodeBasicBlock::Split16BitLoopCount(NativeCodeProcedure* proc) return changed; } +bool NativeCodeBasicBlock::MoveStoresBeforeDiamond(void) +{ + bool changed = false; + if (!mVisited) + { + mVisited = true; + if (mTrueJump && mFalseJump) + { + NativeCodeBasicBlock* dblock = nullptr, * eblock = nullptr; + + if (mTrueJump->mTrueJump == mFalseJump && !mTrueJump->mFalseJump && mFalseJump->mNumEntries == 2 && mTrueJump->mNumEntries == 1) + { + dblock = mTrueJump; + eblock = mFalseJump; + } + else if (mFalseJump->mTrueJump == mTrueJump && !mFalseJump->mFalseJump && mTrueJump->mNumEntries == 2 && mFalseJump->mNumEntries == 1) + { + dblock = mFalseJump; + eblock = mTrueJump; + } + + if (eblock) + { + bool avalid = eblock->mEntryRequiredRegs[CPU_REG_A] && !dblock->ChangesAccu(); + bool xvalid = eblock->mEntryRequiredRegs[CPU_REG_X] && !dblock->ChangesXReg(); + bool yvalid = eblock->mEntryRequiredRegs[CPU_REG_Y] && !dblock->ChangesYReg(); + + int i = 0; + while (i < eblock->mIns.Size()) + { + NativeCodeInstruction& ins(eblock->mIns[i]); + + bool move = false; + if (avalid) + { + if (ins.mType == ASMIT_STA) + move = true; + else if (ins.ChangesAccu()) + avalid = false; + } + else if (xvalid) + { + if (ins.mType == ASMIT_STX) + move = true; + else if (ins.ChangesXReg()) + xvalid = false; + } + else if (yvalid) + { + if (ins.mType == ASMIT_STY) + move = true; + else if (ins.ChangesYReg()) + yvalid = false; + } + else + break; + + if (move && eblock->MayBeMovedBeforeBlock(i, ins) && dblock->MayBeMovedBeforeBlock(dblock->mIns.Size(), ins)) + { + ins.mLive = LIVE_ALL; + mIns.Push(ins); + eblock->mIns.Remove(i); + changed = true; + } + else + i++; + } + } + } + + if (mTrueJump && mTrueJump->MoveStoresBeforeDiamond()) changed = true; + if (mFalseJump && mFalseJump->MoveStoresBeforeDiamond()) changed = true; + } + + return changed; +} + bool NativeCodeBasicBlock::CrossBlockFlagsForwarding(void) { bool changed = false; @@ -26346,6 +26423,19 @@ bool NativeCodeBasicBlock::MayBeMovedBeforeBlock(int at) return true; } +bool NativeCodeBasicBlock::MayBeMovedBeforeBlock(int at, const NativeCodeInstruction& ins) +{ + int i = at; + while (i > 0) + { + i--; + if (!ins.MayBeMovedBefore(mIns[i])) + return false; + } + + return true; +} + bool NativeCodeBasicBlock::SafeInjectSequenceFromBack(NativeCodeBasicBlock* block, int start, int end) { uint32 changes = 0; @@ -38734,12 +38824,13 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc if (rind >= 0) { + bool found = false; for (int i = 0; i < mIns.Size(); i++) { if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == rind) { if (mIns[i].mType == ASMIT_LDA || mIns[i].mType == ASMIT_STA) - ; + found = true; else { rind = -2; @@ -38755,7 +38846,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc } } - if (rind >= 0) + if (rind >= 0 && found) { if (!prevBlock) return OptimizeSimpleLoopInvariant(proc, full); @@ -52485,7 +52576,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) mInterProc->mLinkerObject->mNativeProc = this; - CheckFunc = !strcmp(mIdent->mString, "f"); + CheckFunc = !strcmp(mIdent->mString, "player_move"); int nblocks = proc->mBlocks.Size(); tblocks = new NativeCodeBasicBlock * [nblocks]; @@ -54282,6 +54373,13 @@ void NativeCodeProcedure::Optimize(void) } + if (step == 19) + { + ResetVisited(); + if (mEntryBlock->MoveStoresBeforeDiamond()) + changed = true; + } + #if _DEBUG ResetVisited(); mEntryBlock->CheckAsmCode(); diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index 5f09ea9..2d13c05 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -211,7 +211,7 @@ public: bool IsShift(void) const; bool IsShiftOrInc(void) const; bool IsSimpleJSR(void) const; - bool MayBeMovedBefore(const NativeCodeInstruction& ins); + bool MayBeMovedBefore(const NativeCodeInstruction& ins) const; bool ReplaceYRegWithXReg(void); bool ReplaceXRegWithYReg(void); @@ -603,6 +603,7 @@ public: bool HasTailSTAX16(int& addr, int& index0) const; bool MayBeMovedBeforeBlock(int at); + bool MayBeMovedBeforeBlock(int at, const NativeCodeInstruction & ins); bool MayBeMovedBeforeBlock(int start, int end); bool SafeInjectSequenceFromBack(NativeCodeBasicBlock* block, int start, int end); bool JoinCommonBranchCodeSequences(void); @@ -706,6 +707,7 @@ public: bool EliminateDeadLoops(void); bool LoopRegisterWrapAround(void); bool CrossBlockFlagsForwarding(void); + bool MoveStoresBeforeDiamond(void); bool SinglePathRegisterForwardY(NativeCodeBasicBlock* path, int yreg); bool SinglePathRegisterForward(void);