Fix over eager elimination of byte to word conversion

This commit is contained in:
drmortalwombat 2022-06-14 22:29:42 +02:00
parent d37980e73c
commit e7332192c0
4 changed files with 192 additions and 42 deletions

View File

@ -4970,7 +4970,7 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void)
}
bool InterCodeBasicBlock::BuildGlobalIntegerRangeSets(bool initial)
bool InterCodeBasicBlock::BuildGlobalIntegerRangeSets(bool initial, const GrowingVariableArray& localVars)
{
bool changed = false;
@ -5020,13 +5020,13 @@ bool InterCodeBasicBlock::BuildGlobalIntegerRangeSets(bool initial)
{
mEntryValueRange = mLocalValueRange;
UpdateLocalIntegerRangeSets();
UpdateLocalIntegerRangeSets(localVars);
}
if (mTrueJump && mTrueJump->BuildGlobalIntegerRangeSets(initial))
if (mTrueJump && mTrueJump->BuildGlobalIntegerRangeSets(initial, localVars))
changed = true;
if (mFalseJump && mFalseJump->BuildGlobalIntegerRangeSets(initial))
if (mFalseJump && mFalseJump->BuildGlobalIntegerRangeSets(initial, localVars))
changed = true;
}
@ -5070,7 +5070,7 @@ static int64 BuildLowerBitsMask(int64 v)
return v;
}
void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray& localVars)
{
mLocalValueRange = mEntryValueRange;
@ -5122,6 +5122,20 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
LinkerObject* lo = mInstructions[i - 1]->mSrc[1].mLinkerObject;
int mi = 0, ma = 0;
if (vr.mMinState == IntegerValueRange::S_BOUND && vr.mMaxState == IntegerValueRange::S_BOUND &&
vr.mMinValue >= -128 && vr.mMaxValue <= 127)
{
for (int j = 0; j < lo->mSize; j++)
{
int v = (int8)(lo->mData[j]);
if (v < mi)
mi = v;
if (v > ma)
ma = v;
}
}
else
{
for (int j = 0; j < lo->mSize; j++)
{
int v = lo->mData[j];
@ -5130,6 +5144,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
if (v > ma)
ma = v;
}
}
vr.LimitMax(ma);
vr.LimitMin(mi);
@ -5606,6 +5621,8 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
int asize = 0;
if (ins->mSrc[1].mMemory == IM_GLOBAL)
asize = ins->mSrc[1].mLinkerObject->mSize;
else if (ins->mSrc[1].mMemory == IM_LOCAL)
asize = localVars[ins->mSrc[1].mVarIndex]->mSize;
if (asize > 0)
{
@ -5627,7 +5644,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
{
case IA_EXT8TO16U:
case IA_EXT8TO16S:
if (ins->mSrc[0].mTemp >= 0)
if (ins->mSrc[0].mTemp >= 0 && (vr.mMaxValue != 255 || vr.mMinValue != 0))
mReverseValueRange[ins->mSrc[0].mTemp].Limit(vr);
break;
}
@ -5928,7 +5945,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
void InterCodeBasicBlock::RestartLocalIntegerRangeSets(void)
void InterCodeBasicBlock::RestartLocalIntegerRangeSets(const GrowingVariableArray& localVars)
{
if (!mVisited)
{
@ -5943,14 +5960,14 @@ void InterCodeBasicBlock::RestartLocalIntegerRangeSets(void)
vr.mMaxState = IntegerValueRange::S_UNKNOWN;
}
UpdateLocalIntegerRangeSets();
UpdateLocalIntegerRangeSets(localVars);
if (mTrueJump) mTrueJump->RestartLocalIntegerRangeSets();
if (mFalseJump) mFalseJump->RestartLocalIntegerRangeSets();
if (mTrueJump) mTrueJump->RestartLocalIntegerRangeSets(localVars);
if (mFalseJump) mFalseJump->RestartLocalIntegerRangeSets(localVars);
}
}
void InterCodeBasicBlock::BuildLocalIntegerRangeSets(int num)
void InterCodeBasicBlock::BuildLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars)
{
if (!mVisited)
{
@ -5963,10 +5980,10 @@ void InterCodeBasicBlock::BuildLocalIntegerRangeSets(int num)
mMemoryValueSize.SetSize(num, true);
mEntryMemoryValueSize.SetSize(num, true);
UpdateLocalIntegerRangeSets();
UpdateLocalIntegerRangeSets(localVars);
if (mTrueJump) mTrueJump->BuildLocalIntegerRangeSets(num);
if (mFalseJump) mFalseJump->BuildLocalIntegerRangeSets(num);
if (mTrueJump) mTrueJump->BuildLocalIntegerRangeSets(num, localVars);
if (mFalseJump) mFalseJump->BuildLocalIntegerRangeSets(num, localVars);
}
}
@ -6949,12 +6966,33 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
{
InterInstruction* ains = ltvalue[pins->mSrc[0].mTemp];
if (ains->mCode == IC_BINARY_OPERATOR && ains->mOperator == IA_ADD && ains->mSrc[0].mTemp < 0 && ains->mDst.mType == IT_INT16)
if (ains->mCode == IC_BINARY_OPERATOR && ains->mOperator == IA_ADD && ains->mSrc[0].mTemp < 0)
{
if (ains->mSrc[0].mType == IT_INT16)
{
ins->mSrc[0] = ains->mSrc[1];
ins->mSrc[1].mIntConst += ains->mSrc[0].mIntConst;
changed = true;
}
else if (ains->mSrc[0].mType == IT_INT8)
{
if (spareTemps + 2 >= ltvalue.Size())
return true;
InterInstruction* nins = new InterInstruction();
nins->mCode = IC_CONVERSION_OPERATOR;
nins->mOperator = IA_EXT8TO16U;
nins->mSrc[0] = ains->mSrc[1];
nins->mDst.mTemp = spareTemps++;
nins->mDst.mType = IT_INT16;
nins->mDst.mRange = pins->mDst.mRange;
mInstructions.Insert(i, nins);
ins->mSrc[0] = ains->mSrc[1];
ins->mSrc[1].mIntConst += ains->mSrc[0].mIntConst;
changed = true;
}
}
}
#endif
}
@ -11367,37 +11405,37 @@ void InterCodeProcedure::Close(void)
BuildDataFlowSets();
#if 1
ResetVisited();
mEntryBlock->BuildLocalIntegerRangeSets(mTemporaries.Size());
mEntryBlock->BuildLocalIntegerRangeSets(mTemporaries.Size(), mLocalVars);
do {
DisassembleDebug("tt");
ResetVisited();
} while (mEntryBlock->BuildGlobalIntegerRangeSets(true));
} while (mEntryBlock->BuildGlobalIntegerRangeSets(true, mLocalVars));
do {
DisassembleDebug("tq");
ResetVisited();
} while (mEntryBlock->BuildGlobalIntegerRangeSets(false));
} while (mEntryBlock->BuildGlobalIntegerRangeSets(false, mLocalVars));
DisassembleDebug("Estimated value range");
#if 1
ResetVisited();
mEntryBlock->RestartLocalIntegerRangeSets();
mEntryBlock->RestartLocalIntegerRangeSets(mLocalVars);
do {
DisassembleDebug("tr");
ResetVisited();
} while (mEntryBlock->BuildGlobalIntegerRangeSets(true));
} while (mEntryBlock->BuildGlobalIntegerRangeSets(true, mLocalVars));
do {
DisassembleDebug("tr");
ResetVisited();
} while (mEntryBlock->BuildGlobalIntegerRangeSets(false));
} while (mEntryBlock->BuildGlobalIntegerRangeSets(false, mLocalVars));
DisassembleDebug("Estimated value range 2");
#endif
@ -11465,19 +11503,19 @@ void InterCodeProcedure::Close(void)
#if 1
ResetVisited();
mEntryBlock->RestartLocalIntegerRangeSets();
mEntryBlock->RestartLocalIntegerRangeSets(mLocalVars);
do {
DisassembleDebug("tr");
ResetVisited();
} while (mEntryBlock->BuildGlobalIntegerRangeSets(true));
} while (mEntryBlock->BuildGlobalIntegerRangeSets(true, mLocalVars));
do {
DisassembleDebug("tr");
ResetVisited();
} while (mEntryBlock->BuildGlobalIntegerRangeSets(false));
} while (mEntryBlock->BuildGlobalIntegerRangeSets(false, mLocalVars));
DisassembleDebug("Estimated value range 2");
#endif

