Optimize conditional select of const values
This commit is contained in:
parent
1f9226255a
commit
f0f174e439
|
@ -72,10 +72,10 @@ inline void sidfx_loop_ch(byte ch)
|
|||
sid.voices[ch].ctrl = 0;
|
||||
sid.voices[ch].attdec = 0;
|
||||
sid.voices[ch].susrel = 0;
|
||||
channels[ch].state = SIDFX_RESET_1;
|
||||
channels[ch].state = SIDFX_READY;
|
||||
break;
|
||||
case SIDFX_RESET_1:
|
||||
sid.voices[ch].ctrl = SID_CTRL_TEST;
|
||||
// sid.voices[ch].ctrl = SID_CTRL_TEST;
|
||||
channels[ch].state = SIDFX_READY;
|
||||
break;
|
||||
case SIDFX_READY:
|
||||
|
|
|
@ -11034,6 +11034,12 @@ void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArra
|
|||
if (ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_MUL && ins->mDst.mType == IT_INT16 && spareTemps + 1 < tvalid.Size())
|
||||
{
|
||||
InterInstruction* mi0 = ltvalue[ins->mSrc[0].mTemp], * mi1 = ltvalue[ins->mSrc[1].mTemp];
|
||||
InterInstruction* mci0 = nullptr;
|
||||
InterInstruction* mci1 = nullptr;
|
||||
if (mi0 && mi0->mCode == IC_CONVERSION_OPERATOR)
|
||||
mci0 = ltvalue[mi0->mSrc[0].mTemp];
|
||||
if (mi1 && mi1->mCode == IC_CONVERSION_OPERATOR)
|
||||
mci1 = ltvalue[mi1->mSrc[0].mTemp];
|
||||
|
||||
if (mi0 && mi1 && mi1->mCode == IC_CONSTANT && mi0->mCode == IC_BINARY_OPERATOR && mi0->mOperator == IA_ADD)
|
||||
{
|
||||
|
@ -11178,6 +11184,41 @@ void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArra
|
|||
ins->mSrc[0].mTemp = cai->mDst.mTemp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
else if (mi0 && mci1 && mci1->mCode == IC_RELATIONAL_OPERATOR)
|
||||
{
|
||||
InterInstruction* cai = new InterInstruction(ins->mLocation, IC_CONSTANT);
|
||||
cai->mDst.mTemp = spareTemps++;
|
||||
cai->mDst.mType = ins->mDst.mType;
|
||||
cai->mConst.mIntConst = 0;
|
||||
cai->mConst.mFloatConst = 0;
|
||||
mInstructions.Insert(i, cai);
|
||||
|
||||
ins->mCode = IC_SELECT;
|
||||
ins->mNumOperands = 3;
|
||||
ins->mSrc[2] = mci1->mDst;
|
||||
ins->mSrc[1] = ins->mSrc[0];
|
||||
ins->mSrc[0].mTemp = cai->mDst.mTemp;
|
||||
|
||||
ltvalue[cai->mDst.mTemp] = nullptr;
|
||||
}
|
||||
else if (mci0 && mi1 && mci0->mCode == IC_RELATIONAL_OPERATOR)
|
||||
{
|
||||
InterInstruction* cai = new InterInstruction(ins->mLocation, IC_CONSTANT);
|
||||
cai->mDst.mTemp = spareTemps++;
|
||||
cai->mDst.mType = ins->mDst.mType;
|
||||
cai->mConst.mIntConst = 0;
|
||||
cai->mConst.mFloatConst = 0;
|
||||
mInstructions.Insert(i, cai);
|
||||
|
||||
ins->mCode = IC_SELECT;
|
||||
ins->mNumOperands = 3;
|
||||
ins->mSrc[2] = mci0->mDst;
|
||||
ins->mSrc[0].mTemp = cai->mDst.mTemp;
|
||||
|
||||
ltvalue[cai->mDst.mTemp] = nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1624,6 +1624,12 @@ bool NativeCodeInstruction::IsCommutative(void) const
|
|||
return mType == ASMIT_ADC || mType == ASMIT_AND || mType == ASMIT_ORA || mType == ASMIT_EOR;
|
||||
}
|
||||
|
||||
bool NativeCodeInstruction::IsLogic(void) const
|
||||
{
|
||||
return mType == ASMIT_AND || mType == ASMIT_ORA || mType == ASMIT_EOR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool NativeCodeInstruction::IsSame(const NativeCodeInstruction& ins) const
|
||||
{
|
||||
|
@ -26516,6 +26522,60 @@ bool NativeCodeBasicBlock::EliminateMicroBlocks(void)
|
|||
return changed;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::CombineAlternateLoads(void)
|
||||
{
|
||||
bool changed = false;
|
||||
if (!mVisited)
|
||||
{
|
||||
mVisited = true;
|
||||
|
||||
if (mTrueJump && mFalseJump && (mBranch == ASMIT_BCC || mBranch == ASMIT_BCS) &&
|
||||
mTrueJump->mIns.Size() == 1 && mFalseJump->mIns.Size() == 1 &&
|
||||
mTrueJump->mTrueJump == mFalseJump->mTrueJump &&
|
||||
!mTrueJump->mFalseJump && !mFalseJump->mFalseJump &&
|
||||
mTrueJump->mNumEntries == 1 && mFalseJump->mNumEntries == 1)
|
||||
{
|
||||
if (mTrueJump->mIns[0].mType == ASMIT_LDA && mTrueJump->mIns[0].mMode == ASMIM_IMMEDIATE &&
|
||||
mFalseJump->mIns[0].mType == ASMIT_LDA && mFalseJump->mIns[0].mMode == ASMIM_IMMEDIATE)
|
||||
{
|
||||
mFalseJump->mIns[0].mLive |= LIVE_CPU_REG_C;
|
||||
mIns.Push(mFalseJump->mIns[0]);
|
||||
mFalseJump->mIns.Remove(0);
|
||||
mExitRequiredRegs += CPU_REG_A;
|
||||
mFalseJump->mEntryRequiredRegs += CPU_REG_A;
|
||||
changed = true;
|
||||
}
|
||||
else if (mTrueJump->mIns[0].mType == ASMIT_LDX && mTrueJump->mIns[0].mMode == ASMIM_IMMEDIATE &&
|
||||
mFalseJump->mIns[0].mType == ASMIT_LDX && mFalseJump->mIns[0].mMode == ASMIM_IMMEDIATE)
|
||||
{
|
||||
mFalseJump->mIns[0].mLive |= LIVE_CPU_REG_C;
|
||||
mIns.Push(mFalseJump->mIns[0]);
|
||||
mFalseJump->mIns.Remove(0);
|
||||
mExitRequiredRegs += CPU_REG_X;
|
||||
mFalseJump->mEntryRequiredRegs += CPU_REG_X;
|
||||
changed = true;
|
||||
}
|
||||
else if (mTrueJump->mIns[0].mType == ASMIT_LDY && mTrueJump->mIns[0].mMode == ASMIM_IMMEDIATE &&
|
||||
mFalseJump->mIns[0].mType == ASMIT_LDY && mFalseJump->mIns[0].mMode == ASMIM_IMMEDIATE)
|
||||
{
|
||||
mFalseJump->mIns[0].mLive |= LIVE_CPU_REG_C;
|
||||
mIns.Push(mFalseJump->mIns[0]);
|
||||
mFalseJump->mIns.Remove(0);
|
||||
mExitRequiredRegs += CPU_REG_Y;
|
||||
mFalseJump->mEntryRequiredRegs += CPU_REG_Y;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mTrueJump && mTrueJump->CombineAlternateLoads())
|
||||
changed = true;
|
||||
if (mFalseJump && mFalseJump->CombineAlternateLoads())
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::FoldLoopEntry(void)
|
||||
{
|
||||
bool changed = false;
|
||||
|
@ -33394,6 +33454,58 @@ bool NativeCodeBasicBlock::MoveLoadAddImmStoreAbsXUp(int at)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::MoveLoadLogicStoreAbsUp(int at)
|
||||
{
|
||||
// at + 0 : LDA zp
|
||||
// at + 1 : ORA zp / imm
|
||||
// at + 2 : STA abs / abs,x / abs,y
|
||||
|
||||
int j = at - 1;
|
||||
while (j >= 0)
|
||||
{
|
||||
if (mIns[j].mType == ASMIT_STA && mIns[j].mMode == ASMIM_ZERO_PAGE && mIns[j].mAddress == mIns[at].mAddress)
|
||||
{
|
||||
while (j + 1 < mIns.Size() && mIns[j + 1].mType == ASMIT_STA)
|
||||
j++;
|
||||
|
||||
if (mIns[j].mLive & LIVE_CPU_REG_A)
|
||||
return false;
|
||||
|
||||
mIns[j].mLive |= LIVE_CPU_REG_A;
|
||||
for (int i = j + 1; i < at; i++)
|
||||
mIns[i].mLive |= LIVE_CPU_REG_C;
|
||||
|
||||
mIns[at + 1].mLive |= mIns[j].mLive;
|
||||
mIns[at + 2].mLive |= mIns[j].mLive;
|
||||
|
||||
mIns.Insert(j + 1, mIns[at + 2]); // STA
|
||||
mIns.Insert(j + 1, mIns[at + 2]); // ORA
|
||||
|
||||
mIns[at + 2].mType = ASMIT_NOP; mIns[at + 2].mMode = ASMIM_IMPLIED;
|
||||
mIns[at + 3].mType = ASMIT_NOP; mIns[at + 3].mMode = ASMIM_IMPLIED;
|
||||
mIns[at + 4].mType = ASMIT_NOP; mIns[at + 4].mMode = ASMIM_IMPLIED;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mIns[j].ChangesZeroPage(mIns[at + 0].mAddress))
|
||||
return false;
|
||||
if (mIns[at + 1].mType == ASMIM_ZERO_PAGE && mIns[j].ChangesZeroPage(mIns[at + 1].mAddress))
|
||||
return false;
|
||||
|
||||
if (mIns[j].UsesMemoryOf(mIns[at + 2]))
|
||||
return false;
|
||||
if (mIns[at + 2].mMode == ASMIM_ABSOLUTE_X && mIns[j].ChangesXReg())
|
||||
return false;
|
||||
if (mIns[at + 2].mMode == ASMIM_ABSOLUTE_Y && mIns[j].ChangesYReg())
|
||||
return false;
|
||||
|
||||
j--;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NativeCodeBasicBlock::MoveLoadAddImmStoreUp(int at)
|
||||
{
|
||||
|
@ -42101,6 +42213,27 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerShuffle(int pass)
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
#if 1
|
||||
// move load - add # - store up to initial store
|
||||
//
|
||||
|
||||
for (int i = 1; i + 2 < mIns.Size(); i++)
|
||||
{
|
||||
if (
|
||||
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[i + 1].IsLogic() && (mIns[i + 1].mMode == ASMIM_IMMEDIATE || mIns[i + 1].mMode == ASMIM_ZERO_PAGE) &&
|
||||
mIns[i + 2].mType == ASMIT_STA && (mIns[i + 2].mMode == ASMIM_ZERO_PAGE || mIns[i + 2].mMode == ASMIM_ABSOLUTE || mIns[i + 2].mMode == ASMIM_ABSOLUTE_X || mIns[i + 2].mMode == ASMIM_ABSOLUTE_Y) &&
|
||||
(mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) == 0)
|
||||
{
|
||||
if (MoveLoadLogicStoreAbsUp(i))
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
CheckLive();
|
||||
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
// move load - ora/and/eor # - store up to initial store
|
||||
//
|
||||
|
@ -47266,6 +47399,21 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerIterate6(int i, int pass)
|
|||
mIns[i + 5].mType = ASMIT_NOP; mIns[i + 5].mMode = ASMIM_IMPLIED;
|
||||
return true;
|
||||
}
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 &&
|
||||
mIns[i + 1].mType == ASMIT_ROL && mIns[i + 1].mMode == ASMIM_IMPLIED &&
|
||||
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[i + 3].mType == ASMIT_LDA && !mIns[i + 3].MayBeSameAddress(mIns[i + 2]) &&
|
||||
mIns[i + 4].mType == ASMIT_ASL && mIns[i + 4].mMode == ASMIM_IMPLIED &&
|
||||
mIns[i + 5].mType == ASMIT_ORA && mIns[i + 5].SameEffectiveAddress(mIns[i + 2]) && !(mIns[i + 5].mLive & LIVE_MEM))
|
||||
{
|
||||
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 4].mType = ASMIT_ROL;
|
||||
mIns[i + 5].mType = ASMIT_NOP; mIns[i + 5].mMode = ASMIM_IMPLIED;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pass == 0 &&
|
||||
mIns[i + 0].mType == ASMIT_CLC &&
|
||||
|
@ -52349,6 +52497,10 @@ void NativeCodeProcedure::Optimize(void)
|
|||
|
||||
} while (changed);
|
||||
|
||||
#if 1
|
||||
ResetVisited();
|
||||
mEntryBlock->CombineAlternateLoads();
|
||||
#endif
|
||||
#if 1
|
||||
ResetVisited();
|
||||
mEntryBlock->ReduceLocalYPressure();
|
||||
|
|
|
@ -198,6 +198,7 @@ public:
|
|||
bool IsSame(const NativeCodeInstruction& ins) const;
|
||||
bool IsSameLS(const NativeCodeInstruction& ins) const;
|
||||
bool IsCommutative(void) const;
|
||||
bool IsLogic(void) const;
|
||||
bool IsShift(void) const;
|
||||
bool IsShiftOrInc(void) const;
|
||||
bool IsSimpleJSR(void) const;
|
||||
|
@ -463,6 +464,8 @@ public:
|
|||
bool MoveTYADCStoreDown(int at);
|
||||
bool MoveShiftZeroPageUp(int at);
|
||||
|
||||
bool MoveLoadLogicStoreAbsUp(int at);
|
||||
|
||||
bool MoveLDSTXOutOfRange(int at);
|
||||
|
||||
bool MoveCLCLoadAddZPStoreDown(int at);
|
||||
|
@ -617,6 +620,7 @@ public:
|
|||
|
||||
bool BypassRegisterConditionBlock(void);
|
||||
bool FoldLoopEntry(void);
|
||||
bool CombineAlternateLoads(void);
|
||||
|
||||
bool Is16BitImmSum(int at, int & val, int& reg) const;
|
||||
|
||||
|
|
Loading…
Reference in New Issue