diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 649574f..45ac76e 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -4321,6 +4321,8 @@ static void OptimizeAddress(InterInstruction * ins, const GrowingInstructionPtrA { ins->mSrc[offset].mIntConst += ains->mSrc[0].mIntConst; ins->mSrc[offset].mTemp = ains->mSrc[1].mTemp; + ins->mSrc[offset].mFinal = false; + ains->mSrc[1].mFinal = false; } else if (ains->mCode == IC_BINARY_OPERATOR && ains->mOperator == IA_ADD && ains->mSrc[0].mTemp < 0 && ains->mSrc[1].mTemp >= 0 && tvalue[ains->mSrc[1].mTemp] && ains->mSrc[0].mIntConst >= 0) { @@ -4340,7 +4342,7 @@ static void OptimizeAddress(InterInstruction * ins, const GrowingInstructionPtrA } -void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const GrowingVariableArray& staticVars) +void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const GrowingVariableArray& staticVars, FastNumberSet& fsingle) { switch (ins->mCode) { @@ -4467,6 +4469,28 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI ins->mNumOperands = 1; assert(ins->mSrc[0].mTemp >= 0); } +#if 1 + else if (ins->mSrc[1].mTemp >= 0 && fsingle[ins->mSrc[1].mTemp]) + { + InterInstruction* lins = tvalue[ins->mSrc[1].mTemp]; + while (lins && lins->mCode == IC_LEA && lins->mSrc[1].mTemp >= 0 && fsingle[ins->mSrc[1].mTemp]) + lins = tvalue[lins->mSrc[1].mTemp]; + if (lins && lins->mSrc[1].mTemp < 0 && (lins->mSrc[1].mMemory == IM_ABSOLUTE || lins->mSrc[1].mMemory == IM_GLOBAL)) + { + lins->mSrc[1].mIntConst += tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst; + ins->mCode = IC_LOAD_TEMPORARY; + ins->mSrc[0].mType = ins->mSrc[1].mType; + ins->mSrc[0].mTemp = ins->mSrc[1].mTemp; + ins->mSrc[1].mTemp = -1; + ins->mNumOperands = 1; + } + else + { + ins->mSrc[0].mIntConst = tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst; + ins->mSrc[0].mTemp = -1; + } + } +#endif else { ins->mSrc[0].mIntConst = tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst; @@ -7017,6 +7041,39 @@ bool InterCodeBasicBlock::SingleAssignmentTempForwarding(const GrowingInstructio return changed; } +void InterCodeBasicBlock::CalculateSingleUsedTemps(FastNumberSet& fused, FastNumberSet& fsingle) +{ + if (!mVisited) + { + mVisited = true; + + for (int i = 0; i < mInstructions.Size(); i++) + { + InterInstruction* ins = mInstructions[i]; + + for (int j = 0; j < ins->mNumOperands; j++) + { + if (ins->mSrc[j].mTemp >= 0) + { + if (fused[ins->mSrc[j].mTemp]) + fsingle -= ins->mSrc[j].mTemp; + else + { + fused += ins->mSrc[j].mTemp; + fsingle += ins->mSrc[j].mTemp; + } + } + } + } + + if (mTrueJump) + mTrueJump->CalculateSingleUsedTemps(fused, fsingle); + if (mFalseJump) + mFalseJump->CalculateSingleUsedTemps(fused, fsingle); + } +} + + bool InterCodeBasicBlock::CalculateSingleAssignmentTemps(FastNumberSet& tassigned, GrowingInstructionPtrArray& tvalue, NumberSet& modifiedParams, InterMemory paramMemory) { bool changed = false; @@ -8559,7 +8616,7 @@ void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArra } } -void InterCodeBasicBlock::PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid, const GrowingVariableArray& staticVars) +void InterCodeBasicBlock::PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid, const GrowingVariableArray& staticVars, FastNumberSet &fsingle) { int i; @@ -8609,12 +8666,12 @@ void InterCodeBasicBlock::PerformMachineSpecificValueUsageCheck(const GrowingIns for (i = 0; i < mInstructions.Size(); i++) { - CheckValueUsage(mInstructions[i], ltvalue, staticVars); + CheckValueUsage(mInstructions[i], ltvalue, staticVars, fsingle); mInstructions[i]->PerformValueForwarding(ltvalue, tvalid); } - if (mTrueJump) mTrueJump->PerformMachineSpecificValueUsageCheck(ltvalue, tvalid, staticVars); - if (mFalseJump) mFalseJump->PerformMachineSpecificValueUsageCheck(ltvalue, tvalid, staticVars); + if (mTrueJump) mTrueJump->PerformMachineSpecificValueUsageCheck(ltvalue, tvalid, staticVars, fsingle); + if (mFalseJump) mFalseJump->PerformMachineSpecificValueUsageCheck(ltvalue, tvalid, staticVars, fsingle); } } @@ -8868,6 +8925,29 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray& ins->mNumOperands = 1; changed = true; } + else if (ins->mCode == IC_LEA && ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mMemory == IM_ABSOLUTE && ins->mSrc[0].mTemp >= 0) + { + int offset = ins->mSrc[1].mIntConst; + + j = 0; + while (j < mLoadStoreInstructions.Size() && !( + mLoadStoreInstructions[j]->mCode == IC_LEA && mLoadStoreInstructions[j]->mSrc[1].mTemp < 0 && mLoadStoreInstructions[j]->mSrc[1].mMemory == IM_ABSOLUTE && + mLoadStoreInstructions[j]->mSrc[0].mTemp == ins->mSrc[0].mTemp && + (((mLoadStoreInstructions[j]->mSrc[0].mIntConst + mLoadStoreInstructions[j]->mSrc[1].mIntConst - offset) & 255) == 0))) + j++; + if (j < mLoadStoreInstructions.Size()) + { + ins->mSrc[1] = mLoadStoreInstructions[j]->mDst; + ins->mSrc[1].mMemory = IM_INDIRECT; + ins->mSrc[1].mIntConst = 0; + + ins->mSrc[0].mTemp = -1; + ins->mSrc[0].mIntConst = offset - mLoadStoreInstructions[j]->mSrc[1].mIntConst; + changed = true; + } + else + nins = ins; + } else nins = ins; } @@ -14595,8 +14675,14 @@ void InterCodeProcedure::Close(void) mValueForwardingTable.SetSize(numTemps, true); mTemporaries.SetSize(numTemps, true); + RemoveUnusedInstructions(); + + FastNumberSet fusedSet(numTemps), fsingleSet(numTemps); ResetVisited(); - mEntryBlock->PerformMachineSpecificValueUsageCheck(mValueForwardingTable, tvalidSet, mModule->mGlobalVars); + mEntryBlock->CalculateSingleUsedTemps(fusedSet, fsingleSet); + + ResetVisited(); + mEntryBlock->PerformMachineSpecificValueUsageCheck(mValueForwardingTable, tvalidSet, mModule->mGlobalVars, fsingleSet); GlobalConstantPropagation(); @@ -14859,6 +14945,10 @@ void InterCodeProcedure::Close(void) BuildLoopPrefix(); DisassembleDebug("added dominators"); + ResetEntryBlocks(); + ResetVisited(); + mEntryBlock->CollectEntryBlocks(nullptr); + BuildDataFlowSets(); ResetVisited(); @@ -15008,6 +15098,30 @@ void InterCodeProcedure::Close(void) DisassembleDebug("Rebuilt traces"); #endif +#if 1 + BuildLoopPrefix(); + DisassembleDebug("added dominators"); + + ResetEntryBlocks(); + ResetVisited(); + mEntryBlock->CollectEntryBlocks(nullptr); + + BuildDataFlowSets(); + + ResetVisited(); + mEntryBlock->InnerLoopOptimization(mParamAliasedSet); + + DisassembleDebug("inner loop opt 3"); + + BuildDataFlowSets(); + + ResetEntryBlocks(); + ResetVisited(); + mEntryBlock->CollectEntryBlocks(nullptr); + + BuildTraces(false); +#endif + PropagateConstOperationsUp(); diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index 2a92822..16423bc 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -438,10 +438,10 @@ public: void BuildGlobalRenameRegisterTable(const GrowingIntArray& renameTable, GrowingIntArray& globalRenameTable); void GlobalRenameRegister(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries); - void CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const GrowingVariableArray& staticVars); + void CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const GrowingVariableArray& staticVars, FastNumberSet& fsingle); void PerformTempForwarding(const TempForwardingTable& forwardingTable, bool reverse); void PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, int & spareTemps, const GrowingVariableArray& staticVars); - void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid, const GrowingVariableArray& staticVars); + void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid, const GrowingVariableArray& staticVars, FastNumberSet& fsingle); bool EliminateDeadBranches(void); bool MergeIndexedLoadStore(const GrowingInstructionPtrArray& tvalue); @@ -449,6 +449,8 @@ public: bool SimplifyPointerOffsets(void); bool EliminateAliasValues(const GrowingInstructionPtrArray& tvalue, const GrowingInstructionPtrArray& avalue); + void CalculateSingleUsedTemps(FastNumberSet& fused, FastNumberSet& fsingle); + bool CalculateSingleAssignmentTemps(FastNumberSet& tassigned, GrowingInstructionPtrArray& tvalue, NumberSet& modifiedParams, InterMemory paramMemory); bool SingleAssignmentTempForwarding(const GrowingInstructionPtrArray& tunified, const GrowingInstructionPtrArray& tvalues); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 45b7927..5734d39 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -2,6 +2,7 @@ #include "CompilerTypes.h" static bool CheckFunc; +static bool CheckCase; static const int CPU_REG_A = 256; @@ -21782,6 +21783,8 @@ bool NativeCodeBasicBlock::ReplaceZeroPageUp(int at) return false; if (mIns[i].mMode == ASMIM_INDIRECT_Y && (mIns[i].mAddress == mIns[at + 1].mAddress || mIns[i].mAddress + 1 == mIns[at + 1].mAddress)) return false; + if (mIns[i].mMode == ASMIM_INDIRECT_Y && (mIns[i].mAddress == mIns[at].mAddress || mIns[i].mAddress + 1 == mIns[at].mAddress)) + return false; i--; } @@ -21971,6 +21974,7 @@ bool NativeCodeBasicBlock::Check16BitSum(int at, NativeRegisterSum16Info& info) info.mSrcH = &(mIns[at + 5]); info.mAddL = &(mIns[at + 1]); info.mAddH = &(mIns[at + 4]); + info.mImmediate = true; return true; } @@ -21982,6 +21986,7 @@ bool NativeCodeBasicBlock::Check16BitSum(int at, NativeRegisterSum16Info& info) info.mSrcH = &(mIns[at + 5]); info.mAddL = &(mIns[at + 1]); info.mAddH = &(mIns[at + 4]); + info.mImmediate = true; return true; } @@ -21996,6 +22001,7 @@ bool NativeCodeBasicBlock::Check16BitSum(int at, NativeRegisterSum16Info& info) info.mSrcH = &(mIns[at + 4]); info.mAddL = &(mIns[at + 2]); info.mAddH = &(mIns[at + 5]); + info.mImmediate = true; return true; } @@ -22007,10 +22013,22 @@ bool NativeCodeBasicBlock::Check16BitSum(int at, NativeRegisterSum16Info& info) info.mSrcH = &(mIns[at + 4]); info.mAddL = &(mIns[at + 2]); info.mAddH = &(mIns[at + 5]); + info.mImmediate = true; return true; } } + + if (mIns[at + 1].mMode == ASMIM_ZERO_PAGE && mIns[at + 4].mMode == ASMIM_ZERO_PAGE) + { + info.mSrcL = &(mIns[at + 1]); + info.mSrcH = &(mIns[at + 4]); + info.mAddL = &(mIns[at + 2]); + info.mAddH = &(mIns[at + 5]); + info.mImmediate = false; + + return true; + } } else if (mIns[at + 0].mType == ASMIT_LDA && mIns[at + 1].mType == ASMIT_CLC && @@ -22033,6 +22051,7 @@ bool NativeCodeBasicBlock::Check16BitSum(int at, NativeRegisterSum16Info& info) info.mSrcH = &(mIns[at + 5]); info.mAddL = &(mIns[at + 0]); info.mAddH = &(mIns[at + 4]); + info.mImmediate = true; return true; } @@ -22044,6 +22063,7 @@ bool NativeCodeBasicBlock::Check16BitSum(int at, NativeRegisterSum16Info& info) info.mSrcH = &(mIns[at + 5]); info.mAddL = &(mIns[at + 0]); info.mAddH = &(mIns[at + 4]); + info.mImmediate = true; return true; } @@ -22058,6 +22078,7 @@ bool NativeCodeBasicBlock::Check16BitSum(int at, NativeRegisterSum16Info& info) info.mSrcH = &(mIns[at + 4]); info.mAddL = &(mIns[at + 2]); info.mAddH = &(mIns[at + 5]); + info.mImmediate = true; return true; } @@ -22069,6 +22090,7 @@ bool NativeCodeBasicBlock::Check16BitSum(int at, NativeRegisterSum16Info& info) info.mSrcH = &(mIns[at + 4]); info.mAddL = &(mIns[at + 2]); info.mAddH = &(mIns[at + 5]); + info.mImmediate = true; return true; } @@ -22523,41 +22545,56 @@ bool NativeCodeBasicBlock::Propagate16BitSum(void) { if (info.mSrcL->mAddress == infos[j].mDstL->mAddress && info.mSrcH->mAddress == infos[j].mDstH->mAddress) { - if (!info.mLinkerObject && !infos[j].mLinkerObject) + if (info.mImmediate && infos[j].mImmediate) { - info.mAddress += infos[j].mAddress; - info.mAddL->mAddress = info.mAddress & 0xff; - info.mAddH->mAddress = info.mAddress >> 8; - info.mSrcL->mAddress = infos[j].mSrcL->mAddress; - info.mSrcH->mAddress = infos[j].mSrcH->mAddress; - info.mSrcH->mMode = infos[j].mSrcH->mMode; - changed = true; + if (!info.mLinkerObject && !infos[j].mLinkerObject) + { + info.mAddress += infos[j].mAddress; + info.mAddL->mAddress = info.mAddress & 0xff; + info.mAddH->mAddress = info.mAddress >> 8; + info.mSrcL->mAddress = infos[j].mSrcL->mAddress; + info.mSrcH->mAddress = infos[j].mSrcH->mAddress; + info.mSrcH->mMode = infos[j].mSrcH->mMode; + changed = true; + } + else if (!infos[j].mLinkerObject) + { + info.mAddress += infos[j].mAddress; + info.mAddL->mAddress = info.mAddress; + info.mAddH->mAddress = info.mAddress; + info.mSrcL->mAddress = infos[j].mSrcL->mAddress; + info.mSrcH->mAddress = infos[j].mSrcH->mAddress; + info.mSrcH->mMode = infos[j].mSrcH->mMode; + changed = true; + } + else if (!info.mLinkerObject) + { + info.mAddress += infos[j].mAddress; + info.mLinkerObject = infos[j].mLinkerObject; + info.mAddL->mAddress = info.mAddress; + info.mAddL->mLinkerObject = info.mLinkerObject; + info.mAddL->mMode = ASMIM_IMMEDIATE_ADDRESS; + info.mAddL->mFlags = NCIF_LOWER; + info.mAddH->mAddress = info.mAddress; + info.mAddH->mLinkerObject = info.mLinkerObject; + info.mAddH->mMode = ASMIM_IMMEDIATE_ADDRESS; + info.mAddH->mFlags = NCIF_UPPER; + info.mSrcL->mAddress = infos[j].mSrcL->mAddress; + info.mSrcH->mAddress = infos[j].mSrcH->mAddress; + info.mSrcH->mMode = infos[j].mSrcH->mMode; + changed = true; + } } - else if (!infos[j].mLinkerObject) + } + else if (info.mSrcL->mAddress == infos[j].mSrcL->mAddress && info.mSrcH->mAddress == infos[j].mSrcH->mAddress) + { + if (info.mAddH->mMode == ASMIM_IMMEDIATE && infos[j].mAddH->mMode == ASMIM_IMMEDIATE && + info.mAddL->mMode == ASMIM_ZERO_PAGE && infos[j].mAddL->mMode == ASMIM_ZERO_PAGE && info.mAddL->mAddress == infos[j].mAddL->mAddress) { - info.mAddress += infos[j].mAddress; - info.mAddL->mAddress = info.mAddress; - info.mAddH->mAddress = info.mAddress; - info.mSrcL->mAddress = infos[j].mSrcL->mAddress; - info.mSrcH->mAddress = infos[j].mSrcH->mAddress; - info.mSrcH->mMode = infos[j].mSrcH->mMode; - changed = true; - } - else if (!info.mLinkerObject) - { - info.mAddress += infos[j].mAddress; - info.mLinkerObject = infos[j].mLinkerObject; - info.mAddL->mAddress = info.mAddress; - info.mAddL->mLinkerObject = info.mLinkerObject; - info.mAddL->mMode = ASMIM_IMMEDIATE_ADDRESS; - info.mAddL->mFlags = NCIF_LOWER; - info.mAddH->mAddress = info.mAddress; - info.mAddH->mLinkerObject = info.mLinkerObject; - info.mAddH->mMode = ASMIM_IMMEDIATE_ADDRESS; - info.mAddH->mFlags = NCIF_UPPER; - info.mSrcL->mAddress = infos[j].mSrcL->mAddress; - info.mSrcH->mAddress = infos[j].mSrcH->mAddress; - info.mSrcH->mMode = infos[j].mSrcH->mMode; + info.mAddL->mType = ASMIT_NOP; info.mAddL->mMode = ASMIM_IMPLIED; + info.mSrcL->mAddress = infos[j].mDstL->mAddress; + info.mSrcH->mAddress = infos[j].mDstH->mAddress; + info.mAddH->mAddress -= infos[j].mAddH->mAddress; changed = true; } } @@ -22575,6 +22612,8 @@ bool NativeCodeBasicBlock::Propagate16BitSum(void) if ( infos[j].mSrcL->MayBeChangedOnAddress(mIns[i]) || infos[j].mSrcH->MayBeChangedOnAddress(mIns[i]) || + infos[j].mAddL->MayBeChangedOnAddress(mIns[i]) || + infos[j].mAddH->MayBeChangedOnAddress(mIns[i]) || infos[j].mDstL->MayBeChangedOnAddress(mIns[i]) || infos[j].mDstH->MayBeChangedOnAddress(mIns[i])) { @@ -26344,6 +26383,9 @@ bool NativeCodeBasicBlock::OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCo block->mIns[i].mLive |= LIVE_CPU_REG_Y; } } + + block->mEntryRequiredRegs += CPU_REG_Y; + block->mExitRequiredRegs += CPU_REG_Y; } tail->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); @@ -26421,6 +26463,9 @@ bool NativeCodeBasicBlock::OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCo block->mIns[i].mLive |= LIVE_CPU_REG_X; } } + + block->mEntryRequiredRegs += CPU_REG_X; + block->mExitRequiredRegs += CPU_REG_X; } tail->mIns.Push(NativeCodeInstruction(ASMIT_INX, ASMIM_IMPLIED)); @@ -33493,6 +33538,33 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass } } #endif +#if 1 + if (mIns[i + 0].mType == ASMIT_CLC && + mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && + mIns[i + 2].mType == ASMIT_ADC && (mIns[i + 2].mMode == ASMIM_ZERO_PAGE || mIns[i + 2].mMode == ASMIM_ABSOLUTE) && + mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && + mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_ZERO_PAGE && mIns[i + 4].mAddress == mIns[i + 1].mAddress + 1 && + mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && + mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 3].mAddress + 1 && + !(mIns[i + 6].mLive & LIVE_CPU_REG_A)) + { + int yval = RetrieveYValue(i); + proc->ResetPatched(); + if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 2], i + 7, yval)) + { + proc->ResetPatched(); + if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 2], i + 7, yval)) + progress = true; + + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + + if (mTrueJump) + mTrueJump->CheckLive(); + if (mFalseJump) + mFalseJump->CheckLive(); + } + } +#endif #if 1 if ( mIns[i + 0].mType == ASMIT_CLC && @@ -35260,7 +35332,7 @@ void NativeCodeProcedure::RebuildEntry(void) void NativeCodeProcedure::Optimize(void) { - CheckFunc = !strcmp(mInterProc->mIdent->mString, "memmove"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "disp_menu_color"); #if 1 int step = 0; diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index 7d0a278..83fe731 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -60,6 +60,7 @@ struct NativeRegisterSum16Info { NativeCodeInstruction * mSrcL, * mSrcH, * mDstL, * mDstH, * mAddL, * mAddH; + bool mImmediate; int mAddress; LinkerObject * mLinkerObject; };