Optimize small inline function calls

This commit is contained in:
drmortalwombat 2024-05-30 17:51:34 +02:00
parent b09e9a2434
commit 2e696d9e1a
7 changed files with 321 additions and 36 deletions

View File

@ -121,9 +121,9 @@ bool krnio_load(char fnum, char device, char channel)
jsr $FFD5 // load
lda #0
bcs W1
lda #1
W1: sta accu
rol
eor #1
sta accu
}
}
@ -144,9 +144,9 @@ bool krnio_save(char device, const char* start, const char* end)
jsr $FFD8 // save
lda #0
bcs W1
lda #1
W1: sta accu
rol
eor #1
sta accu
}
}
@ -158,10 +158,11 @@ bool krnio_chkout(char fnum)
{
ldx fnum
jsr $ffc9 // chkout
lda #0
bcs W1
lda #1
W1: sta accu
rol
eor #1
sta accu
}
}
@ -173,11 +174,11 @@ bool krnio_chkin(char fnum)
{
ldx fnum
jsr $ffc6 // chkin
lda #0
sta accu + 1
bcs W1
lda #1
W1: sta accu
rol
eor #1
sta accu
}
}
@ -200,21 +201,17 @@ bool krnio_chrout(char ch)
lda ch
jsr $ffd2 // chrout
sta accu
lda #0
sta accu + 1
}
}
#pragma native(krnio_chrout)
int krnio_chrin(void)
char krnio_chrin(void)
{
__asm
{
jsr $ffcf // chrin
sta accu
lda #0
sta accu + 1
}
}

View File

@ -64,7 +64,7 @@ bool krnio_chrout(char ch);
// read a single byte from the current input channel
int krnio_chrin(void);
char krnio_chrin(void);
// read a single byte from the given file/channel, returns
// a negative result on failure. If this was the last byte

View File

@ -2508,7 +2508,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (vl.mType->mFlags & DTF_DEFINED)
{
int64 index = exp->mRight->mDecValue->mInteger;
if (index < 0 || index * stride >= vl.mType->mSize * vl.mType->mStripe)
if (vl.mType->mSize > 0 && (index < 0 || index * stride >= vl.mType->mSize * vl.mType->mStripe))
mErrors->Error(exp->mLocation, EWARN_INDEX_OUT_OF_BOUNDS, "Constant array index out of bounds");
}
}

View File

@ -46,7 +46,7 @@ bool LinkerReference::operator!=(const LinkerReference& ref)
LinkerObject::LinkerObject(void)
: mReferences(nullptr), mNumTemporaries(0), mSize(0), mAlignment(1), mStackSection(nullptr), mIdent(nullptr), mFullIdent(nullptr), mStartUsed(0x10000), mEndUsed(0x00000), mMemory(nullptr)
, mPrefix(nullptr), mSuffix(nullptr)
, mPrefix(nullptr), mSuffix(nullptr), mProc(nullptr), mNativeProc(nullptr)
{}
LinkerObject::~LinkerObject(void)

View File

