Optimize space in linker when using aligned objects
This commit is contained in:
parent
272b7b08df
commit
d621ab32cd
|
@ -4,7 +4,7 @@
|
|||
|
||||
|
||||
LinkerRegion::LinkerRegion(void)
|
||||
: mSections(nullptr)
|
||||
: mSections(nullptr), mFreeChunks(FreeChunk{ 0, 0 } )
|
||||
{}
|
||||
|
||||
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)
|
||||
{
|
||||
if (mErrors->mErrorCount == 0)
|
||||
|
@ -199,21 +255,18 @@ void Linker::Link(void)
|
|||
for (int k = 0; k < lsec->mObjects.Size(); 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)
|
||||
lrgn->mNonzero = lrgn->mUsed;
|
||||
|
||||
if (lobj->mAddress < lsec->mStart)
|
||||
lsec->mStart = lobj->mAddress;
|
||||
if (lobj->mAddress + lobj->mSize > lsec->mEnd)
|
||||
lsec->mEnd = lobj->mAddress + lobj->mSize;
|
||||
if (lobj->mAddress + lobj->mSize == lrgn->mStart + lrgn->mUsed)
|
||||
{
|
||||
if (lobj->mAddress < lsec->mStart)
|
||||
lsec->mStart = lobj->mAddress;
|
||||
if (lobj->mAddress + lobj->mSize > lsec->mEnd)
|
||||
lsec->mEnd = lobj->mAddress + lobj->mSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,15 @@ public:
|
|||
GrowingArray<LinkerSection*> mSections;
|
||||
|
||||
LinkerRegion(void);
|
||||
|
||||
struct FreeChunk
|
||||
{
|
||||
int mStart, mEnd;
|
||||
};
|
||||
|
||||
GrowingArray<FreeChunk> mFreeChunks;
|
||||
|
||||
bool Allocate(LinkerObject* obj);
|
||||
};
|
||||
|
||||
static const uint32 LREF_LOWBYTE = 0x00000001;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
mIns[i].mFlags &= ~NCIF_YZERO;
|
||||
mIns[i].mAddress = breg;
|
||||
}
|
||||
}
|
||||
|
@ -13026,17 +13027,18 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
|||
mIns[i + 2].mAddress = mIns[i + 0].mAddress;
|
||||
progress = true;
|
||||
}
|
||||
#if 1
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_CLC &&
|
||||
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 + 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 + 0].mType = ASMIT_NOP;
|
||||
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 + 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;
|
||||
if (mIns[i + 2].mAddress == 2)
|
||||
{
|
||||
|
@ -13045,6 +13047,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
|||
|
||||
progress = true;
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
else if (
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
if (step == 3)
|
||||
{
|
||||
ResetVisited();
|
||||
|
@ -14176,6 +14180,7 @@ void NativeCodeProcedure::Optimize(void)
|
|||
if (mEntryBlock->ReduceLocalYPressure())
|
||||
changed = true;
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
else if (step == 4)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue