Fix accu return with temp spilling
This commit is contained in:
parent
33d692194a
commit
d4f979b1bc
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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() &&
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue