Alternate forward and backward int value range check
This commit is contained in:
parent
142bc988b1
commit
86e0cbf9c2
|
@ -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;
|
||||
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> 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];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue