Track state of fast call parameters across function calls to avoid duplicate push

This commit is contained in:
drmortalwombat 2023-03-01 08:49:51 +01:00
parent 49bfd63033
commit df89082846
5 changed files with 69 additions and 32 deletions

View File

@ -558,7 +558,7 @@ public:
GrowingInterCodeBasicBlockPtrArray mBlocks; GrowingInterCodeBasicBlockPtrArray mBlocks;
GrowingTypeArray mTemporaries; GrowingTypeArray mTemporaries;
GrowingIntArray mTempOffset, mTempSizes; GrowingIntArray mTempOffset, mTempSizes;
int mTempSize, mCommonFrameSize, mCallerSavedTemps, mFreeCallerSavedTemps; int mTempSize, mCommonFrameSize, mCallerSavedTemps, mFreeCallerSavedTemps, mFastCallBase;
bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode, mFastCallProcedure; bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode, mFastCallProcedure;
bool mInterrupt, mHardwareInterrupt, mCompiled, mInterruptCalled, mValueReturn; bool mInterrupt, mHardwareInterrupt, mCompiled, mInterruptCalled, mValueReturn;
GrowingInterCodeProcedurePtrArray mCalledFunctions; GrowingInterCodeProcedurePtrArray mCalledFunctions;

View File

@ -3596,6 +3596,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
if (dec->mFastCallSize > 0 && dec->mFastCallBase < BC_REG_FPARAMS_END - BC_REG_FPARAMS) if (dec->mFastCallSize > 0 && dec->mFastCallBase < BC_REG_FPARAMS_END - BC_REG_FPARAMS)
{ {
proc->mFastCallBase = dec->mFastCallBase;
dec->mLinkerObject->mNumTemporaries = 1; dec->mLinkerObject->mNumTemporaries = 1;
dec->mLinkerObject->mTemporaries[0] = BC_REG_FPARAMS + dec->mFastCallBase; dec->mLinkerObject->mTemporaries[0] = BC_REG_FPARAMS + dec->mFastCallBase;
if (dec->mFastCallBase + dec->mFastCallBase < BC_REG_FPARAMS_END - BC_REG_FPARAMS) if (dec->mFastCallBase + dec->mFastCallBase < BC_REG_FPARAMS_END - BC_REG_FPARAMS)
@ -3603,7 +3604,11 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
else else
dec->mLinkerObject->mTempSizes[0] = BC_REG_FPARAMS_END - BC_REG_FPARAMS - dec->mFastCallBase; dec->mLinkerObject->mTempSizes[0] = BC_REG_FPARAMS_END - BC_REG_FPARAMS - dec->mFastCallBase;
} }
else
proc->mFastCallBase = BC_REG_FPARAMS_END - BC_REG_FPARAMS;
} }
else
proc->mFastCallBase = BC_REG_FPARAMS_END - BC_REG_FPARAMS;
if (dec->mBase->mBase->mType != DT_TYPE_VOID && dec->mBase->mBase->mType != DT_TYPE_STRUCT) if (dec->mBase->mBase->mType != DT_TYPE_VOID && dec->mBase->mBase->mType != DT_TYPE_STRUCT)
proc->mValueReturn = true; proc->mValueReturn = true;

View File

@ -141,6 +141,7 @@ static const uint32 LOBJF_STATIC_STACK = 0x00000040;
static const uint32 LOBJF_NO_CROSS = 0x00000080; static const uint32 LOBJF_NO_CROSS = 0x00000080;
static const uint32 LOBJF_ZEROPAGE = 0x00000100; static const uint32 LOBJF_ZEROPAGE = 0x00000100;
static const uint32 LOBJF_FORCE_ALIGN = 0x00000200; static const uint32 LOBJF_FORCE_ALIGN = 0x00000200;
static const uint32 LOBJF_ZEROPAGESET = 0x00000400;
static const uint32 LOBJF_ARG_REG_A = 0x00001000; static const uint32 LOBJF_ARG_REG_A = 0x00001000;
static const uint32 LOBJF_ARG_REG_X = 0x00002000; static const uint32 LOBJF_ARG_REG_X = 0x00002000;

View File

