From 9c5e018c5aa65354f11914edca685a4b4b51fcb1 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Fri, 17 Mar 2023 09:32:22 +0100 Subject: [PATCH] More simple common subexpression elimination in native code --- oscar64/InterCode.cpp | 102 +++++++++++ oscar64/NativeCodeGenerator.cpp | 310 +++++++++++++++++++++++++++++--- oscar64/NativeCodeGenerator.h | 4 + 3 files changed, 393 insertions(+), 23 deletions(-) diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index d534a22..5633d17 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -12685,7 +12685,19 @@ bool InterCodeBasicBlock::PeepholeReplaceOptimization(const GrowingVariableArray mInstructions[i + 1]->mNumOperands = 0; changed = true; } + else if ( + mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && (mInstructions[i + 0]->mOperator == IA_SUB || mInstructions[i + 0]->mOperator == IA_XOR) && + mInstructions[i + 0]->mSrc[0].mTemp >= 0 && mInstructions[i + 0]->mSrc[0].mTemp == mInstructions[i + 0]->mSrc[1].mTemp) + { + mInstructions[i + 0]->mCode = IC_CONSTANT; + mInstructions[i + 0]->mNumOperands = 0; + mInstructions[i + 0]->mConst.mType = mInstructions[i + 0]->mDst.mType; + mInstructions[i + 0]->mConst.mIntConst = 0; + mInstructions[i + 0]->mConst.mFloatConst = 0; + changed = true; + } #endif + #if 1 else if ( mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 0]->mOperator == IA_SHR && mInstructions[i + 0]->mSrc[0].mTemp < 0 && @@ -13137,6 +13149,96 @@ bool InterCodeBasicBlock::PeepholeReplaceOptimization(const GrowingVariableArray changed = true; } +#if 1 + if (i + 2 < mInstructions.Size() && + mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && + mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && + mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR && + mInstructions[i + 0]->mDst.mTemp != mInstructions[i + 1]->mSrc[0].mTemp && + mInstructions[i + 0]->mDst.mTemp != mInstructions[i + 1]->mSrc[1].mTemp && + mInstructions[i + 2]->mSrc[0].mTemp >= 0 && mInstructions[i + 2]->mSrc[1].mTemp >= 0 && + mInstructions[i + 2]->mSrc[0].mFinal && mInstructions[i + 2]->mSrc[1].mFinal && + mInstructions[i + 2]->mDst.mType == IT_INT16) + { + bool fail = false; + int s0, s1, c0, c1, s2 = i + 2; + + if (mInstructions[i + 2]->mSrc[0].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 2]->mSrc[1].mTemp == mInstructions[i + 1]->mDst.mTemp) + { + s0 = i + 0; s1 = i + 1; + } + else if (mInstructions[i + 2]->mSrc[0].mTemp == mInstructions[i + 1]->mDst.mTemp && mInstructions[i + 2]->mSrc[1].mTemp == mInstructions[i + 0]->mDst.mTemp) + { + s0 = i + 1; s1 = i + 0; + } + else + fail = true; + + if (!fail) + { + if (mInstructions[s0]->mSrc[0].mTemp < 0) + c0 = 0; + else if (mInstructions[s0]->mSrc[1].mTemp < 0) + c0 = 1; + else + fail = true; + + if (mInstructions[s1]->mSrc[0].mTemp < 0) + c1 = 0; + else if (mInstructions[s1]->mSrc[1].mTemp < 0) + c1 = 1; + else + fail = true; + + if (!fail) + { + InterOperator o0 = mInstructions[s0]->mOperator; + InterOperator o1 = mInstructions[s1]->mOperator; + InterOperator o2 = mInstructions[s2]->mOperator; + + if (o2 == IA_SUB) + { + if ((o0 == IA_ADD || o0 == IA_SUB && c0 == 0) && (o1 == IA_ADD || o1 == IA_SUB && c1 == 0)) + { + int iconst = + (o1 == IA_ADD ? mInstructions[s1]->mSrc[c1].mIntConst : -mInstructions[s1]->mSrc[c1].mIntConst) - + (o0 == IA_ADD ? mInstructions[s0]->mSrc[c0].mIntConst : -mInstructions[s0]->mSrc[c0].mIntConst); + + mInstructions[s0]->mSrc[0] = mInstructions[s0]->mSrc[1 - c0]; + mInstructions[s0]->mSrc[1] = mInstructions[s1]->mSrc[1 - c1]; + mInstructions[s0]->mDst.mRange.Reset(); + mInstructions[s0]->mOperator = IA_SUB; + mInstructions[s2]->mOperator = IA_ADD; + mInstructions[s2]->mSrc[0].mRange = mInstructions[s0]->mDst.mRange; + mInstructions[s2]->mSrc[1].mTemp = -1; + mInstructions[s2]->mSrc[1].mIntConst = iconst; + changed = true; + } + } + else if (o2 == IA_ADD) + { + if ((o0 == IA_ADD || o0 == IA_SUB && c0 == 0) && (o1 == IA_ADD || o1 == IA_SUB && c1 == 0)) + { + int iconst = + (o1 == IA_ADD ? mInstructions[s1]->mSrc[c1].mIntConst : -mInstructions[s1]->mSrc[c1].mIntConst) + + (o0 == IA_ADD ? mInstructions[s0]->mSrc[c0].mIntConst : -mInstructions[s0]->mSrc[c0].mIntConst); + + mInstructions[s0]->mSrc[0] = mInstructions[s0]->mSrc[1 - c0]; + mInstructions[s0]->mSrc[1] = mInstructions[s1]->mSrc[1 - c1]; + mInstructions[s0]->mDst.mRange.Reset(); + mInstructions[s0]->mOperator = IA_ADD; + mInstructions[s2]->mOperator = IA_ADD; + mInstructions[s2]->mSrc[0].mRange = mInstructions[s0]->mDst.mRange; + mInstructions[s2]->mSrc[1].mTemp = -1; + mInstructions[s2]->mSrc[1].mIntConst = iconst; + changed = true; + } + } + } + } + } +#endif + #if 1 // Postincrement artifact if (mInstructions[i + 0]->mCode == IC_LOAD_TEMPORARY && mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index b40b6f5..c1671ab 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -1400,6 +1400,35 @@ bool NativeCodeInstruction::IsSame(const NativeCodeInstruction& ins) const return false; } +bool NativeCodeInstruction::IsSameLS(const NativeCodeInstruction& ins) const +{ + if ((mType == ins.mType || mType == ASMIT_STA && ins.mType == ASMIT_LDA) && mMode == ins.mMode && mParam == ins.mParam) + { + switch (mMode) + { + case ASMIM_IMPLIED: + return true; + case ASMIM_IMMEDIATE: + case ASMIM_ZERO_PAGE: + case ASMIM_ZERO_PAGE_X: + case ASMIM_ZERO_PAGE_Y: + case ASMIM_INDIRECT_X: + case ASMIM_INDIRECT_Y: + return ins.mAddress == mAddress; + case ASMIM_IMMEDIATE_ADDRESS: + return (ins.mLinkerObject == mLinkerObject && ins.mAddress == mAddress && ins.mFlags == mFlags); + case ASMIM_ABSOLUTE: + case ASMIM_ABSOLUTE_X: + case ASMIM_ABSOLUTE_Y: + return (ins.mLinkerObject == mLinkerObject && ins.mAddress == mAddress); + default: + return false; + } + } + else + return false; +} + bool NativeCodeInstruction::MayBeMovedBefore(const NativeCodeInstruction& ins) { if ((ChangesAddress() || ins.ChangesAddress()) && MayBeSameAddress(ins)) @@ -13823,10 +13852,27 @@ bool NativeCodeBasicBlock::IsSimpleSubExpression(int at) const return true; } } + + if (at >= 3 && + mIns[at - 3].mType == ASMIT_STA && mIns[at - 3].mMode == ASMIM_ZERO_PAGE && mIns[at - 2].mType == ASMIT_CLC && + mIns[at - 1].mType == ASMIT_ADC && mIns[at - 1].mMode == ASMIM_IMMEDIATE) + return true; return false; } +bool NativeCodeBasicBlock::IsSameSimpleSubExpression(int pat, int at) const +{ + if (pat >= 2 && mIns[pat - 2].mType == ASMIT_LDA) + { + return mIns[pat - 2].IsSame(mIns[at - 2]) && mIns[pat - 1].IsSame(mIns[at - 1]); + } + else + { + return mIns[pat - 3].SameEffectiveAddress(mIns[at - 2]) && mIns[pat - 1].IsSame(mIns[at - 1]); + } +} + bool NativeCodeBasicBlock::PropagateCommonSubExpression(void) { bool changed = false; @@ -13849,7 +13895,7 @@ bool NativeCodeBasicBlock::PropagateCommonSubExpression(void) if (IsSimpleSubExpression(i)) { int si = cex[ins.mAddress]; - if (si >= 0 && mIns[si - 2].IsSame(mIns[i - 2]) && mIns[si - 1].IsSame(mIns[i - 1]) && !(ins.mLive & LIVE_CPU_REG_C)) + if (si >= 0 && IsSameSimpleSubExpression(si, i) && !(ins.mLive & LIVE_CPU_REG_C)) { mIns[i].mType = ASMIT_LDA; mIns[si].mLive |= LIVE_MEM; @@ -13876,8 +13922,12 @@ bool NativeCodeBasicBlock::PropagateCommonSubExpression(void) cex[ins.mAddress] = -1; for (int j = 0; j < 256; j++) { - if (cex[j] >= 0 && mIns[cex[j] - 2].mAddress == ins.mAddress) + int k = cex[j]; + if (k >= 0 && ( + mIns[k - 2].mType == ASMIT_LDA && mIns[k - 2].mAddress == ins.mAddress || mIns[k - 3].mAddress == ins.mAddress)) + { cex[j] = -1; + } } } @@ -17533,6 +17583,145 @@ bool NativeCodeBasicBlock::ShortcutPointerAddForward(void) return changed; } +#if 0 +static int NativeCodeExpressionID; + +struct NativeCodeExpression +{ + int mIndex; + AsmInsType mType; + NativeCodeInstruction * mIns; + int mLeft, mRight; + int mReg; + + NativeCodeExpression(AsmInsType type, NativeCodeInstruction* ins) + : mIndex(NativeCodeExpressionID++), mType(type), mIns(ins), mLeft(-1), mRight(-1), mReg(-1) + { + } + + NativeCodeExpression(AsmInsType type, int left, int right) + : mIndex(NativeCodeExpressionID++), mType(type), mIns(nullptr), mLeft(left), mRight(right), mReg(reg) + { + } +}; + +struct NativeCodeExpressions +{ + ExpandingArray mExps; + + void KillReg(int reg); + void KillYReg(void); + void KillXReg(void); + void KillAddr(const NativeCodeInstruction& ins); + int AddLoad(const NativeCodeInstruction& ins); +}; + + +void NativeCodeExpressions::KillReg(int reg) +{ + int i = 0; + while (i < mExps.Size()) + { + if (mExps[i].mReg == reg) + mExps.Remove(i); + else if (mExps[i].mIns) + { + if (reg == CPU_REG_Y && mExps[i].mIns->RequiresYReg()) + mExps.Remove(i); + else if (reg == CPU_REG_X && mExps[i].mIns->RequiresXReg()) + mExps.Remove(i); + else if (mExps[i].mIns->ReferencesZeroPage(reg)) + mExps.Remove(i); + else + i++; + } + else + i++; + } +} + +void NativeCodeExpressions::KillYReg(void) +{ + int i = 0; + while (i < mExps.Size()) + { + if (mExps[i].mIns && mExps[i].mIns->RequiresYReg()) + mExps.Remove(i); + else + i++; + } +} + +void NativeCodeExpressions::KillAddr(const NativeCodeInstruction& ins) +{ + int i = 0; + while (i < mExps.Size()) + { + if (mExps[i].mIns && mExps[i].mIns->MayBeChangedOnAddress(ins)) + mExps.Remove(i); + else + i++; + } +} + +int NativeCodeExpressions::AddLoad(const NativeCodeInstruction& ins) +{ + int i = 0; + while (i < mExps.Size() && !(mExps[i].mType == ASMIT_LDA && mExps[i].mIns->SameAddress(ins)) + i++; + if (i < mExps.Size()) + return mExps[i].mIndex; + else + { + NativeCodeExpressions e(ASMIT_LDA, &ins); + mExps.Push(e); + return e.mIndex; + } +} + +bool NativeCodeBasicBlock::CommonSubExpressionElimination(void) +{ + bool changed = false; + + if (!mVisited) + { + mVisited = true; + + NativeCodeExpressions exps; + + int aexp = -1, xexp = -1, yexp = -1; + + for (int i = 0; i < mIns.Size(); i++) + { + NativeCodeInstruction& ins(mIns[i]); + + + + switch (ins.mType) + { + case ASMIT_LDA: + aexp = exps.AddLoad(ins); + break; + case ASMIT_LDX: + aexp = exps.AddLoad(ins); + break; + case ASMIT_LDY: + aexp = exps.AddLoad(ins); + break; + } + } + + if (mTrueJump && mTrueJump->CommonSubExpressionElimination()) + changed = true; + if (mFalseJump && mFalseJump->CommonSubExpressionElimination()) + changed = true; + } + + return changed; +} + +#endif + bool NativeCodeBasicBlock::CanChangeTailZPStoreToX(int addr, const NativeCodeBasicBlock* nblock, const NativeCodeBasicBlock* fblock) const { if (mExitRequiredRegs[CPU_REG_X]) @@ -34466,6 +34655,56 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass progress = true; } + else if ( + mIns[i + 0].mType == ASMIT_LDX && + mIns[i + 1].mType == ASMIT_INX && mIns[i + 2].mType == ASMIT_INX && + mIns[i + 3].mType == ASMIT_STX && mIns[i + 3].SameEffectiveAddress(mIns[i + 0]) && !(mIns[i + 3].mLive & LIVE_CPU_REG_X)) + { + mIns[i + 0].mType = ASMIT_INC; + mIns[i + 3].mType = ASMIT_INC; + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + + progress = true; + } + else if ( + mIns[i + 0].mType == ASMIT_LDX && + mIns[i + 1].mType == ASMIT_DEX && mIns[i + 2].mType == ASMIT_DEX && + mIns[i + 3].mType == ASMIT_STX && mIns[i + 3].SameEffectiveAddress(mIns[i + 0]) && !(mIns[i + 3].mLive & LIVE_CPU_REG_X)) + { + mIns[i + 0].mType = ASMIT_DEC; + mIns[i + 3].mType = ASMIT_DEC; + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + + progress = true; + } + else if (pass > 10 && + mIns[i + 0].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_INC, mIns[i + 0].mMode) && + mIns[i + 1].mType == ASMIT_CLC && + mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 2 && + mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].SameEffectiveAddress(mIns[i + 0]) && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C))) + { + mIns[i + 0].mType = ASMIT_INC; + mIns[i + 3].mType = ASMIT_INC; + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + + progress = true; + } + else if (pass > 10 && + mIns[i + 0].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_DEC, mIns[i + 0].mMode) && + mIns[i + 1].mType == ASMIT_SEC && + mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 2 && + mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].SameEffectiveAddress(mIns[i + 0]) && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C))) + { + mIns[i + 0].mType = ASMIT_DEC; + mIns[i + 3].mType = ASMIT_DEC; + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + + progress = true; + } else if ( mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 1].ChangesYReg() || mIns[i + 1].mMode == ASMIM_INDIRECT_Y || mIns[i + 1].RequiresXReg()) && @@ -35601,30 +35840,28 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass } } - if (i + 8 < mIns.Size() && pass > 3 && - mIns[i + 0].mType == ASMIT_LDA && - mIns[i + 1].mType == ASMIT_CLC && - mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && - mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && - mIns[i + 4].mType == ASMIT_LDA && - mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && - mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 3].mAddress + 1 && - mIns[i + 7].mType == ASMIT_LDY && mIns[i + 7].mMode == ASMIM_IMMEDIATE && - mIns[i + 8].mMode == ASMIM_INDIRECT_Y && mIns[i + 8].mAddress == mIns[i + 3].mAddress && !(mIns[i + 8].mLive & LIVE_MEM)) + if (i + 7 < mIns.Size() && pass > 3 && + mIns[i + 0].mType == ASMIT_CLC && + mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE && + mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && + mIns[i + 3].mType == ASMIT_LDA && + mIns[i + 4].mType == ASMIT_ADC && mIns[i + 4].mMode == ASMIM_IMMEDIATE && + mIns[i + 5].mType == ASMIT_STA && mIns[i + 5].mMode == ASMIM_ZERO_PAGE && mIns[i + 5].mAddress == mIns[i + 2].mAddress + 1 && + mIns[i + 6].mType == ASMIT_LDY && mIns[i + 6].mMode == ASMIM_IMMEDIATE && + mIns[i + 7].mMode == ASMIM_INDIRECT_Y && mIns[i + 7].mAddress == mIns[i + 2].mAddress && !(mIns[i + 7].mLive & LIVE_MEM)) { - int total = mIns[i + 2].mAddress + mIns[i + 7].mAddress + 256 * mIns[i + 5].mAddress; - if (!(mIns[i + 8].mLive & LIVE_CPU_REG_Y) || !(mIns[i + 8].mLive & LIVE_CPU_REG_Z)) + int total = mIns[i + 1].mAddress + mIns[i + 6].mAddress + 256 * mIns[i + 4].mAddress; + if (!(mIns[i + 7].mLive & LIVE_CPU_REG_Y) || !(mIns[i + 7].mLive & LIVE_CPU_REG_Z)) { - if (mIns[i + 8].mLive & LIVE_CPU_REG_Y) - mIns.Insert(i + 9, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, mIns[i + 7].mAddress)); - mIns[i + 7].mAddress = total & 255; - mIns[i + 5].mAddress = total >> 8; - mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + if (mIns[i + 7].mLive & LIVE_CPU_REG_Y) + mIns.Insert(i + 8, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, mIns[i + 6].mAddress)); + mIns[i + 6].mAddress = total & 255; + mIns[i + 4].mAddress = total >> 8; + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; changed = true; } } - if (i + 6 < mIns.Size()) { if ( @@ -35978,6 +36215,35 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass } } #endif +#if 1 + if (mIns[i + 0].mType == ASMIT_CLC && + mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE && + mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && + mIns[i + 3].mType == ASMIT_LDA && + mIns[i + 4].mType == ASMIT_STA && mIns[i + 4].mMode == ASMIM_ZERO_PAGE && + mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && + mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 2].mAddress + 1 && + mIns[i + 2].mAddress != BC_REG_STACK && + !(mIns[i + 6].mLive & LIVE_CPU_REG_A)) + { + int yval = RetrieveYValue(i); + proc->ResetPatched(); + + if (CheckForwardSumYPointer(this, mIns[i + 2].mAddress, mIns[i + 2].mAddress, mIns[i + 1], i + 7, yval)) + { + proc->ResetPatched(); + if (PatchForwardSumYPointer(this, mIns[i + 2].mAddress, mIns[i + 2].mAddress, mIns[i + 1], i + 7, yval)) + progress = true; + + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + + if (mTrueJump) + mTrueJump->CheckLive(); + if (mFalseJump) + mFalseJump->CheckLive(); + } + } +#endif #if 1 if ( mIns[i + 0].mType == ASMIT_CLC && @@ -37821,7 +38087,7 @@ void NativeCodeProcedure::RebuildEntry(void) void NativeCodeProcedure::Optimize(void) { - CheckFunc = !strcmp(mInterProc->mIdent->mString, "_mapUp"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "setpair"); #if 1 int step = 0; @@ -38017,7 +38283,6 @@ void NativeCodeProcedure::Optimize(void) } - #if 1 if (step > 0) { @@ -38453,7 +38718,6 @@ void NativeCodeProcedure::Optimize(void) else cnt++; - } while (changed); #if 1 diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index f81e1e3..aebe821 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -147,6 +147,7 @@ public: bool MayBeChangedOnAddress(const NativeCodeInstruction& ins, bool sameXY = false) const; bool MayBeSameAddress(const NativeCodeInstruction& ins, bool sameXY = false) const; bool IsSame(const NativeCodeInstruction& ins) const; + bool IsSameLS(const NativeCodeInstruction& ins) const; bool IsCommutative(void) const; bool IsShift(void) const; bool IsShiftOrInc(void) const; @@ -506,6 +507,7 @@ public: bool GlobalSwapXY(void); bool IsSimpleSubExpression(int at) const; + bool IsSameSimpleSubExpression(int pat, int at) const; bool PropagateCommonSubExpression(void); bool ForwardAbsoluteLoadStores(void); @@ -516,6 +518,8 @@ public: bool CheckShortcutPointerAddForward(int at); bool ShortcutPointerAddForward(void); + bool CommonSubExpressionElimination(void); + bool CheckPatchFailReg(const NativeCodeBasicBlock* block, int reg); bool CheckPatchFailRegPair(const NativeCodeBasicBlock* block, int reg); bool CheckPatchFailUse(void);