Optimize space in linker when using aligned objects

This commit is contained in:
drmortalwombat 2022-01-02 15:08:47 +01:00
parent 272b7b08df
commit d621ab32cd
3 changed files with 81 additions and 14 deletions

View File

@ -4,7 +4,7 @@
LinkerRegion::LinkerRegion(void) LinkerRegion::LinkerRegion(void)
: mSections(nullptr) : mSections(nullptr), mFreeChunks(FreeChunk{ 0, 0 } )
{} {}
LinkerSection::LinkerSection(void) LinkerSection::LinkerSection(void)
@ -176,6 +176,62 @@ void Linker::ReferenceObject(LinkerObject* obj)
} }
} }
bool LinkerRegion::Allocate(LinkerObject* lobj)
{
int i = 0;
while (i < mFreeChunks.Size())
{
int start = (mFreeChunks[i].mStart + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1);
int end = start + lobj->mSize;
if (end <= mFreeChunks[i].mEnd)
{
lobj->mFlags |= LOBJF_PLACED;
lobj->mAddress = start;
lobj->mRegion = this;
if (start == mFreeChunks[i].mStart)
{
if (end == mFreeChunks[i].mEnd)
mFreeChunks.Remove(i);
else
mFreeChunks[i].mStart = end;
}
else if (end == mFreeChunks[i].mEnd)
{
mFreeChunks[i].mEnd = start;
}
else
{
mFreeChunks.Insert(i + 1, FreeChunk{ end, mFreeChunks[i].mEnd } );
mFreeChunks[i].mEnd = start;
}
return true;
}
i++;
}
int start = (mStart + mUsed + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1);
int end = start + lobj->mSize;
if (end <= mEnd)
{
lobj->mFlags |= LOBJF_PLACED;
lobj->mAddress = start;
lobj->mRegion = this;
#if 1
if (start != mStart + mUsed)
mFreeChunks.Push( FreeChunk{ mStart + mUsed, start } );
#endif
mUsed = end - mStart;
return true;
}
return false;
}
void Linker::Link(void) void Linker::Link(void)
{ {
if (mErrors->mErrorCount == 0) if (mErrors->mErrorCount == 0)
@ -199,17 +255,13 @@ void Linker::Link(void)
for (int k = 0; k < lsec->mObjects.Size(); k++) for (int k = 0; k < lsec->mObjects.Size(); k++)
{ {
LinkerObject* lobj = lsec->mObjects[k]; LinkerObject* lobj = lsec->mObjects[k];
if ((lobj->mFlags & LOBJF_REFERENCED) && !(lobj->mFlags & LOBJF_PLACED) && lrgn->mStart + lrgn->mUsed + lobj->mSize <= lrgn->mEnd) if ((lobj->mFlags & LOBJF_REFERENCED) && !(lobj->mFlags & LOBJF_PLACED) && lrgn->Allocate(lobj) )
{ {
lobj->mFlags |= LOBJF_PLACED;
lobj->mAddress = (lrgn->mStart + lrgn->mUsed + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1);
lrgn->mUsed = lobj->mAddress + lobj->mSize - lrgn->mStart;
lobj->mRegion = lrgn;
if (lsec->mType == LST_DATA) if (lsec->mType == LST_DATA)
lrgn->mNonzero = lrgn->mUsed; lrgn->mNonzero = lrgn->mUsed;
if (lobj->mAddress + lobj->mSize == lrgn->mStart + lrgn->mUsed)
{
if (lobj->mAddress < lsec->mStart) if (lobj->mAddress < lsec->mStart)
lsec->mStart = lobj->mAddress; lsec->mStart = lobj->mAddress;
if (lobj->mAddress + lobj->mSize > lsec->mEnd) if (lobj->mAddress + lobj->mSize > lsec->mEnd)
@ -218,6 +270,7 @@ void Linker::Link(void)
} }
} }
} }
}
mProgramStart = 0x0801; mProgramStart = 0x0801;
mProgramEnd = 0x0801; mProgramEnd = 0x0801;

View File

@ -48,6 +48,15 @@ public:
GrowingArray<LinkerSection*> mSections; GrowingArray<LinkerSection*> mSections;
LinkerRegion(void); LinkerRegion(void);
struct FreeChunk
{
int mStart, mEnd;
};
GrowingArray<FreeChunk> mFreeChunks;
bool Allocate(LinkerObject* obj);
}; };
static const uint32 LREF_LOWBYTE = 0x00000001; static const uint32 LREF_LOWBYTE = 0x00000001;

View File

@ -9353,6 +9353,7 @@ bool NativeCodeBasicBlock::PatchAddressSumY(int at, int reg, int apos, int breg,
} }
else if (mIns[i].mMode == ASMIM_INDIRECT_Y && mIns[i].mAddress == reg) else if (mIns[i].mMode == ASMIM_INDIRECT_Y && mIns[i].mAddress == reg)
{ {
mIns[i].mFlags &= ~NCIF_YZERO;
mIns[i].mAddress = breg; mIns[i].mAddress = breg;
} }
} }
@ -13026,17 +13027,18 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
mIns[i + 2].mAddress = mIns[i + 0].mAddress; mIns[i + 2].mAddress = mIns[i + 0].mAddress;
progress = true; progress = true;
} }
#if 1
else if ( else if (
mIns[i + 0].mType == ASMIT_CLC && mIns[i + 0].mType == ASMIT_CLC &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && (mIns[i + 2].mAddress == 1 || mIns[i + 2].mAddress == 2) && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && (mIns[i + 2].mAddress == 1 || mIns[i + 2].mAddress == 2) &&
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == mIns[i + 3].mAddress && mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 4].mType == ASMIT_TAY && !(mIns[i + 4].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C))) mIns[i + 4].mType == ASMIT_TAY && !(mIns[i + 4].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
{ {
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mType = ASMIT_NOP;
mIns[i + 1].mType = ASMIT_LDY; mIns[i + 1].mFlags |= LIVE_CPU_REG_Y; mIns[i + 1].mType = ASMIT_LDY; mIns[i + 1].mFlags |= LIVE_CPU_REG_Y;
mIns[i + 2].mType = ASMIT_INY; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mFlags |= LIVE_CPU_REG_Y; mIns[i + 2].mType = ASMIT_INY; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mFlags |= LIVE_CPU_REG_Y;
mIns[i + 3].mType == ASMIT_STY; mIns[i + 3].mFlags |= LIVE_CPU_REG_Y; mIns[i + 3].mType = ASMIT_STY; mIns[i + 3].mFlags |= LIVE_CPU_REG_Y;
mIns[i + 4].mType = ASMIT_NOP; mIns[i + 4].mType = ASMIT_NOP;
if (mIns[i + 2].mAddress == 2) if (mIns[i + 2].mAddress == 2)
{ {
@ -13045,6 +13047,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
progress = true; progress = true;
} }
#endif
#if 1 #if 1
else if ( else if (
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 && mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 &&
@ -14167,6 +14170,7 @@ void NativeCodeProcedure::Optimize(void)
changed = true; changed = true;
} }
#endif #endif
#if 1
if (step == 3) if (step == 3)
{ {
ResetVisited(); ResetVisited();
@ -14176,6 +14180,7 @@ void NativeCodeProcedure::Optimize(void)
if (mEntryBlock->ReduceLocalYPressure()) if (mEntryBlock->ReduceLocalYPressure())
changed = true; changed = true;
} }
#endif
#if 1 #if 1
else if (step == 4) else if (step == 4)
{ {