Shortcut redundant conditional branch sequences

This commit is contained in:
drmortalwombat 2023-03-13 22:13:02 +01:00
parent 718d3ad940
commit 83869ad3a0
3 changed files with 127 additions and 24 deletions

View File

@ -10858,6 +10858,9 @@ bool InterCodeBasicBlock::CollectSingleHeadLoopBody(InterCodeBasicBlock* head, I
int i = 0; int i = 0;
body.Push(head); body.Push(head);
if (head == tail)
return true;
while (i < body.Size()) while (i < body.Size())
{ {
InterCodeBasicBlock* block = body[i++]; InterCodeBasicBlock* block = body[i++];

View File

@ -12147,6 +12147,48 @@ bool NativeCodeBasicBlock::MergeSameBlocks(NativeCodeProcedure* nproc)
return changed; return changed;
} }
NativeCodeBasicBlock* NativeCodeBasicBlock::ForwardAccuBranch(bool eq, bool ne, bool pl, bool mi, int limit)
{
if (limit == 4)
return this;
limit++;
if (mIns.Size() == 0 && mNumEntries == 1 || mIns.Size() == 1 && mIns[0].mType == ASMIT_ORA && mIns[0].mMode == ASMIM_IMMEDIATE && mIns[0].mAddress == 0)
{
if (mBranch == ASMIT_BEQ)
{
if (eq)
return mTrueJump->ForwardAccuBranch(true, false, true, false, limit);
if (ne || mi)
return mFalseJump->ForwardAccuBranch(false, true, pl, mi, limit);
}
else if (mBranch == ASMIT_BNE)
{
if (eq)
return mFalseJump->ForwardAccuBranch(true, false, true, false, limit);
if (ne || mi)
return mTrueJump->ForwardAccuBranch(false, true, pl, mi, limit);
}
else if (mBranch == ASMIT_BPL)
{
if (eq || pl)
return mTrueJump->ForwardAccuBranch(eq, ne, true, false, limit);
if (mi)
return mFalseJump->ForwardAccuBranch(false, true, false, true, limit);
}
else if (mBranch == ASMIT_BMI)
{
if (eq || pl)
return mFalseJump->ForwardAccuBranch(eq, ne, true, false, limit);
if (mi)
return mTrueJump->ForwardAccuBranch(false, true, false, true, limit);
}
}
return this;
}
bool NativeCodeBasicBlock::MergeBasicBlocks(void) bool NativeCodeBasicBlock::MergeBasicBlocks(void)
{ {
bool changed = false; bool changed = false;
@ -12254,6 +12296,49 @@ bool NativeCodeBasicBlock::MergeBasicBlocks(void)
mFalseJump = nullptr; mFalseJump = nullptr;
changed = true; changed = true;
} }
#if 1
if (mIns.Size() > 0 && mIns.Last().ChangesAccuAndFlag() && mTrueJump && mFalseJump)
{
NativeCodeBasicBlock* ntb = mTrueJump, * nfb = mFalseJump;
if (mBranch == ASMIT_BEQ)
{
ntb = ntb->ForwardAccuBranch(true, false, true, false, 0);
nfb = nfb->ForwardAccuBranch(false, true, false, false, 0);
}
else if (mBranch == ASMIT_BNE)
{
nfb = nfb->ForwardAccuBranch(true, false, true, false, 0);
ntb = ntb->ForwardAccuBranch(false, true, false, false, 0);
}
else if (mBranch == ASMIT_BPL)
{
ntb = ntb->ForwardAccuBranch(false, false, true, false, 0);
nfb = nfb->ForwardAccuBranch(false, true, false, true, 0);
}
else if (mBranch == ASMIT_BMI)
{
nfb = nfb->ForwardAccuBranch(false, false, true, false, 0);
ntb = ntb->ForwardAccuBranch(false, true, false, true, 0);
}
if (ntb != mTrueJump)
{
mTrueJump->mNumEntries--;
mTrueJump = ntb;
mTrueJump->mNumEntries++;
changed = true;
}
if (nfb != mFalseJump)
{
mFalseJump->mNumEntries--;
mFalseJump = nfb;
mFalseJump->mNumEntries++;
changed = true;
}
}
#endif
} }
if (mTrueJump) if (mTrueJump)
@ -25273,6 +25358,7 @@ bool NativeCodeBasicBlock::BitFieldForwarding(const NativeRegisterDataSet& data)
mIns.Insert(i + 1, NativeCodeInstruction(carryop)); mIns.Insert(i + 1, NativeCodeInstruction(carryop));
} }
} }
if (mFalseJump) if (mFalseJump)
{ {
mFDataSet = mNDataSet; mFDataSet = mNDataSet;
@ -25281,14 +25367,14 @@ bool NativeCodeBasicBlock::BitFieldForwarding(const NativeRegisterDataSet& data)
{ {
const NativeCodeInstruction& lins(mIns[mIns.Size() - 1]); const NativeCodeInstruction& lins(mIns[mIns.Size() - 1]);
if (lins.mMode == ASMIM_ZERO_PAGE && lins.mType == ASMIT_LDA) if (lins.ChangesAccuAndFlag())
{ {
switch (mBranch) switch (mBranch)
{ {
case ASMIT_BEQ: case ASMIT_BEQ:
if (mNDataSet.mRegs[lins.mAddress].mMask == 0xff) if (mNDataSet.mRegs[CPU_REG_A].mMask == 0xff)
{ {
if (mNDataSet.mRegs[lins.mAddress].mValue != 0) if (mNDataSet.mRegs[CPU_REG_A].mValue != 0)
{ {
mTrueJump->RemoveEntryBlock(this); mTrueJump->RemoveEntryBlock(this);
mTrueJump = mFalseJump; mTrueJump = mFalseJump;
@ -25306,14 +25392,18 @@ bool NativeCodeBasicBlock::BitFieldForwarding(const NativeRegisterDataSet& data)
{ {
mNDataSet.mRegs[CPU_REG_A].mMask = 0xff; mNDataSet.mRegs[CPU_REG_A].mMask = 0xff;
mNDataSet.mRegs[CPU_REG_A].mValue = 0x00; mNDataSet.mRegs[CPU_REG_A].mValue = 0x00;
mNDataSet.mRegs[lins.mAddress].mMask = 0xff;
mNDataSet.mRegs[lins.mAddress].mValue = 0x00; if (lins.mMode == ASMIM_ZERO_PAGE && lins.mType == ASMIT_LDA)
{
mNDataSet.mRegs[lins.mAddress].mMask = 0xff;
mNDataSet.mRegs[lins.mAddress].mValue = 0x00;
}
} }
break; break;
case ASMIT_BNE: case ASMIT_BNE:
if (mNDataSet.mRegs[lins.mAddress].mMask == 0xff) if (mNDataSet.mRegs[CPU_REG_A].mMask == 0xff)
{ {
if (mNDataSet.mRegs[lins.mAddress].mValue == 0) if (mNDataSet.mRegs[CPU_REG_A].mValue == 0)
{ {
mTrueJump->RemoveEntryBlock(this); mTrueJump->RemoveEntryBlock(this);
mTrueJump = mFalseJump; mTrueJump = mFalseJump;
@ -25331,14 +25421,18 @@ bool NativeCodeBasicBlock::BitFieldForwarding(const NativeRegisterDataSet& data)
{ {
mFDataSet.mRegs[CPU_REG_A].mMask = 0xff; mFDataSet.mRegs[CPU_REG_A].mMask = 0xff;
mFDataSet.mRegs[CPU_REG_A].mValue = 0x00; mFDataSet.mRegs[CPU_REG_A].mValue = 0x00;
mFDataSet.mRegs[lins.mAddress].mMask = 0xff;
mFDataSet.mRegs[lins.mAddress].mValue = 0x00; if (lins.mMode == ASMIM_ZERO_PAGE && lins.mType == ASMIT_LDA)
{
mFDataSet.mRegs[lins.mAddress].mMask = 0xff;
mFDataSet.mRegs[lins.mAddress].mValue = 0x00;
}
} }
break; break;
case ASMIT_BPL: case ASMIT_BPL:
if (mNDataSet.mRegs[lins.mAddress].mMask & 0x80) if (mNDataSet.mRegs[CPU_REG_A].mMask & 0x80)
{ {
if (mNDataSet.mRegs[lins.mAddress].mValue & 0x80) if (mNDataSet.mRegs[CPU_REG_A].mValue & 0x80)
{ {
mTrueJump->RemoveEntryBlock(this); mTrueJump->RemoveEntryBlock(this);
mTrueJump = mFalseJump; mTrueJump = mFalseJump;
@ -25359,16 +25453,19 @@ bool NativeCodeBasicBlock::BitFieldForwarding(const NativeRegisterDataSet& data)
mFDataSet.mRegs[CPU_REG_A].mMask |= 0x80; mFDataSet.mRegs[CPU_REG_A].mMask |= 0x80;
mFDataSet.mRegs[CPU_REG_A].mValue |= 0x80; mFDataSet.mRegs[CPU_REG_A].mValue |= 0x80;
mNDataSet.mRegs[lins.mAddress].mMask |= 0x80; if (lins.mMode == ASMIM_ZERO_PAGE && lins.mType == ASMIT_LDA)
mNDataSet.mRegs[lins.mAddress].mValue &= 0x7f; {
mFDataSet.mRegs[lins.mAddress].mMask |= 0x80; mNDataSet.mRegs[lins.mAddress].mMask |= 0x80;
mFDataSet.mRegs[lins.mAddress].mValue |= 0x80; mNDataSet.mRegs[lins.mAddress].mValue &= 0x7f;
mFDataSet.mRegs[lins.mAddress].mMask |= 0x80;
mFDataSet.mRegs[lins.mAddress].mValue |= 0x80;
}
} }
break; break;
case ASMIT_BMI: case ASMIT_BMI:
if (mNDataSet.mRegs[lins.mAddress].mMask & 0x80) if (mNDataSet.mRegs[CPU_REG_A].mMask & 0x80)
{ {
if (!(mNDataSet.mRegs[lins.mAddress].mValue & 0x80)) if (!(mNDataSet.mRegs[CPU_REG_A].mValue & 0x80))
{ {
mTrueJump->RemoveEntryBlock(this); mTrueJump->RemoveEntryBlock(this);
mTrueJump = mFalseJump; mTrueJump = mFalseJump;
@ -25389,10 +25486,13 @@ bool NativeCodeBasicBlock::BitFieldForwarding(const NativeRegisterDataSet& data)
mNDataSet.mRegs[CPU_REG_A].mMask |= 0x80; mNDataSet.mRegs[CPU_REG_A].mMask |= 0x80;
mNDataSet.mRegs[CPU_REG_A].mValue |= 0x80; mNDataSet.mRegs[CPU_REG_A].mValue |= 0x80;
mFDataSet.mRegs[lins.mAddress].mMask |= 0x80; if (lins.mMode == ASMIM_ZERO_PAGE && lins.mType == ASMIT_LDA)
mFDataSet.mRegs[lins.mAddress].mValue &= 0x7f; {
mNDataSet.mRegs[lins.mAddress].mMask |= 0x80; mFDataSet.mRegs[lins.mAddress].mMask |= 0x80;
mNDataSet.mRegs[lins.mAddress].mValue |= 0x80; mFDataSet.mRegs[lins.mAddress].mValue &= 0x7f;
mNDataSet.mRegs[lins.mAddress].mMask |= 0x80;
mNDataSet.mRegs[lins.mAddress].mValue |= 0x80;
}
} }
break; break;
} }
@ -37427,7 +37527,7 @@ void NativeCodeProcedure::RebuildEntry(void)
void NativeCodeProcedure::Optimize(void) void NativeCodeProcedure::Optimize(void)
{ {
CheckFunc = !strcmp(mInterProc->mIdent->mString, "main"); CheckFunc = !strcmp(mInterProc->mIdent->mString, "move");
#if 1 #if 1
int step = 0; int step = 0;
@ -38051,7 +38151,6 @@ void NativeCodeProcedure::Optimize(void)
else else
cnt++; cnt++;
} while (changed); } while (changed);
#if 1 #if 1

View File

@ -311,6 +311,7 @@ public:
bool MergeSameBlocks(NativeCodeProcedure* nproc); bool MergeSameBlocks(NativeCodeProcedure* nproc);
void CountEntries(NativeCodeBasicBlock* fromJump); void CountEntries(NativeCodeBasicBlock* fromJump);
NativeCodeBasicBlock * ForwardAccuBranch(bool eq, bool ne, bool pl, bool mi, int limit);
bool MergeBasicBlocks(void); bool MergeBasicBlocks(void);
void MarkLoopHead(void); void MarkLoopHead(void);
void BuildDominatorTree(NativeCodeBasicBlock * from); void BuildDominatorTree(NativeCodeBasicBlock * from);
@ -379,7 +380,7 @@ public:
bool RegisterValueForwarding(void); bool RegisterValueForwarding(void);
bool CanCombineSameXtoY(int start, int end); bool CanCombineSameXtoY(int start, int end);
bool CanCombineSameYtoX(int start, int end); bool CanCombineSameYtoX(int start, int end);
bool CombineSameXY(void); bool CombineSameXY(void);
bool CombineSameXtoY(int xpos, int ypos, int end); bool CombineSameXtoY(int xpos, int ypos, int end);
bool CombineSameYtoX(int xpos, int ypos, int end); bool CombineSameYtoX(int xpos, int ypos, int end);