Fix load int range estimation

This commit is contained in:
drmortalwombat 2022-09-17 16:15:35 +02:00
parent 31dfc702ab
commit 49a822afbf
4 changed files with 92 additions and 2 deletions

View File

@ -71,6 +71,18 @@ void IntegerValueRange::LimitMax(int64 value)
} }
} }
void IntegerValueRange::LimitMinBound(int64 value)
{
if (mMinState == S_BOUND && mMinValue < value)
mMinValue = value;
}
void IntegerValueRange::LimitMaxBound(int64 value)
{
if (mMaxState == S_BOUND && mMaxValue > value)
mMaxValue = value;
}
void IntegerValueRange::LimitMinWeak(int64 value) void IntegerValueRange::LimitMinWeak(int64 value)
{ {
if (mMinState == S_UNBOUND || mMinValue < value) if (mMinState == S_UNBOUND || mMinValue < value)
@ -5270,7 +5282,18 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
{ {
case IC_LOAD: case IC_LOAD:
vr = ins->mDst.mRange; vr = ins->mDst.mRange;
#if 1
if (ins->mDst.mType == IT_INT8)
{
vr.LimitMin(-128);
vr.LimitMax(255);
}
else if (ins->mDst.mType == IT_INT16)
{
vr.LimitMin(-32768);
vr.LimitMax(65535);
}
#endif
if (i > 0 && if (i > 0 &&
mInstructions[i - 1]->mCode == IC_LEA && mInstructions[i - 1]->mDst.mTemp == ins->mSrc[0].mTemp && mInstructions[i - 1]->mCode == IC_LEA && mInstructions[i - 1]->mDst.mTemp == ins->mSrc[0].mTemp &&
mInstructions[i - 1]->mSrc[1].mTemp < 0 && mInstructions[i - 1]->mSrc[1].mMemory == IM_GLOBAL && (mInstructions[i - 1]->mSrc[1].mLinkerObject->mFlags & LOBJF_CONST)) mInstructions[i - 1]->mSrc[1].mTemp < 0 && mInstructions[i - 1]->mSrc[1].mMemory == IM_GLOBAL && (mInstructions[i - 1]->mSrc[1].mLinkerObject->mFlags & LOBJF_CONST))
@ -5736,7 +5759,18 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
default: default:
vr.mMaxState = vr.mMinState = IntegerValueRange::S_UNBOUND; vr.mMaxState = vr.mMinState = IntegerValueRange::S_UNBOUND;
} }
#if 1
if (ins->mDst.mType == IT_INT8)
{
vr.LimitMinBound(-128);
vr.LimitMaxBound(255);
}
else if (ins->mDst.mType == IT_INT16)
{
vr.LimitMinBound(-32768);
vr.LimitMaxBound(65535);
}
#endif
ins->mDst.mRange = vr; ins->mDst.mRange = vr;
#if 1 #if 1
if (vr.mMaxState == IntegerValueRange::S_BOUND && vr.mMinState == IntegerValueRange::S_BOUND && vr.mMaxValue == vr.mMinValue) if (vr.mMaxState == IntegerValueRange::S_BOUND && vr.mMinState == IntegerValueRange::S_BOUND && vr.mMaxValue == vr.mMinValue)
@ -12811,6 +12845,11 @@ void InterCodeProcedure::Close(void)
DisassembleDebug("Estimated value range 2"); DisassembleDebug("Estimated value range 2");
#endif #endif
ResetVisited();
mEntryBlock->SimplifyIntegerRangeRelops();
DisassembleDebug("Simplified range limited relational ops");
#if 1 #if 1
if (mModule->mCompilerOptions & COPT_OPTIMIZE_AUTO_UNROLL) if (mModule->mCompilerOptions & COPT_OPTIMIZE_AUTO_UNROLL)
{ {

View File

@ -159,6 +159,9 @@ public:
void LimitMin(int64 value); void LimitMin(int64 value);
void LimitMax(int64 value); void LimitMax(int64 value);
void LimitMinBound(int64 value);
void LimitMaxBound(int64 value);
void LimitMinWeak(int64 value); void LimitMinWeak(int64 value);
void LimitMaxWeak(int64 value); void LimitMaxWeak(int64 value);
}; };

View File

@ -1159,6 +1159,12 @@ bool NativeCodeInstruction::IsShift(void) const
return mType == ASMIT_ASL || mType == ASMIT_LSR || mType == ASMIT_ROL || mType == ASMIT_ROR; return mType == ASMIT_ASL || mType == ASMIT_LSR || mType == ASMIT_ROL || mType == ASMIT_ROR;
} }
bool NativeCodeInstruction::IsShiftOrInc(void) const
{
return mType == ASMIT_INC || mType == ASMIT_DEC || mType == ASMIT_ASL || mType == ASMIT_LSR;// || mType == ASMIT_ROL || mType == ASMIT_ROR;
}
bool NativeCodeInstruction::IsCommutative(void) const bool NativeCodeInstruction::IsCommutative(void) const
{ {
return mType == ASMIT_ADC || mType == ASMIT_AND || mType == ASMIT_ORA || mType == ASMIT_EOR; return mType == ASMIT_ADC || mType == ASMIT_AND || mType == ASMIT_ORA || mType == ASMIT_EOR;
@ -14269,6 +14275,46 @@ bool NativeCodeBasicBlock::PropagateSinglePath(void)
CheckLive(); CheckLive();
#if 1
if (mTrueJump && mFalseJump && mTrueJump->mEntryProvidedRegs.Size() && mFalseJump->mEntryRequiredRegs.Size())
{
mTempRegs.Reset(mTrueJump->mEntryRequiredRegs.Size());
for (int i = mIns.Size() - 1; i >= 0; i--)
{
NativeCodeInstruction ins(mIns[i]);
if (ins.mMode == ASMIM_ZERO_PAGE)
{
int addr = ins.mAddress;
if (!mTempRegs[addr])
{
if (ins.IsShiftOrInc() && !(ins.ChangesCarry() && (ins.mLive & LIVE_CPU_REG_C)) && !(ins.mLive & LIVE_CPU_REG_Z))
{
if (mTrueJump->mEntryRequiredRegs[addr] && !mFalseJump->mEntryRequiredRegs[addr] && mTrueJump->mNumEntries == 1 && !mTrueJump->mEntryRequiredRegs[CPU_REG_Z] && !mTrueJump->mEntryRequiredRegs[CPU_REG_C] ||
mFalseJump->mEntryRequiredRegs[addr] && !mTrueJump->mEntryRequiredRegs[addr] && mFalseJump->mNumEntries == 1 && !mFalseJump->mEntryRequiredRegs[CPU_REG_Z] && !mFalseJump->mEntryRequiredRegs[CPU_REG_C])
{
if (mTrueJump->mEntryRequiredRegs[addr])
mTrueJump->mIns.Insert(0, mIns[i]);
else
mFalseJump->mIns.Insert(0, mIns[i]);
mIns.Remove(i);
}
}
else
mTempRegs += addr;
}
}
else if (ins.mMode == ASMIM_INDIRECT_Y)
{
mTempRegs += ins.mAddress;
mTempRegs += ins.mAddress + 1;
}
}
}
#endif
#if 1 #if 1
if (mTrueJump && mFalseJump && mTrueJump->mEntryProvidedRegs.Size() && mFalseJump->mEntryRequiredRegs.Size()) if (mTrueJump && mFalseJump && mTrueJump->mEntryProvidedRegs.Size() && mFalseJump->mEntryRequiredRegs.Size())
{ {

View File

@ -138,6 +138,7 @@ public:
bool IsSame(const NativeCodeInstruction& ins) const; bool IsSame(const NativeCodeInstruction& ins) const;
bool IsCommutative(void) const; bool IsCommutative(void) const;
bool IsShift(void) const; bool IsShift(void) const;
bool IsShiftOrInc(void) const;
bool IsSimpleJSR(void) const; bool IsSimpleJSR(void) const;
bool MayBeMovedBefore(const NativeCodeInstruction& ins); bool MayBeMovedBefore(const NativeCodeInstruction& ins);
@ -262,6 +263,7 @@ public:
NumberSet mLocalRequiredRegs, mLocalProvidedRegs; NumberSet mLocalRequiredRegs, mLocalProvidedRegs;
NumberSet mEntryRequiredRegs, mEntryProvidedRegs; NumberSet mEntryRequiredRegs, mEntryProvidedRegs;
NumberSet mExitRequiredRegs, mExitProvidedRegs; NumberSet mExitRequiredRegs, mExitProvidedRegs;
NumberSet mTempRegs;
void BuildLocalRegSets(void); void BuildLocalRegSets(void);
void BuildGlobalProvidedRegSet(NumberSet fromProvidedTemps); void BuildGlobalProvidedRegSet(NumberSet fromProvidedTemps);