More simple common subexpression elimination in native code
This commit is contained in:
parent
9f28fdfcc0
commit
9c5e018c5a
|
@ -12685,7 +12685,19 @@ bool InterCodeBasicBlock::PeepholeReplaceOptimization(const GrowingVariableArray
|
||||||
mInstructions[i + 1]->mNumOperands = 0;
|
mInstructions[i + 1]->mNumOperands = 0;
|
||||||
changed = true;
|
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
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
else if (
|
else if (
|
||||||
mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 0]->mOperator == IA_SHR && mInstructions[i + 0]->mSrc[0].mTemp < 0 &&
|
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;
|
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
|
#if 1
|
||||||
// Postincrement artifact
|
// Postincrement artifact
|
||||||
if (mInstructions[i + 0]->mCode == IC_LOAD_TEMPORARY && mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR &&
|
if (mInstructions[i + 0]->mCode == IC_LOAD_TEMPORARY && mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR &&
|
||||||
|
|
|
@ -1400,6 +1400,35 @@ bool NativeCodeInstruction::IsSame(const NativeCodeInstruction& ins) const
|
||||||
return false;
|
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)
|
bool NativeCodeInstruction::MayBeMovedBefore(const NativeCodeInstruction& ins)
|
||||||
{
|
{
|
||||||
if ((ChangesAddress() || ins.ChangesAddress()) && MayBeSameAddress(ins))
|
if ((ChangesAddress() || ins.ChangesAddress()) && MayBeSameAddress(ins))
|
||||||
|
@ -13823,10 +13852,27 @@ bool NativeCodeBasicBlock::IsSimpleSubExpression(int at) const
|
||||||
return true;
|
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;
|
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 NativeCodeBasicBlock::PropagateCommonSubExpression(void)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
@ -13849,7 +13895,7 @@ bool NativeCodeBasicBlock::PropagateCommonSubExpression(void)
|
||||||
if (IsSimpleSubExpression(i))
|
if (IsSimpleSubExpression(i))
|
||||||
{
|
{
|
||||||
int si = cex[ins.mAddress];
|
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[i].mType = ASMIT_LDA;
|
||||||
mIns[si].mLive |= LIVE_MEM;
|
mIns[si].mLive |= LIVE_MEM;
|
||||||
|
@ -13876,8 +13922,12 @@ bool NativeCodeBasicBlock::PropagateCommonSubExpression(void)
|
||||||
cex[ins.mAddress] = -1;
|
cex[ins.mAddress] = -1;
|
||||||
for (int j = 0; j < 256; j++)
|
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;
|
cex[j] = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17533,6 +17583,145 @@ bool NativeCodeBasicBlock::ShortcutPointerAddForward(void)
|
||||||
return changed;
|
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<NativeCodeExpression> 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
|
bool NativeCodeBasicBlock::CanChangeTailZPStoreToX(int addr, const NativeCodeBasicBlock* nblock, const NativeCodeBasicBlock* fblock) const
|
||||||
{
|
{
|
||||||
if (mExitRequiredRegs[CPU_REG_X])
|
if (mExitRequiredRegs[CPU_REG_X])
|
||||||
|
@ -34466,6 +34655,56 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
|
|
||||||
progress = true;
|
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 (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
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()) &&
|
!(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 &&
|
if (i + 7 < mIns.Size() && pass > 3 &&
|
||||||
mIns[i + 0].mType == ASMIT_LDA &&
|
mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
mIns[i + 1].mType == ASMIT_CLC &&
|
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE &&
|
||||||
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE &&
|
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
|
||||||
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 3].mType == ASMIT_LDA &&
|
||||||
mIns[i + 4].mType == ASMIT_LDA &&
|
mIns[i + 4].mType == ASMIT_ADC && mIns[i + 4].mMode == ASMIM_IMMEDIATE &&
|
||||||
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].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_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 3].mAddress + 1 &&
|
mIns[i + 6].mType == ASMIT_LDY && mIns[i + 6].mMode == ASMIM_IMMEDIATE &&
|
||||||
mIns[i + 7].mType == ASMIT_LDY && mIns[i + 7].mMode == ASMIM_IMMEDIATE &&
|
mIns[i + 7].mMode == ASMIM_INDIRECT_Y && mIns[i + 7].mAddress == mIns[i + 2].mAddress && !(mIns[i + 7].mLive & LIVE_MEM))
|
||||||
mIns[i + 8].mMode == ASMIM_INDIRECT_Y && mIns[i + 8].mAddress == mIns[i + 3].mAddress && !(mIns[i + 8].mLive & LIVE_MEM))
|
|
||||||
{
|
{
|
||||||
int total = mIns[i + 2].mAddress + mIns[i + 7].mAddress + 256 * mIns[i + 5].mAddress;
|
int total = mIns[i + 1].mAddress + mIns[i + 6].mAddress + 256 * mIns[i + 4].mAddress;
|
||||||
if (!(mIns[i + 8].mLive & LIVE_CPU_REG_Y) || !(mIns[i + 8].mLive & LIVE_CPU_REG_Z))
|
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)
|
if (mIns[i + 7].mLive & LIVE_CPU_REG_Y)
|
||||||
mIns.Insert(i + 9, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, mIns[i + 7].mAddress));
|
mIns.Insert(i + 8, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, mIns[i + 6].mAddress));
|
||||||
mIns[i + 7].mAddress = total & 255;
|
mIns[i + 6].mAddress = total & 255;
|
||||||
mIns[i + 5].mAddress = total >> 8;
|
mIns[i + 4].mAddress = total >> 8;
|
||||||
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (i + 6 < mIns.Size())
|
if (i + 6 < mIns.Size())
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
|
@ -35978,6 +36215,35 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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 1
|
||||||
if (
|
if (
|
||||||
mIns[i + 0].mType == ASMIT_CLC &&
|
mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
|
@ -37821,7 +38087,7 @@ void NativeCodeProcedure::RebuildEntry(void)
|
||||||
|
|
||||||
void NativeCodeProcedure::Optimize(void)
|
void NativeCodeProcedure::Optimize(void)
|
||||||
{
|
{
|
||||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "_mapUp");
|
CheckFunc = !strcmp(mInterProc->mIdent->mString, "setpair");
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
int step = 0;
|
int step = 0;
|
||||||
|
@ -38017,7 +38283,6 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
if (step > 0)
|
if (step > 0)
|
||||||
{
|
{
|
||||||
|
@ -38453,7 +38718,6 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
else
|
else
|
||||||
cnt++;
|
cnt++;
|
||||||
|
|
||||||
|
|
||||||
} while (changed);
|
} while (changed);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
|
|
|
@ -147,6 +147,7 @@ public:
|
||||||
bool MayBeChangedOnAddress(const NativeCodeInstruction& ins, bool sameXY = false) const;
|
bool MayBeChangedOnAddress(const NativeCodeInstruction& ins, bool sameXY = false) const;
|
||||||
bool MayBeSameAddress(const NativeCodeInstruction& ins, bool sameXY = false) const;
|
bool MayBeSameAddress(const NativeCodeInstruction& ins, bool sameXY = false) const;
|
||||||
bool IsSame(const NativeCodeInstruction& ins) const;
|
bool IsSame(const NativeCodeInstruction& ins) const;
|
||||||
|
bool IsSameLS(const NativeCodeInstruction& ins) const;
|
||||||
bool IsCommutative(void) const;
|
bool IsCommutative(void) const;
|
||||||
bool IsShift(void) const;
|
bool IsShift(void) const;
|
||||||
bool IsShiftOrInc(void) const;
|
bool IsShiftOrInc(void) const;
|
||||||
|
@ -506,6 +507,7 @@ public:
|
||||||
bool GlobalSwapXY(void);
|
bool GlobalSwapXY(void);
|
||||||
|
|
||||||
bool IsSimpleSubExpression(int at) const;
|
bool IsSimpleSubExpression(int at) const;
|
||||||
|
bool IsSameSimpleSubExpression(int pat, int at) const;
|
||||||
bool PropagateCommonSubExpression(void);
|
bool PropagateCommonSubExpression(void);
|
||||||
|
|
||||||
bool ForwardAbsoluteLoadStores(void);
|
bool ForwardAbsoluteLoadStores(void);
|
||||||
|
@ -516,6 +518,8 @@ public:
|
||||||
bool CheckShortcutPointerAddForward(int at);
|
bool CheckShortcutPointerAddForward(int at);
|
||||||
bool ShortcutPointerAddForward(void);
|
bool ShortcutPointerAddForward(void);
|
||||||
|
|
||||||
|
bool CommonSubExpressionElimination(void);
|
||||||
|
|
||||||
bool CheckPatchFailReg(const NativeCodeBasicBlock* block, int reg);
|
bool CheckPatchFailReg(const NativeCodeBasicBlock* block, int reg);
|
||||||
bool CheckPatchFailRegPair(const NativeCodeBasicBlock* block, int reg);
|
bool CheckPatchFailRegPair(const NativeCodeBasicBlock* block, int reg);
|
||||||
bool CheckPatchFailUse(void);
|
bool CheckPatchFailUse(void);
|
||||||
|
|
Loading…
Reference in New Issue