Optimize linker placement, avoiding array crossing page boundaries
This commit is contained in:
parent
58c99a5dca
commit
aafb4adfa2
|
@ -48,6 +48,7 @@ void Compiler::AddDefine(const Ident* ident, const char* value)
|
||||||
bool Compiler::ParseSource(void)
|
bool Compiler::ParseSource(void)
|
||||||
{
|
{
|
||||||
mPreprocessor->mCompilerOptions = mCompilerOptions;
|
mPreprocessor->mCompilerOptions = mCompilerOptions;
|
||||||
|
mLinker->mCompilerOptions = mCompilerOptions;
|
||||||
|
|
||||||
CompilationUnit* cunit;
|
CompilationUnit* cunit;
|
||||||
while (mErrors->mErrorCount == 0 && (cunit = mCompilationUnits->PendingUnit()))
|
while (mErrors->mErrorCount == 0 && (cunit = mCompilationUnits->PendingUnit()))
|
||||||
|
|
|
@ -8712,6 +8712,17 @@ void InterCodeBasicBlock::PeepholeOptimization(void)
|
||||||
int j = i;
|
int j = i;
|
||||||
while (j > 0 && CanBypassLoadUp(ins, mInstructions[j - 1]))
|
while (j > 0 && CanBypassLoadUp(ins, mInstructions[j - 1]))
|
||||||
{
|
{
|
||||||
|
if (ins->mSrc[0].mFinal)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < mInstructions[j - 1]->mNumOperands; k++)
|
||||||
|
{
|
||||||
|
if (mInstructions[j - 1]->mSrc[k].mTemp == ins->mSrc[0].mTemp)
|
||||||
|
{
|
||||||
|
mInstructions[j - 1]->mSrc[k].mFinal = true;
|
||||||
|
ins->mSrc[0].mFinal = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
mInstructions[j] = mInstructions[j - 1];
|
mInstructions[j] = mInstructions[j - 1];
|
||||||
j--;
|
j--;
|
||||||
}
|
}
|
||||||
|
@ -8728,12 +8739,24 @@ void InterCodeBasicBlock::PeepholeOptimization(void)
|
||||||
while (i >= 0)
|
while (i >= 0)
|
||||||
{
|
{
|
||||||
// move non indirect loads down
|
// move non indirect loads down
|
||||||
if (mInstructions[i]->mCode == IC_LOAD && (mInstructions[i]->mSrc[0].mMemory != IM_INDIRECT || mInstructions[i]->mDst.mType != IT_INT8))
|
if (mInstructions[i]->mCode == IC_LOAD && (mInstructions[i]->mSrc[0].mMemory != IM_INDIRECT || mInstructions[i]->mDst.mType != IT_INT8 || !mInstructions[i]->mSrc[0].mFinal))
|
||||||
{
|
{
|
||||||
InterInstruction* ins(mInstructions[i]);
|
InterInstruction* ins(mInstructions[i]);
|
||||||
int j = i;
|
int j = i;
|
||||||
while (j < limit && CanBypassLoad(ins, mInstructions[j + 1]))
|
while (j < limit && CanBypassLoad(ins, mInstructions[j + 1]))
|
||||||
{
|
{
|
||||||
|
if (!ins->mSrc[0].mFinal)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < mInstructions[j + 1]->mNumOperands; k++)
|
||||||
|
{
|
||||||
|
if (mInstructions[j + 1]->mSrc[k].mTemp == ins->mSrc[0].mTemp && mInstructions[j + 1]->mSrc[k].mFinal)
|
||||||
|
{
|
||||||
|
mInstructions[j + 1]->mSrc[k].mFinal = false;
|
||||||
|
ins->mSrc[0].mFinal = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mInstructions[j] = mInstructions[j + 1];
|
mInstructions[j] = mInstructions[j + 1];
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
@ -8776,7 +8799,17 @@ void InterCodeBasicBlock::PeepholeOptimization(void)
|
||||||
{
|
{
|
||||||
if (i + 2 < mInstructions.Size())
|
if (i + 2 < mInstructions.Size())
|
||||||
{
|
{
|
||||||
if (mInstructions[i + 0]->mDst.mTemp >= 0 &&
|
if (mInstructions[i + 0]->mCode == IC_LOAD &&
|
||||||
|
mInstructions[i + 1]->mCode == IC_LOAD &&
|
||||||
|
mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i + 0]->mSrc[0].mTemp &&
|
||||||
|
mInstructions[i + 0]->mSrc[0].mIntConst > mInstructions[i + 1]->mSrc[0].mIntConst)
|
||||||
|
{
|
||||||
|
InterInstruction* ins(mInstructions[i + 0]);
|
||||||
|
mInstructions[i + 0] = mInstructions[i + 1];
|
||||||
|
mInstructions[i + 1] = ins;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (mInstructions[i + 0]->mDst.mTemp >= 0 &&
|
||||||
mInstructions[i + 1]->mCode == IC_LOAD_TEMPORARY && mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i]->mDst.mTemp &&
|
mInstructions[i + 1]->mCode == IC_LOAD_TEMPORARY && mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i]->mDst.mTemp &&
|
||||||
(mInstructions[i + 2]->mCode == IC_RELATIONAL_OPERATOR || mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR) && mInstructions[i + 2]->mSrc[0].mTemp == mInstructions[i]->mDst.mTemp && mInstructions[i + 2]->mSrc[0].mFinal)
|
(mInstructions[i + 2]->mCode == IC_RELATIONAL_OPERATOR || mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR) && mInstructions[i + 2]->mSrc[0].mTemp == mInstructions[i]->mDst.mTemp && mInstructions[i + 2]->mSrc[0].mFinal)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "Linker.h"
|
#include "Linker.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "CompilerTypes.h"
|
||||||
|
|
||||||
LinkerRegion::LinkerRegion(void)
|
LinkerRegion::LinkerRegion(void)
|
||||||
: mSections(nullptr), mFreeChunks(FreeChunk{ 0, 0 } )
|
: mSections(nullptr), mFreeChunks(FreeChunk{ 0, 0 } )
|
||||||
|
@ -43,7 +43,7 @@ uint8* LinkerObject::AddSpace(int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
Linker::Linker(Errors* errors)
|
Linker::Linker(Errors* errors)
|
||||||
: mErrors(errors), mSections(nullptr), mReferences(nullptr), mObjects(nullptr), mRegions(nullptr)
|
: mErrors(errors), mSections(nullptr), mReferences(nullptr), mObjects(nullptr), mRegions(nullptr), mCompilerOptions(COPT_DEFAULT)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 64; i++)
|
for (int i = 0; i < 64; i++)
|
||||||
{
|
{
|
||||||
|
@ -177,7 +177,7 @@ void Linker::ReferenceObject(LinkerObject* obj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LinkerRegion::Allocate(LinkerObject* lobj)
|
bool LinkerRegion::Allocate(Linker * linker, LinkerObject* lobj)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < mFreeChunks.Size())
|
while (i < mFreeChunks.Size())
|
||||||
|
@ -185,7 +185,9 @@ bool LinkerRegion::Allocate(LinkerObject* lobj)
|
||||||
int start = (mFreeChunks[i].mStart + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1);
|
int start = (mFreeChunks[i].mStart + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1);
|
||||||
int end = start + lobj->mSize;
|
int end = start + lobj->mSize;
|
||||||
|
|
||||||
if (end <= mFreeChunks[i].mEnd)
|
if (!(linker->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) && (lobj->mFlags & LOBJF_NO_CROSS) && lobj->mSize <= 256 && (start & 0xff00) != ((end - 1) & 0xff00))
|
||||||
|
;
|
||||||
|
else if (end <= mFreeChunks[i].mEnd)
|
||||||
{
|
{
|
||||||
lobj->mFlags |= LOBJF_PLACED;
|
lobj->mFlags |= LOBJF_PLACED;
|
||||||
lobj->mAddress = start;
|
lobj->mAddress = start;
|
||||||
|
@ -217,6 +219,12 @@ bool LinkerRegion::Allocate(LinkerObject* lobj)
|
||||||
int start = (mStart + mUsed + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1);
|
int start = (mStart + mUsed + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1);
|
||||||
int end = start + lobj->mSize;
|
int end = start + lobj->mSize;
|
||||||
|
|
||||||
|
if (!(linker->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) && (lobj->mFlags & LOBJF_NO_CROSS) && lobj->mSize <= 256 && (start & 0xff00) != ((end - 1) & 0xff00))
|
||||||
|
{
|
||||||
|
start = (start + 0x00ff) & 0xff00;
|
||||||
|
end = start + lobj->mSize;
|
||||||
|
}
|
||||||
|
|
||||||
if (end <= mEnd)
|
if (end <= mEnd)
|
||||||
{
|
{
|
||||||
lobj->mFlags |= LOBJF_PLACED;
|
lobj->mFlags |= LOBJF_PLACED;
|
||||||
|
@ -294,7 +302,7 @@ 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->Allocate(lobj) )
|
if ((lobj->mFlags & LOBJF_REFERENCED) && !(lobj->mFlags & LOBJF_PLACED) && lrgn->Allocate(this, lobj) )
|
||||||
{
|
{
|
||||||
if (lsec->mType == LST_DATA)
|
if (lsec->mType == LST_DATA)
|
||||||
lrgn->mNonzero = lrgn->mUsed;
|
lrgn->mNonzero = lrgn->mUsed;
|
||||||
|
|
|
@ -91,7 +91,7 @@ public:
|
||||||
|
|
||||||
GrowingArray<FreeChunk> mFreeChunks;
|
GrowingArray<FreeChunk> mFreeChunks;
|
||||||
|
|
||||||
bool Allocate(LinkerObject* obj);
|
bool Allocate(Linker * linker, LinkerObject* obj);
|
||||||
void PlaceStackSection(LinkerSection* stackSection, LinkerSection* section);
|
void PlaceStackSection(LinkerSection* stackSection, LinkerSection* section);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -129,6 +129,7 @@ static const uint32 LOBJF_INLINE = 0x00000008;
|
||||||
static const uint32 LOBJF_CONST = 0x00000010;
|
static const uint32 LOBJF_CONST = 0x00000010;
|
||||||
static const uint32 LOBJF_RELEVANT = 0x00000020;
|
static const uint32 LOBJF_RELEVANT = 0x00000020;
|
||||||
static const uint32 LOBJF_STATIC_STACK = 0x00000040;
|
static const uint32 LOBJF_STATIC_STACK = 0x00000040;
|
||||||
|
static const uint32 LOBJF_NO_CROSS = 0x00000080;
|
||||||
|
|
||||||
class LinkerObject
|
class LinkerObject
|
||||||
{
|
{
|
||||||
|
@ -187,6 +188,8 @@ public:
|
||||||
bool WriteCrtFile(const char* filename);
|
bool WriteCrtFile(const char* filename);
|
||||||
bool WriteBinFile(const char* filename);
|
bool WriteBinFile(const char* filename);
|
||||||
|
|
||||||
|
uint64 mCompilerOptions;
|
||||||
|
|
||||||
GrowingArray<LinkerReference*> mReferences;
|
GrowingArray<LinkerReference*> mReferences;
|
||||||
GrowingArray<LinkerRegion*> mRegions;
|
GrowingArray<LinkerRegion*> mRegions;
|
||||||
GrowingArray<LinkerSection*> mSections;
|
GrowingArray<LinkerSection*> mSections;
|
||||||
|
|
|
@ -3029,6 +3029,9 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block)
|
||||||
rl.mRefObject = mLinkerObject;
|
rl.mRefObject = mLinkerObject;
|
||||||
rl.mRefOffset = mAddress;
|
rl.mRefOffset = mAddress;
|
||||||
|
|
||||||
|
if (mLinkerObject)
|
||||||
|
mLinkerObject->mFlags |= LOBJF_NO_CROSS;
|
||||||
|
|
||||||
block->mRelocations.Push(rl);
|
block->mRelocations.Push(rl);
|
||||||
block->PutByte(0);
|
block->PutByte(0);
|
||||||
}
|
}
|
||||||
|
@ -3058,6 +3061,9 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block)
|
||||||
rl.mOffset++;
|
rl.mOffset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mode != ASMIM_ABSOLUTE)
|
||||||
|
mLinkerObject->mFlags |= LOBJF_NO_CROSS;
|
||||||
|
|
||||||
block->mRelocations.Push(rl);
|
block->mRelocations.Push(rl);
|
||||||
block->PutWord(0);
|
block->PutWord(0);
|
||||||
}
|
}
|
||||||
|
@ -9656,6 +9662,15 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
|
||||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
else if (yoffset == 1)
|
||||||
|
{
|
||||||
|
for (int j = ypred; j < i; j++)
|
||||||
|
mIns[j].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
|
||||||
|
mIns[i + 0].mType = ASMIT_DEY; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
yoffset = 0;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
else if (yoffset == 2 && i + 2 < mIns.Size() && mIns[i + 1].mType == ASMIT_INY && mIns[i + 2].mType == ASMIT_INY)
|
else if (yoffset == 2 && i + 2 < mIns.Size() && mIns[i + 1].mType == ASMIT_INY && mIns[i + 2].mType == ASMIT_INY)
|
||||||
{
|
{
|
||||||
for (int j = ypred; j < i; j++)
|
for (int j = ypred; j < i; j++)
|
||||||
|
@ -9666,6 +9681,35 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
|
||||||
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
else if (yoffset == 2 && i + 1 < mIns.Size() && mIns[i + 1].mType == ASMIT_INY)
|
||||||
|
{
|
||||||
|
for (int j = ypred; j < i; j++)
|
||||||
|
mIns[j].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 1].mType = ASMIT_DEY;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (yoffset == 3 && i + 2 < mIns.Size() && mIns[i + 1].mType == ASMIT_INY && mIns[i + 2].mType == ASMIT_INY)
|
||||||
|
{
|
||||||
|
for (int j = ypred; j < i; j++)
|
||||||
|
mIns[j].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 1].mType = ASMIT_DEY; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 2].mType = ASMIT_DEY; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (yoffset == 3 && i + 1 < mIns.Size() && mIns[i + 1].mType == ASMIT_INY)
|
||||||
|
{
|
||||||
|
for (int j = ypred; j < i; j++)
|
||||||
|
mIns[j].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
|
||||||
|
mIns[i + 0].mType = ASMIT_DEY; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 1].mType = ASMIT_DEY; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
yoffset = 2;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
yoffset = 0;
|
yoffset = 0;
|
||||||
ypred = i;
|
ypred = i;
|
||||||
|
@ -9744,7 +9788,7 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
|
||||||
}
|
}
|
||||||
else if (mIns[i].mType == ASMIT_DEY)
|
else if (mIns[i].mType == ASMIT_DEY)
|
||||||
{
|
{
|
||||||
yoffset = (yoffset + 1) & 255;
|
yoffset = (yoffset - 1) & 255;
|
||||||
}
|
}
|
||||||
else if (mIns[i].ChangesYReg())
|
else if (mIns[i].ChangesYReg())
|
||||||
{
|
{
|
||||||
|
@ -9890,7 +9934,7 @@ bool NativeCodeBasicBlock::ForwardZpXIndex(bool full)
|
||||||
}
|
}
|
||||||
else if (mIns[i].mType == ASMIT_DEX)
|
else if (mIns[i].mType == ASMIT_DEX)
|
||||||
{
|
{
|
||||||
xoffset = (xoffset + 1) & 255;
|
xoffset = (xoffset - 1) & 255;
|
||||||
}
|
}
|
||||||
else if (mIns[i].ChangesXReg())
|
else if (mIns[i].ChangesXReg())
|
||||||
{
|
{
|
||||||
|
@ -10569,7 +10613,7 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::SplitMatchingTails(NativeCodeProced
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc)
|
bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool loops)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
|
@ -10612,14 +10656,14 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc)
|
||||||
NativeCodeBasicBlock* nblock = SplitMatchingTails(proc);
|
NativeCodeBasicBlock* nblock = SplitMatchingTails(proc);
|
||||||
if (nblock)
|
if (nblock)
|
||||||
{
|
{
|
||||||
if (nblock->JoinTailCodeSequences(proc))
|
if (nblock->JoinTailCodeSequences(proc, loops))
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if 1
|
#if 1
|
||||||
if (mIns.Size() >= 1 && mEntryBlocks.Size() == 2)
|
if (loops && mIns.Size() >= 1 && mEntryBlocks.Size() == 2)
|
||||||
{
|
{
|
||||||
NativeCodeBasicBlock* pblock = mEntryBlocks[0], * lblock = mEntryBlocks[1];
|
NativeCodeBasicBlock* pblock = mEntryBlocks[0], * lblock = mEntryBlocks[1];
|
||||||
int ps = pblock->mIns.Size(), ls = lblock->mIns.Size();
|
int ps = pblock->mIns.Size(), ls = lblock->mIns.Size();
|
||||||
|
@ -10815,9 +10859,9 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (mTrueJump && mTrueJump->JoinTailCodeSequences(proc))
|
if (mTrueJump && mTrueJump->JoinTailCodeSequences(proc, loops))
|
||||||
changed = true;
|
changed = true;
|
||||||
if (mFalseJump && mFalseJump->JoinTailCodeSequences(proc))
|
if (mFalseJump && mFalseJump->JoinTailCodeSequences(proc, loops))
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10901,6 +10945,8 @@ bool NativeCodeBasicBlock::CheckSingleUseGlobalLoad(const NativeCodeBasicBlock*
|
||||||
if (!mEntryRequiredRegs[reg])
|
if (!mEntryRequiredRegs[reg])
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
assert(mNumEntries == mEntryBlocks.Size());
|
||||||
|
|
||||||
if (mNumEntries > 1)
|
if (mNumEntries > 1)
|
||||||
{
|
{
|
||||||
if (mLoopHead)
|
if (mLoopHead)
|
||||||
|
@ -11139,6 +11185,20 @@ bool NativeCodeBasicBlock::IsDominatedBy(const NativeCodeBasicBlock* block) cons
|
||||||
{
|
{
|
||||||
if (this == block)
|
if (this == block)
|
||||||
return true;
|
return true;
|
||||||
|
#if 0
|
||||||
|
if (mEntryBlocks.Size())
|
||||||
|
{
|
||||||
|
if (mLoopHead)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int i = 0; i < mEntryBlocks.Size(); i++)
|
||||||
|
if (!mEntryBlocks[i]->IsDominatedBy(block))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NativeCodeBasicBlock* dom = mDominator;
|
NativeCodeBasicBlock* dom = mDominator;
|
||||||
|
@ -11151,6 +11211,7 @@ bool NativeCodeBasicBlock::IsDominatedBy(const NativeCodeBasicBlock* block) cons
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::CheckGlobalAddressSumYPointer(const NativeCodeBasicBlock * block, int reg, int at, int yval)
|
bool NativeCodeBasicBlock::CheckGlobalAddressSumYPointer(const NativeCodeBasicBlock * block, int reg, int at, int yval)
|
||||||
|
@ -11704,6 +11765,25 @@ bool NativeCodeBasicBlock::JoinTAXARange(int from, int to)
|
||||||
}
|
}
|
||||||
mIns.Remove(start);
|
mIns.Remove(start);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (mIns[start].mType == ASMIT_LDA && mIns[start].mMode == ASMIM_ABSOLUTE_X && mIns[start + 1].ChangesAccu() && !mIns[start + 1].ChangesAddress() && !mIns[start + 1].RequiresYReg())
|
||||||
|
{
|
||||||
|
|
||||||
|
for (int i = from + 1; i < to; i++)
|
||||||
|
{
|
||||||
|
if (mIns[start].MayBeChangedOnAddress(mIns[i]) || mIns[start + 1].MayBeChangedOnAddress(mIns[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mIns.Remove(to);
|
||||||
|
for (int i = start; i < from; i++)
|
||||||
|
{
|
||||||
|
mIns.Insert(to, mIns[start]);
|
||||||
|
mIns.Remove(start);
|
||||||
|
}
|
||||||
|
mIns.Remove(start);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14492,6 +14572,7 @@ bool NativeCodeBasicBlock::OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCo
|
||||||
{
|
{
|
||||||
block->mIns[i].mType = ASMIT_NOP; block->mIns[i].mMode = ASMIM_IMPLIED;
|
block->mIns[i].mType = ASMIT_NOP; block->mIns[i].mMode = ASMIM_IMPLIED;
|
||||||
}
|
}
|
||||||
|
block->mIns[i].mLive |= LIVE_CPU_REG_Y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14559,6 +14640,7 @@ bool NativeCodeBasicBlock::OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCo
|
||||||
{
|
{
|
||||||
block->mIns[i].mType = ASMIT_NOP; block->mIns[i].mMode = ASMIM_IMPLIED;
|
block->mIns[i].mType = ASMIT_NOP; block->mIns[i].mMode = ASMIM_IMPLIED;
|
||||||
}
|
}
|
||||||
|
block->mIns[i].mLive |= LIVE_CPU_REG_X;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18917,146 +18999,6 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#if 0
|
|
||||||
if (i + 7 < mIns.Size())
|
|
||||||
{
|
|
||||||
if (
|
|
||||||
mIns[i + 0].mType == ASMIT_CLC &&
|
|
||||||
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
|
||||||
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
|
|
||||||
mIns[i + 3].mType == ASMIT_LDA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress == mIns[i + 1].mAddress + 1 &&
|
|
||||||
mIns[i + 4].mType == ASMIT_ADC && mIns[i + 4].mMode == ASMIM_IMMEDIATE && mIns[i + 4].mAddress == 0 &&
|
|
||||||
mIns[i + 5].mType == ASMIT_STA && mIns[i + 5].mMode == ASMIM_ZERO_PAGE && mIns[i + 5].mAddress == mIns[i + 2].mAddress + 1 &&
|
|
||||||
|
|
||||||
mIns[i + 6].mType == ASMIT_LDY && mIns[i + 6].mMode == ASMIM_IMMEDIATE && mIns[i + 6].mAddress == 0 &&
|
|
||||||
mIns[i + 7].mMode == ASMIM_INDIRECT_Y && mIns[i + 7].mAddress == mIns[i + 2].mAddress && !(mIns[i + 7].mLive & LIVE_MEM))
|
|
||||||
{
|
|
||||||
for (int j = 0; j < 6; j++)
|
|
||||||
{
|
|
||||||
mIns[i + j].mType = ASMIT_NOP; mIns[i + j].mMode = ASMIM_IMPLIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mIns[i + 7].mLive & LIVE_CPU_REG_Y)
|
|
||||||
{
|
|
||||||
mIns.Insert(i + 8, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
|
|
||||||
mIns[i + 8].mLive |= LIVE_CPU_REG_Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
mIns[i + 6].mType = ASMIT_TAY;
|
|
||||||
mIns[i + 6].mMode = ASMIM_IMPLIED;
|
|
||||||
mIns[i + 7].mAddress = mIns[i + 1].mAddress;
|
|
||||||
progress = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
if (i + 8 < mIns.Size())
|
|
||||||
{
|
|
||||||
if (
|
|
||||||
mIns[i + 0].mType == ASMIT_CLC &&
|
|
||||||
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
|
||||||
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
|
|
||||||
mIns[i + 3].mType == ASMIT_LDA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress == mIns[i + 1].mAddress + 1 &&
|
|
||||||
mIns[i + 4].mType == ASMIT_ADC && mIns[i + 4].mMode == ASMIM_IMMEDIATE && mIns[i + 4].mAddress == 0 &&
|
|
||||||
mIns[i + 5].mType == ASMIT_STA && mIns[i + 5].mMode == ASMIM_ZERO_PAGE && mIns[i + 5].mAddress == mIns[i + 2].mAddress + 1 &&
|
|
||||||
!mIns[i + 6].ChangesZeroPage(mIns[i + 1].mAddress) && !mIns[i + 6].ChangesZeroPage(mIns[i + 1].mAddress + 1) && !mIns[i + 6].RequiresYReg() &&
|
|
||||||
mIns[i + 7].mType == ASMIT_LDY && mIns[i + 7].mMode == ASMIM_IMMEDIATE && mIns[i + 7].mAddress == 0 &&
|
|
||||||
mIns[i + 8].mMode == ASMIM_INDIRECT_Y && mIns[i + 8].mAddress == mIns[i + 2].mAddress && !(mIns[i + 8].mLive & LIVE_MEM))
|
|
||||||
{
|
|
||||||
for (int j = 0; j < 6; j++)
|
|
||||||
{
|
|
||||||
mIns[i + j].mType = ASMIT_NOP; mIns[i + j].mMode = ASMIM_IMPLIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mIns[i + 8].mLive & LIVE_CPU_REG_Y)
|
|
||||||
{
|
|
||||||
mIns.Insert(i + 9, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
|
|
||||||
mIns[i + 9].mLive |= LIVE_CPU_REG_Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
mIns[i + 0].mType = ASMIT_TAY;
|
|
||||||
mIns[i + 0].mMode = ASMIM_IMPLIED;
|
|
||||||
mIns[i + 7].mType = ASMIT_NOP; mIns[i + 7].mMode = ASMIM_IMPLIED;
|
|
||||||
mIns[i + 8].mAddress = mIns[i + 1].mAddress;
|
|
||||||
progress = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
if (i + 11 < mIns.Size())
|
|
||||||
{
|
|
||||||
if (
|
|
||||||
mIns[i + 0].mType == ASMIT_CLC &&
|
|
||||||
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
|
||||||
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
|
|
||||||
mIns[i + 3].mType == ASMIT_LDA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress == mIns[i + 1].mAddress + 1 &&
|
|
||||||
mIns[i + 4].mType == ASMIT_ADC && mIns[i + 4].mMode == ASMIM_IMMEDIATE && mIns[i + 4].mAddress == 0 &&
|
|
||||||
mIns[i + 5].mType == ASMIT_STA && mIns[i + 5].mMode == ASMIM_ZERO_PAGE && mIns[i + 5].mAddress == mIns[i + 2].mAddress + 1 &&
|
|
||||||
!mIns[i + 6].ChangesZeroPage(mIns[i + 1].mAddress) && !mIns[i + 6].ChangesZeroPage(mIns[i + 1].mAddress + 1) && !mIns[i + 6].RequiresYReg() &&
|
|
||||||
mIns[i + 7].mType == ASMIT_LDY && mIns[i + 7].mMode == ASMIM_IMMEDIATE && mIns[i + 7].mAddress == 0 &&
|
|
||||||
mIns[i + 8].mMode == ASMIM_INDIRECT_Y && mIns[i + 8].mAddress == mIns[i + 2].mAddress &&
|
|
||||||
!mIns[i + 9].ChangesZeroPage(mIns[i + 1].mAddress) && !mIns[i + 9].ChangesZeroPage(mIns[i + 1].mAddress + 1) && !mIns[i + 9].RequiresYReg() &&
|
|
||||||
mIns[i + 10].mType == ASMIT_LDY && mIns[i + 10].mMode == ASMIM_IMMEDIATE && mIns[i + 10].mAddress == 1 &&
|
|
||||||
mIns[i + 11].mMode == ASMIM_INDIRECT_Y && mIns[i + 11].mAddress == mIns[i + 2].mAddress &&
|
|
||||||
!(mIns[i + 11].mLive & LIVE_MEM))
|
|
||||||
{
|
|
||||||
for (int j = 0; j < 6; j++)
|
|
||||||
{
|
|
||||||
mIns[i + j].mType = ASMIT_NOP; mIns[i + j].mMode = ASMIM_IMPLIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mIns[i + 11].mLive & LIVE_CPU_REG_Y)
|
|
||||||
{
|
|
||||||
mIns.Insert(i + 12, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 1));
|
|
||||||
mIns[i + 12].mLive |= LIVE_CPU_REG_Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
mIns[i + 0].mType = ASMIT_TAY;
|
|
||||||
mIns[i + 0].mMode = ASMIM_IMPLIED;
|
|
||||||
mIns[i + 7].mType = ASMIT_NOP; mIns[i + 7].mMode = ASMIM_IMPLIED;
|
|
||||||
mIns[i + 8].mAddress = mIns[i + 1].mAddress;
|
|
||||||
mIns[i + 10].mType = ASMIT_INY; mIns[i + 10].mMode = ASMIM_IMPLIED;
|
|
||||||
mIns[i + 11].mAddress = mIns[i + 1].mAddress;
|
|
||||||
progress = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
if (i + 9 < mIns.Size())
|
|
||||||
{
|
|
||||||
if (
|
|
||||||
mIns[i + 0].mType == ASMIT_CLC &&
|
|
||||||
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
|
||||||
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
|
|
||||||
mIns[i + 3].mType == ASMIT_LDA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress == mIns[i + 1].mAddress + 1 &&
|
|
||||||
mIns[i + 4].mType == ASMIT_ADC && mIns[i + 4].mMode == ASMIM_IMMEDIATE && mIns[i + 4].mAddress == 0 &&
|
|
||||||
mIns[i + 5].mType == ASMIT_STA && mIns[i + 5].mMode == ASMIM_ZERO_PAGE && mIns[i + 5].mAddress == mIns[i + 2].mAddress + 1 &&
|
|
||||||
|
|
||||||
mIns[i + 6].mType == ASMIT_LDY && mIns[i + 6].mMode == ASMIM_IMMEDIATE && mIns[i + 6].mAddress == 0 &&
|
|
||||||
mIns[i + 7].mType == ASMIT_LDA && mIns[i + 7].mMode == ASMIM_INDIRECT_Y && mIns[i + 7].mAddress == mIns[i + 2].mAddress &&
|
|
||||||
!mIns[i + 8].ChangesYReg() && (mIns[i + 8].mMode == ASMIM_IMMEDIATE || mIns[i + 8].mMode == ASMIM_ZERO_PAGE && mIns[i + 8].mAddress != mIns[i + 2].mAddress && mIns[i + 8].mAddress != mIns[i + 1].mAddress) &&
|
|
||||||
mIns[i + 9].mType == ASMIT_STA && mIns[i + 9].mMode == ASMIM_INDIRECT_Y && mIns[i + 9].mAddress == mIns[i + 2].mAddress && !(mIns[i + 9].mLive & LIVE_MEM)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
for(int j=0; j<6; j++)
|
|
||||||
{
|
|
||||||
mIns[i + j].mType = ASMIT_NOP; mIns[i + j].mMode = ASMIM_IMPLIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mIns[i + 9].mLive & LIVE_CPU_REG_Y)
|
|
||||||
{
|
|
||||||
mIns.Insert(i + 10, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
|
|
||||||
mIns[i + 10].mLive |= LIVE_CPU_REG_Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
mIns[i + 6].mType = ASMIT_TAY;
|
|
||||||
mIns[i + 6].mMode = ASMIM_IMPLIED;
|
|
||||||
mIns[i + 7].mAddress = mIns[i + 1].mAddress;
|
|
||||||
mIns[i + 9].mAddress = mIns[i + 1].mAddress;
|
|
||||||
progress = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#if 1
|
#if 1
|
||||||
|
@ -20179,8 +20121,16 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
mBlocks[i]->mFromJump = nullptr;
|
mBlocks[i]->mFromJump = nullptr;
|
||||||
mBlocks[i]->mDominator = nullptr;
|
mBlocks[i]->mDominator = nullptr;
|
||||||
}
|
}
|
||||||
|
ResetEntryBlocks();
|
||||||
|
|
||||||
mEntryBlock->CountEntries(nullptr);
|
mEntryBlock->CountEntries(nullptr);
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->CollectEntryBlocks(nullptr);
|
||||||
|
|
||||||
|
|
||||||
mEntryBlock->BuildDominatorTree(nullptr);
|
mEntryBlock->BuildDominatorTree(nullptr);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -20246,7 +20196,7 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
if (step > 2)
|
if (step > 2)
|
||||||
{
|
{
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
if (mEntryBlock->JoinTailCodeSequences(this))
|
if (mEntryBlock->JoinTailCodeSequences(this, step > 3))
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -283,7 +283,7 @@ public:
|
||||||
|
|
||||||
NativeCodeBasicBlock * SplitMatchingTails(NativeCodeProcedure* proc);
|
NativeCodeBasicBlock * SplitMatchingTails(NativeCodeProcedure* proc);
|
||||||
|
|
||||||
bool JoinTailCodeSequences(NativeCodeProcedure* proc);
|
bool JoinTailCodeSequences(NativeCodeProcedure* proc, bool loops);
|
||||||
bool SameTail(const NativeCodeInstruction& ins) const;
|
bool SameTail(const NativeCodeInstruction& ins) const;
|
||||||
|
|
||||||
NativeRegisterDataSet mEntryRegisterDataSet;
|
NativeRegisterDataSet mEntryRegisterDataSet;
|
||||||
|
|
Loading…
Reference in New Issue