Fix loop exit value of loop counter derived values

This commit is contained in:
drmortalwombat 2024-09-19 11:27:30 +02:00
parent ce710fca5d
commit c508d94d7c
2 changed files with 102 additions and 34 deletions

View File

@ -194,6 +194,14 @@ void IntegerValueRange::Limit(const IntegerValueRange& range)
} }
void IntegerValueRange::SetConstant(int64 value)
{
mMinState = S_BOUND;
mMaxState = S_BOUND;
mMinValue = value;
mMaxValue = value;
}
void IntegerValueRange::SetLimit(int64 minValue, int64 maxValue) void IntegerValueRange::SetLimit(int64 minValue, int64 maxValue)
{ {
mMinState = S_BOUND; mMinState = S_BOUND;
@ -8829,6 +8837,24 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
mTrueParamValueRange = mLocalParamValueRange; mTrueParamValueRange = mLocalParamValueRange;
mFalseParamValueRange = mLocalParamValueRange; mFalseParamValueRange = mLocalParamValueRange;
if (singleLoop)
{
for (int i = 0; i < tempChain.Size(); i++)
{
if (tempChain[i].mBaseTemp == i)
{
IntegerValueRange& r(pblock->mTrueValueRange[i]);
if (r.IsConstant())
{
if (mTrueJump == this)
mFalseValueRange[i].SetConstant(r.mMinValue + nloop * tempChain[i].mOffset);
else
mTrueValueRange[i].SetConstant(r.mMinValue + nloop * tempChain[i].mOffset);
}
}
}
}
if (sz >= 1) if (sz >= 1)
{ {
if (mInstructions[sz - 1]->mCode == IC_BRANCH && mInstructions[sz - 1]->mSrc[0].mTemp >= 0 && mInstructions[sz - 1]->mSrc[0].mType == IT_BOOL) if (mInstructions[sz - 1]->mCode == IC_BRANCH && mInstructions[sz - 1]->mSrc[0].mTemp >= 0 && mInstructions[sz - 1]->mSrc[0].mType == IT_BOOL)
@ -18022,53 +18048,64 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
{ {
if (dep[t] < DEP_VARIABLE && dep[t] != DEP_INDEX) if (dep[t] < DEP_VARIABLE && dep[t] != DEP_INDEX)
{ {
int j = 0; #if 0
while (j < ins->mNumOperands && !(ins->mSrc[j].mTemp >= 0 && dep[ins->mSrc[j].mTemp] >= DEP_INDEX)) if (tailBlock->mEntryRequiredTemps[ins->mDst.mTemp])
j++;
if (j < ins->mNumOperands)
{ {
if (ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_MUL && IsIntegerType(ins->mDst.mType) && ins->mSrc[1].mTemp < 0 && (dep[ins->mSrc[0].mTemp] == DEP_INDEX || dep[ins->mSrc[0].mTemp] == DEP_INDEX_EXTENDED || dep[ins->mSrc[0].mTemp] == DEP_INDEX_DERIVED) || dep[t] = DEP_VARIABLE;
ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_MUL && IsIntegerType(ins->mDst.mType) && ins->mSrc[0].mTemp < 0 && (dep[ins->mSrc[1].mTemp] == DEP_INDEX || dep[ins->mSrc[1].mTemp] == DEP_INDEX_EXTENDED || dep[ins->mSrc[1].mTemp] == DEP_INDEX_DERIVED) || ins->mInvariant = false;
ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_SHL && IsIntegerType(ins->mDst.mType) && ins->mSrc[0].mTemp < 0 && (dep[ins->mSrc[1].mTemp] == DEP_INDEX || dep[ins->mSrc[1].mTemp] == DEP_INDEX_EXTENDED || dep[ins->mSrc[1].mTemp] == DEP_INDEX_DERIVED) || changed = true;
ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_ADD && IsIntegerType(ins->mDst.mType) && (ins->mSrc[0].mTemp < 0 || dep[ins->mSrc[0].mTemp] == DEP_UNKNOWN || dep[ins->mSrc[0].mTemp] == DEP_DEFINED) && dep[ins->mSrc[1].mTemp] == DEP_INDEX_DERIVED || }
ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_ADD && IsIntegerType(ins->mDst.mType) && (ins->mSrc[1].mTemp < 0 || dep[ins->mSrc[1].mTemp] == DEP_UNKNOWN || dep[ins->mSrc[1].mTemp] == DEP_DEFINED) && dep[ins->mSrc[0].mTemp] == DEP_INDEX_DERIVED || else
ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_ADD && #endif
IsIntegerType(ins->mDst.mType) && {
(ins->mSrc[0].mTemp >= 0 && ins->mSrc[0].IsNotUByte() && (dep[ins->mSrc[0].mTemp] == DEP_UNKNOWN || dep[ins->mSrc[0].mTemp] == DEP_DEFINED)) && int j = 0;
(dep[ins->mSrc[1].mTemp] == DEP_INDEX || dep[ins->mSrc[1].mTemp] == DEP_INDEX_EXTENDED || dep[ins->mSrc[1].mTemp] == DEP_INDEX_DERIVED) || while (j < ins->mNumOperands && !(ins->mSrc[j].mTemp >= 0 && dep[ins->mSrc[j].mTemp] >= DEP_INDEX))
ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_ADD && j++;
IsIntegerType(ins->mDst.mType) && if (j < ins->mNumOperands)
(ins->mSrc[1].mTemp >= 0 && ins->mSrc[1].IsNotUByte() && (dep[ins->mSrc[1].mTemp] == DEP_UNKNOWN || dep[ins->mSrc[1].mTemp] == DEP_DEFINED)) &&
(dep[ins->mSrc[0].mTemp] == DEP_INDEX || dep[ins->mSrc[0].mTemp] == DEP_INDEX_EXTENDED || dep[ins->mSrc[0].mTemp] == DEP_INDEX_DERIVED) ||
ins->mCode == IC_LEA && (ins->mSrc[1].mTemp < 0 || dep[ins->mSrc[1].mTemp] == DEP_UNKNOWN || dep[ins->mSrc[1].mTemp] == DEP_DEFINED) && dep[ins->mSrc[0].mTemp] == DEP_INDEX_DERIVED )
{ {
if (dep[ins->mDst.mTemp] != DEP_INDEX_DERIVED) if (ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_MUL && IsIntegerType(ins->mDst.mType) && ins->mSrc[1].mTemp < 0 && (dep[ins->mSrc[0].mTemp] == DEP_INDEX || dep[ins->mSrc[0].mTemp] == DEP_INDEX_EXTENDED || dep[ins->mSrc[0].mTemp] == DEP_INDEX_DERIVED) ||
ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_MUL && IsIntegerType(ins->mDst.mType) && ins->mSrc[0].mTemp < 0 && (dep[ins->mSrc[1].mTemp] == DEP_INDEX || dep[ins->mSrc[1].mTemp] == DEP_INDEX_EXTENDED || dep[ins->mSrc[1].mTemp] == DEP_INDEX_DERIVED) ||
ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_SHL && IsIntegerType(ins->mDst.mType) && ins->mSrc[0].mTemp < 0 && (dep[ins->mSrc[1].mTemp] == DEP_INDEX || dep[ins->mSrc[1].mTemp] == DEP_INDEX_EXTENDED || dep[ins->mSrc[1].mTemp] == DEP_INDEX_DERIVED) ||
ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_ADD && IsIntegerType(ins->mDst.mType) && (ins->mSrc[0].mTemp < 0 || dep[ins->mSrc[0].mTemp] == DEP_UNKNOWN || dep[ins->mSrc[0].mTemp] == DEP_DEFINED) && dep[ins->mSrc[1].mTemp] == DEP_INDEX_DERIVED ||
ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_ADD && IsIntegerType(ins->mDst.mType) && (ins->mSrc[1].mTemp < 0 || dep[ins->mSrc[1].mTemp] == DEP_UNKNOWN || dep[ins->mSrc[1].mTemp] == DEP_DEFINED) && dep[ins->mSrc[0].mTemp] == DEP_INDEX_DERIVED ||
ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_ADD &&
IsIntegerType(ins->mDst.mType) &&
(ins->mSrc[0].mTemp >= 0 && ins->mSrc[0].IsNotUByte() && (dep[ins->mSrc[0].mTemp] == DEP_UNKNOWN || dep[ins->mSrc[0].mTemp] == DEP_DEFINED)) &&
(dep[ins->mSrc[1].mTemp] == DEP_INDEX || dep[ins->mSrc[1].mTemp] == DEP_INDEX_EXTENDED || dep[ins->mSrc[1].mTemp] == DEP_INDEX_DERIVED) ||
ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_ADD &&
IsIntegerType(ins->mDst.mType) &&
(ins->mSrc[1].mTemp >= 0 && ins->mSrc[1].IsNotUByte() && (dep[ins->mSrc[1].mTemp] == DEP_UNKNOWN || dep[ins->mSrc[1].mTemp] == DEP_DEFINED)) &&
(dep[ins->mSrc[0].mTemp] == DEP_INDEX || dep[ins->mSrc[0].mTemp] == DEP_INDEX_EXTENDED || dep[ins->mSrc[0].mTemp] == DEP_INDEX_DERIVED) ||
ins->mCode == IC_LEA && (ins->mSrc[1].mTemp < 0 || dep[ins->mSrc[1].mTemp] == DEP_UNKNOWN || dep[ins->mSrc[1].mTemp] == DEP_DEFINED) && dep[ins->mSrc[0].mTemp] == DEP_INDEX_DERIVED)
{ {
dep[ins->mDst.mTemp] = DEP_INDEX_DERIVED; if (dep[ins->mDst.mTemp] != DEP_INDEX_DERIVED)
ins->mInvariant = false; {
changed = true; dep[ins->mDst.mTemp] = DEP_INDEX_DERIVED;
ins->mInvariant = false;
changed = true;
}
} }
} else if (ins->mCode == IC_CONVERSION_OPERATOR && (ins->mOperator == IA_EXT8TO16S || ins->mOperator == IA_EXT8TO16U) && dep[ins->mSrc[0].mTemp] == DEP_INDEX)
else if (ins->mCode == IC_CONVERSION_OPERATOR && (ins->mOperator == IA_EXT8TO16S || ins->mOperator == IA_EXT8TO16U) && dep[ins->mSrc[0].mTemp] == DEP_INDEX)
{
if (dep[ins->mDst.mTemp] != DEP_INDEX_EXTENDED)
{ {
dep[ins->mDst.mTemp] = DEP_INDEX_EXTENDED; if (dep[ins->mDst.mTemp] != DEP_INDEX_EXTENDED)
{
dep[ins->mDst.mTemp] = DEP_INDEX_EXTENDED;
ins->mInvariant = false;
changed = true;
}
}
else
{
dep[t] = DEP_VARIABLE;
ins->mInvariant = false; ins->mInvariant = false;
changed = true; changed = true;
} }
} }
else else
{ {
dep[t] = DEP_VARIABLE; dep[t] = DEP_DEFINED;
ins->mInvariant = false;
changed = true;
} }
} }
else
{
dep[t] = DEP_DEFINED;
}
} }
} }
} }
@ -18124,6 +18161,16 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
ins->mSrc[1].mIntConst = ins->mSrc[1].mIntConst * indexStep[ins->mSrc[0].mTemp]; ins->mSrc[1].mIntConst = ins->mSrc[1].mIntConst * indexStep[ins->mSrc[0].mTemp];
ins->mSrc[0] = ins->mDst; ins->mSrc[0] = ins->mDst;
if (tailBlock->mEntryRequiredTemps[ins->mDst.mTemp])
{
InterInstruction* rins = new InterInstruction(ins->mLocation, IC_BINARY_OPERATOR);
rins->mOperator = IA_SUB;
rins->mDst = ins->mDst;
rins->mSrc[1] = ins->mDst;
rins->mSrc[0] = ins->mSrc[1];
tailBlock->mInstructions.Insert(0, rins);
}
indexins.Push(ins); indexins.Push(ins);
} }
else if (ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_MUL && IsIntegerType(ins->mDst.mType) && ins->mSrc[0].mTemp < 0 && (dep[ins->mSrc[1].mTemp] == DEP_INDEX || dep[ins->mSrc[1].mTemp] == DEP_INDEX_EXTENDED || dep[ins->mSrc[1].mTemp] == DEP_INDEX_DERIVED)) else if (ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_MUL && IsIntegerType(ins->mDst.mType) && ins->mSrc[0].mTemp < 0 && (dep[ins->mSrc[1].mTemp] == DEP_INDEX || dep[ins->mSrc[1].mTemp] == DEP_INDEX_EXTENDED || dep[ins->mSrc[1].mTemp] == DEP_INDEX_DERIVED))
@ -18149,6 +18196,16 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
ins->mSrc[0].mIntConst = ins->mSrc[0].mIntConst * indexStep[ins->mSrc[1].mTemp]; ins->mSrc[0].mIntConst = ins->mSrc[0].mIntConst * indexStep[ins->mSrc[1].mTemp];
ins->mSrc[1] = ins->mDst; ins->mSrc[1] = ins->mDst;
if (tailBlock->mEntryRequiredTemps[ins->mDst.mTemp])
{
InterInstruction* rins = new InterInstruction(ins->mLocation, IC_BINARY_OPERATOR);
rins->mOperator = IA_SUB;
rins->mDst = ins->mDst;
rins->mSrc[1] = ins->mDst;
rins->mSrc[0] = ins->mSrc[0];
tailBlock->mInstructions.Insert(0, rins);
}
indexins.Push(ins); indexins.Push(ins);
} }
else if (ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_SHL && IsIntegerType(ins->mDst.mType) && ins->mSrc[0].mTemp < 0 && (dep[ins->mSrc[1].mTemp] == DEP_INDEX || dep[ins->mSrc[1].mTemp] == DEP_INDEX_EXTENDED || dep[ins->mSrc[1].mTemp] == DEP_INDEX_DERIVED)) else if (ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_SHL && IsIntegerType(ins->mDst.mType) && ins->mSrc[0].mTemp < 0 && (dep[ins->mSrc[1].mTemp] == DEP_INDEX || dep[ins->mSrc[1].mTemp] == DEP_INDEX_EXTENDED || dep[ins->mSrc[1].mTemp] == DEP_INDEX_DERIVED))
@ -18176,6 +18233,16 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
if (ins->mDst.mRange.mMaxState == IntegerValueRange::S_BOUND) if (ins->mDst.mRange.mMaxState == IntegerValueRange::S_BOUND)
ins->mDst.mRange.mMaxValue += ins->mSrc[0].mIntConst; ins->mDst.mRange.mMaxValue += ins->mSrc[0].mIntConst;
if (tailBlock->mEntryRequiredTemps[ins->mDst.mTemp])
{
InterInstruction* rins = new InterInstruction(ins->mLocation, IC_BINARY_OPERATOR);
rins->mOperator = IA_SUB;
rins->mDst = ins->mDst;
rins->mSrc[1] = ins->mDst;
rins->mSrc[0] = ins->mSrc[0];
tailBlock->mInstructions.Insert(0, rins);
}
indexins.Push(ins); indexins.Push(ins);
} }
else if (ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_ADD && IsIntegerType(ins->mDst.mType) && (ins->mSrc[0].mTemp < 0 || dep[ins->mSrc[0].mTemp] == DEP_UNKNOWN || dep[ins->mSrc[0].mTemp] == DEP_DEFINED) && (dep[ins->mSrc[1].mTemp] == DEP_INDEX || dep[ins->mSrc[1].mTemp] == DEP_INDEX_EXTENDED || dep[ins->mSrc[1].mTemp] == DEP_INDEX_DERIVED)) else if (ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_ADD && IsIntegerType(ins->mDst.mType) && (ins->mSrc[0].mTemp < 0 || dep[ins->mSrc[0].mTemp] == DEP_UNKNOWN || dep[ins->mSrc[0].mTemp] == DEP_DEFINED) && (dep[ins->mSrc[1].mTemp] == DEP_INDEX || dep[ins->mSrc[1].mTemp] == DEP_INDEX_EXTENDED || dep[ins->mSrc[1].mTemp] == DEP_INDEX_DERIVED))

View File

@ -177,6 +177,7 @@ public:
void LimitWeak(const IntegerValueRange& range); void LimitWeak(const IntegerValueRange& range);
void MergeUnknown(const IntegerValueRange& range); void MergeUnknown(const IntegerValueRange& range);
void SetLimit(int64 minValue, int64 maxValue); void SetLimit(int64 minValue, int64 maxValue);
void SetConstant(int64 value);
bool IsBound(void) const; bool IsBound(void) const;
bool IsConstant(void) const; bool IsConstant(void) const;