More aggressive reverse value range limit forwarding

This commit is contained in:
drmortalwombat 2022-06-12 13:39:46 +02:00
parent 078007c9fe
commit 6e37060c24
7 changed files with 161 additions and 49 deletions

View File

@ -69,6 +69,21 @@ void spr_move(char sp, int xpos, int ypos)
vic.spr_msbx &= ~(1 << sp);
}
void spr_move16(char sp, int xpos, int ypos)
{
__assume (sp < 8);
if (ypos < 0 || ypos >= 256 || xpos < 0 || xpos >= 512)
ypos = 0;
vic.spr_pos[sp].y = ypos;
vic.spr_pos[sp].x = xpos & 0xff;
if (xpos & 0x100)
vic.spr_msbx |= 1 << sp;
else
vic.spr_msbx &= ~(1 << sp);
}
void spr_image(char sp, char image)
{
__assume (sp < 8);

View File

@ -15,10 +15,13 @@ void spr_set(char sp, bool show, int xpos, int ypos, char image, char color, boo
inline void spr_show(char sp, bool show);
// move a sprite the
// move a sprite to the given position, only uses 8 bit y and 9 bit x
inline void spr_move(char sp, int xpos, int ypos);
// move a sprite to the given position
void spr_move16(char sp, int xpos, int ypos);
// change the image of a sprite
inline void spr_image(char sp, char image);

View File

@ -22,6 +22,7 @@ enum ErrorID
EWARN_SYNTAX,
EWARN_NOT_INTERRUPT_SAFE,
EWARN_BOOL_SHORTCUT,
EWARN_OPTIMIZER_LOCKED,
EERR_GENERIC = 3000,
EERR_FILE_NOT_FOUND,

View File

@ -372,10 +372,27 @@ void ValueSet::FlushCallAliases(const GrowingInstructionPtrArray& tvalue, const
}
}
static bool CollidingMem(const InterOperand& op1, const InterOperand& op2)
static bool CollidingMem(const InterOperand& op1, const InterOperand& op2, const GrowingVariableArray& staticVars)
{
if (op1.mMemory != op2.mMemory)
return op1.mMemory == IM_INDIRECT || op2.mMemory == IM_INDIRECT;
{
if (op1.mMemory == IM_INDIRECT)
{
if (op2.mMemory == IM_GLOBAL)
return staticVars[op2.mVarIndex]->mAliased;
else
return true;
}
else if (op2.mMemory == IM_INDIRECT)
{
if (op1.mMemory == IM_GLOBAL)
return staticVars[op1.mVarIndex]->mAliased;
else
return true;
}
else
return false;
}
switch (op1.mMemory)
{
@ -400,12 +417,12 @@ static bool CollidingMem(const InterOperand& op1, const InterOperand& op2)
}
}
static bool CollidingMem(const InterOperand& op, const InterInstruction* ins)
static bool CollidingMem(const InterOperand& op, const InterInstruction* ins, const GrowingVariableArray& staticVars)
{
if (ins->mCode == IC_LOAD)
return CollidingMem(op, ins->mSrc[0]);
return CollidingMem(op, ins->mSrc[0], staticVars);
else if (ins->mCode == IC_STORE)
return CollidingMem(op, ins->mSrc[1]);
return CollidingMem(op, ins->mSrc[1], staticVars);
else
return false;
}
@ -3558,7 +3575,8 @@ void InterInstruction::Disassemble(FILE* file)
InterCodeBasicBlock::InterCodeBasicBlock(void)
: mInstructions(nullptr), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr), mMergeAValues(nullptr), mTrueJump(nullptr), mFalseJump(nullptr), mLoopPrefix(nullptr), mDominator(nullptr),
mEntryValueRange(IntegerValueRange()), mTrueValueRange(IntegerValueRange()), mFalseValueRange(IntegerValueRange()), mLocalValueRange(IntegerValueRange()), mReverseValueRange(IntegerValueRange()), mEntryBlocks(nullptr), mLoadStoreInstructions(nullptr), mLoopPathBlocks(nullptr)
mEntryValueRange(IntegerValueRange()), mTrueValueRange(IntegerValueRange()), mFalseValueRange(IntegerValueRange()), mLocalValueRange(IntegerValueRange()),
mReverseValueRange(IntegerValueRange()), mEntryBlocks(nullptr), mLoadStoreInstructions(nullptr), mLoopPathBlocks(nullptr), mMemoryValueSize(0), mEntryMemoryValueSize(0)
{
mInPath = false;
mLoopHead = false;
@ -4583,7 +4601,7 @@ void InterCodeBasicBlock::CollectConstTemps(GrowingInstructionPtrArray& ctemps,
}
}
bool InterCodeBasicBlock::PropagateVariableCopy(const GrowingInstructionPtrArray& ctemps)
bool InterCodeBasicBlock::PropagateVariableCopy(const GrowingInstructionPtrArray& ctemps, const GrowingVariableArray& staticVars)
{
bool changed = false;
@ -4635,8 +4653,8 @@ bool InterCodeBasicBlock::PropagateVariableCopy(const GrowingInstructionPtrArray
j = 0;
for(int k=0; k<ltemps.Size(); k++)
{
if (!CollidingMem(ltemps[k]->mSrc[0], ins->mSrc[1]) &&
!CollidingMem(ltemps[k]->mSrc[1], ins->mSrc[1]))
if (!CollidingMem(ltemps[k]->mSrc[0], ins->mSrc[1], staticVars) &&
!CollidingMem(ltemps[k]->mSrc[1], ins->mSrc[1], staticVars))
{
ltemps[j++] = ltemps[k];
}
@ -4657,8 +4675,8 @@ bool InterCodeBasicBlock::PropagateVariableCopy(const GrowingInstructionPtrArray
j = 0;
for (int k = 0; k < ltemps.Size(); k++)
{
if (!CollidingMem(ltemps[k]->mSrc[0], ins->mSrc[1]) &&
!CollidingMem(ltemps[k]->mSrc[1], ins->mSrc[1]))
if (!CollidingMem(ltemps[k]->mSrc[0], ins->mSrc[1], staticVars) &&
!CollidingMem(ltemps[k]->mSrc[1], ins->mSrc[1], staticVars))
{
ltemps[j++] = ltemps[k];
}
@ -4670,9 +4688,9 @@ bool InterCodeBasicBlock::PropagateVariableCopy(const GrowingInstructionPtrArray
}
if (mTrueJump && mTrueJump->PropagateVariableCopy(ltemps))
if (mTrueJump && mTrueJump->PropagateVariableCopy(ltemps, staticVars))
changed = true;
if (mFalseJump && mFalseJump->PropagateVariableCopy(ltemps))
if (mFalseJump && mFalseJump->PropagateVariableCopy(ltemps, staticVars))
changed = true;
}
@ -4985,6 +5003,15 @@ bool InterCodeBasicBlock::BuildGlobalIntegerRangeSets(bool initial)
if (mVisited && mNumEntered >= 2 * mEntryBlocks.Size())
return changed;
if (mTrueJump && !mFalseJump)
{
for (int i = 0; i < mEntryMemoryValueSize.Size(); i++)
{
if (mEntryMemoryValueSize[i] != mTrueJump->mMemoryValueSize[i])
changed = true;
}
}
if (!mVisited || changed)
{
mVisited = true;
@ -4994,6 +5021,7 @@ bool InterCodeBasicBlock::BuildGlobalIntegerRangeSets(bool initial)
mEntryValueRange = mLocalValueRange;
UpdateLocalIntegerRangeSets();
}
if (mTrueJump && mTrueJump->BuildGlobalIntegerRangeSets(initial))
@ -5547,27 +5575,33 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
#if 1
mReverseValueRange.SetSize(mLocalValueRange.Size());
GrowingArray<int64> msize(0);
msize.SetSize(mLocalValueRange.Size());
for (int i = 0; i < mReverseValueRange.Size(); i++)
mReverseValueRange[i].Reset();
if (mTrueJump && !mFalseJump)
{
for (int i = 0; i < mMemoryValueSize.Size(); i++)
{
mEntryMemoryValueSize[i] = mMemoryValueSize[i] = mTrueJump->mMemoryValueSize[i];
}
}
for (int i = sz - 1; i >= 0; i--)
{
InterInstruction* ins(mInstructions[i]);
if (ins->mCode == IC_LOAD && ins->mSrc[0].mMemory == IM_INDIRECT && ins->mSrc[0].mTemp >= 0)
msize[ins->mSrc[0].mTemp] = int64max(msize[ins->mSrc[0].mTemp], ins->mSrc[0].mIntConst + InterTypeSize[ins->mDst.mType]);
mMemoryValueSize[ins->mSrc[0].mTemp] = int64max(mMemoryValueSize[ins->mSrc[0].mTemp], ins->mSrc[0].mIntConst + InterTypeSize[ins->mDst.mType]);
else if (ins->mCode == IC_STORE && ins->mSrc[1].mMemory == IM_INDIRECT && ins->mSrc[1].mTemp >= 0)
msize[ins->mSrc[1].mTemp] = int64max(msize[ins->mSrc[1].mTemp], ins->mSrc[1].mIntConst + InterTypeSize[ins->mSrc[0].mType]);
mMemoryValueSize[ins->mSrc[1].mTemp] = int64max(mMemoryValueSize[ins->mSrc[1].mTemp], ins->mSrc[1].mIntConst + InterTypeSize[ins->mSrc[0].mType]);
else if (ins->mCode == IC_COPY)
{
if (ins->mSrc[0].mMemory == IM_INDIRECT && ins->mSrc[0].mTemp >= 0)
msize[ins->mSrc[0].mTemp] = ins->mConst.mOperandSize;
mMemoryValueSize[ins->mSrc[0].mTemp] = ins->mConst.mOperandSize;
if (ins->mSrc[1].mMemory == IM_INDIRECT && ins->mSrc[1].mTemp >= 0)
msize[ins->mSrc[1].mTemp] = ins->mConst.mOperandSize;
mMemoryValueSize[ins->mSrc[1].mTemp] = ins->mConst.mOperandSize;
}
else if (ins->mCode == IC_LEA && ins->mSrc[1].mMemory != IM_INDIRECT && ins->mSrc[0].mTemp >= 0 && msize[ins->mDst.mTemp] > 0)
else if (ins->mCode == IC_LEA && ins->mSrc[1].mMemory != IM_INDIRECT && ins->mSrc[0].mTemp >= 0 && mMemoryValueSize[ins->mDst.mTemp] > 0)
{
int asize = 0;
if (ins->mSrc[1].mMemory == IM_GLOBAL)
@ -5576,7 +5610,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
if (asize > 0)
{
mReverseValueRange[ins->mSrc[0].mTemp].LimitMin(0);
mReverseValueRange[ins->mSrc[0].mTemp].LimitMax(asize - msize[ins->mDst.mTemp]);
mReverseValueRange[ins->mSrc[0].mTemp].LimitMax(asize - mMemoryValueSize[ins->mDst.mTemp]);
}
}
@ -5588,6 +5622,16 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
switch (ins->mCode)
{
case IC_CONVERSION_OPERATOR:
switch (ins->mOperator)
{
case IA_EXT8TO16U:
case IA_EXT8TO16S:
if (ins->mSrc[0].mTemp >= 0)
mReverseValueRange[ins->mSrc[0].mTemp].Limit(vr);
break;
}
break;
case IC_BINARY_OPERATOR:
switch (ins->mOperator)
{
@ -5666,15 +5710,15 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
break;
case IC_LEA:
if (ins->mSrc[1].mMemory == IM_INDIRECT && msize[ins->mDst.mTemp] > 0)
if (ins->mSrc[1].mMemory == IM_INDIRECT && mMemoryValueSize[ins->mDst.mTemp] > 0)
{
if (ins->mSrc[0].mTemp < 0)
{
msize[ins->mSrc[1].mTemp] = msize[ins->mDst.mTemp] - ins->mSrc[0].mIntConst;
mMemoryValueSize[ins->mSrc[1].mTemp] = mMemoryValueSize[ins->mDst.mTemp] - ins->mSrc[0].mIntConst;
}
else if (ins->mSrc[0].mRange.mMinState == IntegerValueRange::S_BOUND)
{
msize[ins->mSrc[1].mTemp] = msize[ins->mDst.mTemp] - ins->mSrc[0].mRange.mMinValue;
mMemoryValueSize[ins->mSrc[1].mTemp] = mMemoryValueSize[ins->mDst.mTemp] - ins->mSrc[0].mRange.mMinValue;
}
}
break;
@ -5689,7 +5733,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
}
if (ins->mDst.mTemp >= 0)
msize[ins->mDst.mTemp] = 0;
mMemoryValueSize[ins->mDst.mTemp] = 0;
}
#endif
@ -5916,6 +5960,8 @@ void InterCodeBasicBlock::BuildLocalIntegerRangeSets(int num)
mTrueValueRange.SetSize(num, true);
mFalseValueRange.SetSize(num, true);
mLocalValueRange.SetSize(num, true);
mMemoryValueSize.SetSize(num, true);
mEntryMemoryValueSize.SetSize(num, true);
UpdateLocalIntegerRangeSets();
@ -6330,7 +6376,6 @@ void InterCodeBasicBlock::PerformTempForwarding(TempForwardingTable& forwardingT
bool InterCodeBasicBlock::BuildGlobalRequiredTempSet(NumberSet& fromRequiredTemps)
{
bool revisit = false;
int i;
if (!mVisited)
{
@ -6575,7 +6620,6 @@ void InterCodeBasicBlock::BuildGlobalProvidedVariableSet(const GrowingVariableAr
bool InterCodeBasicBlock::BuildGlobalRequiredVariableSet(const GrowingVariableArray& localVars, NumberSet& fromRequiredVars, const GrowingVariableArray& params, NumberSet& fromRequiredParams, InterMemory paramMemory)
{
bool revisit = false;
int i;
if (!mVisited)
{
@ -7451,7 +7495,7 @@ static int Find(GrowingIntArray& table, int i)
return j;
}
bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray& tvalue)
bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray& tvalue, const GrowingVariableArray& staticVars)
{
bool changed = false;
@ -7551,7 +7595,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
j = 0;
while (j < mLoadStoreInstructions.Size())
{
if (!CollidingMem(ins->mSrc[1], mLoadStoreInstructions[j]))
if (!CollidingMem(ins->mSrc[1], mLoadStoreInstructions[j], staticVars))
mLoadStoreInstructions[k++] = mLoadStoreInstructions[j];
j++;
}
@ -7608,9 +7652,9 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
mLoadStoreInstructions.Push(nins);
}
if (mTrueJump && mTrueJump->LoadStoreForwarding(mLoadStoreInstructions))
if (mTrueJump && mTrueJump->LoadStoreForwarding(mLoadStoreInstructions, staticVars))
changed = true;
if (mFalseJump && mFalseJump->LoadStoreForwarding(mLoadStoreInstructions))
if (mFalseJump && mFalseJump->LoadStoreForwarding(mLoadStoreInstructions, staticVars))
changed = true;
}
@ -9175,7 +9219,7 @@ void InterCodeBasicBlock::SingleBlockLoopUnrolling(void)
}
void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedParams)
void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedParams, const GrowingVariableArray& staticVars)
{
if (!mVisited)
{
@ -9206,7 +9250,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
{
// Find the last store that overlaps the load
int j = mInstructions.Size() - 1;
while (j > i && !(mInstructions[j]->mCode == IC_STORE && CollidingMem(ins->mSrc[0], mInstructions[j]->mSrc[1])))
while (j > i && !(mInstructions[j]->mCode == IC_STORE && CollidingMem(ins->mSrc[0], mInstructions[j]->mSrc[1], staticVars)))
j--;
if (j > i)
@ -9295,7 +9339,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
for (int j = 0; j < mInstructions.Size(); j++)
{
InterInstruction* sins = mInstructions[j];
if (sins->mCode == IC_STORE)
if (sins->mCode == IC_STORE && CollidingMem(ins->mSrc[0], sins->mSrc[1], staticVars))
{
if (sins->mSrc[1].mTemp >= 0)
{
@ -9319,7 +9363,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
ins->mInvariant = false;
}
}
else if (CollidingMem(ins->mSrc[0], sins->mSrc[1]))
else if (CollidingMem(ins->mSrc[0], sins->mSrc[1], staticVars))
{
ins->mInvariant = false;
}
@ -9708,9 +9752,9 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
}
if (mTrueJump)
mTrueJump->SingleBlockLoopOptimisation(aliasedParams);
mTrueJump->SingleBlockLoopOptimisation(aliasedParams, staticVars);
if (mFalseJump)
mFalseJump->SingleBlockLoopOptimisation(aliasedParams);
mFalseJump->SingleBlockLoopOptimisation(aliasedParams, staticVars);
}
}
@ -11190,7 +11234,7 @@ void InterCodeProcedure::Close(void)
RemoveUnusedInstructions();
ResetVisited();
mEntryBlock->SingleBlockLoopOptimisation(mParamAliasedSet);
mEntryBlock->SingleBlockLoopOptimisation(mParamAliasedSet, mModule->mGlobalVars);
DisassembleDebug("single block loop opt");
@ -11280,7 +11324,7 @@ void InterCodeProcedure::Close(void)
{
GrowingInstructionPtrArray cipa(nullptr);
ResetVisited();
changed = mEntryBlock->PropagateVariableCopy(cipa);
changed = mEntryBlock->PropagateVariableCopy(cipa, mModule->mGlobalVars);
RemoveUnusedStoreInstructions(paramMemory);
} while (changed);
@ -11290,7 +11334,7 @@ void InterCodeProcedure::Close(void)
do {
GrowingInstructionPtrArray gipa(nullptr);
ResetVisited();
changed = mEntryBlock->LoadStoreForwarding(gipa);
changed = mEntryBlock->LoadStoreForwarding(gipa, mModule->mGlobalVars);
DisassembleDebug("Load/Store forwardingX");
@ -11492,7 +11536,7 @@ void InterCodeProcedure::Close(void)
do {
GrowingInstructionPtrArray gipa(nullptr);
ResetVisited();
changed = mEntryBlock->LoadStoreForwarding(gipa);
changed = mEntryBlock->LoadStoreForwarding(gipa, mModule->mGlobalVars);
RemoveUnusedStoreInstructions(paramMemory);
@ -11510,7 +11554,7 @@ void InterCodeProcedure::Close(void)
BuildDataFlowSets();
ResetVisited();
mEntryBlock->SingleBlockLoopOptimisation(mParamAliasedSet);
mEntryBlock->SingleBlockLoopOptimisation(mParamAliasedSet, mModule->mGlobalVars);
DisassembleDebug("single block loop opt 2");
@ -11538,7 +11582,7 @@ void InterCodeProcedure::Close(void)
BuildDataFlowSets();
ResetVisited();
mEntryBlock->SingleBlockLoopOptimisation(mParamAliasedSet);
mEntryBlock->SingleBlockLoopOptimisation(mParamAliasedSet, mModule->mGlobalVars);
DisassembleDebug("single block loop opt 3");

View File

@ -355,6 +355,7 @@ public:
GrowingInstructionArray mLoadStoreInstructions;
GrowingIntegerValueRangeArray mEntryValueRange, mTrueValueRange, mFalseValueRange, mLocalValueRange, mReverseValueRange;
GrowingArray<int64> mMemoryValueSize, mEntryMemoryValueSize;
GrowingArray<InterCodeBasicBlock*> mEntryBlocks, mLoopPathBlocks;
@ -383,7 +384,7 @@ public:
void CollectConstTemps(GrowingInstructionPtrArray& ctemps, NumberSet& assignedTemps);
bool PropagateConstTemps(const GrowingInstructionPtrArray& ctemps);
bool PropagateVariableCopy(const GrowingInstructionPtrArray& ctemps);
bool PropagateVariableCopy(const GrowingInstructionPtrArray& ctemps, const GrowingVariableArray& staticVars);
void BuildLocalTempSets(int num);
void BuildGlobalProvidedTempSet(NumberSet fromProvidedTemps);
@ -412,7 +413,7 @@ public:
GrowingIntArray mEntryRenameTable;
GrowingIntArray mExitRenameTable;
bool LoadStoreForwarding(const GrowingInstructionPtrArray& tvalue);
bool LoadStoreForwarding(const GrowingInstructionPtrArray& tvalue, const GrowingVariableArray& staticVars);
void LocalRenameRegister(const GrowingIntArray& renameTable, int& num);
void BuildGlobalRenameRegisterTable(const GrowingIntArray& renameTable, GrowingIntArray& globalRenameTable);
@ -464,7 +465,7 @@ public:
bool MergeCommonPathInstructions(void);
void PeepholeOptimization(const GrowingVariableArray& staticVars);
void SingleBlockLoopOptimisation(const NumberSet& aliasedParams);
void SingleBlockLoopOptimisation(const NumberSet& aliasedParams, const GrowingVariableArray& staticVars);
void SingleBlockLoopUnrolling(void);
bool CollectLoopBody(InterCodeBasicBlock* head, GrowingArray<InterCodeBasicBlock*> & body);
void CollectLoopPath(const GrowingArray<InterCodeBasicBlock*>& body, GrowingArray<InterCodeBasicBlock*>& path);

View File

@ -2944,7 +2944,9 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
else if (data.mRegs[CPU_REG_A].mMode == NRDM_ZERO_PAGE)
{
#if 1
if (data.mRegs[data.mRegs[CPU_REG_A].mValue].mMode == NRDM_UNKNOWN && mAddress >= BC_REG_FPARAMS && mAddress < BC_REG_FPARAMS_END)
if (data.mRegs[data.mRegs[CPU_REG_A].mValue].mMode == NRDM_UNKNOWN &&
(mAddress >= BC_REG_FPARAMS && mAddress < BC_REG_FPARAMS_END) &&
!(data.mRegs[CPU_REG_A].mValue >= BC_REG_FPARAMS && data.mRegs[CPU_REG_A].mValue < BC_REG_FPARAMS_END))
{
data.mRegs[data.mRegs[CPU_REG_A].mValue].mMode = NRDM_ZERO_PAGE;
data.mRegs[data.mRegs[CPU_REG_A].mValue].mValue = mAddress;
@ -9670,7 +9672,7 @@ void NativeCodeBasicBlock::LoadStoreOpAbsolute2D(InterCodeProcedure* proc, const
}
else
{
for (int i = 0; i < InterTypeSize[mins->mSrc[0].mType]; i++)
for (int i = 0; i < InterTypeSize[mins->mDst.mType]; i++)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, lins1->mSrc[1].mIntConst + i, lins1->mSrc[1].mLinkerObject));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[mins->mDst.mTemp] + i));
@ -16442,6 +16444,33 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
mNDataSet.mRegs[CPU_REG_C].Reset();
mNDataSet.mRegs[CPU_REG_Z].Reset();
bool loopx = false, loopy = false;
int loopya, loopxa;
if (mIns.Size() > 2)
{
int sz = mIns.Size();
if ((mIns[sz - 2].mType == ASMIT_LDY || mIns[sz - 2].mType == ASMIT_STY) && mIns[sz - 2].mMode == ASMIM_ZERO_PAGE)
{
if (mNDataSet.mRegs[CPU_REG_Y].mMode == NRDM_ZERO_PAGE && mIns[sz - 2].mAddress == mNDataSet.mRegs[CPU_REG_Y].mValue ||
mNDataSet.mRegs[CPU_REG_Y].SameData(mNDataSet.mRegs[mIns[sz - 2].mAddress]))
{
loopya = mIns[sz - 2].mAddress;
loopy = true;
}
}
else if ((mIns[sz - 2].mType == ASMIT_LDX || mIns[sz - 2].mType == ASMIT_STX) && mIns[sz - 2].mMode == ASMIM_ZERO_PAGE)
{
if (mNDataSet.mRegs[CPU_REG_X].mMode == NRDM_ZERO_PAGE && mIns[sz - 2].mAddress == mNDataSet.mRegs[CPU_REG_X].mValue ||
mNDataSet.mRegs[CPU_REG_X].SameData(mNDataSet.mRegs[mIns[sz - 2].mAddress]))
{
loopxa = mIns[sz - 2].mAddress;
loopx = true;
}
}
}
// Single block loop
for (int i = 0; i < mIns.Size(); i++)
{
@ -16452,6 +16481,7 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
mNDataSet.mRegs[CPU_REG_X].Reset();
if (ins.ChangesYReg())
mNDataSet.mRegs[CPU_REG_Y].Reset();
if (ins.mMode == ASMIM_ZERO_PAGE && ins.ChangesAddress())
mNDataSet.ResetZeroPage(ins.mAddress);
if (ins.mType == ASMIT_JSR)
@ -16476,6 +16506,19 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
// break;
}
}
if (loopy)
{
mNDataSet.mRegs[CPU_REG_Y].mMode = NRDM_ZERO_PAGE;
mNDataSet.mRegs[CPU_REG_Y].mValue = loopya;
}
if (loopx)
{
mNDataSet.mRegs[CPU_REG_X].mMode = NRDM_ZERO_PAGE;
mNDataSet.mRegs[CPU_REG_X].mValue = loopxa;
}
}
else
#endif
@ -25108,6 +25151,11 @@ void NativeCodeProcedure::Optimize(void)
#endif
if (cnt > 200)
{
changed = false;
mGenerator->mErrors->Error(mInterProc->mLocation, EWARN_OPTIMIZER_LOCKED, "Optimizer locked in infinite loop", mInterProc->mIdent);
}
#if 1
if (!changed && step < 8)
{

Binary file not shown.