diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index de32e82..c0a2c13 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -277,6 +277,90 @@ void NativeRegisterDataSet::Intersect(const NativeRegisterDataSet& set) } while (changed); } +ValueNumberingData::ValueNumberingData(void) +{ + mIndex = GlobalValueNumber++; + mOffset = 0; +} + +void ValueNumberingData::Reset(void) +{ + mIndex = GlobalValueNumber++; + mOffset = 0; +} + +bool ValueNumberingData::SameBase(const ValueNumberingData& d) const +{ + return mIndex == d.mIndex; +} + +void ValueNumberingDataSet::Reset(void) +{ + for (int i = 0; i < 261; i++) + mRegs[i].Reset(); +} + +void ValueNumberingDataSet::ResetWorkRegs(void) +{ + mRegs[BC_REG_WORK_Y].Reset(); + mRegs[BC_REG_ADDR].Reset(); + mRegs[BC_REG_ADDR + 1].Reset(); + + for (int i = 0; i < 4; i++) + mRegs[BC_REG_ACCU + i].Reset(); + for (int i = 0; i < 8; i++) + mRegs[BC_REG_WORK + i].Reset(); +} + +void ValueNumberingDataSet::ResetCall(const NativeCodeInstruction& ins) +{ + mRegs[CPU_REG_C].Reset(); + mRegs[CPU_REG_Z].Reset(); + mRegs[CPU_REG_A].Reset(); + mRegs[CPU_REG_X].Reset(); + mRegs[CPU_REG_Y].Reset(); + + ResetWorkRegs(); + + if (!(ins.mFlags & NCIF_RUNTIME) || (ins.mFlags & NCIF_FEXEC)) + { + if (ins.mLinkerObject && ins.mLinkerObject->mProc) + { + if (!(ins.mFlags & NCIF_FEXEC) && (ins.mLinkerObject->mFlags & LOBJF_ZEROPAGESET)) + { + for (int i = 0; i < 256; i++) + if (ins.mLinkerObject->mZeroPageSet[i]) + mRegs[i].Reset(); + return; + } + + for (int i = BC_REG_TMP; i < BC_REG_TMP + ins.mLinkerObject->mProc->mCallerSavedTemps; i++) + mRegs[i].Reset(); + } + else + { + for (int i = BC_REG_TMP; i < BC_REG_TMP_SAVED; i++) + mRegs[i].Reset(); + } + + for (int i = BC_REG_FPARAMS; i < BC_REG_FPARAMS_END; i++) + mRegs[i].Reset(); + } + +} + + +void ValueNumberingDataSet::Intersect(const ValueNumberingDataSet& set) +{ + for (int i = 0; i < 261; i++) + { + if (mRegs[i].mIndex != set.mRegs[i].mIndex || mRegs[i].mOffset != set.mRegs[i].mOffset) + mRegs[i].Reset(); + } +} + + + NativeCodeInstruction::NativeCodeInstruction(void) : mIns(nullptr), mType(ASMIT_INV), mMode(ASMIM_IMPLIED), mAddress(0), mLinkerObject(nullptr), mFlags(NCIF_LOWER | NCIF_UPPER), mParam(0), mLive(LIVE_ALL) {} @@ -26860,6 +26944,105 @@ bool NativeCodeBasicBlock::ReverseBitfieldForwarding(void) } +bool NativeCodeBasicBlock::OffsetValueForwarding(const ValueNumberingDataSet& data) +{ + bool changed = false; + + if (!mVisited) + { + mNNumDataSet = data; + + assert(mIndex == 1000 || mNumEntries == mEntryBlocks.Size()); + + if (mLoopHead) + { + mNNumDataSet.Reset(); + } + else if (mNumEntries > 0) + { + if (mNumEntered > 0) + mNNumDataSet.Intersect(mNumDataSet); + + mNumEntered++; + + if (mNumEntered < mNumEntries) + { + mNumDataSet = mNNumDataSet; + return false; + } + } + + mVisited = true; + + int carry = -1; + + for (int i = 0; i < mIns.Size(); i++) + { + NativeCodeInstruction& ins(mIns[i]); + + if (ins.mType == ASMIT_JSR) + { + mNNumDataSet.ResetCall(ins); + carry = -1; + } + else if (ins.mType == ASMIT_LDA && ins.mMode == ASMIM_ZERO_PAGE) + { + mNNumDataSet.mRegs[CPU_REG_A] = mNNumDataSet.mRegs[mIns[i + 0].mAddress]; + } + else if (ins.mType == ASMIT_STA && ins.mMode == ASMIM_ZERO_PAGE) + { + int reg = ins.mAddress; + + if (mNNumDataSet.mRegs[reg].SameBase(mNNumDataSet.mRegs[CPU_REG_A])) + { + int d = mNNumDataSet.mRegs[CPU_REG_A].mOffset - mNNumDataSet.mRegs[reg].mOffset; + if (d == 0) + { + ins.mType = ASMIT_NOP; ins.mMode = ASMIM_IMPLIED; + changed = true; + } + else if (d == 1 && !(ins.mLive & LIVE_CPU_REG_Z)) + { + ins.mType = ASMIT_INC; + changed = true; + } + else if (d == -1 && !(ins.mLive & LIVE_CPU_REG_Z)) + { + ins.mType = ASMIT_DEC; + changed = true; + } + } + + mNNumDataSet.mRegs[reg] = mNNumDataSet.mRegs[CPU_REG_A]; + } + else if (ins.mType == ASMIT_ADC && ins.mMode == ASMIM_IMMEDIATE && carry != -1) + mNNumDataSet.mRegs[CPU_REG_A].mOffset += ins.mAddress + carry; + else if (ins.mType == ASMIT_SBC && ins.mMode == ASMIM_IMMEDIATE && carry != -1) + mNNumDataSet.mRegs[CPU_REG_A].mOffset -= ins.mAddress + 1 - carry; + else if (ins.ChangesAccu()) + mNNumDataSet.mRegs[CPU_REG_A].Reset(); + else if (ins.mMode == ASMIM_ZERO_PAGE && ins.ChangesAddress()) + mNNumDataSet.mRegs[ins.mAddress].Reset(); + + if (ins.mType == ASMIT_CLC) + carry = 0; + else if (ins.mType == ASMIT_SEC) + carry = 1; + else if (ins.ChangesCarry()) + carry = -1; + } + + mFNumDataSet = mNNumDataSet; + + if (this->mTrueJump && this->mTrueJump->OffsetValueForwarding(mNNumDataSet)) + changed = true; + if (this->mFalseJump && this->mFalseJump->OffsetValueForwarding(mFNumDataSet)) + changed = true; + } + + return changed; +} + bool NativeCodeBasicBlock::BitFieldForwarding(const NativeRegisterDataSet& data) { @@ -40263,6 +40446,19 @@ void NativeCodeProcedure::Optimize(void) ResetVisited(); mEntryBlock->RemoveUnusedResultInstructions(); + if (step == 8) + { + ResetVisited(); + ValueNumberingDataSet data; + if (mEntryBlock->OffsetValueForwarding(data)) + { + changed = true; + + BuildDataFlowSets(); + ResetVisited(); + mEntryBlock->RemoveUnusedResultInstructions(); + } + } #if _DEBUG ResetVisited(); diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index fc7d87e..397bd28 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -56,6 +56,27 @@ struct NativeRegisterDataSet void IntersectMask(const NativeRegisterDataSet& set); }; +struct ValueNumberingData +{ + uint32 mIndex, mOffset; + + ValueNumberingData(void); + + void Reset(void); + bool SameBase(const ValueNumberingData& d) const; +}; + +struct ValueNumberingDataSet +{ + ValueNumberingData mRegs[261]; + + void Reset(void); + void ResetWorkRegs(void); + void ResetCall(const NativeCodeInstruction& ins); + + void Intersect(const ValueNumberingDataSet& set); +}; + struct NativeRegisterSum16Info { NativeCodeInstruction * mSrcL, * mSrcH, * mDstL, * mDstH, * mAddL, * mAddH; @@ -214,6 +235,8 @@ public: NativeCodeBasicBlock* mLoopHeadBlock, * mLoopTailBlock; NativeRegisterDataSet mDataSet, mNDataSet, mFDataSet; + ValueNumberingDataSet mNumDataSet, mNNumDataSet, mFNumDataSet; + int mYAlias[256], mYOffset; ExpandingArray mRSumInfos; @@ -440,6 +463,7 @@ public: bool GlobalValueForwarding(NativeCodeProcedure* proc, bool final); bool BitFieldForwarding(const NativeRegisterDataSet& data); bool ReverseBitfieldForwarding(void); + bool OffsetValueForwarding(const ValueNumberingDataSet & data); void CollectEntryBlocks(NativeCodeBasicBlock* block); diff --git a/oscar64/oscar64.cpp b/oscar64/oscar64.cpp index 03663ef..80550e2 100644 --- a/oscar64/oscar64.cpp +++ b/oscar64/oscar64.cpp @@ -74,7 +74,7 @@ int main2(int argc, const char** argv) #else strcpy(strProductName, "oscar64"); - strcpy(strProductVersion, "1.19.202"); + strcpy(strProductVersion, "1.19.203"); #ifdef __APPLE__ uint32_t length = sizeof(basePath); diff --git a/oscar64/oscar64.rc b/oscar64/oscar64.rc index 7e9de7d..645356c 100644 --- a/oscar64/oscar64.rc +++ b/oscar64/oscar64.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,19,202,0 - PRODUCTVERSION 1,19,202,0 + FILEVERSION 1,19,203,0 + PRODUCTVERSION 1,19,203,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,12 +43,12 @@ BEGIN BEGIN VALUE "CompanyName", "oscar64" VALUE "FileDescription", "oscar64 compiler" - VALUE "FileVersion", "1.19.202.0" + VALUE "FileVersion", "1.19.203.0" VALUE "InternalName", "oscar64.exe" VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "OriginalFilename", "oscar64.exe" VALUE "ProductName", "oscar64" - VALUE "ProductVersion", "1.19.202.0" + VALUE "ProductVersion", "1.19.203.0" END END BLOCK "VarFileInfo" diff --git a/oscar64setup/oscar64setup.vdproj b/oscar64setup/oscar64setup.vdproj index c02c7db..51b3af4 100644 --- a/oscar64setup/oscar64setup.vdproj +++ b/oscar64setup/oscar64setup.vdproj @@ -5233,15 +5233,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:oscar64" - "ProductCode" = "8:{121C9EAF-FA66-4A4C-9CBB-B9CAC3B869C7}" - "PackageCode" = "8:{249C96D2-72FE-4889-8F29-99C7507EC96D}" + "ProductCode" = "8:{5EDB40F8-9CC0-43BE-8F95-2B719EAF6B5F}" + "PackageCode" = "8:{A08732D1-FED2-4E95-B9FB-431475D196F6}" "UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}" "AspNetVersion" = "8:2.0.50727.0" "RestartWWWService" = "11:FALSE" "RemovePreviousVersions" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE" "InstallAllUsers" = "11:FALSE" - "ProductVersion" = "8:1.19.202" + "ProductVersion" = "8:1.19.203" "Manufacturer" = "8:oscar64" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:"