@ -10,6 +10,7 @@
class InterCodeProcedure;
class InterVariable;
class NativeCodeProcedure;
enum LinkerObjectType
{
@ -192,6 +193,7 @@ public:
LinkerRegion * mRegion;
uint8 * mData, * mMemory;
InterCodeProcedure * mProc;
NativeCodeProcedure * mNativeProc;
InterVariable * mVariable;
uint32 mFlags;
uint8 mTemporaries[16], mTempSizes[16];

View File

@ -5053,6 +5053,21 @@ int NativeCodeBasicBlock::PutJump(NativeCodeProcedure* proc, NativeCodeBasicBloc
return 1;
}
}
else if (target->mIns.Size() == 2 && target->mIns[0].IsSimpleJSR() && target->mIns[1].mType == ASMIT_RTS)
{
PutByte(0x4c);
LinkerReference rl;
rl.mObject = nullptr;
rl.mOffset = mCode.Size();
rl.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE;
rl.mRefObject = target->mIns[0].mLinkerObject;
rl.mRefOffset = target->mIns[0].mAddress;
mRelocations.Push(rl);
PutWord(0);
return 3;
}
#if JUMP_TO_BRANCH
else if (offset >= -126 && offset <= 129)
{
@ -5113,6 +5128,10 @@ int NativeCodeBasicBlock::JumpByteSize(NativeCodeBasicBlock* target, int offset)
else
return 1;
}
else if (target->mIns.Size() == 2 && target->mIns[0].IsSimpleJSR() && target->mIns[1].mType == ASMIT_RTS)
{
return 3;
}
#if JUMP_TO_BRANCH
else if (offset >= -126 && offset <= 129)
{
@ -6636,7 +6655,6 @@ bool NativeCodeBasicBlock::LoadLoadOpStoreIndirectValue(InterCodeProcedure* proc
}
else if (rins0->mSrc[0].mMemory == IM_INDIRECT && wins->mSrc[1].mMemory == IM_INDIRECT && rins1->mSrc[0].mMemory == IM_FPARAM)
{
printf("OOpsie0\n");
return false;
}
#endif
@ -13380,7 +13398,7 @@ void NativeCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, NativeCodePro
simple = false;
if (dins.mType == ASMIT_JSR)
{
dins.mFlags |= uflags;
dins.mFlags |= uflags | NCIF_JSRFLAGS;
}
if (dins.mType == ASMIT_BRK || dins.mMode == ASMIM_INDIRECT_X || dins.mMode == ASMIM_INDIRECT ||
@ -18503,6 +18521,42 @@ bool NativeCodeBasicBlock::CrossBlockStoreLoadBypass(NativeCodeProcedure* proc)
return changed;
}
bool NativeCodeBasicBlock::SimpleInlineCalls(void)
{
bool changed = false;
if (!mVisited)
{
mVisited = true;
for (int i = 0; i < mIns.Size(); i++)
{
if (mIns[i].mType == ASMIT_JSR)
{
if (mIns[i].mLinkerObject && mIns[i].mLinkerObject->mNativeProc)
{
NativeCodeProcedure* proc = mIns[i].mLinkerObject->mNativeProc;
if (proc->mSimpleInline)
{
NativeCodeBasicBlock* sins = proc->mEntryBlock->mTrueJump;
mIns.Remove(i);
for(int j=0; j<sins->mIns.Size(); j++)
mIns.Insert(i + j, sins->mIns[j]);
changed = true;
}
}
}
}
if (mTrueJump && mTrueJump->SimpleInlineCalls())
changed = true;
if (mFalseJump && mFalseJump->SimpleInlineCalls())
changed = true;
}
return changed;
}
bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
{
bool changed = false;
@ -22528,6 +22582,8 @@ void NativeCodeBasicBlock::MarkLiveBlockChain(int index, NativeCodeBasicBlock* b
bool NativeCodeBasicBlock::CanJoinEntryLoadStoreZP(int saddr, int daddr)
{
mChecked = true;
// Avoid moving code into loops
if (mLoopHead && (mTrueJump == this || mFalseJump == this))
return false;
@ -22551,11 +22607,26 @@ bool NativeCodeBasicBlock::CanJoinEntryLoadStoreZP(int saddr, int daddr)
at--;
}
if (!mLoopHead && mEntryBlocks.Size() > 0 && daddr >= BC_REG_FPARAMS && daddr < BC_REG_FPARAMS_END)
{
for (int i = 0; i < mEntryBlocks.Size(); i++)
{
if (!mEntryBlocks[i]->CanJoinEntryLoadStoreZP(saddr, daddr))
return false;
}
return true;
}
return false;
}
bool NativeCodeBasicBlock::DoJoinEntryLoadStoreZP(int saddr, int daddr)
{
if (!mChecked)
return true;
mChecked = false;
int at = mIns.Size() - 1;
while (at >= 0)
{
@ -22566,24 +22637,40 @@ bool NativeCodeBasicBlock::DoJoinEntryLoadStoreZP(int saddr, int daddr)
{
ins.mLive |= LIVE_CPU_REG_A;
mIns.Insert(at + 1, NativeCodeInstruction(ins.mIns, ASMIT_STA, ASMIM_ZERO_PAGE, daddr));
mExitRequiredRegs += daddr;
return true;
}
else if (ins.mType == ASMIT_STX)
{
ins.mLive |= LIVE_CPU_REG_X;
mIns.Insert(at + 1, NativeCodeInstruction(ins.mIns, ASMIT_STX, ASMIM_ZERO_PAGE, daddr));
mExitRequiredRegs += daddr;
return true;
}
else if (ins.mType == ASMIT_STY)
{
ins.mLive |= LIVE_CPU_REG_Y;
mIns.Insert(at + 1, NativeCodeInstruction(ins.mIns, ASMIT_STY, ASMIM_ZERO_PAGE, daddr));
mExitRequiredRegs += daddr;
return true;
}
}
at--;
}
if (!mLoopHead)
{
for (int i = 0; i < mEntryBlocks.Size(); i++)
{
if (!mEntryBlocks[i]->DoJoinEntryLoadStoreZP(saddr, daddr))
return false;
}
mEntryRequiredRegs += daddr;
mExitRequiredRegs += daddr;
return true;
}
return false;
}
@ -22597,7 +22684,7 @@ bool NativeCodeBasicBlock::JoinEntryLoadStoreZP(void)
CheckLive();
if (!mEntryRequiredRegs[CPU_REG_A] || !mEntryRequiredRegs[CPU_REG_X])
if (!mLoopHead && mEntryBlocks.Size() < 64 && (!mEntryRequiredRegs[CPU_REG_A] || !mEntryRequiredRegs[CPU_REG_X]))
{
for (int i = 0; i + 1 < mIns.Size(); i++)
{
@ -22608,10 +22695,14 @@ bool NativeCodeBasicBlock::JoinEntryLoadStoreZP(void)
if (!ReferencesZeroPage(saddr, 0, i) && !ReferencesZeroPage(daddr, 0, i))
{
int n = 0;
uint64 mask = 0;
for (int j = 0; j < mEntryBlocks.Size(); j++)
{
if (mEntryBlocks[j]->CanJoinEntryLoadStoreZP(saddr, daddr))
{
mask |= 1ull << j;
n++;
}
}
if (n == mEntryBlocks.Size())
@ -22630,16 +22721,16 @@ bool NativeCodeBasicBlock::JoinEntryLoadStoreZP(void)
{
NativeCodeBasicBlock* xblock = mProc->AllocateBlock();
int j = 0;
while (j < mEntryBlocks.Size())
int j = mEntryBlocks.Size();
while (j > 0)
{
j--;
NativeCodeBasicBlock* eb = mEntryBlocks[j];
if (eb->CanJoinEntryLoadStoreZP(saddr, daddr))
if (mask & (1ull << j))
{
eb->DoJoinEntryLoadStoreZP(saddr, daddr);
eb->mExitRequiredRegs += daddr;
j++;
}
else
{
@ -25229,6 +25320,57 @@ bool NativeCodeBasicBlock::CrossBlockXYPreservation(void)
return changed;
}
bool NativeCodeBasicBlock::EliminateMicroBlocks(void)
{
bool changed = false;
if (!mVisited)
{
mVisited = true;
if (mIns.Size() > 0 && mIns.Size() <= 2 && mTrueJump && !mFalseJump)
{
if (mIns[0].mType == ASMIT_STA && !(mIns[0].mLive & LIVE_CPU_REG_A))
{
for (int i = 0; i < mEntryBlocks.Size(); i++)
{
NativeCodeBasicBlock* block = mEntryBlocks[i];
int sz = block->mIns.Size();
if (sz > 0 && !block->mFalseJump)
{
if (block->mIns[sz - 1].mType == ASMIT_TYA && HasAsmInstructionMode(ASMIT_STY, mIns[0].mMode))
{
block->mIns[sz - 1] = NativeCodeInstruction(mIns[0].mIns, ASMIT_STY, mIns[0]);
if (mIns.Size() > 1)
block->mIns.Push(mIns[1]);
block->mTrueJump->RemEntryBlock(block);
mTrueJump->AddEntryBlock(block);
block->mTrueJump = mTrueJump;
changed = true;
}
else if (block->mIns[sz - 1].mType == ASMIT_TXA && HasAsmInstructionMode(ASMIT_STX, mIns[0].mMode))
{
block->mIns[sz - 1] = NativeCodeInstruction(mIns[0].mIns, ASMIT_STX, mIns[0]);
if (mIns.Size() > 1)
block->mIns.Push(mIns[1]);
block->mTrueJump->RemEntryBlock(block);
mTrueJump->AddEntryBlock(block);
block->mTrueJump = mTrueJump;
changed = true;
}
}
}
}
}
if (mTrueJump && mTrueJump->EliminateMicroBlocks())
changed = true;
if (mFalseJump && mFalseJump->EliminateMicroBlocks())
changed = true;
}
return changed;
}
bool NativeCodeBasicBlock::FoldLoopEntry(void)
{
bool changed = false;
@ -34467,6 +34609,23 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
return true;
}
if (sz >= 2 && mIns[0].mType == ASMIT_LDA && mIns[sz - 1].mType == ASMIT_LDA && mIns[0].SameEffectiveAddress(mIns[sz - 1]))
{
if (!prevBlock)
return OptimizeSimpleLoopInvariant(proc, full);
prevBlock->mIns.Push(mIns[0]);
mIns.Remove(0);
mEntryRequiredRegs += CPU_REG_A;
mExitRequiredRegs += CPU_REG_A;
prevBlock->mExitRequiredRegs += CPU_REG_A;
CheckLive();
return true;
}
if (sz >= 3 && mIns[0].mType == ASMIT_LDY && mIns[sz - 2].mType == ASMIT_LDA && mIns[0].SameEffectiveAddress(mIns[sz - 2]) &&
mIns[sz - 1].mType == ASMIT_CMP && HasAsmInstructionMode(ASMIT_CPY, mIns[sz - 1].mMode) && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A))
{
@ -35005,6 +35164,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
mEntryRequiredRegs += CPU_REG_X;
mExitRequiredRegs += CPU_REG_X;
prevBlock->mExitRequiredRegs += CPU_REG_X;
CheckLive();
@ -36902,7 +37062,11 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc, bool f
#if 1
assert(mBranch != ASMIT_JMP || mFalseJump == nullptr);
if (!changed)
{
CheckLive();
changed = OptimizeSimpleLoopInvariant(proc, nullptr, nullptr, full);
CheckLive();
}
assert(mBranch != ASMIT_JMP || mFalseJump == nullptr);
#endif
}
@ -41694,7 +41858,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
}
else if (
mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_IMMEDIATE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ABSOLUTE_X) &&
mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_IMMEDIATE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ABSOLUTE_X || mIns[i + 0].mMode == ASMIM_IMMEDIATE_ADDRESS) &&
mIns[i + 1].mType == ASMIT_TAY && !(mIns[i + 1].mLive & LIVE_CPU_REG_A))
{
mIns[i + 0].mType = ASMIT_LDY; mIns[i + 0].mLive |= mIns[i + 1].mLive;
@ -41703,7 +41867,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_IMMEDIATE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ABSOLUTE_Y) &&
mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_IMMEDIATE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ABSOLUTE_Y || mIns[i + 0].mMode == ASMIM_IMMEDIATE_ADDRESS) &&
mIns[i + 1].mType == ASMIT_TAX && !(mIns[i + 1].mLive & LIVE_CPU_REG_A))
{
mIns[i + 0].mType = ASMIT_LDX; mIns[i + 0].mLive |= mIns[i + 1].mLive;
@ -45325,6 +45489,25 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 1].mType == ASMIT_ASL && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress != mIns[i + 0].mAddress &&
mIns[i + 2].mType == ASMIT_ROL && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress != mIns[i + 0].mAddress &&
mIns[i + 3].mType == ASMIT_ROL && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress != mIns[i + 0].mAddress &&
mIns[i + 4].mType == ASMIT_ROL && mIns[i + 4].mMode == ASMIM_ZERO_PAGE && mIns[i + 4].mAddress == mIns[i + 0].mAddress &&
!(mIns[i + 4].mLive & LIVE_CPU_REG_A))
{
mIns.Insert(i + 5, mIns[i + 0]);
mIns.Remove(i);
mIns[i + 0].mLive |= LIVE_CPU_REG_A;
mIns[i + 1].mLive |= LIVE_CPU_REG_A;
mIns[i + 2].mLive |= LIVE_CPU_REG_A;
mIns[i + 3].mLive |= LIVE_CPU_REG_A;
mIns[i + 3].mMode = ASMIM_IMPLIED;
mIns[i + 4].mLive |= mIns[i + 3].mLive;
progress = true;
}
#if 0
else if (
@ -47857,7 +48040,7 @@ NativeCodeBasicBlock::~NativeCodeBasicBlock(void)
}
NativeCodeProcedure::NativeCodeProcedure(NativeCodeGenerator* generator)
: mGenerator(generator)
: mGenerator(generator), mSimpleInline(false)
{
mTempBlocks = 1000;
}
@ -48064,8 +48247,9 @@ void NativeCodeProcedure::LoadTempsFromStack(int tempSave)
void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{
mInterProc = proc;
mInterProc->mLinkerObject->mNativeProc = this;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "buildRamTiles");
CheckFunc = !strcmp(mInterProc->mIdent->mString, "longor");
int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks];
@ -48515,6 +48699,83 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
proc->mLinkerObject->mType = LOT_NATIVE_CODE;
if (!mInterProc->mNoInline)
{
if (mEntryBlock->mIns.Size() == 0 && mExitBlock->mIns.Size() == 1 && !mEntryBlock->mTrueJump->mFalseJump && mEntryBlock->mTrueJump->mTrueJump == mExitBlock)
{
NativeCodeBasicBlock* block = mEntryBlock->mTrueJump;
int sz = block->mIns.Size();
if (sz < 20)
{
int cost = -6;
for (int i = 0; i < sz; i++)
{
const NativeCodeInstruction& ins(block->mIns[i]);
switch (ins.mType)
{
case ASMIT_LDA:
case ASMIT_LDX:
case ASMIT_LDY:
if (ins.mMode == ASMIM_ZERO_PAGE && ins.mAddress >= BC_REG_FPARAMS && ins.mAddress < BC_REG_FPARAMS_END)
cost -= 2;
else
cost += AsmInsSize(ins.mType, ins.mMode);
break;
case ASMIT_STA:
case ASMIT_STX:
case ASMIT_STY:
if (ins.mMode == ASMIM_ZERO_PAGE && ins.mAddress >= BC_REG_ACCU && ins.mAddress < BC_REG_ACCU + 4)
cost -= 2;
else
cost += AsmInsSize(ins.mType, ins.mMode);
break;
case ASMIT_JSR:
if (ins.mLinkerObject && (ins.mLinkerObject->mFlags & LOBJF_INLINE))
cost += 1000;
else
cost += 3;
break;
case ASMIT_TAX:
case ASMIT_TXA:
case ASMIT_TAY:
case ASMIT_TYA:
case ASMIT_ASL:
case ASMIT_LSR:
case ASMIT_ROL:
case ASMIT_ROR:
case ASMIT_CLC:
case ASMIT_SEC:
case ASMIT_INX:
case ASMIT_INY:
case ASMIT_DEX:
case ASMIT_DEY:
case ASMIT_ADC:
case ASMIT_SBC:
case ASMIT_AND:
case ASMIT_ORA:
case ASMIT_EOR:
case ASMIT_BIT:
case ASMIT_CMP:
case ASMIT_CPX:
case ASMIT_CPY:
cost += AsmInsSize(ins.mType, ins.mMode);
break;
default:
cost += 1000;
break;
}
}
if (cost <= 0)
{
mSimpleInline = true;
}
}
}
}
if (mInterProc->mCompilerOptions & COPT_OPTIMIZE_MERGE_CALLS)
{
ResetVisited();
@ -48524,7 +48785,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
void NativeCodeProcedure::Assemble(void)
{
CheckFunc = !strcmp(mInterProc->mIdent->mString, "mh_size");
CheckFunc = !strcmp(mInterProc->mIdent->mString, "longor");
if (mInterProc->mCompilerOptions & COPT_OPTIMIZE_MERGE_CALLS)
{
@ -49569,6 +49830,16 @@ void NativeCodeProcedure::Optimize(void)
}
#endif
if (step == 15)
{
if (mInterProc->mCompilerOptions & COPT_OPTIMIZE_INLINE)
{
ResetVisited();
if (mEntryBlock->SimpleInlineCalls())
changed = true;
}
}
#if _DEBUG
ResetVisited();
mEntryBlock->CheckAsmCode();
@ -49577,7 +49848,7 @@ void NativeCodeProcedure::Optimize(void)
#if 1
if (cnt > 190)
{
printf("Oops\n");
printf("Oops %d\n", step);
}
#endif
@ -49588,7 +49859,7 @@ void NativeCodeProcedure::Optimize(void)
}
#if 1
if (!changed && step < 14)
if (!changed && step < 15)
{
ResetIndexFlipped();
@ -49617,6 +49888,18 @@ void NativeCodeProcedure::Optimize(void)
CompressTemporaries(true);
#endif
do {
ResetVisited();
NativeRegisterDataSet data;
mEntryBlock->BuildEntryDataSet(data);
ResetVisited();
} while (mEntryBlock->ExpandADCToBranch(this));
do {
ResetVisited();
} while (mEntryBlock->EliminateMicroBlocks());
#if 1
do
{

View File

@ -631,6 +631,8 @@ public:
bool RemoveDoubleZPStore(void);
bool ExpandADCToBranch(NativeCodeProcedure* proc);
bool SimpleInlineCalls(void);
bool Split16BitLoopCount(NativeCodeProcedure* proc);
bool SimplifyDiamond(NativeCodeProcedure* proc);
bool SimplifyLoopEnd(NativeCodeProcedure* proc);
@ -663,6 +665,7 @@ public:
bool CrossBlockXYPreservation(void);
bool CrossBlockIncToZeroShortcut(void);
bool EliminateMicroBlocks(void);
bool AlternateXYUsage(void);
bool OptimizeXYPairUsage(void);
@ -773,7 +776,7 @@ class NativeCodeProcedure
int mProgStart, mProgSize, mIndex, mFrameOffset, mStackExpand;
int mFastCallBase;
bool mNoFrame;
bool mNoFrame, mSimpleInline;
int mTempBlocks;
ExpandingArray<LinkerReference> mRelocations;