Optimize carry propagation
This commit is contained in:
parent
4d9d628b67
commit
197e2a91be
|
@ -8006,6 +8006,38 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void)
|
||||||
mInstructions[i]->ConstantFolding();
|
mInstructions[i]->ConstantFolding();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#if 1
|
||||||
|
// Check shortcut double jump
|
||||||
|
if (mTrueJump && mTrueJump->mInstructions.Size() == 1 && mTrueJump->mInstructions[0]->mCode == IC_BRANCH &&
|
||||||
|
mTrueJump->mInstructions[0]->mSrc[0].mTemp >= 0 &&
|
||||||
|
mTrueJump->mInstructions[0]->mSrc[0].mTemp < mTrueValueRange.Size() &&
|
||||||
|
mTrueValueRange[mTrueJump->mInstructions[0]->mSrc[0].mTemp].IsConstant())
|
||||||
|
{
|
||||||
|
mTrueJump->mNumEntries--;
|
||||||
|
mTrueJump->mEntryBlocks.RemoveAll(this);
|
||||||
|
if (mTrueValueRange[mTrueJump->mInstructions[0]->mSrc[0].mTemp].mMaxValue == 0)
|
||||||
|
mTrueJump = mTrueJump->mFalseJump;
|
||||||
|
else
|
||||||
|
mTrueJump = mTrueJump->mTrueJump;
|
||||||
|
mTrueJump->mNumEntries++;
|
||||||
|
mTrueJump->mEntryBlocks.Push(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mFalseJump && mFalseJump->mInstructions.Size() == 1 && mFalseJump->mInstructions[0]->mCode == IC_BRANCH &&
|
||||||
|
mFalseJump->mInstructions[0]->mSrc[0].mTemp >= 0 &&
|
||||||
|
mFalseJump->mInstructions[0]->mSrc[0].mTemp < mFalseValueRange.Size() &&
|
||||||
|
mFalseValueRange[mFalseJump->mInstructions[0]->mSrc[0].mTemp].IsConstant())
|
||||||
|
{
|
||||||
|
mFalseJump->mNumEntries--;
|
||||||
|
mFalseJump->mEntryBlocks.RemoveAll(this);
|
||||||
|
if (mFalseValueRange[mFalseJump->mInstructions[0]->mSrc[0].mTemp].mMaxValue == 0)
|
||||||
|
mFalseJump = mFalseJump->mFalseJump;
|
||||||
|
else
|
||||||
|
mFalseJump = mFalseJump->mTrueJump;
|
||||||
|
mFalseJump->mNumEntries++;
|
||||||
|
mFalseJump->mEntryBlocks.Push(this);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2106,6 +2106,8 @@ bool NativeCodeInstruction::SameEffectiveAddress(const NativeCodeInstruction& in
|
||||||
case ASMIM_ABSOLUTE_X:
|
case ASMIM_ABSOLUTE_X:
|
||||||
case ASMIM_ABSOLUTE_Y:
|
case ASMIM_ABSOLUTE_Y:
|
||||||
return (ins.mLinkerObject == mLinkerObject && ins.mAddress == mAddress);
|
return (ins.mLinkerObject == mLinkerObject && ins.mAddress == mAddress);
|
||||||
|
case ASMIM_IMMEDIATE_ADDRESS:
|
||||||
|
return (ins.mLinkerObject == mLinkerObject && ins.mAddress == mAddress && ins.mFlags == mFlags);
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -7850,6 +7852,9 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
||||||
{
|
{
|
||||||
if (ins->mSrc[0].mMemory == IM_GLOBAL)
|
if (ins->mSrc[0].mMemory == IM_GLOBAL)
|
||||||
{
|
{
|
||||||
|
if (ins->mDst.IsUByte())
|
||||||
|
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst, ins->mSrc[0].mLinkerObject, flags, 0, uint8(ins->mDst.mRange.mMinValue), uint8(ins->mDst.mRange.mMaxValue)));
|
||||||
|
else
|
||||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst, ins->mSrc[0].mLinkerObject, flags));
|
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst, ins->mSrc[0].mLinkerObject, flags));
|
||||||
}
|
}
|
||||||
else if (ins->mSrc[0].mMemory == IM_ABSOLUTE)
|
else if (ins->mSrc[0].mMemory == IM_ABSOLUTE)
|
||||||
|
@ -7858,6 +7863,9 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
||||||
}
|
}
|
||||||
else if (ins->mSrc[0].mMemory == IM_FPARAM)
|
else if (ins->mSrc[0].mMemory == IM_FPARAM)
|
||||||
{
|
{
|
||||||
|
if (ins->mDst.IsUByte())
|
||||||
|
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst, nullptr, flags, 0, uint8(ins->mDst.mRange.mMinValue), uint8(ins->mDst.mRange.mMaxValue)));
|
||||||
|
else
|
||||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst, nullptr, flags));
|
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst, nullptr, flags));
|
||||||
}
|
}
|
||||||
else if (ins->mSrc[0].mMemory == IM_LOCAL || ins->mSrc[0].mMemory == IM_PARAM)
|
else if (ins->mSrc[0].mMemory == IM_LOCAL || ins->mSrc[0].mMemory == IM_PARAM)
|
||||||
|
@ -21373,6 +21381,48 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if 1
|
||||||
|
if (i + 6 < mIns.Size() &&
|
||||||
|
mIns[i + 0].mType == ASMIT_TAY &&
|
||||||
|
mIns[i + 1].mType == ASMIT_ASL && mIns[i + 1].mMode == ASMIM_IMPLIED &&
|
||||||
|
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 0 &&
|
||||||
|
mIns[i + 3].mType == ASMIT_ADC && mIns[i + 3].mMode == ASMIM_IMMEDIATE && mIns[i + 3].mAddress == 0xff &&
|
||||||
|
mIns[i + 4].mType == ASMIT_EOR && mIns[i + 4].mMode == ASMIM_IMMEDIATE && mIns[i + 4].mAddress == 0xff &&
|
||||||
|
mIns[i + 5].mType == ASMIT_STA && mIns[i + 5].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 6].mType == ASMIT_TYA &&
|
||||||
|
!(mIns[i + 6].mLive & (LIVE_CPU_REG_Y | LIVE_CPU_REG_C | LIVE_CPU_REG_Z)))
|
||||||
|
{
|
||||||
|
changed = true;
|
||||||
|
|
||||||
|
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
||||||
|
NativeCodeBasicBlock* neblock = proc->AllocateBlock();
|
||||||
|
NativeCodeBasicBlock* rblock = proc->AllocateBlock();
|
||||||
|
|
||||||
|
rblock->mTrueJump = mTrueJump;
|
||||||
|
rblock->mFalseJump = mFalseJump;
|
||||||
|
rblock->mBranch = mBranch;
|
||||||
|
rblock->mBranchIns = mBranchIns;
|
||||||
|
|
||||||
|
rblock->mIns.Push(NativeCodeInstruction(mIns[i].mIns, ASMIT_STY, mIns[i + 5]));
|
||||||
|
for (int j = i + 7; j < mIns.Size(); j++)
|
||||||
|
rblock->mIns.Push(mIns[j]);
|
||||||
|
mIns.SetSize(i + 1);
|
||||||
|
mIns[i + 0].mType = ASMIT_ORA; mIns[i + 0].mMode = ASMIM_IMMEDIATE; mIns[i + 0].mAddress = 0x00;
|
||||||
|
mIns[i + 0].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_Z;
|
||||||
|
|
||||||
|
mTrueJump = eblock;
|
||||||
|
mFalseJump = neblock;
|
||||||
|
mBranch = ASMIT_BPL;
|
||||||
|
mBranchIns = mIns[i + 0].mIns;
|
||||||
|
|
||||||
|
eblock->mIns.Push(NativeCodeInstruction(mIns[i].mIns, ASMIT_LDY, ASMIM_IMMEDIATE, 0x00));
|
||||||
|
neblock->mIns.Push(NativeCodeInstruction(mIns[i].mIns, ASMIT_LDY, ASMIM_IMMEDIATE, 0xff));
|
||||||
|
|
||||||
|
eblock->Close(mIns[i].mIns, rblock, nullptr, ASMIT_JMP);
|
||||||
|
neblock->Close(mIns[i].mIns, rblock, nullptr, ASMIT_JMP);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if 1
|
#if 1
|
||||||
if (i + 4 < mIns.Size() &&
|
if (i + 4 < mIns.Size() &&
|
||||||
(mIns[i + 0].mType == ASMIT_CPX || mIns[i + 0].mType == ASMIT_CPY) && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0x01 &&
|
(mIns[i + 0].mType == ASMIT_CPX || mIns[i + 0].mType == ASMIT_CPY) && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0x01 &&
|
||||||
|
@ -22588,6 +22638,33 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
if (mFalseJump && mIns.Size() >= 3)
|
||||||
|
{
|
||||||
|
int sz = mIns.Size();
|
||||||
|
if (mIns[sz - 3].mType == ASMIT_CLC &&
|
||||||
|
mIns[sz - 2].mType == ASMIT_ADC &&
|
||||||
|
mIns[sz - 1].mType == ASMIT_CMP && mIns[sz - 1].SameEffectiveAddress(mIns[sz - 2]))
|
||||||
|
{
|
||||||
|
if (mTrueJump->mNumEntries == 1 && !mFalseJump->mEntryRequiredRegs[CPU_REG_A])
|
||||||
|
{
|
||||||
|
mTrueJump->mIns.Insert(0, mIns[sz - 3]);
|
||||||
|
mTrueJump->mIns.Insert(1, mIns[sz - 2]);
|
||||||
|
mIns[sz - 1].mMode = ASMIM_IMMEDIATE; mIns[sz - 1].mAddress = 0;
|
||||||
|
mIns.Remove(sz - 3, 2);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (mFalseJump->mNumEntries == 1 && !mTrueJump->mEntryRequiredRegs[CPU_REG_A])
|
||||||
|
{
|
||||||
|
mFalseJump->mIns.Insert(0, mIns[sz - 3]);
|
||||||
|
mFalseJump->mIns.Insert(1, mIns[sz - 2]);
|
||||||
|
mIns[sz - 1].mMode = ASMIM_IMMEDIATE; mIns[sz - 1].mAddress = 0;
|
||||||
|
mIns.Remove(sz - 3, 2);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (mTrueJump && mTrueJump->ExpandADCToBranch(proc))
|
if (mTrueJump && mTrueJump->ExpandADCToBranch(proc))
|
||||||
changed = true;
|
changed = true;
|
||||||
if (mFalseJump && mFalseJump->ExpandADCToBranch(proc))
|
if (mFalseJump && mFalseJump->ExpandADCToBranch(proc))
|
||||||
|
@ -43836,7 +43913,7 @@ bool NativeCodeBasicBlock::BlockSizeCopyReduction(NativeCodeProcedure* proc, int
|
||||||
// Size reduction violating various assumptions such as no branches in basic blocks
|
// Size reduction violating various assumptions such as no branches in basic blocks
|
||||||
// must be last step before actual assembly
|
// must be last step before actual assembly
|
||||||
|
|
||||||
void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc, int xenter, int yenter)
|
void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc, int xenter, int yenter, int center)
|
||||||
{
|
{
|
||||||
if (!mVisited)
|
if (!mVisited)
|
||||||
{
|
{
|
||||||
|
@ -44665,7 +44742,15 @@ void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc, int xen
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool carrySet = false, carryClear = false;
|
bool carrySet = false, carryClear = false;
|
||||||
|
if (mEntryBlocks.Size() == 1 && center >= 0)
|
||||||
|
{
|
||||||
|
if (center)
|
||||||
|
carrySet = true;
|
||||||
|
else
|
||||||
|
carryClear = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (mEntryBlocks.Size() > 0)
|
if (mEntryBlocks.Size() > 0)
|
||||||
{
|
{
|
||||||
carrySet = true;
|
carrySet = true;
|
||||||
|
@ -44696,6 +44781,7 @@ void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc, int xen
|
||||||
else
|
else
|
||||||
carryClear = carrySet = false;
|
carryClear = carrySet = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
|
|
||||||
|
@ -45026,11 +45112,16 @@ void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc, int xen
|
||||||
}
|
}
|
||||||
mIns.SetSize(j);
|
mIns.SetSize(j);
|
||||||
|
|
||||||
|
int cval = -1;
|
||||||
|
if (carrySet)
|
||||||
|
cval = 1;
|
||||||
|
else if (carryClear)
|
||||||
|
cval = 0;
|
||||||
#endif
|
#endif
|
||||||
if (mTrueJump)
|
if (mTrueJump)
|
||||||
mTrueJump->BlockSizeReduction(proc, ximm ? xval : -1, yimm ? yval: -1);
|
mTrueJump->BlockSizeReduction(proc, ximm ? xval : -1, yimm ? yval: -1, cval);
|
||||||
if (mFalseJump)
|
if (mFalseJump)
|
||||||
mFalseJump->BlockSizeReduction(proc, ximm ? xval : -1, yimm ? yval : -1);
|
mFalseJump->BlockSizeReduction(proc, ximm ? xval : -1, yimm ? yval : -1, cval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55276,7 +55367,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
|
|
||||||
mInterProc->mLinkerObject->mNativeProc = this;
|
mInterProc->mLinkerObject->mNativeProc = this;
|
||||||
|
|
||||||
CheckFunc = !strcmp(mIdent->mString, "floaters_update");
|
CheckFunc = !strcmp(mIdent->mString, "sprite_mobs_update_slide");
|
||||||
|
|
||||||
int nblocks = proc->mBlocks.Size();
|
int nblocks = proc->mBlocks.Size();
|
||||||
tblocks = new NativeCodeBasicBlock * [nblocks];
|
tblocks = new NativeCodeBasicBlock * [nblocks];
|
||||||
|
@ -57336,7 +57427,7 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->BlockSizeReduction(this, -1, -1);
|
mEntryBlock->BlockSizeReduction(this, -1, -1, -1);
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->MergeBasicBlocks();
|
mEntryBlock->MergeBasicBlocks();
|
||||||
|
|
|
@ -345,7 +345,7 @@ public:
|
||||||
bool PeepHoleOptimizerIterate(int pass);
|
bool PeepHoleOptimizerIterate(int pass);
|
||||||
bool PeepHoleOptimizerExits(int pass);
|
bool PeepHoleOptimizerExits(int pass);
|
||||||
|
|
||||||
void BlockSizeReduction(NativeCodeProcedure* proc, int xenter, int yenter);
|
void BlockSizeReduction(NativeCodeProcedure* proc, int xenter, int yenter, int center);
|
||||||
bool BlockSizeCopyReduction(NativeCodeProcedure* proc, int & si, int & di);
|
bool BlockSizeCopyReduction(NativeCodeProcedure* proc, int & si, int & di);
|
||||||
|
|
||||||
bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, bool full);
|
bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, bool full);
|
||||||
|
|
Loading…
Reference in New Issue