@ -2767,7 +2767,7 @@ bool NativeCodeInstruction::BitFieldForwarding(NativeRegisterDataSet& data, AsmI
return changed; return changed;
} }
bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsType& carryop, bool initial, bool final) bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsType& carryop, bool initial, bool final, int fastCallBase)
{ {
bool changed = false; bool changed = false;
@ -2803,8 +2803,17 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
data.ResetZeroPage(i); data.ResetZeroPage(i);
} }
for(int i = BC_REG_FPARAMS; i < BC_REG_FPARAMS_END; i++) if (mLinkerObject && (mLinkerObject->mFlags & LOBJF_ZEROPAGESET))
data.ResetZeroPage(i); {
for (int i = BC_REG_FPARAMS; i < BC_REG_FPARAMS + fastCallBase; i++)
if (mLinkerObject->mZeroPageSet[i])
data.ResetZeroPage(i);
}
else
{
for (int i = BC_REG_FPARAMS; i < BC_REG_FPARAMS + fastCallBase; i++)
data.ResetZeroPage(i);
}
} }
return false; return false;
@ -12363,7 +12372,7 @@ void NativeCodeBasicBlock::FindZeroPageAlias(const NumberSet& statics, NumberSet
} }
} }
void NativeCodeBasicBlock::CollectZeroPageSet(ZeroPageSet& locals, ZeroPageSet& global) bool NativeCodeBasicBlock::CollectZeroPageSet(ZeroPageSet& locals, ZeroPageSet& global)
{ {
if (!mVisited) if (!mVisited)
{ {
@ -12393,18 +12402,33 @@ void NativeCodeBasicBlock::CollectZeroPageSet(ZeroPageSet& locals, ZeroPageSet&
{ {
LinkerObject* lo = mIns[i].mLinkerObject; LinkerObject* lo = mIns[i].mLinkerObject;
global |= lo->mZeroPageSet; if (lo->mFlags & LOBJF_ZEROPAGESET)
{
global |= lo->mZeroPageSet;
}
else if (!lo->mProc)
{
for (int i = 0; i < lo->mNumTemporaries; i++)
{
for (int j = 0; j < lo->mTempSizes[i]; j++)
global += lo->mTemporaries[i] + j;
}
}
else
return false;
} }
} }
break; break;
} }
} }
if (mTrueJump) if (mTrueJump && !mTrueJump->CollectZeroPageSet(locals, global))
mTrueJump->CollectZeroPageSet(locals, global); return false;
if (mFalseJump) if (mFalseJump && !mFalseJump->CollectZeroPageSet(locals, global))
mFalseJump->CollectZeroPageSet(locals, global); return false;
} }
return true;
} }
void NativeCodeBasicBlock::CollectZeroPageUsage(NumberSet& used, NumberSet &modified, NumberSet& pairs) void NativeCodeBasicBlock::CollectZeroPageUsage(NumberSet& used, NumberSet &modified, NumberSet& pairs)
@ -24332,7 +24356,7 @@ bool NativeCodeBasicBlock::BitFieldForwarding(const NativeRegisterDataSet& data)
return changed; return changed;
} }
bool NativeCodeBasicBlock::GlobalValueForwarding(bool final) bool NativeCodeBasicBlock::GlobalValueForwarding(NativeCodeProcedure* proc, bool final)
{ {
bool changed = false; bool changed = false;
@ -24362,16 +24386,16 @@ bool NativeCodeBasicBlock::GlobalValueForwarding(bool final)
{ {
AsmInsType carryop; AsmInsType carryop;
if (mIns[i].ValueForwarding(mDataSet, carryop, true, final)) if (mIns[i].ValueForwarding(mDataSet, carryop, true, final, proc->mFastCallBase))
changed = true; changed = true;
if (carryop != ASMIT_NOP) if (carryop != ASMIT_NOP)
mIns.Insert(i + 1, NativeCodeInstruction(carryop)); mIns.Insert(i + 1, NativeCodeInstruction(carryop));
} }
if (this->mTrueJump && this->mTrueJump->GlobalValueForwarding(final)) if (this->mTrueJump && this->mTrueJump->GlobalValueForwarding(proc, final))
changed = true; changed = true;
if (this->mFalseJump && this->mFalseJump->GlobalValueForwarding(final)) if (this->mFalseJump && this->mFalseJump->GlobalValueForwarding(proc, final))
changed = true; changed = true;
} }
@ -24379,7 +24403,7 @@ bool NativeCodeBasicBlock::GlobalValueForwarding(bool final)
} }
bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bool global, bool final) bool NativeCodeBasicBlock::ValueForwarding(NativeCodeProcedure* proc, const NativeRegisterDataSet& data, bool global, bool final)
{ {
bool changed = false; bool changed = false;
@ -24561,7 +24585,7 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
} }
#endif #endif
if (mIns[i].ValueForwarding(mNDataSet, carryop, !global, final)) if (mIns[i].ValueForwarding(mNDataSet, carryop, !global, final, proc->mFastCallBase))
changed = true; changed = true;
if (carryop != ASMIT_NOP) if (carryop != ASMIT_NOP)
mIns.Insert(i + 1, NativeCodeInstruction(carryop)); mIns.Insert(i + 1, NativeCodeInstruction(carryop));
@ -24917,9 +24941,9 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
#endif #endif
assert(mIndex == 1000 || mNumEntries == mEntryBlocks.Size()); assert(mIndex == 1000 || mNumEntries == mEntryBlocks.Size());
if (this->mTrueJump && this->mTrueJump->ValueForwarding(mNDataSet, global, final)) if (this->mTrueJump && this->mTrueJump->ValueForwarding(proc, mNDataSet, global, final))
changed = true; changed = true;
if (this->mFalseJump && this->mFalseJump->ValueForwarding(mFDataSet, global, final)) if (this->mFalseJump && this->mFalseJump->ValueForwarding(proc, mFDataSet, global, final))
changed = true; changed = true;
@ -35452,6 +35476,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
tblocks[i] = nullptr; tblocks[i] = nullptr;
mIndex = proc->mID; mIndex = proc->mID;
mFastCallBase = proc->mFastCallBase;
int tempSave = proc->mTempSize > BC_REG_TMP_SAVED - BC_REG_TMP && !proc->mSaveTempsLinkerObject && !mInterProc->mInterrupt ? proc->mTempSize - (BC_REG_TMP_SAVED - BC_REG_TMP) : 0; int tempSave = proc->mTempSize > BC_REG_TMP_SAVED - BC_REG_TMP && !proc->mSaveTempsLinkerObject && !mInterProc->mInterrupt ? proc->mTempSize - (BC_REG_TMP_SAVED - BC_REG_TMP) : 0;
int commonFrameSize = proc->mCommonFrameSize; int commonFrameSize = proc->mCommonFrameSize;
@ -35552,8 +35577,10 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
ZeroPageSet zpLocal, zpGlobal; ZeroPageSet zpLocal, zpGlobal;
ResetVisited(); ResetVisited();
mEntryBlock->CollectZeroPageSet(zpLocal, zpGlobal); if (mEntryBlock->CollectZeroPageSet(zpLocal, zpGlobal))
zpLocal |= zpGlobal; zpLocal |= zpGlobal;
else
mGenerator->mErrors->Error(mInterProc->mLocation, ERRR_INTERRUPT_TO_COMPLEX, "No recursive functions in interrupt");
if (proc->mHardwareInterrupt) if (proc->mHardwareInterrupt)
{ {
@ -35835,10 +35862,13 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
ZeroPageSet zpLocal, zpGlobal; ZeroPageSet zpLocal, zpGlobal;
ResetVisited(); ResetVisited();
mEntryBlock->CollectZeroPageSet(zpLocal, zpGlobal); if (mEntryBlock->CollectZeroPageSet(zpLocal, zpGlobal))
zpLocal |= zpGlobal; {
zpLocal |= zpGlobal;
proc->mLinkerObject->mZeroPageSet = zpLocal; proc->mLinkerObject->mZeroPageSet = zpLocal;
proc->mLinkerObject->mFlags |= LOBJF_ZEROPAGESET;
}
} }
if (proc->mHardwareInterrupt) if (proc->mHardwareInterrupt)
@ -36050,7 +36080,7 @@ void NativeCodeProcedure::Optimize(void)
{ {
ResetVisited(); ResetVisited();
NativeRegisterDataSet data; NativeRegisterDataSet data;
if (mEntryBlock->ValueForwarding(data, step > 0, step == 7)) if (mEntryBlock->ValueForwarding(this, data, step > 0, step == 7))
{ {
changed = true; changed = true;
} }
@ -36063,7 +36093,7 @@ void NativeCodeProcedure::Optimize(void)
if (step > 1) if (step > 1)
{ {
ResetVisited(); ResetVisited();
if (mEntryBlock->GlobalValueForwarding(step == 7)) if (mEntryBlock->GlobalValueForwarding(this, step == 7))
changed = true; changed = true;
} }
#endif #endif
@ -36569,7 +36599,7 @@ void NativeCodeProcedure::Optimize(void)
{ {
ResetVisited(); ResetVisited();
NativeRegisterDataSet data; NativeRegisterDataSet data;
if (mEntryBlock->ValueForwarding(data, true, true)) if (mEntryBlock->ValueForwarding(this, data, true, true))
{ {
changed = true; changed = true;
} }
@ -36580,7 +36610,7 @@ void NativeCodeProcedure::Optimize(void)
mEntryBlock->CheckVisited(); mEntryBlock->CheckVisited();
ResetVisited(); ResetVisited();
if (mEntryBlock->GlobalValueForwarding(true)) if (mEntryBlock->GlobalValueForwarding(this, true))
changed = true; changed = true;
#endif #endif
} }
@ -36609,7 +36639,7 @@ void NativeCodeProcedure::Optimize(void)
ResetVisited(); ResetVisited();
NativeRegisterDataSet data; NativeRegisterDataSet data;
mEntryBlock->ValueForwarding(data, true, true); mEntryBlock->ValueForwarding(this, data, true, true);
#if 1 #if 1
ResetVisited(); ResetVisited();

View File

@ -106,7 +106,7 @@ public:
void FilterRegUsage(NumberSet& requiredTemps, NumberSet& providedTemps); void FilterRegUsage(NumberSet& requiredTemps, NumberSet& providedTemps);
bool IsUsedResultInstructions(NumberSet& requiredTemps); bool IsUsedResultInstructions(NumberSet& requiredTemps);
bool BitFieldForwarding(NativeRegisterDataSet& data, AsmInsType& carryop); bool BitFieldForwarding(NativeRegisterDataSet& data, AsmInsType& carryop);
bool ValueForwarding(NativeRegisterDataSet& data, AsmInsType & carryop, bool initial, bool final); bool ValueForwarding(NativeRegisterDataSet& data, AsmInsType & carryop, bool initial, bool final, int fastCallBase);
void Simulate(NativeRegisterDataSet& data); void Simulate(NativeRegisterDataSet& data);
bool ApplySimulation(const NativeRegisterDataSet& data); bool ApplySimulation(const NativeRegisterDataSet& data);
@ -387,8 +387,8 @@ public:
bool ReverseReplaceTAX(int at); bool ReverseReplaceTAX(int at);
bool ValueForwarding(const NativeRegisterDataSet& data, bool global, bool final); bool ValueForwarding(NativeCodeProcedure* proc, const NativeRegisterDataSet& data, bool global, bool final);
bool GlobalValueForwarding(bool final); bool GlobalValueForwarding(NativeCodeProcedure* proc, bool final);
bool BitFieldForwarding(const NativeRegisterDataSet& data); bool BitFieldForwarding(const NativeRegisterDataSet& data);
bool ReverseBitfieldForwarding(void); bool ReverseBitfieldForwarding(void);
@ -446,7 +446,7 @@ public:
void BuildEntryDataSet(const NativeRegisterDataSet& set); void BuildEntryDataSet(const NativeRegisterDataSet& set);
bool ApplyEntryDataSet(void); bool ApplyEntryDataSet(void);
void CollectZeroPageSet(ZeroPageSet& locals, ZeroPageSet& global); bool CollectZeroPageSet(ZeroPageSet& locals, ZeroPageSet& global);
void CollectZeroPageUsage(NumberSet& used, NumberSet& modified, NumberSet& pairs); void CollectZeroPageUsage(NumberSet& used, NumberSet& modified, NumberSet& pairs);
void FindZeroPageAlias(const NumberSet& statics, NumberSet& invalid, uint8* alias, int accu); void FindZeroPageAlias(const NumberSet& statics, NumberSet& invalid, uint8* alias, int accu);
bool RemapZeroPage(const uint8* remap); bool RemapZeroPage(const uint8* remap);
@ -555,6 +555,7 @@ class NativeCodeProcedure
InterCodeProcedure* mInterProc; InterCodeProcedure* mInterProc;
int mProgStart, mProgSize, mIndex, mFrameOffset, mStackExpand; int mProgStart, mProgSize, mIndex, mFrameOffset, mStackExpand;
int mFastCallBase;
bool mNoFrame; bool mNoFrame;
int mTempBlocks; int mTempBlocks;