diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 4c60638..b20e417 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -4583,6 +4583,30 @@ bool InterCodeBasicBlock::PropagateNonLocalUsedConstTemps(void) return changed; } +void InterCodeBasicBlock::CollectAllUsedDefinedTemps(NumberSet& defined, NumberSet& used) +{ + if (!mVisited) + { + mVisited = true; + + for (int i = 0; i < mInstructions.Size(); i++) + { + InterInstruction* ins(mInstructions[i]); + + if (ins->mDst.mTemp >= 0) + defined += ins->mDst.mTemp; + for (int j = 0; j < ins->mNumOperands; j++) + { + if (ins->mSrc[j].mTemp >= 0) + used += ins->mSrc[j].mTemp; + } + } + + if (mTrueJump) mTrueJump->CollectAllUsedDefinedTemps(defined, used); + if (mFalseJump) mFalseJump->CollectAllUsedDefinedTemps(defined, used); + } +} + void InterCodeBasicBlock::CollectLocalUsedTemps(int numTemps) { if (!mVisited) @@ -9995,6 +10019,24 @@ void InterCodeBasicBlock::CompactInstructions(void) } } +static void SwapInstructions(InterInstruction* it, InterInstruction* ib) +{ + for (int i = 0; i < ib->mNumOperands; i++) + { + if (ib->mSrc[i].mTemp >= 0 && ib->mSrc[i].mFinal) + { + for (int j = 0; j < it->mNumOperands; j++) + { + if (it->mSrc[j].mTemp == ib->mSrc[i].mTemp) + { + it->mSrc[j].mFinal = true; + ib->mSrc[i].mFinal = false; + } + } + } + } +} + void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& staticVars) { int i; @@ -10070,6 +10112,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati int j = i; while (j < limit && CanBypass(ins, mInstructions[j + 1])) { + SwapInstructions(ins, mInstructions[j + 1]); mInstructions[j] = mInstructions[j + 1]; j++; } @@ -10098,6 +10141,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati int j = i; while (j < limit && CanBypassLoad(ins, mInstructions[j + 1])) { + SwapInstructions(ins, mInstructions[j + 1]); mInstructions[j] = mInstructions[j + 1]; j++; } @@ -10120,6 +10164,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati int j = i; while (j < k) { + SwapInstructions(ins, mInstructions[j + 1]); mInstructions[j] = mInstructions[j + 1]; j++; } @@ -10133,6 +10178,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati int j = i; while (j < limit && CanBypass(ins, mInstructions[j + 1])) { + SwapInstructions(ins, mInstructions[j + 1]); mInstructions[j] = mInstructions[j + 1]; j++; } @@ -10187,6 +10233,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati int j = i; while (j > 0 && CanBypassStore(ins, mInstructions[j - 1])) { + SwapInstructions(mInstructions[j - 1], ins); mInstructions[j] = mInstructions[j - 1]; j--; } @@ -10199,6 +10246,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati int j = i; while (j > 0 && CanBypassUp(ins, mInstructions[j - 1])) { + SwapInstructions(mInstructions[j - 1], ins); mInstructions[j] = mInstructions[j - 1]; j--; } @@ -10211,17 +10259,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati int j = i; while (j > 0 && CanBypassLoadUp(ins, mInstructions[j - 1])) { - if (ins->mSrc[0].mFinal) - { - for (int k = 0; k < mInstructions[j - 1]->mNumOperands; k++) - { - if (mInstructions[j - 1]->mSrc[k].mTemp == ins->mSrc[0].mTemp) - { - mInstructions[j - 1]->mSrc[k].mFinal = true; - ins->mSrc[0].mFinal = false; - } - } - } + SwapInstructions(mInstructions[j - 1], ins); mInstructions[j] = mInstructions[j - 1]; j--; } @@ -10244,18 +10282,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati int j = i; while (j < limit && CanBypassLoad(ins, mInstructions[j + 1])) { - if (!ins->mSrc[0].mFinal) - { - for (int k = 0; k < mInstructions[j + 1]->mNumOperands; k++) - { - if (mInstructions[j + 1]->mSrc[k].mTemp == ins->mSrc[0].mTemp && mInstructions[j + 1]->mSrc[k].mFinal) - { - mInstructions[j + 1]->mSrc[k].mFinal = false; - ins->mSrc[0].mFinal = true; - } - } - } - + SwapInstructions(ins, mInstructions[j + 1]); mInstructions[j] = mInstructions[j + 1]; j++; } @@ -10268,6 +10295,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati int j = i; while (j < limit && CanBypass(ins, mInstructions[j + 1])) { + SwapInstructions(ins, mInstructions[j + 1]); mInstructions[j] = mInstructions[j + 1]; j++; } @@ -10323,6 +10351,11 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati mInstructions[i + 1]->mCode == IC_LOAD_TEMPORARY && mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i]->mDst.mTemp && (mInstructions[i + 2]->mCode == IC_RELATIONAL_OPERATOR || mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR) && mInstructions[i + 2]->mSrc[0].mTemp == mInstructions[i]->mDst.mTemp && mInstructions[i + 2]->mSrc[0].mFinal) { +#if _DEBUG + for (int j = i + 3; j < mInstructions.Size(); j++) + assert(!mInstructions[j]->ReferencesTemp(mInstructions[i]->mDst.mTemp)); +#endif + int t = mInstructions[i + 0]->mDst.mTemp; mInstructions[i + 0]->mDst.mTemp = mInstructions[i + 1]->mDst.mTemp; mInstructions[i + 1]->mCode = IC_NONE; @@ -10339,6 +10372,11 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati mInstructions[i + 1]->mCode == IC_LOAD_TEMPORARY && mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i]->mDst.mTemp && (mInstructions[i + 2]->mCode == IC_RELATIONAL_OPERATOR || mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR) && mInstructions[i + 2]->mSrc[1].mTemp == mInstructions[i]->mDst.mTemp && mInstructions[i + 2]->mSrc[1].mFinal) { +#if _DEBUG + for (int j = i + 3; j < mInstructions.Size(); j++) + assert(!mInstructions[j]->ReferencesTemp(mInstructions[i]->mDst.mTemp)); +#endif + mInstructions[i + 0]->mDst.mTemp = mInstructions[i + 1]->mDst.mTemp; mInstructions[i + 1]->mCode = IC_NONE; mInstructions[i + 2]->mSrc[1].mTemp = mInstructions[i + 1]->mDst.mTemp; @@ -11213,10 +11251,30 @@ void InterCodeProcedure::SingleAssignmentForwarding(void) } +void InterCodeProcedure::CheckUsedDefinedTemps(void) +{ +#if _DEBUG + int numTemps = mTemporaries.Size(); + + NumberSet defined(numTemps), used(numTemps); + + ResetVisited(); + mEntryBlock->CollectAllUsedDefinedTemps(defined, used); + + for (int i = 0; i < numTemps; i++) + { + assert(!used[i] || defined[i]); + } + +#endif +} + void InterCodeProcedure::TempForwarding(void) { int numTemps = mTemporaries.Size(); + CheckUsedDefinedTemps(); + ValueSet valueSet; FastNumberSet tvalidSet(numTemps); @@ -11425,10 +11483,12 @@ void InterCodeProcedure::PromoteSimpleLocalsToTemp(InterMemory paramMemory, int void InterCodeProcedure::SimplifyIntegerNumeric(FastNumberSet& activeSet) { GrowingInstructionPtrArray silvalues(nullptr); - int silvused; + int silvused = mTemporaries.Size(); do { + mTemporaries.SetSize(silvused, true); + BuildDataFlowSets(); TempForwarding(); @@ -11677,12 +11737,17 @@ void InterCodeProcedure::Close(void) BuildDataFlowSets(); #endif + CheckUsedDefinedTemps(); SingleAssignmentForwarding(); + CheckUsedDefinedTemps(); + ResetVisited(); mEntryBlock->PeepholeOptimization(mModule->mGlobalVars); + DisassembleDebug("Broken Peephole"); + TempForwarding(); RemoveUnusedInstructions(); diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index 115bafc..ff85320 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -377,6 +377,8 @@ public: void LocalToTemp(int vindex, int temp); + void CollectAllUsedDefinedTemps(NumberSet& defined, NumberSet& used); + void CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable); void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams); @@ -565,6 +567,7 @@ protected: void LoadStoreForwarding(InterMemory paramMemory); void MergeBasicBlocks(void); + void CheckUsedDefinedTemps(void); void DisassembleDebug(const char* name); }; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 0370878..93ed746 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -6269,6 +6269,15 @@ void NativeCodeBasicBlock::ShiftRegisterLeftFromByte(InterCodeProcedure* proc, i if (shift == 0) { + } + else if (shift >= 8) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, reg)); + for (int i = 8; i < shift; i++) + mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); } else if (shift == 1) {