View File

@ -404,10 +404,10 @@ public:
bool BuildGlobalRequiredStaticVariableSet(const GrowingVariableArray& staticVars, NumberSet& fromRequiredVars);
bool RemoveUnusedStaticStoreInstructions(const GrowingVariableArray& staticVars);
void RestartLocalIntegerRangeSets(void);
void BuildLocalIntegerRangeSets(int num);
void UpdateLocalIntegerRangeSets(void);
bool BuildGlobalIntegerRangeSets(bool initial);
void RestartLocalIntegerRangeSets(const GrowingVariableArray& localVars);
void BuildLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars);
void UpdateLocalIntegerRangeSets(const GrowingVariableArray& localVars);
bool BuildGlobalIntegerRangeSets(bool initial, const GrowingVariableArray& localVars);
void SimplifyIntegerRangeRelops(void);
GrowingIntArray mEntryRenameTable;

View File

@ -23077,6 +23077,74 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
progress = true;
}
}
else 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_IMMEDIATE && (mIns[i + 2].mAddress == 1 || mIns[i + 2].mAddress == 2) &&
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 4].mType == ASMIT_STA && mIns[i + 4].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 4].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
{
if (!(mIns[i + 4].mLive & LIVE_CPU_REG_X))
{
mIns[i + 0].mType = ASMIT_LDX; mIns[i + 0].CopyMode(mIns[i + 1]); mIns[i + 0].mLive |= LIVE_CPU_REG_X;
mIns[i + 1].mType = ASMIT_INX; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 1].mLive |= LIVE_CPU_REG_X;
if (mIns[i + 2].mAddress == 2)
mIns[i + 2].mType = ASMIT_INX;
else
mIns[i + 2].mType = ASMIT_NOP;
mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mLive |= LIVE_CPU_REG_X;
mIns[i + 3].mType = ASMIT_STX; mIns[i + 3].mLive |= LIVE_CPU_REG_X;
mIns[i + 4].mType = ASMIT_STX;
progress = true;
}
else if (!(mIns[i + 4].mLive & LIVE_CPU_REG_Y))
{
mIns[i + 0].mType = ASMIT_LDY; mIns[i + 0].CopyMode(mIns[i + 1]); mIns[i + 0].mLive |= LIVE_CPU_REG_Y;
mIns[i + 1].mType = ASMIT_INY; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 1].mLive |= LIVE_CPU_REG_Y;
if (mIns[i + 2].mAddress == 2)
mIns[i + 2].mType = ASMIT_INY;
else
mIns[i + 2].mType = ASMIT_NOP;
mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mLive |= LIVE_CPU_REG_Y;
mIns[i + 3].mType = ASMIT_STY; mIns[i + 3].mLive |= LIVE_CPU_REG_Y;
mIns[i + 4].mType = ASMIT_STY;
progress = true;
}
}
else if (
mIns[i + 0].mType == ASMIT_SEC &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && (mIns[i + 2].mAddress == 1 || mIns[i + 2].mAddress == 2) &&
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 4].mType == ASMIT_STA && mIns[i + 4].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 4].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
{
if (!(mIns[i + 4].mLive & LIVE_CPU_REG_X))
{
mIns[i + 0].mType = ASMIT_LDX; mIns[i + 0].CopyMode(mIns[i + 1]); mIns[i + 0].mLive |= LIVE_CPU_REG_X;
mIns[i + 1].mType = ASMIT_DEX; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 1].mLive |= LIVE_CPU_REG_X;
if (mIns[i + 2].mAddress == 2)
mIns[i + 2].mType = ASMIT_DEX;
else
mIns[i + 2].mType = ASMIT_NOP;
mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mLive |= LIVE_CPU_REG_X;
mIns[i + 3].mType = ASMIT_STX; mIns[i + 3].mLive |= LIVE_CPU_REG_X;
mIns[i + 4].mType = ASMIT_STX;
progress = true;
}
else if (!(mIns[i + 4].mLive & LIVE_CPU_REG_Y))
{
mIns[i + 0].mType = ASMIT_LDY; mIns[i + 0].CopyMode(mIns[i + 1]); mIns[i + 0].mLive |= LIVE_CPU_REG_Y;
mIns[i + 1].mType = ASMIT_DEY; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 1].mLive |= LIVE_CPU_REG_Y;
if (mIns[i + 2].mAddress == 2)
mIns[i + 2].mType = ASMIT_DEY;
else
mIns[i + 2].mType = ASMIT_NOP;
mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mLive |= LIVE_CPU_REG_Y;
mIns[i + 3].mType = ASMIT_STY; mIns[i + 3].mLive |= LIVE_CPU_REG_Y;
mIns[i + 4].mType = ASMIT_STY;
progress = true;
}
}
}
#endif
CheckLive();
@ -23273,6 +23341,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_AND && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 1 &&
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 3].mType == ASMIT_ASL && mIns[i + 3].mMode == ASMIM_IMPLIED &&
mIns[i + 4].mType == ASMIT_CLC &&
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_ZERO_PAGE && mIns[i + 5].mAddress == mIns[i + 1].mAddress && !(mIns[i + 5].mLive & (LIVE_MEM | LIVE_CPU_REG_C)))
{
mIns[i + 0].mType = ASMIT_LSR; mIns[i + 0].mMode = ASMIM_IMPLIED; mIns[i + 0].mLive |= LIVE_CPU_REG_C;
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
mIns[i + 2].mLive |= LIVE_CPU_REG_C;
mIns[i + 3].mType = ASMIT_ROL;
mIns[i + 4].mType = ASMIT_NOP; mIns[i + 4].mMode = ASMIM_IMPLIED;
mIns[i + 5].mType = ASMIT_NOP; mIns[i + 5].mMode = ASMIM_IMPLIED;
progress = true;
}
#endif
else if (pass > 0 &&
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
@ -23384,6 +23468,26 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 5].mType = ASMIT_NOP; mIns[i + 5].mMode = ASMIM_IMPLIED;
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 1].mType == ASMIT_ASL && mIns[i + 1].mMode == ASMIM_IMPLIED &&
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 3].mType == ASMIT_LDA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 4].mType == ASMIT_AND && mIns[i + 4].mMode == ASMIM_IMMEDIATE && mIns[i + 4].mAddress == 1 &&
mIns[i + 5].mType == ASMIT_CLC &&
mIns[i + 6].mType == ASMIT_ADC && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 2].mAddress && !(mIns[i + 6].mLive & (LIVE_MEM | LIVE_CPU_REG_C)))
{
int addr = mIns[i + 0].mAddress;
mIns[i + 0].mAddress = mIns[i + 3].mAddress;
mIns[i + 3].mAddress = addr;
mIns[i + 1].mType = ASMIT_LSR; mIns[i + 1].mLive |= LIVE_CPU_REG_C;
mIns[i + 3].mLive |= LIVE_CPU_REG_C;
mIns[i + 5].mType = ASMIT_ROL;
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
mIns[i + 4].mType = ASMIT_NOP; mIns[i + 4].mMode = ASMIM_IMPLIED;
mIns[i + 6].mType = ASMIT_NOP; mIns[i + 6].mMode = ASMIM_IMPLIED;
progress = true;
}
#if 1
if (pass == 0 &&
mIns[i + 0].mType == ASMIT_CLC &&
@ -23494,7 +23598,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
progress = true;
}
}
#if 1
if (
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_INDIRECT_Y &&
@ -23507,13 +23611,21 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
j++;
if (j < mIns.Size() && mIns[j].mType == ASMIT_LDY && mIns[j].mMode == ASMIM_IMMEDIATE && mIns[j].mAddress == mIns[i + 0].mAddress)
{
int reg = mIns[1].mAddress; mIns[1].mAddress = mIns[4].mAddress; mIns[4].mAddress = reg;
int yr = mIns[0].mAddress; mIns[0].mAddress = mIns[3].mAddress; mIns[3].mAddress = yr;
mIns[1].mLive |= LIVE_MEM;
mIns[4].mLive |= LIVE_MEM;
int reg = mIns[i + 1].mAddress; mIns[i + 1].mAddress = mIns[i + 4].mAddress; mIns[i + 4].mAddress = reg;
int yr = mIns[i + 0].mAddress; mIns[i + 0].mAddress = mIns[i + 3].mAddress; mIns[i + 3].mAddress = yr;
mIns[i + 1].mLive |= LIVE_MEM;
mIns[i + 4].mLive |= LIVE_MEM;
mIns[j].mType = ASMIT_NOP; mIns[j].mMode = ASMIM_IMPLIED;
while (j > i)
{
j--;
mIns[j].mLive |= LIVE_CPU_REG_Y;
}
progress = true;
}
}
#endif
#endif
}

Binary file not shown.