Integer value range optimizations
This commit is contained in:
parent
a86a19fc8c
commit
2b7c7300d7
|
@ -41,6 +41,44 @@ bool IntegerValueRange::Same(const IntegerValueRange& range) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IntegerValueRange::LimitMin(int64 value)
|
||||||
|
{
|
||||||
|
if (mMinState != S_BOUND || mMinValue < value)
|
||||||
|
{
|
||||||
|
mMinState = S_BOUND;
|
||||||
|
mMinValue = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IntegerValueRange::LimitMax(int64 value)
|
||||||
|
{
|
||||||
|
if (mMaxState != S_BOUND || mMaxValue > value)
|
||||||
|
{
|
||||||
|
mMaxState = S_BOUND;
|
||||||
|
mMaxValue = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IntegerValueRange::LimitMinWeak(int64 value)
|
||||||
|
{
|
||||||
|
if (mMinState == S_UNBOUND || mMinValue < value)
|
||||||
|
{
|
||||||
|
mMinState = S_BOUND;
|
||||||
|
mMinValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void IntegerValueRange::LimitMaxWeak(int64 value)
|
||||||
|
{
|
||||||
|
if (mMaxState == S_UNBOUND || mMaxValue > value)
|
||||||
|
{
|
||||||
|
mMaxState = S_BOUND;
|
||||||
|
mMaxValue = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool IntegerValueRange::Merge(const IntegerValueRange& range)
|
bool IntegerValueRange::Merge(const IntegerValueRange& range)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
@ -3367,6 +3405,10 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void)
|
||||||
if (mInstructions[sz - 2]->mSrc[1].IsUnsigned())
|
if (mInstructions[sz - 2]->mSrc[1].IsUnsigned())
|
||||||
mInstructions[sz - 2]->mOperator = IA_CMPLU;
|
mInstructions[sz - 2]->mOperator = IA_CMPLU;
|
||||||
}
|
}
|
||||||
|
else if (mInstructions[sz - 2]->mSrc[0].IsUnsigned() && mInstructions[sz - 2]->mSrc[1].IsUnsigned())
|
||||||
|
{
|
||||||
|
mInstructions[sz - 2]->mOperator = IA_CMPLU;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -3427,6 +3469,32 @@ bool InterCodeBasicBlock::BuildGlobalIntegerRangeSets(void)
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int64 SignedTypeMin(InterType type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case IT_INT8:
|
||||||
|
return -128;
|
||||||
|
case IT_INT16:
|
||||||
|
return -32768;
|
||||||
|
default:
|
||||||
|
return -0x80000000LL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 SignedTypeMax(InterType type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case IT_INT8:
|
||||||
|
return 127;
|
||||||
|
case IT_INT16:
|
||||||
|
return 32767;
|
||||||
|
default:
|
||||||
|
return 0x7fffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
|
void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
|
||||||
{
|
{
|
||||||
mLocalValueRange = mEntryValueRange;
|
mLocalValueRange = mEntryValueRange;
|
||||||
|
@ -3793,14 +3861,28 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
|
||||||
{
|
{
|
||||||
if (mInstructions[sz - 2]->mOperator == IA_CMPLS)
|
if (mInstructions[sz - 2]->mOperator == IA_CMPLS)
|
||||||
{
|
{
|
||||||
if (mInstructions[sz - 2]->mSrc[0].mTemp < 0)
|
int s1 = mInstructions[sz - 2]->mSrc[1].mTemp, s0 = mInstructions[sz - 2]->mSrc[0].mTemp;
|
||||||
{
|
|
||||||
int t = mInstructions[sz - 2]->mSrc[1].mTemp;
|
|
||||||
mTrueValueRange[t].mMaxState = IntegerValueRange::S_BOUND;
|
|
||||||
mTrueValueRange[t].mMaxValue = mInstructions[sz - 2]->mSrc[0].mIntConst - 1;
|
|
||||||
|
|
||||||
mFalseValueRange[t].mMinState = IntegerValueRange::S_BOUND;
|
if (s0 < 0)
|
||||||
mFalseValueRange[t].mMinValue = mInstructions[sz - 2]->mSrc[0].mIntConst;
|
{
|
||||||
|
mTrueValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst - 1);
|
||||||
|
mTrueValueRange[s1].LimitMinWeak(SignedTypeMin(mInstructions[sz - 2]->mSrc[1].mType));
|
||||||
|
|
||||||
|
mFalseValueRange[s1].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst);
|
||||||
|
}
|
||||||
|
else if (s1 < 0)
|
||||||
|
{
|
||||||
|
mTrueValueRange[s0].LimitMin(mInstructions[sz - 2]->mSrc[1].mIntConst + 1);
|
||||||
|
mTrueValueRange[s0].LimitMaxWeak(SignedTypeMax(mInstructions[sz - 2]->mSrc[0].mType));
|
||||||
|
|
||||||
|
mFalseValueRange[s0].LimitMax(mInstructions[sz - 2]->mSrc[1].mIntConst);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mLocalValueRange[s0].mMaxState == IntegerValueRange::S_BOUND)
|
||||||
|
mTrueValueRange[s1].LimitMax(mLocalValueRange[s0].mMaxValue - 1);
|
||||||
|
if (mLocalValueRange[s0].mMinState == IntegerValueRange::S_BOUND)
|
||||||
|
mFalseValueRange[s1].LimitMin(mLocalValueRange[s0].mMinValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mInstructions[sz - 2]->mOperator == IA_CMPLES)
|
else if (mInstructions[sz - 2]->mOperator == IA_CMPLES)
|
||||||
|
@ -3808,11 +3890,8 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
|
||||||
if (mInstructions[sz - 2]->mSrc[0].mTemp < 0)
|
if (mInstructions[sz - 2]->mSrc[0].mTemp < 0)
|
||||||
{
|
{
|
||||||
int t = mInstructions[sz - 2]->mSrc[1].mTemp;
|
int t = mInstructions[sz - 2]->mSrc[1].mTemp;
|
||||||
mTrueValueRange[t].mMaxState = IntegerValueRange::S_BOUND;
|
mTrueValueRange[t].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst);
|
||||||
mTrueValueRange[t].mMaxValue = mInstructions[sz - 2]->mSrc[0].mIntConst;
|
mFalseValueRange[t].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst + 1);
|
||||||
|
|
||||||
mFalseValueRange[t].mMinState = IntegerValueRange::S_BOUND;
|
|
||||||
mFalseValueRange[t].mMinValue = mInstructions[sz - 2]->mSrc[0].mIntConst + 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mInstructions[sz - 2]->mOperator == IA_CMPGS)
|
else if (mInstructions[sz - 2]->mOperator == IA_CMPGS)
|
||||||
|
@ -3820,11 +3899,8 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
|
||||||
if (mInstructions[sz - 2]->mSrc[0].mTemp < 0)
|
if (mInstructions[sz - 2]->mSrc[0].mTemp < 0)
|
||||||
{
|
{
|
||||||
int t = mInstructions[sz - 2]->mSrc[1].mTemp;
|
int t = mInstructions[sz - 2]->mSrc[1].mTemp;
|
||||||
mTrueValueRange[t].mMinState = IntegerValueRange::S_BOUND;
|
mTrueValueRange[t].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst + 1);
|
||||||
mTrueValueRange[t].mMinValue = mInstructions[sz - 2]->mSrc[0].mIntConst + 1;
|
mFalseValueRange[t].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst);
|
||||||
|
|
||||||
mFalseValueRange[t].mMaxState = IntegerValueRange::S_BOUND;
|
|
||||||
mFalseValueRange[t].mMaxValue = mInstructions[sz - 2]->mSrc[0].mIntConst;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mInstructions[sz - 2]->mOperator == IA_CMPGES)
|
else if (mInstructions[sz - 2]->mOperator == IA_CMPGES)
|
||||||
|
@ -3832,11 +3908,8 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
|
||||||
if (mInstructions[sz - 2]->mSrc[0].mTemp < 0)
|
if (mInstructions[sz - 2]->mSrc[0].mTemp < 0)
|
||||||
{
|
{
|
||||||
int t = mInstructions[sz - 2]->mSrc[1].mTemp;
|
int t = mInstructions[sz - 2]->mSrc[1].mTemp;
|
||||||
mTrueValueRange[t].mMinState = IntegerValueRange::S_BOUND;
|
mTrueValueRange[t].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst);
|
||||||
mTrueValueRange[t].mMinValue = mInstructions[sz - 2]->mSrc[0].mIntConst;
|
mFalseValueRange[t].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst - 1);
|
||||||
|
|
||||||
mFalseValueRange[t].mMaxState = IntegerValueRange::S_BOUND;
|
|
||||||
mFalseValueRange[t].mMaxValue = mInstructions[sz - 2]->mSrc[0].mIntConst - 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mInstructions[sz - 2]->mOperator == IA_CMPLU)
|
else if (mInstructions[sz - 2]->mOperator == IA_CMPLU)
|
||||||
|
@ -3846,28 +3919,22 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
|
||||||
int t = mInstructions[sz - 2]->mSrc[1].mTemp;
|
int t = mInstructions[sz - 2]->mSrc[1].mTemp;
|
||||||
if (mInstructions[sz - 2]->mSrc[0].mTemp < 0)
|
if (mInstructions[sz - 2]->mSrc[0].mTemp < 0)
|
||||||
{
|
{
|
||||||
mTrueValueRange[t].mMaxState = IntegerValueRange::S_BOUND;
|
mTrueValueRange[t].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst - 1);
|
||||||
mTrueValueRange[t].mMaxValue = mInstructions[sz - 2]->mSrc[0].mIntConst - 1;
|
mTrueValueRange[t].LimitMin(0);
|
||||||
mTrueValueRange[t].mMinState = IntegerValueRange::S_BOUND;
|
|
||||||
mTrueValueRange[t].mMinValue = 0;
|
|
||||||
|
|
||||||
if (mFalseValueRange[t].mMinState == IntegerValueRange::S_BOUND && mFalseValueRange[t].mMinValue >= 0)
|
if (mFalseValueRange[t].mMinState == IntegerValueRange::S_BOUND && mFalseValueRange[t].mMinValue >= 0)
|
||||||
{
|
{
|
||||||
mFalseValueRange[t].mMinState = IntegerValueRange::S_BOUND;
|
mFalseValueRange[t].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst);
|
||||||
mFalseValueRange[t].mMinValue = mInstructions[sz - 2]->mSrc[0].mIntConst;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mInstructions[sz - 2]->mSrc[0].mRange.mMaxState == IntegerValueRange::S_BOUND)
|
else if (mInstructions[sz - 2]->mSrc[0].mRange.mMaxState == IntegerValueRange::S_BOUND)
|
||||||
{
|
{
|
||||||
mTrueValueRange[t].mMaxState = IntegerValueRange::S_BOUND;
|
mTrueValueRange[t].LimitMax(mInstructions[sz - 2]->mSrc[0].mRange.mMaxValue - 1);
|
||||||
mTrueValueRange[t].mMaxValue = mInstructions[sz - 2]->mSrc[0].mRange.mMaxValue - 1;
|
mTrueValueRange[t].LimitMin(0);
|
||||||
mTrueValueRange[t].mMinState = IntegerValueRange::S_BOUND;
|
|
||||||
mTrueValueRange[t].mMinValue = 0;
|
|
||||||
|
|
||||||
if (mFalseValueRange[t].mMinState == IntegerValueRange::S_BOUND && mFalseValueRange[t].mMinValue >= 0)
|
if (mFalseValueRange[t].mMinState == IntegerValueRange::S_BOUND && mFalseValueRange[t].mMinValue >= 0)
|
||||||
{
|
{
|
||||||
mFalseValueRange[t].mMinState = IntegerValueRange::S_BOUND;
|
mFalseValueRange[t].LimitMin(mInstructions[sz - 2]->mSrc[0].mRange.mMaxValue);
|
||||||
mFalseValueRange[t].mMinValue = mInstructions[sz - 2]->mSrc[0].mRange.mMaxValue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3877,15 +3944,12 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
|
||||||
if (mInstructions[sz - 2]->mSrc[0].mTemp < 0)
|
if (mInstructions[sz - 2]->mSrc[0].mTemp < 0)
|
||||||
{
|
{
|
||||||
int t = mInstructions[sz - 2]->mSrc[1].mTemp;
|
int t = mInstructions[sz - 2]->mSrc[1].mTemp;
|
||||||
mTrueValueRange[t].mMaxState = IntegerValueRange::S_BOUND;
|
mTrueValueRange[t].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst);
|
||||||
mTrueValueRange[t].mMaxValue = mInstructions[sz - 2]->mSrc[0].mIntConst;
|
mTrueValueRange[t].LimitMin(0);
|
||||||
mTrueValueRange[t].mMinState = IntegerValueRange::S_BOUND;
|
|
||||||
mTrueValueRange[t].mMinValue = 0;
|
|
||||||
|
|
||||||
if (mFalseValueRange[t].mMinState == IntegerValueRange::S_BOUND && mFalseValueRange[t].mMinValue >= 0)
|
if (mFalseValueRange[t].mMinState == IntegerValueRange::S_BOUND && mFalseValueRange[t].mMinValue >= 0)
|
||||||
{
|
{
|
||||||
mFalseValueRange[t].mMinState = IntegerValueRange::S_BOUND;
|
mFalseValueRange[t].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst + 1);
|
||||||
mFalseValueRange[t].mMinValue = mInstructions[sz - 2]->mSrc[0].mIntConst + 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3896,14 +3960,11 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
|
||||||
int t = mInstructions[sz - 2]->mSrc[1].mTemp;
|
int t = mInstructions[sz - 2]->mSrc[1].mTemp;
|
||||||
// if (mTrueValueRange[t].mMinState == IntegerValueRange::S_BOUND && mTrueValueRange[t].mMinValue >= 0)
|
// if (mTrueValueRange[t].mMinState == IntegerValueRange::S_BOUND && mTrueValueRange[t].mMinValue >= 0)
|
||||||
{
|
{
|
||||||
mTrueValueRange[t].mMinState = IntegerValueRange::S_BOUND;
|
mTrueValueRange[t].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst + 1);
|
||||||
mTrueValueRange[t].mMinValue = mInstructions[sz - 2]->mSrc[0].mIntConst + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mFalseValueRange[t].mMaxState = IntegerValueRange::S_BOUND;
|
mFalseValueRange[t].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst);
|
||||||
mFalseValueRange[t].mMaxValue = mInstructions[sz - 2]->mSrc[0].mIntConst;
|
mFalseValueRange[t].LimitMin(0);
|
||||||
mFalseValueRange[t].mMinState = IntegerValueRange::S_BOUND;
|
|
||||||
mFalseValueRange[t].mMinValue = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mInstructions[sz - 2]->mOperator == IA_CMPGEU)
|
else if (mInstructions[sz - 2]->mOperator == IA_CMPGEU)
|
||||||
|
@ -3913,14 +3974,11 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
|
||||||
int t = mInstructions[sz - 2]->mSrc[1].mTemp;
|
int t = mInstructions[sz - 2]->mSrc[1].mTemp;
|
||||||
if (mTrueValueRange[t].mMinState == IntegerValueRange::S_BOUND && mTrueValueRange[t].mMinValue >= 0)
|
if (mTrueValueRange[t].mMinState == IntegerValueRange::S_BOUND && mTrueValueRange[t].mMinValue >= 0)
|
||||||
{
|
{
|
||||||
mTrueValueRange[t].mMinState = IntegerValueRange::S_BOUND;
|
mTrueValueRange[t].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst);
|
||||||
mTrueValueRange[t].mMinValue = mInstructions[sz - 2]->mSrc[0].mIntConst;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mFalseValueRange[t].mMaxState = IntegerValueRange::S_BOUND;
|
mFalseValueRange[t].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst - 1);
|
||||||
mFalseValueRange[t].mMaxValue = mInstructions[sz - 2]->mSrc[0].mIntConst - 1;
|
mFalseValueRange[t].LimitMin(0);
|
||||||
mFalseValueRange[t].mMinState = IntegerValueRange::S_BOUND;
|
|
||||||
mFalseValueRange[t].mMinValue = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6928,7 +6986,12 @@ void InterCodeProcedure::SingleAssignmentForwarding(void)
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->SingleAssignmentTempForwarding(tunified, tvalues);
|
mEntryBlock->SingleAssignmentTempForwarding(tunified, tvalues);
|
||||||
|
|
||||||
|
BuildDataFlowSets();
|
||||||
|
TempForwarding();
|
||||||
|
RemoveUnusedInstructions();
|
||||||
|
|
||||||
DisassembleDebug("single assignment forwarding");
|
DisassembleDebug("single assignment forwarding");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterCodeProcedure::TempForwarding(void)
|
void InterCodeProcedure::TempForwarding(void)
|
||||||
|
@ -7277,6 +7340,7 @@ void InterCodeProcedure::Close(void)
|
||||||
DisassembleDebug("Peephole optimized");
|
DisassembleDebug("Peephole optimized");
|
||||||
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
#if 1
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
BuildDataFlowSets();
|
BuildDataFlowSets();
|
||||||
|
@ -7287,7 +7351,7 @@ void InterCodeProcedure::Close(void)
|
||||||
DisassembleDebug("Pushed single path result");
|
DisassembleDebug("Pushed single path result");
|
||||||
|
|
||||||
} while (changed);
|
} while (changed);
|
||||||
|
#endif
|
||||||
|
|
||||||
BuildDataFlowSets();
|
BuildDataFlowSets();
|
||||||
|
|
||||||
|
@ -7341,7 +7405,7 @@ void InterCodeProcedure::Close(void)
|
||||||
mEntryBlock->CollectEntryBlocks(nullptr);
|
mEntryBlock->CollectEntryBlocks(nullptr);
|
||||||
|
|
||||||
BuildDataFlowSets();
|
BuildDataFlowSets();
|
||||||
|
#if 1
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->BuildLocalIntegerRangeSets(mTemporaries.Size());
|
mEntryBlock->BuildLocalIntegerRangeSets(mTemporaries.Size());
|
||||||
|
|
||||||
|
@ -7357,7 +7421,7 @@ void InterCodeProcedure::Close(void)
|
||||||
mEntryBlock->SimplifyIntegerRangeRelops();
|
mEntryBlock->SimplifyIntegerRangeRelops();
|
||||||
|
|
||||||
DisassembleDebug("Simplified range limited relational ops");
|
DisassembleDebug("Simplified range limited relational ops");
|
||||||
|
#endif
|
||||||
MapVariables();
|
MapVariables();
|
||||||
|
|
||||||
DisassembleDebug("mapped variabled");
|
DisassembleDebug("mapped variabled");
|
||||||
|
|
|
@ -146,6 +146,12 @@ public:
|
||||||
|
|
||||||
bool Same(const IntegerValueRange& range) const;
|
bool Same(const IntegerValueRange& range) const;
|
||||||
bool Merge(const IntegerValueRange& range);
|
bool Merge(const IntegerValueRange& range);
|
||||||
|
|
||||||
|
void LimitMin(int64 value);
|
||||||
|
void LimitMax(int64 value);
|
||||||
|
|
||||||
|
void LimitMinWeak(int64 value);
|
||||||
|
void LimitMaxWeak(int64 value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6037,9 +6037,19 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
|
||||||
if (InterTypeSize[ins->mDst.mType] > 1)
|
if (InterTypeSize[ins->mDst.mType] > 1)
|
||||||
{
|
{
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1));
|
#if 1
|
||||||
mIns.Push(NativeCodeInstruction(atype, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
if (ins->mDst.IsUByte())
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
{
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1));
|
||||||
|
mIns.Push(NativeCodeInstruction(atype, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7708,9 +7718,11 @@ void NativeCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
|
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]));
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[1].mIntConst >> 8) & 0xff));
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[1].mIntConst >> 8) & 0xff));
|
||||||
|
#if 1
|
||||||
if (ins->mSrc[0].IsUByte())
|
if (ins->mSrc[0].IsUByte())
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0));
|
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0));
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1));
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1));
|
||||||
}
|
}
|
||||||
|
@ -7720,9 +7732,11 @@ void NativeCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
|
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]));
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSrc[0].mIntConst, ins->mSrc[1].mLinkerObject, NCIF_UPPER));
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSrc[0].mIntConst, ins->mSrc[1].mLinkerObject, NCIF_UPPER));
|
||||||
|
#if 1
|
||||||
if (ins->mSrc[0].IsUByte())
|
if (ins->mSrc[0].IsUByte())
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0));
|
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0));
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1));
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1));
|
||||||
}
|
}
|
||||||
|
@ -9975,6 +9989,43 @@ bool NativeCodeBasicBlock::MoveLoadAddZPStoreUp(int at)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::MoveCLCLoadAddZPStoreDown(int at)
|
||||||
|
{
|
||||||
|
int j = at + 4;
|
||||||
|
while (j < mIns.Size())
|
||||||
|
{
|
||||||
|
if (mIns[j].mType == ASMIT_LDA && mIns[j].mMode == ASMIM_ZERO_PAGE && mIns[j].mAddress == mIns[at + 3].mAddress)
|
||||||
|
{
|
||||||
|
if (j == at + 4)
|
||||||
|
return false;
|
||||||
|
if (mIns[j].mLive & LIVE_CPU_REG_C)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
mIns.Insert(j, mIns[at + 3]); // STA
|
||||||
|
mIns.Insert(j, mIns[at + 2]); // ADC
|
||||||
|
mIns.Insert(j, mIns[at + 1]); // LDA
|
||||||
|
mIns.Insert(j, mIns[at + 0]); // CLC
|
||||||
|
|
||||||
|
mIns[at + 0].mType = ASMIT_NOP; mIns[at + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[at + 1].mType = ASMIT_NOP; mIns[at + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[at + 2].mType = ASMIT_NOP; mIns[at + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[at + 3].mType = ASMIT_NOP; mIns[at + 3].mMode = ASMIM_IMPLIED;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mIns[j].ChangesZeroPage(mIns[at + 1].mAddress))
|
||||||
|
return false;
|
||||||
|
if (mIns[j].ChangesZeroPage(mIns[at + 2].mAddress))
|
||||||
|
return false;
|
||||||
|
if (mIns[j].UsesZeroPage(mIns[at + 3].mAddress))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bool global)
|
bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bool global)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
@ -10148,6 +10199,8 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock* prevBlock, NativeCodeBasicBlock* exitBlock)
|
bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock* prevBlock, NativeCodeBasicBlock* exitBlock)
|
||||||
{
|
{
|
||||||
|
return false;
|
||||||
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
int ai = 0;
|
int ai = 0;
|
||||||
|
@ -11354,6 +11407,7 @@ void NativeCodeBasicBlock::BlockSizeReduction(void)
|
||||||
carryClear = carrySet = false;
|
carryClear = carrySet = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
if (carryClear || carrySet)
|
if (carryClear || carrySet)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -11367,7 +11421,7 @@ void NativeCodeBasicBlock::BlockSizeReduction(void)
|
||||||
mIns.Remove(i);
|
mIns.Remove(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (mTrueJump)
|
if (mTrueJump)
|
||||||
mTrueJump->BlockSizeReduction();
|
mTrueJump->BlockSizeReduction();
|
||||||
if (mFalseJump)
|
if (mFalseJump)
|
||||||
|
@ -11515,6 +11569,26 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
// move simple add down to consumer
|
||||||
|
|
||||||
|
if (!changed)
|
||||||
|
{
|
||||||
|
for (int i = 0; i + 4 < mIns.Size(); i++)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
|
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && (mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_C)) == 0)
|
||||||
|
{
|
||||||
|
if (MoveCLCLoadAddZPStoreDown(i))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// shorten x/y register livetime
|
// shorten x/y register livetime
|
||||||
|
|
||||||
|
@ -12978,6 +13052,21 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if 1
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_IMMEDIATE &&
|
||||||
|
mIns[i + 1].mType == ASMIT_ADC &&
|
||||||
|
mIns[i + 2].mType == ASMIT_CLC &&
|
||||||
|
mIns[i + 3].mType == ASMIT_ADC && mIns[i + 3].mMode == ASMIM_IMMEDIATE && !(mIns[i + 3].mLive & LIVE_CPU_REG_C))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mAddress += mIns[i + 3].mAddress;
|
||||||
|
|
||||||
|
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||||
|
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_LDA &&
|
mIns[i + 0].mType == ASMIT_LDA &&
|
||||||
mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) &&
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) &&
|
||||||
|
|
|
@ -206,6 +206,7 @@ public:
|
||||||
bool MoveLoadAddImmStoreUp(int at);
|
bool MoveLoadAddImmStoreUp(int at);
|
||||||
bool MoveCLCLoadAddZPStoreUp(int at);
|
bool MoveCLCLoadAddZPStoreUp(int at);
|
||||||
bool MoveLoadAddZPStoreUp(int at);
|
bool MoveLoadAddZPStoreUp(int at);
|
||||||
|
bool MoveCLCLoadAddZPStoreDown(int at);
|
||||||
bool FindDirectAddressSumY(int at, int reg, int& apos, int& breg);
|
bool FindDirectAddressSumY(int at, int reg, int& apos, int& breg);
|
||||||
bool PatchDirectAddressSumY(int at, int reg, int apos, int breg);
|
bool PatchDirectAddressSumY(int at, int reg, int apos, int breg);
|
||||||
bool FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg);
|
bool FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg);
|
||||||
|
|
Loading…
Reference in New Issue