From 86e0cbf9c243d51693a760c4ec203fdd91a67ba1 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sun, 19 May 2024 10:19:42 +0200 Subject: [PATCH] Alternate forward and backward int value range check --- oscar64/InterCode.cpp | 208 +++++++++++++++++++------------- oscar64/InterCode.h | 5 + oscar64/NativeCodeGenerator.cpp | 21 ++++ 3 files changed, 153 insertions(+), 81 deletions(-) diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index d529375..b514744 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -148,6 +148,14 @@ void IntegerValueRange::MergeUnknown(const IntegerValueRange& range) } +void IntegerValueRange::LimitWeak(const IntegerValueRange& range) +{ + if (range.mMinState == S_BOUND) + LimitMinWeak(range.mMinValue); + if (range.mMaxState == S_BOUND) + LimitMaxWeak(range.mMaxValue); +} + void IntegerValueRange::Limit(const IntegerValueRange& range) { if (range.mMinState == S_BOUND) @@ -7473,8 +7481,6 @@ bool InterCodeBasicBlock::BuildGlobalIntegerRangeSets(bool initial, const Growin mEntryValueRange[i].Expand(mProc->mLocalValueRange[i]); for (int i = 0; i < mLocalParamValueRange.Size(); i++) mEntryParamValueRange[i].Expand(mLocalParamValueRange[i]); - mProc->mLocalValueRange = mEntryValueRange; - mLocalParamValueRange = mEntryParamValueRange; // mEntryValueRange = mLocalValueRange; // mEntryParamValueRange = mLocalParamValueRange; @@ -7593,78 +7599,10 @@ void InterCodeBasicBlock::MarkIntegerRangeBoundUp(int temp, int64 value, Growing } } -void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars) +void InterCodeBasicBlock::UpdateLocalIntegerRangeSetsForward(const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars) { - mProc->mLocalValueRange = mEntryValueRange; - int sz = mInstructions.Size(); - assert(mProc->mLocalValueRange.Size() == mExitRequiredTemps.Size()); - - InterCodeBasicBlock * pblock; - int64 nloop; - - bool singleLoop = CheckSingleBlockLimitedLoop(pblock, nloop); - -#if 0 - FastNumberSet dependTemps(mExitRequiredTemps.Size()); -#endif - - if (singleLoop) - { - struct TempChain - { - int mBaseTemp; - int64 mOffset; - }; - - ExpandingArray tempChain; - tempChain.SetSize(mExitRequiredTemps.Size()); - - for (int i = 0; i < mExitRequiredTemps.Size(); i++) - { - tempChain[i].mBaseTemp = i; - tempChain[i].mOffset = 0; - } - - for (int i = 0; i < sz; i++) - { - InterInstruction* ins(mInstructions[i]); - if (ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_ADD && - ins->mSrc[1].mTemp >= 0 && ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mIntConst > 0 && - tempChain[ins->mSrc[1].mTemp].mBaseTemp >= 0) - { - tempChain[ins->mDst.mTemp].mBaseTemp = tempChain[ins->mSrc[1].mTemp].mBaseTemp; - tempChain[ins->mDst.mTemp].mOffset = tempChain[ins->mSrc[1].mTemp].mOffset + ins->mSrc[0].mIntConst; - } - else if (ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_ADD && - ins->mSrc[0].mTemp >= 0 && ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mIntConst > 0 && - tempChain[ins->mSrc[0].mTemp].mBaseTemp >= 0) - { - tempChain[ins->mDst.mTemp].mBaseTemp = tempChain[ins->mSrc[0].mTemp].mBaseTemp; - tempChain[ins->mDst.mTemp].mOffset = tempChain[ins->mSrc[0].mTemp].mOffset + ins->mSrc[1].mIntConst; - } - else if (ins->mCode == IC_CONVERSION_OPERATOR && ins->mOperator == IA_EXT8TO16U && ins->mSrc[0].mTemp >= 0) - tempChain[ins->mDst.mTemp] = tempChain[ins->mSrc[0].mTemp]; - else if (ins->mDst.mTemp >= 0) - { - tempChain[ins->mDst.mTemp].mBaseTemp = -1; - } - } - - for (int i = 0; i < tempChain.Size(); i++) - { - if (tempChain[i].mBaseTemp == i) - { - IntegerValueRange& r(pblock->mTrueValueRange[i]); - if (r.IsConstant()) - { - mProc->mLocalValueRange[i].LimitMax(r.mMinValue + (nloop - 1) * tempChain[i].mOffset); - } - } - } - } - for (int i = 0; i < sz; i++) { InterInstruction* ins(mInstructions[i]); @@ -7677,7 +7615,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray { ins->mSrc[i].mRange.MergeUnknown(mProc->mLocalValueRange[ins->mSrc[i].mTemp]); #if 1 - if (ins->mCode != IC_ASSEMBLER&& ins->mSrc[i].mRange.mMinState == IntegerValueRange::S_BOUND && ins->mSrc[i].mRange.mMaxState == IntegerValueRange::S_BOUND && ins->mSrc[i].mRange.mMinValue == ins->mSrc[i].mRange.mMaxValue) + if (ins->mCode != IC_ASSEMBLER && ins->mSrc[i].mRange.mMinState == IntegerValueRange::S_BOUND && ins->mSrc[i].mRange.mMaxState == IntegerValueRange::S_BOUND && ins->mSrc[i].mRange.mMinValue == ins->mSrc[i].mRange.mMaxValue) { if (ins->mCode == IC_LOAD_TEMPORARY) { @@ -8106,7 +8044,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray { vr.mMinState = IntegerValueRange::S_BOUND; vr.mMaxState = IntegerValueRange::S_BOUND; - + if (ins->mSrc[1].mIntConst < 0) { vr.mMinValue = ins->mSrc[1].mIntConst << ins->mSrc[0].mRange.mMaxValue; @@ -8197,11 +8135,11 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray switch (ins->mSrc[1].mType) { case IT_INT16: - vr.mMaxValue = (short)(int64min( 32767, vr.mMaxValue)) >> ins->mSrc[0].mIntConst; + vr.mMaxValue = (short)(int64min(32767, vr.mMaxValue)) >> ins->mSrc[0].mIntConst; vr.mMinValue = (short)(int64max(-32768, vr.mMinValue)) >> ins->mSrc[0].mIntConst; break; case IT_INT8: - vr.mMaxValue = (char)(int64min( 127, vr.mMaxValue)) >> ins->mSrc[0].mIntConst; + vr.mMaxValue = (char)(int64min(127, vr.mMaxValue)) >> ins->mSrc[0].mIntConst; vr.mMinValue = (char)(int64max(-128, vr.mMinValue)) >> ins->mSrc[0].mIntConst; break; case IT_INT32: @@ -8269,7 +8207,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray } } } - else + else vr.mMaxState = vr.mMinState = IntegerValueRange::S_UNBOUND; break; @@ -8357,9 +8295,10 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray assert(mProc->mLocalValueRange.Size() == mExitRequiredTemps.Size()); } +} -#if 1 - +void InterCodeBasicBlock::UpdateLocalIntegerRangeSetsBackward(const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars) +{ mProc->mReverseValueRange.SetSize(mProc->mLocalValueRange.Size()); for (int i = 0; i < mProc->mReverseValueRange.Size(); i++) @@ -8373,6 +8312,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray } } + int sz = mInstructions.Size(); for (int i = sz - 1; i >= 0; i--) { InterInstruction* ins(mInstructions[i]); @@ -8402,7 +8342,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray if (asize > 0) { - mProc->mReverseValueRange[ins->mSrc[0].mTemp].LimitMin(- ins->mSrc[1].mIntConst); + mProc->mReverseValueRange[ins->mSrc[0].mTemp].LimitMin(-ins->mSrc[1].mIntConst); mProc->mReverseValueRange[ins->mSrc[0].mTemp].LimitMax(asize - ins->mSrc[1].mIntConst - mMemoryValueSize[ins->mDst.mTemp]); } } @@ -8473,6 +8413,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray ins->mSrc[1].mRange.LimitMin(vr.mMinValue + ins->mSrc[0].mIntConst); if (vr.mMaxState == IntegerValueRange::S_BOUND) ins->mSrc[1].mRange.LimitMax(vr.mMaxValue + ins->mSrc[0].mIntConst); + mProc->mReverseValueRange[ins->mSrc[1].mTemp].Limit(ins->mSrc[1].mRange); } break; @@ -8558,6 +8499,111 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray if (ins->mDst.mTemp >= 0) mMemoryValueSize[ins->mDst.mTemp] = 0; } +} + +void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars) +{ + mProc->mLocalValueRange = mEntryValueRange; + mLocalParamValueRange = mEntryParamValueRange; + + int sz = mInstructions.Size(); + + assert(mProc->mLocalValueRange.Size() == mExitRequiredTemps.Size()); + + InterCodeBasicBlock * pblock; + int64 nloop; + + bool singleLoop = CheckSingleBlockLimitedLoop(pblock, nloop); + +#if 0 + FastNumberSet dependTemps(mExitRequiredTemps.Size()); +#endif + + struct TempChain + { + int mBaseTemp; + int64 mOffset; + }; + + ExpandingArray tempChain; + + if (singleLoop) + { + tempChain.SetSize(mExitRequiredTemps.Size()); + + for (int i = 0; i < mExitRequiredTemps.Size(); i++) + { + tempChain[i].mBaseTemp = i; + tempChain[i].mOffset = 0; + } + + for (int i = 0; i < sz; i++) + { + InterInstruction* ins(mInstructions[i]); + if (ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_ADD && + ins->mSrc[1].mTemp >= 0 && ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mIntConst > 0 && + tempChain[ins->mSrc[1].mTemp].mBaseTemp >= 0) + { + tempChain[ins->mDst.mTemp].mBaseTemp = tempChain[ins->mSrc[1].mTemp].mBaseTemp; + tempChain[ins->mDst.mTemp].mOffset = tempChain[ins->mSrc[1].mTemp].mOffset + ins->mSrc[0].mIntConst; + } + else if (ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_ADD && + ins->mSrc[0].mTemp >= 0 && ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mIntConst > 0 && + tempChain[ins->mSrc[0].mTemp].mBaseTemp >= 0) + { + tempChain[ins->mDst.mTemp].mBaseTemp = tempChain[ins->mSrc[0].mTemp].mBaseTemp; + tempChain[ins->mDst.mTemp].mOffset = tempChain[ins->mSrc[0].mTemp].mOffset + ins->mSrc[1].mIntConst; + } + else if (ins->mCode == IC_CONVERSION_OPERATOR && ins->mOperator == IA_EXT8TO16U && ins->mSrc[0].mTemp >= 0) + tempChain[ins->mDst.mTemp] = tempChain[ins->mSrc[0].mTemp]; + else if (ins->mDst.mTemp >= 0) + { + tempChain[ins->mDst.mTemp].mBaseTemp = -1; + } + } + + for (int i = 0; i < tempChain.Size(); i++) + { + if (tempChain[i].mBaseTemp == i) + { + IntegerValueRange& r(pblock->mTrueValueRange[i]); + if (r.IsConstant()) + { + mProc->mLocalValueRange[i].LimitMax(r.mMinValue + (nloop - 1) * tempChain[i].mOffset); + } + } + } + } + + UpdateLocalIntegerRangeSetsForward(localVars, paramVars); +#if 1 + + UpdateLocalIntegerRangeSetsBackward(localVars, paramVars); +#if 1 + mProc->mLocalValueRange = mEntryValueRange; + for (int i = 0; i < mProc->mLocalValueRange.Size(); i++) + mProc->mLocalValueRange[i].LimitWeak(mProc->mReverseValueRange[i]); + mLocalParamValueRange = mEntryParamValueRange; + + if (singleLoop) + { + for (int i = 0; i < tempChain.Size(); i++) + { + if (tempChain[i].mBaseTemp == i) + { + IntegerValueRange& r(pblock->mTrueValueRange[i]); + if (r.IsConstant()) + { + mProc->mLocalValueRange[i].LimitMax(r.mMinValue + (nloop - 1) * tempChain[i].mOffset); + } + } + } + } + + UpdateLocalIntegerRangeSetsForward(localVars, paramVars); + UpdateLocalIntegerRangeSetsBackward(localVars, paramVars); +#endif + #endif mTrueValueRange = mProc->mLocalValueRange; @@ -16650,7 +16696,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa ins->mInvariant = false; } } - else if (sins->mCode == IC_COPY || sins->mCode == IC_FILL) + else if ((sins->mCode == IC_COPY || sins->mCode == IC_FILL) && DestroyingMem(ins, sins)) { ins->mInvariant = false; } @@ -20633,7 +20679,7 @@ void InterCodeProcedure::Close(void) { GrowingTypeArray tstack(IT_NONE); - CheckFunc = !strcmp(mIdent->mString, "window_mask3"); + CheckFunc = !strcmp(mIdent->mString, "main"); CheckCase = false; mEntryBlock = mBlocks[0]; diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index 05b46fc..944d09c 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -168,6 +168,7 @@ public: void Union(const IntegerValueRange& range); void Limit(const IntegerValueRange& range); + void LimitWeak(const IntegerValueRange& range); void MergeUnknown(const IntegerValueRange& range); void SetLimit(int64 minValue, int64 maxValue); @@ -459,6 +460,10 @@ public: void RestartLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars); void BuildLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars); void UpdateLocalIntegerRangeSets(const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars); + + void UpdateLocalIntegerRangeSetsForward(const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars); + void UpdateLocalIntegerRangeSetsBackward(const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars); + bool BuildGlobalIntegerRangeSets(bool initial, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars); void SimplifyIntegerRangeRelops(void); void MarkIntegerRangeBoundUp(int temp, int64 value, GrowingIntegerValueRangeArray& range); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 56cf114..bf02431 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -18135,6 +18135,27 @@ bool NativeCodeBasicBlock::LoopRegisterWrapAround(void) } } } +#if 0 + int esz = eblock->mIns.Size(); + if (mIns.Size() > 0 && esz >= 2 && + mIns[0].mType == ASMIT_LDX && + eblock->mIns[esz - 2].mType == ASMIT_LDA && mIns[0].SameEffectiveAddress(eblock->mIns[esz - 2]) && + eblock->mIns[esz - 1].mType == ASMIT_CMP && HasAsmInstructionMode(ASMIT_CPX, eblock->mIns[esz - 1].mMode) && + !(eblock->mIns[esz - 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_X))) + { + printf("Doopsie\n"); + + bblock->mIns.Push(mIns[0]); + bblock->mExitRequiredRegs += CPU_REG_X; + mEntryRequiredRegs += CPU_REG_X; + mIns.Remove(0); + + eblock->mExitRequiredRegs += CPU_REG_X; + eblock->mIns[esz - 2].mType = ASMIT_LDX; eblock->mIns[esz - 2].mLive |= LIVE_CPU_REG_X; + eblock->mIns[esz - 1].mType = ASMIT_CPX; eblock->mIns[esz - 1].mLive |= LIVE_CPU_REG_X; + changed = true; + } +#endif } }