More native code load/store forwarding

This commit is contained in:
drmortalwombat 2024-06-19 21:40:38 +02:00
parent cf9a006005
commit 17002e4c78
2 changed files with 224 additions and 3 deletions

View File

@ -371,10 +371,27 @@ void NativeRegisterDataSet::Intersect(const NativeRegisterDataSet& set)
} }
} }
} }
else if (mRegs[i].mMode == NRDM_ABSOLUTE_X || mRegs[i].mMode == NRDM_ABSOLUTE_Y) else if (mRegs[i].mMode == NRDM_ABSOLUTE_X)
{ {
mRegs[i].Reset(); if (set.mRegs[i].mMode != NRDM_ABSOLUTE_X ||
changed = true; mRegs[i].mLinkerObject != set.mRegs[i].mLinkerObject ||
mRegs[i].mValue != set.mRegs[i].mValue ||
!mRegs[CPU_REG_X].SameData(set.mRegs[CPU_REG_X]))
{
mRegs[i].Reset();
changed = true;
}
}
else if (mRegs[i].mMode == NRDM_ABSOLUTE_Y)
{
if (set.mRegs[i].mMode != NRDM_ABSOLUTE_Y ||
mRegs[i].mLinkerObject != set.mRegs[i].mLinkerObject ||
mRegs[i].mValue != set.mRegs[i].mValue ||
!mRegs[CPU_REG_Y].SameData(set.mRegs[CPU_REG_Y]))
{
mRegs[i].Reset();
changed = true;
}
} }
} }
@ -15939,6 +15956,192 @@ bool NativeCodeBasicBlock::JoinXYCascade(void)
return changed; return changed;
} }
bool NativeCodeBasicBlock::GlobalLoadStoreForwarding(const NativeCodeInstruction & als, const NativeCodeInstruction & xls, const NativeCodeInstruction & yls)
{
bool changed = false;
if (!mVisited)
{
mNumEntered++;
if (mLoopHead)
{
mALSIns.mType = ASMIT_INV;
mXLSIns.mType = ASMIT_INV;
mYLSIns.mType = ASMIT_INV;
}
else if (mNumEntered == 1)
{
mALSIns = als;
mXLSIns = xls;
mYLSIns = yls;
}
else
{
if (als.mType == ASMIT_INV || (mALSIns.mType != ASMIT_INV && !mALSIns.SameEffectiveAddress(als))) mALSIns.mType = ASMIT_INV;
if (xls.mType == ASMIT_INV || (mXLSIns.mType != ASMIT_INV && !mXLSIns.SameEffectiveAddress(xls))) mXLSIns.mType = ASMIT_INV;
if (yls.mType == ASMIT_INV || (mYLSIns.mType != ASMIT_INV && !mYLSIns.SameEffectiveAddress(yls))) mYLSIns.mType = ASMIT_INV;
}
if (!mLoopHead && mNumEntered != mNumEntries)
return false;
mVisited = true;
for (int i = 0; i < mIns.Size(); i++)
{
NativeCodeInstruction& ins(mIns[i]);
if (ins.mType == ASMIT_STA)
{
if (mALSIns.mType != ASMIT_INV && ins.SameEffectiveAddress(mALSIns) && !(ins.mFlags & NCIF_VOLATILE))
{
ins.mType = ASMIT_NOP;
ins.mMode = ASMIM_IMPLIED;
changed = true;
}
else
{
if ((ins.mMode == ASMIM_ABSOLUTE || ins.mMode == ASMIM_ABSOLUTE_X || ins.mMode == ASMIM_ABSOLUTE_Y) && !(ins.mFlags & NCIF_VOLATILE))
mALSIns = ins;
if (mXLSIns.mType != ASMIT_INV && ins.MayBeSameAddress(mXLSIns))
mXLSIns.mType = ASMIT_INV;
if (mYLSIns.mType != ASMIT_INV && ins.MayBeSameAddress(mYLSIns))
mYLSIns.mType = ASMIT_INV;
}
}
else if (ins.mType == ASMIT_LDA)
{
if (mALSIns.mType != ASMIT_INV && ins.SameEffectiveAddress(mALSIns) && !(ins.mFlags & NCIF_VOLATILE))
{
ins.mType = ASMIT_ORA;
ins.mMode = ASMIM_IMMEDIATE;
ins.mAddress = 0;
changed = true;
}
else if ((ins.mMode == ASMIM_ABSOLUTE || ins.mMode == ASMIM_ABSOLUTE_X || ins.mMode == ASMIM_ABSOLUTE_Y) && !(ins.mFlags & NCIF_VOLATILE))
mALSIns = ins;
else
mALSIns.mType = ASMIT_INV;
}
else if (ins.mType == ASMIT_STX)
{
if (mXLSIns.mType != ASMIT_INV && ins.SameEffectiveAddress(mXLSIns) && !(ins.mFlags & NCIF_VOLATILE))
{
ins.mType = ASMIT_NOP;
ins.mMode = ASMIM_IMPLIED;
changed = true;
}
else
{
if ((ins.mMode == ASMIM_ABSOLUTE || ins.mMode == ASMIM_ABSOLUTE_Y) && !(ins.mFlags & NCIF_VOLATILE))
mXLSIns = ins;
if (mALSIns.mType != ASMIT_INV && ins.MayBeSameAddress(mALSIns))
mALSIns.mType = ASMIT_INV;
if (mYLSIns.mType != ASMIT_INV && ins.MayBeSameAddress(mYLSIns))
mYLSIns.mType = ASMIT_INV;
}
}
else if (ins.mType == ASMIT_LDX)
{
if (mXLSIns.mType != ASMIT_INV && ins.SameEffectiveAddress(mXLSIns) && !(ins.mLive & LIVE_CPU_REG_Z) && !(ins.mFlags & NCIF_VOLATILE))
{
ins.mType = ASMIT_NOP;
ins.mMode = ASMIM_IMPLIED;
ins.mAddress = 0;
changed = true;
}
else
{
if ((ins.mMode == ASMIM_ABSOLUTE || ins.mMode == ASMIM_ABSOLUTE_Y) && !(ins.mFlags & NCIF_VOLATILE))
mXLSIns = ins;
else
mXLSIns.mType = ASMIT_INV;
if (mALSIns.mType != ASMIT_INV && mALSIns.mMode == ASMIM_ABSOLUTE_X)
mALSIns.mType = ASMIT_INV;
if (mYLSIns.mType != ASMIT_INV && mYLSIns.mMode == ASMIM_ABSOLUTE_X)
mYLSIns.mType = ASMIT_INV;
}
}
else if (ins.mType == ASMIT_STY)
{
if (mYLSIns.mType != ASMIT_INV && ins.SameEffectiveAddress(mYLSIns) && !(ins.mFlags & NCIF_VOLATILE))
{
ins.mType = ASMIT_NOP;
ins.mMode = ASMIM_IMPLIED;
changed = true;
}
else
{
if ((ins.mMode == ASMIM_ABSOLUTE || ins.mMode == ASMIM_ABSOLUTE_X) && !(ins.mFlags & NCIF_VOLATILE))
mYLSIns = ins;
if (mALSIns.mType != ASMIT_INV && ins.MayBeSameAddress(mALSIns))
mALSIns.mType = ASMIT_INV;
if (mXLSIns.mType != ASMIT_INV && ins.MayBeSameAddress(mXLSIns))
mXLSIns.mType = ASMIT_INV;
}
}
else if (ins.mType == ASMIT_LDY)
{
if (mYLSIns.mType != ASMIT_INV && ins.SameEffectiveAddress(mYLSIns) && !(ins.mLive & LIVE_CPU_REG_Z) && !(ins.mFlags & NCIF_VOLATILE))
{
ins.mType = ASMIT_NOP;
ins.mMode = ASMIM_IMPLIED;
ins.mAddress = 0;
changed = true;
}
else
{
if ((ins.mMode == ASMIM_ABSOLUTE || ins.mMode == ASMIM_ABSOLUTE_X) && !(ins.mFlags & NCIF_VOLATILE))
mYLSIns = ins;
else
mYLSIns.mType = ASMIT_INV;
if (mALSIns.mType != ASMIT_INV && mALSIns.mMode == ASMIM_ABSOLUTE_Y)
mALSIns.mType = ASMIT_INV;
if (mXLSIns.mType != ASMIT_INV && mYLSIns.mMode == ASMIM_ABSOLUTE_Y)
mXLSIns.mType = ASMIT_INV;
}
}
else
{
if (ins.ChangesAccu())
mALSIns.mType = ASMIT_INV;
if (ins.ChangesXReg())
{
mXLSIns.mType = ASMIT_INV;
if (mALSIns.mMode == ASMIM_ABSOLUTE_X)
mALSIns.mType = ASMIT_INV;
if (mYLSIns.mMode == ASMIM_ABSOLUTE_X)
mYLSIns.mType = ASMIT_INV;
}
if (ins.ChangesYReg())
{
mYLSIns.mType = ASMIT_INV;
if (mALSIns.mMode == ASMIM_ABSOLUTE_Y)
mALSIns.mType = ASMIT_INV;
if (mXLSIns.mMode == ASMIM_ABSOLUTE_Y)
mXLSIns.mType = ASMIT_INV;
}
if (ins.ChangesAddress())
{
if (mALSIns.mType != ASMIT_INV && mALSIns.MayBeSameAddress(ins))
mALSIns.mType = ASMIT_INV;
if (mXLSIns.mType != ASMIT_INV && mXLSIns.MayBeSameAddress(ins))
mXLSIns.mType = ASMIT_INV;
if (mYLSIns.mType != ASMIT_INV && mYLSIns.MayBeSameAddress(ins))
mYLSIns.mType = ASMIT_INV;
}
}
}
if (mTrueJump && mTrueJump->GlobalLoadStoreForwarding(mALSIns, mXLSIns, mYLSIns))
changed = true;
if (mFalseJump && mFalseJump->GlobalLoadStoreForwarding(mALSIns, mXLSIns, mYLSIns))
changed = true;
}
return changed;
}
bool NativeCodeBasicBlock::RegisterValueForwarding(void) bool NativeCodeBasicBlock::RegisterValueForwarding(void)
{ {
bool changed = false; bool changed = false;
@ -49343,6 +49546,7 @@ void NativeCodeProcedure::Optimize(void)
{ {
ResetVisited(); ResetVisited();
NativeRegisterDataSet data; NativeRegisterDataSet data;
if (mEntryBlock->ValueForwarding(this, data, step > 0, step == 8)) if (mEntryBlock->ValueForwarding(this, data, step > 0, step == 8))
{ {
changed = true; changed = true;
@ -50106,6 +50310,19 @@ void NativeCodeProcedure::Optimize(void)
} }
} }
#endif #endif
#if 1
if (step == 12)
{
ResetVisited();
if (mEntryBlock->GlobalLoadStoreForwarding(NativeCodeInstruction(), NativeCodeInstruction(), NativeCodeInstruction()))
{
ResetVisited();
NativeRegisterDataSet data;
mEntryBlock->BuildEntryDataSet(data);
changed = true;
}
}
#endif
#if 1 #if 1
if (step == 14 && cnt == 0) if (step == 14 && cnt == 0)
{ {

View File

@ -254,6 +254,8 @@ public:
ExpandingArray<NativeRegisterSum16Info> mRSumInfos; ExpandingArray<NativeRegisterSum16Info> mRSumInfos;
NativeCodeInstruction mALSIns, mXLSIns, mYLSIns;
NativeCodeInstruction DecodeNative(const InterInstruction* ins, LinkerObject * lobj, int& offset) const; NativeCodeInstruction DecodeNative(const InterInstruction* ins, LinkerObject * lobj, int& offset) const;
int PutBranch(NativeCodeProcedure* proc, NativeCodeBasicBlock* target, AsmInsType code, int offset); int PutBranch(NativeCodeProcedure* proc, NativeCodeBasicBlock* target, AsmInsType code, int offset);
@ -492,6 +494,8 @@ public:
// Join sequences of TXA, CLC, ADC #xx into INX, TXA sequences if possible // Join sequences of TXA, CLC, ADC #xx into INX, TXA sequences if possible
bool JoinXYCascade(void); bool JoinXYCascade(void);
bool GlobalLoadStoreForwarding(const NativeCodeInstruction & als, const NativeCodeInstruction & xls, const NativeCodeInstruction & yls);
bool RegisterValueForwarding(void); bool RegisterValueForwarding(void);
bool CanCombineSameXtoY(int start, int end); bool CanCombineSameXtoY(int start, int end);
bool CanCombineSameYtoX(int start, int end); bool CanCombineSameYtoX(int start, int end);