From 83869ad3a0a40610b41bfc1e6c7dd200f94b6364 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Mon, 13 Mar 2023 22:13:02 +0100 Subject: [PATCH] Shortcut redundant conditional branch sequences --- oscar64/InterCode.cpp | 3 + oscar64/NativeCodeGenerator.cpp | 145 +++++++++++++++++++++++++++----- oscar64/NativeCodeGenerator.h | 3 +- 3 files changed, 127 insertions(+), 24 deletions(-) diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 3aa8045..d534a22 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -10858,6 +10858,9 @@ bool InterCodeBasicBlock::CollectSingleHeadLoopBody(InterCodeBasicBlock* head, I int i = 0; body.Push(head); + if (head == tail) + return true; + while (i < body.Size()) { InterCodeBasicBlock* block = body[i++]; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 0562e1e..4ca0818 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -12147,6 +12147,48 @@ bool NativeCodeBasicBlock::MergeSameBlocks(NativeCodeProcedure* nproc) 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 changed = false; @@ -12254,6 +12296,49 @@ bool NativeCodeBasicBlock::MergeBasicBlocks(void) mFalseJump = nullptr; 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) @@ -25273,6 +25358,7 @@ bool NativeCodeBasicBlock::BitFieldForwarding(const NativeRegisterDataSet& data) mIns.Insert(i + 1, NativeCodeInstruction(carryop)); } } + if (mFalseJump) { mFDataSet = mNDataSet; @@ -25281,14 +25367,14 @@ bool NativeCodeBasicBlock::BitFieldForwarding(const NativeRegisterDataSet& data) { const NativeCodeInstruction& lins(mIns[mIns.Size() - 1]); - if (lins.mMode == ASMIM_ZERO_PAGE && lins.mType == ASMIT_LDA) + if (lins.ChangesAccuAndFlag()) { switch (mBranch) { 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 = mFalseJump; @@ -25306,14 +25392,18 @@ bool NativeCodeBasicBlock::BitFieldForwarding(const NativeRegisterDataSet& data) { mNDataSet.mRegs[CPU_REG_A].mMask = 0xff; 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; 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 = mFalseJump; @@ -25331,14 +25421,18 @@ bool NativeCodeBasicBlock::BitFieldForwarding(const NativeRegisterDataSet& data) { mFDataSet.mRegs[CPU_REG_A].mMask = 0xff; 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; 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 = mFalseJump; @@ -25359,16 +25453,19 @@ bool NativeCodeBasicBlock::BitFieldForwarding(const NativeRegisterDataSet& data) mFDataSet.mRegs[CPU_REG_A].mMask |= 0x80; mFDataSet.mRegs[CPU_REG_A].mValue |= 0x80; - mNDataSet.mRegs[lins.mAddress].mMask |= 0x80; - mNDataSet.mRegs[lins.mAddress].mValue &= 0x7f; - mFDataSet.mRegs[lins.mAddress].mMask |= 0x80; - mFDataSet.mRegs[lins.mAddress].mValue |= 0x80; + if (lins.mMode == ASMIM_ZERO_PAGE && lins.mType == ASMIT_LDA) + { + mNDataSet.mRegs[lins.mAddress].mMask |= 0x80; + mNDataSet.mRegs[lins.mAddress].mValue &= 0x7f; + mFDataSet.mRegs[lins.mAddress].mMask |= 0x80; + mFDataSet.mRegs[lins.mAddress].mValue |= 0x80; + } } break; 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 = mFalseJump; @@ -25389,10 +25486,13 @@ bool NativeCodeBasicBlock::BitFieldForwarding(const NativeRegisterDataSet& data) mNDataSet.mRegs[CPU_REG_A].mMask |= 0x80; mNDataSet.mRegs[CPU_REG_A].mValue |= 0x80; - mFDataSet.mRegs[lins.mAddress].mMask |= 0x80; - mFDataSet.mRegs[lins.mAddress].mValue &= 0x7f; - mNDataSet.mRegs[lins.mAddress].mMask |= 0x80; - mNDataSet.mRegs[lins.mAddress].mValue |= 0x80; + if (lins.mMode == ASMIM_ZERO_PAGE && lins.mType == ASMIT_LDA) + { + mFDataSet.mRegs[lins.mAddress].mMask |= 0x80; + mFDataSet.mRegs[lins.mAddress].mValue &= 0x7f; + mNDataSet.mRegs[lins.mAddress].mMask |= 0x80; + mNDataSet.mRegs[lins.mAddress].mValue |= 0x80; + } } break; } @@ -37427,7 +37527,7 @@ void NativeCodeProcedure::RebuildEntry(void) void NativeCodeProcedure::Optimize(void) { - CheckFunc = !strcmp(mInterProc->mIdent->mString, "main"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "move"); #if 1 int step = 0; @@ -38051,7 +38151,6 @@ void NativeCodeProcedure::Optimize(void) else cnt++; - } while (changed); #if 1 diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index c92fa6d..b497f9c 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -311,6 +311,7 @@ public: bool MergeSameBlocks(NativeCodeProcedure* nproc); void CountEntries(NativeCodeBasicBlock* fromJump); + NativeCodeBasicBlock * ForwardAccuBranch(bool eq, bool ne, bool pl, bool mi, int limit); bool MergeBasicBlocks(void); void MarkLoopHead(void); void BuildDominatorTree(NativeCodeBasicBlock * from); @@ -379,7 +380,7 @@ public: bool RegisterValueForwarding(void); bool CanCombineSameXtoY(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 CombineSameYtoX(int xpos, int ypos, int end);