diff --git a/oscar64/ByteCodeGenerator.cpp b/oscar64/ByteCodeGenerator.cpp index 2c6992a..17a3120 100644 --- a/oscar64/ByteCodeGenerator.cpp +++ b/oscar64/ByteCodeGenerator.cpp @@ -4561,7 +4561,7 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase) // assert(!(live & LIVE_ACCU)); int accuTemp = -1, addrTemp = -1, accuVal = 0, accuTempByte = -1; - bool accuConst = false; + bool accuConst = false, accuLong = false; for (int i = 0; i < mIns.Size(); i++) { @@ -5564,7 +5564,7 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase) } break; case BC_CONST_32: - if (mIns[i].mValue == accuVal) + if (mIns[i].mValue == accuVal && accuLong) { mIns[i].mCode = BC_NOP; progress = true; @@ -5585,6 +5585,7 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase) accuTemp = -1; accuTempByte = -1; accuConst = false; + accuLong = false; } if (mIns[i].ChangesAddr()) addrTemp = -1; @@ -5613,6 +5614,7 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase) case BC_CONST_32: accuVal = mIns[i].mValue; accuConst = true; + accuLong = true; break; case BC_CONST_8: accuVal = mIns[i].mValue & 0xff; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 8b3ca10..ec2a52d 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -625,6 +625,113 @@ void ValueSet::Intersect(ValueSet& set) mNum = k; } +TempForwardingTable::TempForwardingTable(void) : mAssoc(Assoc(-1, -1, -1)) +{ +} + +TempForwardingTable::TempForwardingTable(const TempForwardingTable& table) : mAssoc(Assoc(-1, -1, -1)) +{ + for (int i = 0; i < table.mAssoc.Size(); i++) + { + mAssoc[i].mAssoc = table.mAssoc[i].mAssoc; + mAssoc[i].mSucc = table.mAssoc[i].mSucc; + mAssoc[i].mPred = table.mAssoc[i].mPred; + } +} + +TempForwardingTable& TempForwardingTable::operator=(const TempForwardingTable& table) +{ + mAssoc.SetSize(table.mAssoc.Size()); + for (int i = 0; i < table.mAssoc.Size(); i++) + { + mAssoc[i].mAssoc = table.mAssoc[i].mAssoc; + mAssoc[i].mSucc = table.mAssoc[i].mSucc; + mAssoc[i].mPred = table.mAssoc[i].mPred; + } + + return *this; +} + +void TempForwardingTable::Intersect(const TempForwardingTable& table) +{ + for (int i = 0; i < table.mAssoc.Size(); i++) + { + if (mAssoc[i].mAssoc != table.mAssoc[i].mAssoc) + this->Destroy(i); + } +} + +void TempForwardingTable::SetSize(int size) +{ + int i; + mAssoc.SetSize(size); + + for (i = 0; i < size; i++) + mAssoc[i] = Assoc(i, i, i); +} + +void TempForwardingTable::Reset(void) +{ + int i; + + for (i = 0; i < mAssoc.Size(); i++) + mAssoc[i] = Assoc(i, i, i); +} + +int TempForwardingTable::operator[](int n) +{ + return mAssoc[n].mAssoc; +} + +void TempForwardingTable::Destroy(int n) +{ + int i, j; + + if (mAssoc[n].mAssoc == n) + { + i = mAssoc[n].mSucc; + while (i != n) + { + j = mAssoc[i].mSucc; + mAssoc[i] = Assoc(i, i, i); + i = j; + } + } + else + { + mAssoc[mAssoc[n].mPred].mSucc = mAssoc[n].mSucc; + mAssoc[mAssoc[n].mSucc].mPred = mAssoc[n].mPred; + } + + mAssoc[n] = Assoc(n, n, n); +} + +void TempForwardingTable::Build(int from, int to) +{ + int i; + + from = mAssoc[from].mAssoc; + to = mAssoc[to].mAssoc; + + if (from != to) + { + i = mAssoc[from].mSucc; + while (i != from) + { + mAssoc[i].mAssoc = to; + i = mAssoc[i].mSucc; + } + mAssoc[from].mAssoc = to; + + mAssoc[mAssoc[to].mSucc].mPred = mAssoc[from].mPred; + mAssoc[mAssoc[from].mPred].mSucc = mAssoc[to].mSucc; + mAssoc[to].mSucc = from; + mAssoc[from].mPred = to; + } +} + + + bool InterInstruction::ReferencesTemp(int temp) const { if (temp == mDst.mTemp) @@ -1710,28 +1817,6 @@ static bool TypeArithmetic(InterType t) return t == IT_INT8 || t == IT_INT16 || t == IT_INT32 || t == IT_BOOL || t == IT_FLOAT; } -static InterType TypeCheckArithmecitResult(InterType t1, InterType t2) -{ - if (t1 == IT_FLOAT && t2 == IT_FLOAT) - return IT_FLOAT; - else if (TypeInteger(t1) && TypeInteger(t2)) - return t1 > t2 ? t1 : t2; - else - throw InterCodeTypeMismatchException(); -} - -static void TypeCheckAssign(InterType& t, InterType s) -{ - if (s == IT_NONE) - throw InterCodeUninitializedException(); - else if (t == IT_NONE) - t = s; - else if (!TypeCompatible(t, s)) - throw InterCodeTypeMismatchException(); -} - - - static void FilterTempUseUsage(NumberSet& requiredTemps, NumberSet& providedTemps, int temp) { if (temp >= 0) @@ -2674,7 +2759,7 @@ void InterInstruction::Disassemble(FILE* file) } InterCodeBasicBlock::InterCodeBasicBlock(void) - : mInstructions(nullptr), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr), mTrueJump(nullptr), mFalseJump(nullptr), mDominator(nullptr), + : mInstructions(nullptr), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr), mTrueJump(nullptr), mFalseJump(nullptr), mLoopPrefix(nullptr), mEntryValueRange(IntegerValueRange()), mTrueValueRange(IntegerValueRange()), mFalseValueRange(IntegerValueRange()), mLocalValueRange(IntegerValueRange()), mEntryBlocks(nullptr) { mInPath = false; @@ -2729,6 +2814,47 @@ void InterCodeBasicBlock::CollectEntryBlocks(InterCodeBasicBlock* from) } } +void InterCodeBasicBlock::BuildDominatorTree(InterCodeBasicBlock* from) +{ + if (!mDominator) + mDominator = from; + else if (from == mDominator) + return; + else + { + GrowingInterCodeBasicBlockPtrArray d1(nullptr), d2(nullptr); + + InterCodeBasicBlock* b = mDominator; + while (b) + { + d1.Push(b); + b = b->mDominator; + } + b = from; + while (b) + { + d2.Push(b); + b = b->mDominator; + } + + b = nullptr; + while (d1.Size() > 0 && d2.Size() > 0 && d1.Last() == d2.Last()) + { + b = d1.Pop(); d2.Pop(); + } + + if (mDominator == b) + return; + + mDominator = b; + } + + if (mTrueJump) + mTrueJump->BuildDominatorTree(this); + if (mFalseJump) + mFalseJump->BuildDominatorTree(this); +} + void InterCodeBasicBlock::CollectEntries(void) { mNumEntries++; @@ -6278,16 +6404,16 @@ InterCodeBasicBlock* InterCodeBasicBlock::PropagateDominator(InterCodeProcedure* if (mLoopHead) { - mDominator = new InterCodeBasicBlock(); - proc->Append(mDominator); + mLoopPrefix = new InterCodeBasicBlock(); + proc->Append(mLoopPrefix); InterInstruction * jins = new InterInstruction(); jins->mCode = IC_JUMP; - mDominator->Append(jins); - mDominator->Close(this, nullptr); + mLoopPrefix->Append(jins); + mLoopPrefix->Close(this, nullptr); } } - return mDominator ? mDominator : this; + return mLoopPrefix ? mLoopPrefix : this; } bool InterCodeBasicBlock::CollectLoopBody(InterCodeBasicBlock* head, GrowingArray & body) @@ -6349,7 +6475,7 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams) for (int i = 0; i < mEntryBlocks.Size(); i++) { - if (mEntryBlocks[i] != mDominator) + if (mEntryBlocks[i] != mLoopPrefix) { if (!mEntryBlocks[i]->CollectLoopBody(this, body)) innerLoop = false; @@ -6581,7 +6707,7 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams) InterInstruction* ins = block->mInstructions[i]; if (ins->mInvariant && ins->mExpensive) { - mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, ins); + mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ins); } else { @@ -6679,7 +6805,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa }; GrowingArray dep(DEP_UNKNOWN); - GrowingArray indexStep(0), indexBase(0); + GrowingArray indexStep(0), indexBase(0); GrowingArray tvalues(nullptr); for (int i = 0; i < mInstructions.Size(); i++) @@ -6787,7 +6913,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa InterInstruction* ins = mInstructions[i]; if (ins->mInvariant) { - mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, ins); + mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ins); } else if (ins->mDst.mTemp >= 0 && dep[ins->mDst.mTemp] == DEP_INDEX) { @@ -6807,7 +6933,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa bins->mDst = ins->mDst; bins->mSrc[0] = ins->mSrc[0]; bins->mSrc[1] = ins->mSrc[1]; - mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, bins); + mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, bins); InterInstruction* ains = new InterInstruction(); ains->mCode = IC_BINARY_OPERATOR; @@ -6815,7 +6941,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa ains->mDst = ins->mDst; ains->mSrc[0] = ins->mDst; ains->mSrc[1] = ins->mSrc[1]; ains->mSrc[1].mIntConst = ins->mSrc[1].mIntConst * indexBase[ins->mSrc[0].mTemp]; - mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, ains); + mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ains); ins->mOperator = IA_ADD; ins->mSrc[1].mIntConst = ins->mSrc[1].mIntConst * indexStep[ins->mSrc[0].mTemp]; @@ -6834,7 +6960,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa bins->mDst = ins->mDst; bins->mSrc[0] = ins->mSrc[0]; bins->mSrc[1] = ins->mSrc[1]; - mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, bins); + mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, bins); InterInstruction* ains = new InterInstruction(); ains->mCode = IC_BINARY_OPERATOR; @@ -6842,7 +6968,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa ains->mDst = ins->mDst; ains->mSrc[1] = ins->mDst; ains->mSrc[0] = ins->mSrc[0]; ains->mSrc[0].mIntConst = ins->mSrc[0].mIntConst * indexBase[ins->mSrc[1].mTemp]; - mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, ains); + mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ains); ins->mOperator = IA_ADD; ins->mSrc[0].mIntConst = ins->mSrc[0].mIntConst * indexStep[ins->mSrc[1].mTemp]; @@ -6861,7 +6987,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa bins->mDst = ins->mDst; bins->mSrc[0] = ins->mSrc[0]; bins->mSrc[1] = ins->mSrc[1]; - mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, bins); + mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, bins); InterInstruction* ains = new InterInstruction(); ains->mCode = IC_BINARY_OPERATOR; @@ -6869,7 +6995,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa ains->mDst = ins->mDst; ains->mSrc[1] = ins->mDst; ains->mSrc[0] = ins->mSrc[0]; ains->mSrc[0].mIntConst = indexBase[ins->mSrc[1].mTemp] << ins->mSrc[0].mIntConst; - mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, ains); + mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ains); ins->mOperator = IA_ADD; ins->mSrc[0].mIntConst = indexStep[ins->mSrc[1].mTemp] << ins->mSrc[0].mIntConst; @@ -6882,7 +7008,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa indexStep[ins->mDst.mTemp] = indexStep[ins->mSrc[1].mTemp]; indexBase[ins->mDst.mTemp] = 0; - mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, ins); + mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ins); InterInstruction* ains = new InterInstruction(); ains->mCode = IC_BINARY_OPERATOR; @@ -6900,7 +7026,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa indexStep[ins->mDst.mTemp] = indexStep[ins->mSrc[0].mTemp]; indexBase[ins->mDst.mTemp] = 0; - mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, ins); + mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ins); InterInstruction* ains = new InterInstruction(); ains->mCode = IC_BINARY_OPERATOR; @@ -6918,7 +7044,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa indexStep[ins->mDst.mTemp] = indexStep[ins->mSrc[0].mTemp]; indexBase[ins->mDst.mTemp] = 0; - mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, ins); + mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ins); InterInstruction* ains = new InterInstruction(); ains->mCode = IC_LEA; @@ -6938,7 +7064,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa indexStep[ins->mDst.mTemp] = indexStep[ins->mSrc[0].mTemp]; indexBase[ins->mDst.mTemp] = indexBase[ins->mSrc[0].mTemp]; - mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, ins); + mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ins); InterInstruction* ains = new InterInstruction(); ains->mCode = ins->mCode; @@ -7454,7 +7580,7 @@ void InterCodeBasicBlock::Disassemble(FILE* file, bool dumpSets) mVisited = true; const char* s = mLoopHead ? "Head" : ""; - fprintf(file, "L%d: (%d) %s\n", mIndex, mNumEntries, s); + fprintf(file, "L%d: <= D%d: (%d) %s \n", mIndex, (mDominator ? mDominator->mIndex : -1), mNumEntries, s); if (dumpSets) { @@ -7560,6 +7686,11 @@ void InterCodeProcedure::BuildTraces(bool expand) for (int i = 0; i < mBlocks.Size(); i++) mBlocks[i]->mNumEntries = 0; mEntryBlock->CollectEntries(); + + ResetVisited(); + for (int i = 0; i < mBlocks.Size(); i++) + mBlocks[i]->mDominator = nullptr; + mEntryBlock->BuildDominatorTree(nullptr); } void InterCodeProcedure::BuildDataFlowSets(void) @@ -8164,6 +8295,17 @@ void InterCodeProcedure::Close(void) BuildTraces(false); +#endif + +#if 1 + ResetVisited(); + mEntryBlock->PeepholeOptimization(); + + TempForwarding(); + RemoveUnusedInstructions(); + + DisassembleDebug("Peephole optimized"); + #endif MapVariables(); diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index ef55807..7814847 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -198,110 +198,22 @@ protected: GrowingArray mAssoc; public: - TempForwardingTable(void) : mAssoc(Assoc(-1, -1, -1)) - { - } + TempForwardingTable(void); + TempForwardingTable(const TempForwardingTable& table); - TempForwardingTable(const TempForwardingTable & table) : mAssoc(Assoc(-1, -1, -1)) - { - for (int i = 0; i < table.mAssoc.Size(); i++) - { - mAssoc[i].mAssoc = table.mAssoc[i].mAssoc; - mAssoc[i].mSucc = table.mAssoc[i].mSucc; - mAssoc[i].mPred = table.mAssoc[i].mPred; - } - } + TempForwardingTable& operator=(const TempForwardingTable& table); - TempForwardingTable& operator=(const TempForwardingTable& table) - { - mAssoc.SetSize(table.mAssoc.Size()); - for (int i = 0; i < table.mAssoc.Size(); i++) - { - mAssoc[i].mAssoc = table.mAssoc[i].mAssoc; - mAssoc[i].mSucc = table.mAssoc[i].mSucc; - mAssoc[i].mPred = table.mAssoc[i].mPred; - } + void Intersect(const TempForwardingTable& table); - return *this; - } + void SetSize(int size); - void Intersect(const TempForwardingTable& table) - { - for (int i = 0; i < table.mAssoc.Size(); i++) - { - if (mAssoc[i].mAssoc != table.mAssoc[i].mAssoc) - this->Destroy(i); - } - } + void Reset(void); - void SetSize(int size) - { - int i; - mAssoc.SetSize(size); + int operator[](int n); - for (i = 0; i < size; i++) - mAssoc[i] = Assoc(i, i, i); - } + void Destroy(int n); - void Reset(void) - { - int i; - - for (i = 0; i < mAssoc.Size(); i++) - mAssoc[i] = Assoc(i, i, i); - } - - int operator[](int n) - { - return mAssoc[n].mAssoc; - } - - void Destroy(int n) - { - int i, j; - - if (mAssoc[n].mAssoc == n) - { - i = mAssoc[n].mSucc; - while (i != n) - { - j = mAssoc[i].mSucc; - mAssoc[i] = Assoc(i, i, i); - i = j; - } - } - else - { - mAssoc[mAssoc[n].mPred].mSucc = mAssoc[n].mSucc; - mAssoc[mAssoc[n].mSucc].mPred = mAssoc[n].mPred; - } - - mAssoc[n] = Assoc(n, n, n); - } - - void Build(int from, int to) - { - int i; - - from = mAssoc[from].mAssoc; - to = mAssoc[to].mAssoc; - - if (from != to) - { - i = mAssoc[from].mSucc; - while (i != from) - { - mAssoc[i].mAssoc = to; - i = mAssoc[i].mSucc; - } - mAssoc[from].mAssoc = to; - - mAssoc[mAssoc[to].mSucc].mPred = mAssoc[from].mPred; - mAssoc[mAssoc[from].mPred].mSucc = mAssoc[to].mSucc; - mAssoc[to].mSucc = from; - mAssoc[from].mPred = to; - } - } + void Build(int from, int to); }; class InterVariable @@ -400,56 +312,11 @@ public: void Disassemble(FILE* file); }; - -class InterCodeException -{ -public: - InterCodeException() - { - } -}; - -class InterCodeStackException : public InterCodeException -{ -public: - InterCodeStackException() - : InterCodeException() - { - } -}; - -class InterCodeUndefinedException : public InterCodeException -{ -public: - InterCodeUndefinedException() - : InterCodeException() - { - } -}; - -class InterCodeTypeMismatchException : public InterCodeException -{ -public: - InterCodeTypeMismatchException() - : InterCodeException() - { - } -}; - -class InterCodeUninitializedException : public InterCodeException -{ -public: - InterCodeUninitializedException() - : InterCodeException() - { - } -}; - class InterCodeBasicBlock { public: int mIndex, mNumEntries, mNumEntered, mTraceIndex; - InterCodeBasicBlock * mTrueJump, * mFalseJump, * mDominator; + InterCodeBasicBlock * mTrueJump, * mFalseJump, * mLoopPrefix, * mDominator; GrowingInstructionArray mInstructions; bool mVisited, mInPath, mLoopHead, mChecked, mConditionBlockTrue, mUnreachable; @@ -487,6 +354,7 @@ public: void CollectEntries(void); void CollectEntryBlocks(InterCodeBasicBlock* from); void GenerateTraces(bool expand); + void BuildDominatorTree(InterCodeBasicBlock * from); void LocalToTemp(int vindex, int temp); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index ec4e221..a120bf9 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -9495,7 +9495,7 @@ bool NativeCodeBasicBlock::PatchGlobalAdressSumYByX(int at, int reg, const Nativ yindex = 0; for (int i = at; i <= last; i++) { - mIns[i].mLive | LIVE_CPU_REG_X; + mIns[i].mLive |= LIVE_CPU_REG_X; if (mIns[i].mType == ASMIT_LDY && mIns[i].mMode == ASMIM_IMMEDIATE) yindex = mIns[i].mAddress; @@ -9561,7 +9561,7 @@ bool NativeCodeBasicBlock::PatchDirectAddressSumY(int at, int reg, int apos, int for (int i = apos; i <= last; i++) { - mIns[i].mLive | LIVE_CPU_REG_Y; + mIns[i].mLive |= LIVE_CPU_REG_Y; if (mIns[i].mType == ASMIT_LDY && mIns[i].mMode == ASMIM_IMMEDIATE) { @@ -9842,6 +9842,7 @@ bool NativeCodeBasicBlock::MoveIndirectLoadStoreDown(int at) { mIns[j].mMode = ASMIM_INDIRECT_Y; mIns[j].mAddress = mIns[at].mAddress; + mIns[j].mLive |= LIVE_MEM; mIns[at + 0].mType = ASMIT_NOP; mIns[at + 0].mMode = ASMIM_IMPLIED; mIns[at + 1].mType = ASMIT_NOP; mIns[at + 1].mMode = ASMIM_IMPLIED; @@ -12430,7 +12431,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) if (FindAddressSumY(i, sreg, apos, breg, ireg)) { #if 1 - if (!(breg == sreg || ireg == sreg)|| !(mIns[i + 0].mLive & LIVE_MEM)) + if (!(breg == sreg || ireg == sreg) || !(mIns[i + 0].mLive & LIVE_MEM)) { if (breg == sreg || ireg == sreg) {