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)
|
void cistream::refill(void)
|
||||||
{
|
{
|
||||||
mBufferFill = 0;
|
|
||||||
mBufferPos = 0;
|
mBufferPos = 0;
|
||||||
|
|
||||||
char ch;
|
char fill = 0;
|
||||||
while (mBufferFill < 32)
|
while (fill < 32)
|
||||||
{
|
{
|
||||||
char ch = getchar();
|
char ch = getchar();
|
||||||
mBuffer[mBufferFill++] = ch;
|
mBuffer[fill++] = ch;
|
||||||
if (ch == '\n')
|
if (ch == '\n')
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mBufferFill = fill;
|
||||||
}
|
}
|
||||||
|
|
||||||
cistream cin;
|
cistream cin;
|
||||||
|
|
|
@ -12837,6 +12837,10 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams)
|
||||||
for (int i = 0; i < block->mInstructions.Size(); i++)
|
for (int i = 0; i < block->mInstructions.Size(); i++)
|
||||||
{
|
{
|
||||||
InterInstruction* ins = block->mInstructions[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;
|
int t = ins->mDst.mTemp;
|
||||||
if (t >= 0)
|
if (t >= 0)
|
||||||
{
|
{
|
||||||
|
@ -12866,6 +12870,8 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams)
|
||||||
ins->mExpensive = true;
|
ins->mExpensive = true;
|
||||||
else if (ins->mSrc[0].mTemp >= 0 && ins->mSrc[0].mRange.mMaxState == IntegerValueRange::S_BOUND && ins->mSrc[0].mRange.mMaxValue >= 256)
|
else if (ins->mSrc[0].mTemp >= 0 && ins->mSrc[0].mRange.mMaxState == IntegerValueRange::S_BOUND && ins->mSrc[0].mRange.mMaxValue >= 256)
|
||||||
ins->mExpensive = true;
|
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;
|
break;
|
||||||
case IC_LOAD:
|
case IC_LOAD:
|
||||||
case IC_STORE:
|
case IC_STORE:
|
||||||
|
@ -15631,6 +15637,17 @@ bool InterCodeBasicBlock::PeepholeReplaceOptimization(const GrowingVariableArray
|
||||||
return changed;
|
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)
|
void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& staticVars)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -15945,25 +15962,26 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
||||||
j--;
|
j--;
|
||||||
while (j >= 0)
|
while (j >= 0)
|
||||||
{
|
{
|
||||||
|
InterInstruction* jins = mInstructions[j];
|
||||||
|
|
||||||
if (j < ti - 1)
|
if (j < ti - 1)
|
||||||
{
|
{
|
||||||
if (CanMoveInstructionDown(j, ti))
|
if (CanMoveInstructionDown(j, ti))
|
||||||
{
|
{
|
||||||
InterInstruction* jins = mInstructions[j];
|
|
||||||
for (int k = j; k < ti - 1; k++)
|
for (int k = j; k < ti - 1; k++)
|
||||||
{
|
{
|
||||||
SwapInstructions(jins, mInstructions[k + 1]);
|
SwapInstructions(jins, mInstructions[k + 1]);
|
||||||
mInstructions[k] = mInstructions[k + 1];
|
mInstructions[k] = mInstructions[k + 1];
|
||||||
}
|
}
|
||||||
mInstructions[ti - 1] = jins;
|
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.Insert(i, mInstructions[j]);
|
||||||
// mInstructions.Remove(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--;
|
ti--;
|
||||||
|
|
||||||
j--;
|
j--;
|
||||||
|
@ -15974,6 +15992,33 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
||||||
#endif
|
#endif
|
||||||
CheckFinalLocal();
|
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
|
// sort stores up
|
||||||
|
|
||||||
bool changed;
|
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)
|
void NativeCodeBasicBlock::LoadStoreIndirectValue(InterCodeProcedure* proc, const InterInstruction* rins, const InterInstruction* wins)
|
||||||
{
|
{
|
||||||
int size = InterTypeSize[wins->mSrc[0].mType];
|
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();
|
CheckLive();
|
||||||
|
|
||||||
if (mTrueJump && mFalseJump)
|
if (mTrueJump && mFalseJump)
|
||||||
|
@ -26343,6 +26415,9 @@ bool NativeCodeBasicBlock::ForwardReplaceZeroPage(int at, int from, int to)
|
||||||
changed = true;
|
changed = true;
|
||||||
if (mFalseJump && mFalseJump->ForwardReplaceZeroPage(0, from, to))
|
if (mFalseJump && mFalseJump->ForwardReplaceZeroPage(0, from, to))
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
mEntryRequiredRegs += to;
|
||||||
}
|
}
|
||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
|
@ -41351,7 +41426,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
{
|
{
|
||||||
mInterProc = proc;
|
mInterProc = proc;
|
||||||
|
|
||||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "mod<struct lambda#0>");
|
CheckFunc = !strcmp(mInterProc->mIdent->mString, "fill_row");
|
||||||
|
|
||||||
int nblocks = proc->mBlocks.Size();
|
int nblocks = proc->mBlocks.Size();
|
||||||
tblocks = new NativeCodeBasicBlock * [nblocks];
|
tblocks = new NativeCodeBasicBlock * [nblocks];
|
||||||
|
@ -41429,7 +41504,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
mEntryBlock->mTrueJump = CompileBlock(mInterProc, mInterProc->mBlocks[0]);
|
mEntryBlock->mTrueJump = CompileBlock(mInterProc, mInterProc->mBlocks[0]);
|
||||||
mEntryBlock->mBranch = ASMIT_JMP;
|
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 1
|
||||||
if (proc->mParamVars.Size() == 1 && proc->mParamVars[0]->mSize == 1)
|
if (proc->mParamVars.Size() == 1 && proc->mParamVars[0]->mSize == 1)
|
||||||
|
@ -42712,6 +42787,7 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
else
|
else
|
||||||
cnt++;
|
cnt++;
|
||||||
|
|
||||||
|
|
||||||
} while (changed);
|
} while (changed);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
|
@ -43141,6 +43217,16 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
||||||
block->StoreByteIndexedValue(iproc, ins, iblock->mInstructions[i + 1]);
|
block->StoreByteIndexedValue(iproc, ins, iblock->mInstructions[i + 1]);
|
||||||
i++;
|
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() &&
|
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[1].mTemp < 0 && ins->mSrc[1].mMemory == IM_GLOBAL && ins->mSrc[1].mLinkerObject->mSize <= 256 &&
|
||||||
// ins->mSrc[0].IsUByte() &&
|
// ins->mSrc[0].IsUByte() &&
|
||||||
|
|
|
@ -331,6 +331,8 @@ public:
|
||||||
bool LoadUnopStoreIndirectValue(InterCodeProcedure* proc, const InterInstruction* rins, const InterInstruction* oins, const InterInstruction* wins);
|
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);
|
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 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);
|
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 UnaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
|
||||||
void RelationalOperator(InterCodeProcedure* proc, const InterInstruction * ins, NativeCodeProcedure * nproc, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock * falseJump);
|
void RelationalOperator(InterCodeProcedure* proc, const InterInstruction * ins, NativeCodeProcedure * nproc, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock * falseJump);
|
||||||
|
|
Loading…
Reference in New Issue