Fix accu return with temp spilling

This commit is contained in:
drmortalwombat 2023-10-08 21:30:53 +02:00
parent 33d692194a
commit d4f979b1bc
4 changed files with 144 additions and 10 deletions

View File

@ -983,17 +983,18 @@ cistream::cistream(void)
void cistream::refill(void)
{
mBufferFill = 0;
mBufferPos = 0;
char ch;
while (mBufferFill < 32)
char fill = 0;
while (fill < 32)
{
char ch = getchar();
mBuffer[mBufferFill++] = ch;
mBuffer[fill++] = ch;
if (ch == '\n')
break;
}
mBufferFill = fill;
}
cistream cin;

View File

@ -12837,6 +12837,10 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams)
for (int i = 0; i < block->mInstructions.Size(); i++)
{
InterInstruction* ins = block->mInstructions[i];
InterInstruction* nins = nullptr;
if (i + 1 < block->mInstructions.Size())
nins = block->mInstructions[i + 1];
int t = ins->mDst.mTemp;
if (t >= 0)
{
@ -12866,6 +12870,8 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams)
ins->mExpensive = true;
else if (ins->mSrc[0].mTemp >= 0 && ins->mSrc[0].mRange.mMaxState == IntegerValueRange::S_BOUND && ins->mSrc[0].mRange.mMaxValue >= 256)
ins->mExpensive = true;
else if (nins && nins->mCode == IC_LEA && nins->mSrc[0].mTemp >= 0 && (nins->mSrc[0].mRange.mMaxState == IntegerValueRange::S_UNBOUND || nins->mSrc[0].mRange.mMaxValue >= 255))
ins->mExpensive = true;
break;
case IC_LOAD:
case IC_STORE:
@ -15631,6 +15637,17 @@ bool InterCodeBasicBlock::PeepholeReplaceOptimization(const GrowingVariableArray
return changed;
}
static int TempUseDelta(const InterInstruction* ins)
{
int d = 0;
if (ins->mDst.mTemp >= 0)
d++;
for (int i = 0; i < ins->mNumOperands; i++)
if (ins->mSrc[i].mTemp >= 0 && ins->mSrc[i].mFinal)
d--;
return d;
}
void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& staticVars)
{
int i;
@ -15945,25 +15962,26 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
j--;
while (j >= 0)
{
InterInstruction* jins = mInstructions[j];
if (j < ti - 1)
{
if (CanMoveInstructionDown(j, ti))
{
InterInstruction* jins = mInstructions[j];
for (int k = j; k < ti - 1; k++)
{
SwapInstructions(jins, mInstructions[k + 1]);
mInstructions[k] = mInstructions[k + 1];
}
mInstructions[ti - 1] = jins;
if (mInstructions[ti - 1]->NumUsedTemps() <= 1)
ti--;
if (jins->NumUsedTemps() <= 1 && !(jins->mCode == IC_CALL || jins->mCode == IC_CALL_NATIVE))
ti--;
// mInstructions.Insert(i, mInstructions[j]);
// mInstructions.Remove(j);
}
}
else if (mInstructions[j]->NumUsedTemps() <= 1)
else if (jins->NumUsedTemps() <= 1 && !(jins->mCode == IC_CALL || jins->mCode == IC_CALL_NATIVE))
ti--;
j--;
@ -15974,6 +15992,33 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
#endif
CheckFinalLocal();
// check move calls our of range to save register spilling
i = 0;
while (i < mInstructions.Size())
{
InterInstruction* ins(mInstructions[i]);
if ((ins->mCode == IC_CALL || ins->mCode == IC_CALL_NATIVE) && ins->mSrc[0].mTemp < 0)
{
int j = i;
while (j > 0 && CanSwapInstructions(ins, mInstructions[j - 1]) && TempUseDelta(mInstructions[j - 1]) >= 0)
j--;
while (j < i && TempUseDelta(mInstructions[j]) == 0)
j++;
if (j < i)
{
while (i > j)
{
i--;
SwapInstructions(mInstructions[i], ins);
mInstructions[i + 1] = mInstructions[i];
}
mInstructions[j] = ins;
}
}
i++;
}
// sort stores up
bool changed;

View File

@ -5921,6 +5921,29 @@ void NativeCodeBasicBlock::StoreByteIndexedValue(InterCodeProcedure* proc, const
}
void NativeCodeBasicBlock::StoreByteOffsetIndexedValue(InterCodeProcedure* proc, const InterInstruction* iins, const InterInstruction* wins)
{
mIns.Push(NativeCodeInstruction(iins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[iins->mSrc[0].mTemp]));
mIns.Push(NativeCodeInstruction(iins, ASMIT_CLC));
mIns.Push(NativeCodeInstruction(iins, ASMIT_ADC, ASMIM_IMMEDIATE, wins->mSrc[1].mIntConst));
mIns.Push(NativeCodeInstruction(iins, ASMIT_TAY));
uint32 flags = NCIF_LOWER | NCIF_UPPER;
if (wins->mVolatile)
flags |= NCIF_VOLATILE;
for (int i = 0; i < InterTypeSize[wins->mSrc[0].mType]; i++)
{
if (i != 0)
mIns.Push(NativeCodeInstruction(wins, ASMIT_INY, ASMIM_IMPLIED));
if (wins->mSrc[0].mTemp < 0)
mIns.Push(NativeCodeInstruction(wins, ASMIT_LDA, ASMIM_IMMEDIATE, (wins->mSrc[0].mIntConst >> (8 * i)) & 0xff));
else
mIns.Push(NativeCodeInstruction(wins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[wins->mSrc[0].mTemp] + i));
mIns.Push(NativeCodeInstruction(wins, ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[iins->mSrc[1].mTemp], nullptr, flags));
}
}
void NativeCodeBasicBlock::LoadStoreIndirectValue(InterCodeProcedure* proc, const InterInstruction* rins, const InterInstruction* wins)
{
int size = InterTypeSize[wins->mSrc[0].mType];
@ -19830,6 +19853,55 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
}
}
#if 1
if (mTrueJump && mFalseJump && mIns.Size() >= 2)
{
int nins = mIns.Size();
if (mIns[nins - 2].mType == ASMIT_LDA && mIns[nins - 2].mMode == ASMIM_IMMEDIATE &&
mIns[nins - 1].mType == ASMIT_CMP && mIns[nins - 1].mMode == ASMIM_ZERO_PAGE && (mIns[nins - 1].mLive & LIVE_MEM) && !(mIns[nins - 1].mLive & LIVE_CPU_REG_A) &&
!mTrueJump->mEntryRequiredRegs[CPU_REG_C] && !mFalseJump->mEntryRequiredRegs[CPU_REG_C] && !mTrueJump->mEntryRequiredRegs[CPU_REG_Z] && !mFalseJump->mEntryRequiredRegs[CPU_REG_Z])
{
int im = mIns[nins - 2].mAddress;
mIns[nins - 2].CopyMode(mIns[nins - 1]);
mIns[nins - 2].mLive |= LIVE_MEM;
mIns[nins - 1].mMode = ASMIM_IMMEDIATE;
mIns[nins - 1].mFlags = NCIF_LOWER | NCIF_UPPER;
if (mBranch == ASMIT_BCC)
{
if (im == 255)
{
mIns[nins - 1].mType = ASMIT_SEC;
mIns[nins - 1].mMode = ASMIM_IMPLIED;
}
else
{
mIns[nins - 1].mAddress = im + 1;
mBranch = ASMIT_BCS;
}
}
else if (mBranch == ASMIT_BCS)
{
if (im == 255)
{
mIns[nins - 1].mType = ASMIT_SEC;
mIns[nins - 1].mMode = ASMIM_IMPLIED;
}
else
{
mIns[nins - 1].mAddress = im + 1;
mBranch = ASMIT_BCC;
}
}
else
mIns[nins - 1].mAddress = im;
changed = true;
}
}
#endif
CheckLive();
if (mTrueJump && mFalseJump)
@ -26343,6 +26415,9 @@ bool NativeCodeBasicBlock::ForwardReplaceZeroPage(int at, int from, int to)
changed = true;
if (mFalseJump && mFalseJump->ForwardReplaceZeroPage(0, from, to))
changed = true;
if (changed)
mEntryRequiredRegs += to;
}
return changed;
@ -41351,7 +41426,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{
mInterProc = proc;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "mod<struct lambda#0>");
CheckFunc = !strcmp(mInterProc->mIdent->mString, "fill_row");
int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks];
@ -41429,7 +41504,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
mEntryBlock->mTrueJump = CompileBlock(mInterProc, mInterProc->mBlocks[0]);
mEntryBlock->mBranch = ASMIT_JMP;
if (proc->mLeafProcedure && proc->mFastCallProcedure && !proc->mInterrupt && !proc->mDispatchedCall && mNoFrame && mStackExpand == 0 && commonFrameSize == 0 && (mGenerator->mCompilerOptions & COPT_NATIVE))
if (proc->mLeafProcedure && proc->mFastCallProcedure && !proc->mInterrupt && !proc->mDispatchedCall && mNoFrame && mStackExpand == 0 && commonFrameSize == 0 && proc->mTempSize <= BC_REG_TMP_SAVED - BC_REG_TMP && (mGenerator->mCompilerOptions & COPT_NATIVE))
{
#if 1
if (proc->mParamVars.Size() == 1 && proc->mParamVars[0]->mSize == 1)
@ -42712,6 +42787,7 @@ void NativeCodeProcedure::Optimize(void)
else
cnt++;
} while (changed);
#if 1
@ -43141,6 +43217,16 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
block->StoreByteIndexedValue(iproc, ins, iblock->mInstructions[i + 1]);
i++;
}
else if (i + 1 < iblock->mInstructions.Size() &&
iblock->mInstructions[i + 1]->mCode == IC_STORE && iblock->mInstructions[i + 1]->mSrc[1].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 1]->mSrc[1].mFinal &&
ins->mSrc[1].mTemp >= 0 && ins->mSrc[0].IsUByte() && ins->mSrc[0].mTemp >= 0 &&
iblock->mInstructions[i + 1]->mSrc[1].mIntConst + ins->mSrc[0].mRange.mMaxValue + InterTypeSize[iblock->mInstructions[i + 1]->mSrc[0].mType] <= 256 &&
(iblock->mInstructions[i + 1]->mSrc[0].mTemp >= 0 || iblock->mInstructions[i + 1]->mSrc[0].mType <= IT_INT32) &&
(InterTypeSize[iblock->mInstructions[i + 1]->mSrc[0].mType] == 1 || iblock->mInstructions[i + 1]->mSrc[1].mStride == 1))
{
block->StoreByteOffsetIndexedValue(iproc, ins, iblock->mInstructions[i + 1]);
i++;
}
else if (i + 2 < iblock->mInstructions.Size() &&
ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mMemory == IM_GLOBAL && ins->mSrc[1].mLinkerObject->mSize <= 256 &&
// ins->mSrc[0].IsUByte() &&

View File

@ -331,6 +331,8 @@ public:
bool LoadUnopStoreIndirectValue(InterCodeProcedure* proc, const InterInstruction* rins, const InterInstruction* oins, const InterInstruction* wins);
bool LoadLoadOpStoreIndirectValue(InterCodeProcedure* proc, const InterInstruction* rins1, const InterInstruction* rins0, const InterInstruction* oins, const InterInstruction* wins);
void LoadStoreIndirectValue(InterCodeProcedure* proc, const InterInstruction* rins, const InterInstruction* wins);
void StoreByteOffsetIndexedValue(InterCodeProcedure* proc, const InterInstruction* iins, const InterInstruction* sins);
NativeCodeBasicBlock* BinaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0);
void UnaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
void RelationalOperator(InterCodeProcedure* proc, const InterInstruction * ins, NativeCodeProcedure * nproc, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock * falseJump);