Peephole optimizations
This commit is contained in:
parent
4c7dafed25
commit
db3c6a3135
|
@ -11082,6 +11082,47 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[0].mTemp >= 0 && ins->mSrc[1].mTemp >= 0 &&
|
||||
ltvalue[ins->mSrc[0].mTemp] && ltvalue[ins->mSrc[1].mTemp] &&
|
||||
ins->mSrc[0].mFinal && ins->mSrc[1].mFinal)
|
||||
{
|
||||
InterInstruction* ai0 = ltvalue[ins->mSrc[0].mTemp], * ai1 = ltvalue[ins->mSrc[1].mTemp];
|
||||
if (ai0->mCode == IC_BINARY_OPERATOR && ai0->mOperator == IA_SUB && ai0->mSrc[0].mTemp < 0 && ai0->mSrc[1].mFinal &&
|
||||
ai1->mCode == IC_BINARY_OPERATOR && ai1->mOperator == IA_SUB && ai1->mSrc[0].mTemp < 0 && ai1->mSrc[1].mFinal)
|
||||
{
|
||||
if (spareTemps + 2 >= ltvalue.Size())
|
||||
return true;
|
||||
|
||||
InterInstruction* sins = new InterInstruction(ins->mLocation, IC_BINARY_OPERATOR);
|
||||
sins->mOperator = IA_SUB;
|
||||
sins->mDst = ins->mDst;
|
||||
sins->mSrc[1].mType = IT_INT16;
|
||||
sins->mSrc[1].mTemp = spareTemps++;
|
||||
sins->mSrc[1].mFinal = true;
|
||||
sins->mSrc[0] = ai0->mSrc[0];
|
||||
sins->mSrc[0].mIntConst += ai1->mSrc[0].mIntConst;
|
||||
sins->mSrc[0].mRange.AddConstValue(IT_INT16, -ai1->mSrc[0].mIntConst);
|
||||
mInstructions.Insert(i + 1, sins);
|
||||
|
||||
ins->mDst = sins->mSrc[1];
|
||||
|
||||
ai0->mCode = IC_LOAD_TEMPORARY;
|
||||
ai0->mSrc[0] = ai0->mSrc[1];
|
||||
ai0->mDst.mRange = ai0->mSrc[0].mRange;
|
||||
ai0->mNumOperands = 1;
|
||||
|
||||
ai1->mCode = IC_LOAD_TEMPORARY;
|
||||
ai1->mSrc[0] = ai1->mSrc[1];
|
||||
ai1->mDst.mRange = ai1->mSrc[0].mRange;
|
||||
ai1->mNumOperands = 1;
|
||||
|
||||
ins->mSrc[0].mRange = ai0->mDst.mRange;
|
||||
ins->mSrc[1].mRange = ai1->mDst.mRange;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
@ -20749,6 +20790,28 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
|||
mInstructions[i + 0] = ins;
|
||||
changed = true;
|
||||
}
|
||||
#if 1
|
||||
else if (i + 2 < mInstructions.Size() && mInstructions[i + 0]->mCode == IC_STORE && mInstructions[i + 2]->mCode == IC_STORE &&
|
||||
mInstructions[i + 1]->mCode == IC_LOAD &&
|
||||
CanSwapInstructions(mInstructions[i + 0], mInstructions[i + 1]) &&
|
||||
mInstructions[i + 1]->mDst.mTemp == mInstructions[i + 2]->mSrc[0].mTemp && mInstructions[i + 2]->mSrc[0].mFinal &&
|
||||
!mInstructions[i + 0]->mVolatile && !mInstructions[i + 2]->mVolatile &&
|
||||
SameMemRegion(mInstructions[i + 0]->mSrc[1], mInstructions[i + 2]->mSrc[1]) &&
|
||||
|
||||
(mInstructions[i + 0]->mSrc[1].mVarIndex > mInstructions[i + 2]->mSrc[1].mVarIndex ||
|
||||
mInstructions[i + 0]->mSrc[1].mVarIndex == mInstructions[i + 2]->mSrc[1].mVarIndex &&
|
||||
mInstructions[i + 0]->mSrc[1].mIntConst > mInstructions[i + 2]->mSrc[1].mIntConst))
|
||||
{
|
||||
InterInstruction* ins = mInstructions[i + 0];
|
||||
SwapInstructions(ins, mInstructions[i + 1]);
|
||||
mInstructions[i + 0] = mInstructions[i + 1];
|
||||
SwapInstructions(ins, mInstructions[i + 2]);
|
||||
mInstructions[i + 1] = mInstructions[i + 2];
|
||||
mInstructions[i + 2] = ins;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
} while (changed);
|
||||
|
@ -22491,7 +22554,7 @@ void InterCodeProcedure::Close(void)
|
|||
{
|
||||
GrowingTypeArray tstack(IT_NONE);
|
||||
|
||||
CheckFunc = !strcmp(mIdent->mString, "main");
|
||||
CheckFunc = !strcmp(mIdent->mString, "bm_init");
|
||||
CheckCase = false;
|
||||
|
||||
mEntryBlock = mBlocks[0];
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "CompilerTypes.h"
|
||||
|
||||
#define JUMP_TO_BRANCH 1
|
||||
#define CHECK_NULLPTR 0
|
||||
|
||||
static bool CheckFunc;
|
||||
static bool CheckCase;
|
||||
|
@ -21083,7 +21084,7 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
|
|||
if (mFalseJump->mFalseJump == mTrueJump)
|
||||
{
|
||||
mBranch = ASMIT_BCS;
|
||||
mFalseJump = mFalseJump->mFalseJump;
|
||||
mFalseJump = mFalseJump->mTrueJump;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
@ -21092,7 +21093,7 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
|
|||
if (mFalseJump->mTrueJump == mTrueJump)
|
||||
{
|
||||
mBranch = ASMIT_BCS;
|
||||
mFalseJump = mFalseJump->mTrueJump;
|
||||
mFalseJump = mFalseJump->mFalseJump;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
@ -32863,6 +32864,88 @@ bool NativeCodeBasicBlock::Propagate16BitSum(const ExpandingArray<NativeRegister
|
|||
return changed;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::FindAccuExitValue(int& at)
|
||||
{
|
||||
int i = mIns.Size() - 1;
|
||||
while (i >= 0)
|
||||
{
|
||||
if ((mIns[i].mType == ASMIT_LDA || mIns[i].mType == ASMIT_STA) && (mIns[i].mMode == ASMIM_ZERO_PAGE || mIns[i].mMode == ASMIM_ABSOLUTE))
|
||||
{
|
||||
at = i;
|
||||
i++;
|
||||
while (i < mIns.Size())
|
||||
{
|
||||
if (mIns[at].MayBeChangedOnAddress(mIns[i]))
|
||||
return false;
|
||||
i++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (mIns[i].ChangesAccu())
|
||||
return false;
|
||||
i--;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::MoveLoadXAbsUpCrossBlock(int at)
|
||||
{
|
||||
int i = at - 1;
|
||||
while (i >= 0)
|
||||
{
|
||||
if ((mIns[i].mType == ASMIT_STA || mIns[i].mType == ASMIT_LDA) && mIns[i].SameEffectiveAddress(mIns[at]))
|
||||
{
|
||||
mIns[i].mLive |= LIVE_CPU_REG_A;
|
||||
i++;
|
||||
mIns.Insert(i, NativeCodeInstruction(mIns[at].mIns, ASMIT_TAX));
|
||||
mIns[at + 1].mType = ASMIT_NOP;
|
||||
mIns[at + 1].mMode = ASMIM_IMPLIED;
|
||||
while (i < at + 1)
|
||||
{
|
||||
mIns[i].mLive |= LIVE_CPU_REG_X;
|
||||
i++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mIns[i].RequiresXReg() || mIns[i].ChangesXReg() || (mIns[i].mLive & LIVE_CPU_REG_X))
|
||||
return false;
|
||||
if (mIns[at].MayBeChangedOnAddress(mIns[i]))
|
||||
return false;
|
||||
i--;
|
||||
}
|
||||
|
||||
if (mEntryBlocks.Size() == 1)
|
||||
{
|
||||
NativeCodeBasicBlock* eb = mEntryBlocks[0];
|
||||
if (eb->FindAccuExitValue(i) && eb->mIns[i].SameEffectiveAddress(mIns[at]))
|
||||
{
|
||||
while (i < eb->mIns.Size())
|
||||
{
|
||||
eb->mIns[i].mLive |= LIVE_CPU_REG_A;
|
||||
i++;
|
||||
}
|
||||
eb->mExitRequiredRegs += CPU_REG_A;
|
||||
mEntryRequiredRegs += CPU_REG_A;
|
||||
|
||||
mIns.Insert(0, NativeCodeInstruction(mIns[at].mIns, ASMIT_TAX));
|
||||
mIns[at + 1].mType = ASMIT_NOP;
|
||||
mIns[at + 1].mMode = ASMIM_IMPLIED;
|
||||
i = 0;
|
||||
while (i < at + 1)
|
||||
{
|
||||
mIns[i].mLive |= LIVE_CPU_REG_X;
|
||||
i++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NativeCodeBasicBlock::MoveLoadXUp(int at)
|
||||
{
|
||||
|
@ -42680,6 +42763,23 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerShuffle(int pass)
|
|||
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
if (pass > 10)
|
||||
{
|
||||
for (int i = 0; i < mIns.Size(); i++)
|
||||
{
|
||||
if (!(mIns[i].mFlags & NCIF_VOLATILE))
|
||||
{
|
||||
if (mIns[i].mType == ASMIT_LDX && (mIns[i].mMode == ASMIM_ZERO_PAGE || mIns[i].mMode == ASMIM_ABSOLUTE) && !(mIns[i].mLive & LIVE_CPU_REG_Z))
|
||||
{
|
||||
if (MoveLoadXAbsUpCrossBlock(i))
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
CheckLive();
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
// move ldy, sty down if live
|
||||
|
||||
|
@ -49923,6 +50023,58 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerExits(int pass)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
if (sz > 0 && mFalseJump && mIns[sz - 1].ChangesAccuAndFlag() && mBranch == ASMIT_BMI)
|
||||
{
|
||||
if (mFalseJump->mIns.Size() == 1 && mFalseJump->mIns[0].mType == ASMIT_CMP && mFalseJump->mBranch == ASMIT_BCS && mFalseJump->mTrueJump == mTrueJump)
|
||||
{
|
||||
mTrueJump->RemEntryBlock(this);
|
||||
mTrueJump = mFalseJump;
|
||||
mFalseJump = nullptr;
|
||||
mBranch = ASMIT_JMP;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
if (pass > 15 && sz > 0 && (mIns[sz - 1].mType == ASMIT_CMP || mIns[sz - 1].mType == ASMIT_CPX || mIns[sz - 1].mType == ASMIT_CPY))
|
||||
{
|
||||
if (mTrueJump && mTrueJump->mEntryBlocks.Size() == 1 && mTrueJump->mIns.Size() > 0 && mTrueJump->mIns[0].IsSame(mIns[sz - 1]))
|
||||
{
|
||||
mTrueJump->mIns[0].mType = ASMIT_NOP; mTrueJump->mIns[0].mMode = ASMIM_IMPLIED;
|
||||
if (mTrueJump->mIns[0].mLive & LIVE_CPU_REG_Z)
|
||||
{
|
||||
mExitRequiredRegs += CPU_REG_Z;
|
||||
mTrueJump->mEntryRequiredRegs += CPU_REG_Z;
|
||||
mIns[sz - 1].mLive |= LIVE_CPU_REG_Z;
|
||||
}
|
||||
if (mTrueJump->mIns[0].mLive & LIVE_CPU_REG_C)
|
||||
{
|
||||
mExitRequiredRegs += CPU_REG_C;
|
||||
mTrueJump->mEntryRequiredRegs += CPU_REG_C;
|
||||
mIns[sz - 1].mLive |= LIVE_CPU_REG_C;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
if (mFalseJump && mFalseJump->mEntryBlocks.Size() == 1 && mFalseJump->mIns.Size() > 0 && mFalseJump->mIns[0].IsSame(mIns[sz - 1]))
|
||||
{
|
||||
mFalseJump->mIns[0].mType = ASMIT_NOP; mFalseJump->mIns[0].mMode = ASMIM_IMPLIED;
|
||||
if (mFalseJump->mIns[0].mLive & LIVE_CPU_REG_Z)
|
||||
{
|
||||
mExitRequiredRegs += CPU_REG_Z;
|
||||
mFalseJump->mEntryRequiredRegs += CPU_REG_Z;
|
||||
mIns[sz - 1].mLive |= LIVE_CPU_REG_Z;
|
||||
}
|
||||
if (mFalseJump->mIns[0].mLive & LIVE_CPU_REG_C)
|
||||
{
|
||||
mExitRequiredRegs += CPU_REG_C;
|
||||
mFalseJump->mEntryRequiredRegs += CPU_REG_C;
|
||||
mIns[sz - 1].mLive |= LIVE_CPU_REG_C;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
CheckLive();
|
||||
if (mTrueJump)
|
||||
mTrueJump->CheckLive();
|
||||
|
@ -50101,8 +50253,10 @@ void NativeCodeBasicBlock::CheckAsmCode(void)
|
|||
assert(HasAsmInstructionMode(mIns[j].mType, ASMIM_IMMEDIATE));
|
||||
else
|
||||
assert(HasAsmInstructionMode(mIns[j].mType, mIns[j].mMode));
|
||||
#if CHECK_NULLPTR
|
||||
if (mIns[j].mMode == ASMIM_ABSOLUTE || mIns[j].mMode == ASMIM_ABSOLUTE_Y || mIns[j].mMode == ASMIM_ABSOLUTE_X)
|
||||
assert(mIns[j].mLinkerObject != nullptr || mIns[j].mAddress > 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (mTrueJump) mTrueJump->CheckAsmCode();
|
||||
|
@ -50189,9 +50343,10 @@ void NativeCodeBasicBlock::CheckLive(void)
|
|||
else
|
||||
assert(HasAsmInstructionMode(mIns[j].mType, mIns[j].mMode));
|
||||
|
||||
#if CHECK_NULLPTR
|
||||
if (mIns[j].mMode == ASMIM_ABSOLUTE || mIns[j].mMode == ASMIM_ZERO_PAGE || mIns[j].mMode == ASMIM_ABSOLUTE_X || mIns[j].mMode == ASMIM_ABSOLUTE_Y)
|
||||
assert(mIns[j].mLinkerObject != nullptr || mIns[j].mAddress > 0);
|
||||
|
||||
#endif
|
||||
if (mIns[j].mType != ASMIT_NOP)
|
||||
{
|
||||
assert(!(live & ~mIns[j].mLive));
|
||||
|
@ -50943,7 +51098,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
|||
mInterProc = proc;
|
||||
mInterProc->mLinkerObject->mNativeProc = this;
|
||||
|
||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "a");
|
||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "particle_add");
|
||||
|
||||
int nblocks = proc->mBlocks.Size();
|
||||
tblocks = new NativeCodeBasicBlock * [nblocks];
|
||||
|
|
|
@ -504,6 +504,9 @@ public:
|
|||
bool MoveTXADCDown(int at);
|
||||
bool FoldShiftORAIntoLoadImmUp(int at);
|
||||
|
||||
bool FindAccuExitValue(int& at);
|
||||
bool MoveLoadXAbsUpCrossBlock(int at);
|
||||
|
||||
bool MoveSimpleADCToINCDECDown(int at);
|
||||
bool MoveTAXADCSTADown(int at);
|
||||
|
||||
|
|
|
@ -1974,14 +1974,9 @@ Expression* Parser::ParseInitExpression(Declaration* dtype, bool inner)
|
|||
}
|
||||
else if (exp->mDecValue->mType == DT_CONST_INTEGER && exp->mDecValue->mInteger == 0)
|
||||
{
|
||||
Declaration * ndec = new Declaration(exp->mDecValue->mLocation, DT_CONST_ADDRESS);
|
||||
ndec->mBase = TheVoidPointerTypeDeclaration;
|
||||
ndec->mInteger = 0;
|
||||
dec = ndec;
|
||||
|
||||
Expression* nexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||
nexp->mDecValue = ndec;
|
||||
nexp->mDecType = ndec->mBase;
|
||||
nexp->mDecValue = TheNullptrConstDeclaration;
|
||||
nexp->mDecType = TheNullPointerTypeDeclaration;
|
||||
exp = nexp;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
call ..\..\bin\oscar64 -n fireworks_ptr.c
|
||||
call ..\..\bin\oscar64 -n fireworks_hires.c
|
||||
call ..\..\bin\oscar64 -n fireworks_stripe.c
|
||||
call ..\..\bin\oscar64 -n fireworks_stripe.c -O2
|
||||
|
||||
|
|
Loading…
Reference in New Issue