Optimize parameter handling in loops

This commit is contained in:
drmortalwombat 2022-06-18 17:32:14 +02:00
parent e7332192c0
commit fc7bb2c377
6 changed files with 473 additions and 139 deletions

View File

@ -5,7 +5,7 @@ bool joyb[2];
void joy_poll(char n) void joy_poll(char n)
{ {
char b = ((char *)0xdc00)[n]; char b = ((volatile char *)0xdc00)[n];
if (!(b & 1)) if (!(b & 1))
joyy[n] = -1; joyy[n] = -1;

View File

@ -380,6 +380,8 @@ static bool CollidingMem(const InterOperand& op1, const InterOperand& op2, const
{ {
if (op2.mMemory == IM_GLOBAL) if (op2.mMemory == IM_GLOBAL)
return staticVars[op2.mVarIndex]->mAliased; return staticVars[op2.mVarIndex]->mAliased;
else if (op2.mMemory == IM_FPARAM)
return false;
else else
return true; return true;
} }
@ -387,6 +389,8 @@ static bool CollidingMem(const InterOperand& op1, const InterOperand& op2, const
{ {
if (op1.mMemory == IM_GLOBAL) if (op1.mMemory == IM_GLOBAL)
return staticVars[op1.mVarIndex]->mAliased; return staticVars[op1.mVarIndex]->mAliased;
else if (op1.mMemory == IM_FPARAM)
return false;
else else
return true; return true;
} }
@ -1204,6 +1208,11 @@ void TempForwardingTable::Intersect(const TempForwardingTable& table)
} }
} }
int TempForwardingTable::Size(void) const
{
return mAssoc.Size();
}
void TempForwardingTable::SetSize(int size) void TempForwardingTable::SetSize(int size)
{ {
int i; int i;
@ -2767,6 +2776,15 @@ bool InterInstruction::RemoveUnusedResultInstructions(InterInstruction* pre, Num
changed = true; changed = true;
} }
else if (mCode == IC_LOAD_TEMPORARY && mDst.mTemp == mSrc[0].mTemp)
{
mCode = IC_NONE;
mDst.mTemp = -1;
for (int i = 0; i < mNumOperands; i++)
mSrc[i].mTemp = -1;
changed = true;
}
else if (mDst.mTemp != -1) else if (mDst.mTemp != -1)
{ {
if (!requiredTemps[mDst.mTemp] && mDst.mTemp >= 0) if (!requiredTemps[mDst.mTemp] && mDst.mTemp >= 0)
@ -2793,15 +2811,6 @@ bool InterInstruction::RemoveUnusedResultInstructions(InterInstruction* pre, Num
else else
requiredTemps -= mDst.mTemp; requiredTemps -= mDst.mTemp;
} }
else if (mCode == IC_LOAD_TEMPORARY && mDst.mTemp == mSrc[0].mTemp)
{
mCode = IC_NONE;
mDst.mTemp = -1;
for (int i = 0; i < mNumOperands; i++)
mSrc[i].mTemp = -1;
changed = true;
}
for (int i = 0; i < mNumOperands; i++) for (int i = 0; i < mNumOperands; i++)
{ {
@ -3710,7 +3719,7 @@ static bool IsInfiniteLoop(InterCodeBasicBlock* head, InterCodeBasicBlock* block
return false; return false;
} }
void InterCodeBasicBlock::GenerateTraces(bool expand) void InterCodeBasicBlock::GenerateTraces(bool expand, bool compact)
{ {
int i; int i;
@ -3760,12 +3769,31 @@ void InterCodeBasicBlock::GenerateTraces(bool expand)
mFalseJump->mNumEntries++; mFalseJump->mNumEntries++;
} }
} }
#if 1
else if (compact && mTrueJump && !mFalseJump && mTrueJump->mInstructions.Size() == 1 && mTrueJump->mInstructions[0]->mCode == IC_BRANCH && mTrueJump->mFalseJump)
{
InterCodeBasicBlock* tj = mTrueJump;
int ns = mInstructions.Size();
tj->mNumEntries--;
tj->mTrueJump->mNumEntries++;
tj->mFalseJump->mNumEntries++;
mInstructions[ns - 1]->mCode = IC_BRANCH;
mInstructions[ns - 1]->mOperator = tj->mInstructions[0]->mOperator;
mInstructions[ns - 1]->mSrc[0].Forward(tj->mInstructions[0]->mSrc[0]);
mTrueJump = tj->mTrueJump;
mFalseJump = tj->mFalseJump;
}
#endif
else else
break; break;
} }
if (mTrueJump) mTrueJump->GenerateTraces(expand); if (mTrueJump) mTrueJump->GenerateTraces(expand, compact);
if (mFalseJump) mFalseJump->GenerateTraces(expand); if (mFalseJump) mFalseJump->GenerateTraces(expand, compact);
mInPath = false; mInPath = false;
} }
@ -6353,6 +6381,17 @@ void InterCodeBasicBlock::PerformTempForwarding(TempForwardingTable& forwardingT
if (mLoopHead) if (mLoopHead)
{ {
if (mNumEntries == 2 && (mTrueJump == this || mFalseJump == this) && mLocalModifiedTemps.Size())
{
assert(localForwardingTable.Size() == mLocalModifiedTemps.Size());
for (int i = 0; i < mLocalModifiedTemps.Size(); i++)
{
if (mLocalModifiedTemps[i])
localForwardingTable.Destroy(i);
}
}
else
localForwardingTable.Reset(); localForwardingTable.Reset();
} }
#if 0 #if 0
@ -7550,10 +7589,46 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
int i = 0; int i = 0;
while (i < mLoadStoreInstructions.Size()) while (i < mLoadStoreInstructions.Size())
{ {
if (tvalue.IndexOf(mLoadStoreInstructions[i]) == -1) InterInstruction* ins(mLoadStoreInstructions[i]);
mLoadStoreInstructions.Remove(i); InterInstruction* nins = nullptr;
int j = tvalue.IndexOf(ins);
if (j != -1)
nins = ins;
else else
i++; {
if (ins->mCode == IC_LOAD)
{
j = 0;
while (j < tvalue.Size() && !SameMem(ins->mSrc[0], tvalue[j]))
j++;
if (j < tvalue.Size())
{
if (tvalue[j]->mCode == IC_LOAD && tvalue[j]->mDst.IsEqual(ins->mDst))
nins = ins;
else if (tvalue[j]->mCode == IC_STORE && tvalue[j]->mSrc[0].IsEqual(ins->mDst))
nins = ins;
}
}
else if (ins->mCode == IC_STORE)
{
j = 0;
while (j < tvalue.Size() && !SameMem(ins->mSrc[1], tvalue[j]))
j++;
if (j < tvalue.Size())
{
if (tvalue[j]->mCode == IC_LOAD && tvalue[j]->mDst.IsEqual(ins->mSrc[0]))
nins = tvalue[j];
else if (tvalue[j]->mCode == IC_STORE && tvalue[j]->mSrc[0].IsEqual(ins->mSrc[0]))
nins = ins;
}
}
}
if (nins)
mLoadStoreInstructions[i++] = nins;
else
mLoadStoreInstructions.Remove(i);
} }
} }
@ -8008,7 +8083,9 @@ bool InterCodeBasicBlock::MergeCommonPathInstructions(void)
while (ti < mTrueJump->mInstructions.Size() && !changed) while (ti < mTrueJump->mInstructions.Size() && !changed)
{ {
InterInstruction* tins = mTrueJump->mInstructions[ti]; InterInstruction* tins = mTrueJump->mInstructions[ti];
if (tins->mCode != IC_BRANCH && tins->mCode != IC_JUMP && tins->mCode != IC_RELATIONAL_OPERATOR) InterInstruction* nins = (ti + 1 < mTrueJump->mInstructions.Size()) ? mTrueJump->mInstructions[ti + 1] : nullptr;
if (tins->mCode != IC_BRANCH && tins->mCode != IC_JUMP && !(nins && nins->mCode == IC_BRANCH && tins->mDst.mTemp == nins->mSrc[0].mTemp))
{ {
int fi = 0; int fi = 0;
while (fi < mFalseJump->mInstructions.Size() && !tins->IsEqualSource(mFalseJump->mInstructions[fi])) while (fi < mFalseJump->mInstructions.Size() && !tins->IsEqualSource(mFalseJump->mInstructions[fi]))
@ -8789,6 +8866,50 @@ void InterCodeBasicBlock::FollowJumps(void)
} }
} }
void InterCodeBasicBlock::BuildLoopSuffix(InterCodeProcedure* proc)
{
if (!mVisited)
{
mVisited = true;
if (mLoopHead && mNumEntries == 2 && mFalseJump)
{
if (mTrueJump == this && mFalseJump != this)
{
if (mFalseJump->mNumEntries > 1)
{
InterCodeBasicBlock* suffix = new InterCodeBasicBlock();
proc->Append(suffix);
InterInstruction* jins = new InterInstruction();
jins->mCode = IC_JUMP;
suffix->Append(jins);
suffix->Close(mFalseJump, nullptr);
mFalseJump = suffix;
suffix->mNumEntries = 1;
}
}
else if (mFalseJump == this && mTrueJump != this)
{
if (mTrueJump->mNumEntries > 1)
{
InterCodeBasicBlock* suffix = new InterCodeBasicBlock();
proc->Append(suffix);
InterInstruction* jins = new InterInstruction();
jins->mCode = IC_JUMP;
suffix->Append(jins);
suffix->Close(mTrueJump, nullptr);
mTrueJump = suffix;
suffix->mNumEntries = 1;
}
}
}
if (mTrueJump)
mTrueJump->BuildLoopSuffix(proc);
if (mFalseJump)
mFalseJump->BuildLoopSuffix(proc);
}
}
InterCodeBasicBlock* InterCodeBasicBlock::BuildLoopPrefix(InterCodeProcedure* proc) InterCodeBasicBlock* InterCodeBasicBlock::BuildLoopPrefix(InterCodeProcedure* proc)
{ {
@ -8809,40 +8930,6 @@ InterCodeBasicBlock* InterCodeBasicBlock::BuildLoopPrefix(InterCodeProcedure* pr
jins->mCode = IC_JUMP; jins->mCode = IC_JUMP;
mLoopPrefix->Append(jins); mLoopPrefix->Append(jins);
mLoopPrefix->Close(this, nullptr); mLoopPrefix->Close(this, nullptr);
if (mNumEntries == 2 && mFalseJump)
{
if (mTrueJump == this && mFalseJump != this)
{
if (mFalseJump->mNumEntries > 1)
{
InterCodeBasicBlock* suffix = new InterCodeBasicBlock();
proc->Append(suffix);
InterInstruction* jins = new InterInstruction();
jins->mCode = IC_JUMP;
suffix->Append(jins);
suffix->Close(mFalseJump, nullptr);
mFalseJump->mNumEntries--;
mFalseJump = suffix;
suffix->mNumEntries = 1;
}
}
else if (mFalseJump == this && mTrueJump != this)
{
if (mTrueJump->mNumEntries > 1)
{
InterCodeBasicBlock* suffix = new InterCodeBasicBlock();
proc->Append(suffix);
InterInstruction* jins = new InterInstruction();
jins->mCode = IC_JUMP;
suffix->Append(jins);
suffix->Close(mTrueJump, nullptr);
mTrueJump->mNumEntries--;
mTrueJump = suffix;
suffix->mNumEntries = 1;
}
}
}
} }
} }
@ -9276,6 +9363,8 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
#if 1 #if 1
if (!hasCall) if (!hasCall)
{ {
assert(this == mTrueJump && mFalseJump->mNumEntries == 1 || this == mFalseJump && mTrueJump->mNumEntries == 1);
// Check forwarding globals // Check forwarding globals
int i = 0; int i = 0;
@ -9284,7 +9373,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
InterInstruction* ins = mInstructions[i]; InterInstruction* ins = mInstructions[i];
// A global load // A global load
if (ins->mCode == IC_LOAD && ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mMemory == IM_GLOBAL) if (ins->mCode == IC_LOAD && ins->mSrc[0].mTemp < 0 && (ins->mSrc[0].mMemory == IM_GLOBAL || ins->mSrc[0].mMemory == IM_FPARAM))
{ {
// Find the last store that overlaps the load // Find the last store that overlaps the load
int j = mInstructions.Size() - 1; int j = mInstructions.Size() - 1;
@ -9312,6 +9401,8 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
k++; k++;
if (k == mInstructions.Size()) if (k == mInstructions.Size())
{ {
assert(!mEntryRequiredTemps[sins->mSrc[0].mTemp]);
// Move load before loop // Move load before loop
mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ins); mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ins);
InterInstruction* nins = new InterInstruction(); InterInstruction* nins = new InterInstruction();
@ -9760,13 +9851,13 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
mInstructions.SetSize(j); mInstructions.SetSize(j);
NumberSet requiredTemps(mTrueJump == this ? mFalseJump->mExitRequiredTemps : mTrueJump->mExitRequiredTemps); NumberSet requiredTemps(mTrueJump == this ? mFalseJump->mEntryRequiredTemps : mTrueJump->mEntryRequiredTemps);
for (int i = 0; i < mInstructions.Size(); i++) for (int i = 0; i < mInstructions.Size(); i++)
{ {
InterInstruction* ins = mInstructions[i]; InterInstruction* ins = mInstructions[i];
for(int j=0; j<ins->mNumOperands; j++) for(int j=0; j<ins->mNumOperands; j++)
if (ins->mSrc[j].mTemp >= 0) if (ins->mSrc[j].mTemp >= 0 && ins->mDst.mTemp != ins->mSrc[j].mTemp)
requiredTemps += ins->mSrc[j].mTemp; requiredTemps += ins->mSrc[j].mTemp;
} }
@ -9787,6 +9878,16 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
di++; di++;
} }
} }
int i = 0;
while (i < mInstructions.Size())
{
InterInstruction* ins = mInstructions[i];
if (!HasSideEffect(ins->mCode) && !ins->mVolatile && ins->mDst.mTemp >= 0 && !requiredTemps[ins->mDst.mTemp])
mInstructions.Remove(i);
else
i++;
}
} }
if (mTrueJump) if (mTrueJump)
@ -10103,7 +10204,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
} }
#endif #endif
bool changed; bool changed = false;
do do
{ {
int j = 0; int j = 0;
@ -10272,6 +10373,28 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
changed = true; changed = true;
} }
#endif #endif
#if 1
else if (
mInstructions[i + 0]->mCode == IC_LOAD_TEMPORARY &&
mInstructions[i + 1]->mCode == IC_LEA && mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[0].mFinal
)
{
mInstructions[i + 1]->mSrc[0].Forward(mInstructions[i + 0]->mSrc[0]);
mInstructions[i + 0]->mCode = IC_NONE; mInstructions[i + 0]->mNumOperands = 0;
changed = true;
}
#endif
#if 1
else if (
mInstructions[i + 0]->mCode == IC_LOAD_TEMPORARY &&
mInstructions[i + 1]->mCode == IC_LOAD && mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[0].mFinal
)
{
mInstructions[i + 1]->mSrc[0].Forward(mInstructions[i + 0]->mSrc[0]);
mInstructions[i + 0]->mCode = IC_NONE; mInstructions[i + 0]->mNumOperands = 0;
changed = true;
}
#endif
#if 1 #if 1
else if ( else if (
mInstructions[i + 1]->mCode == IC_LOAD_TEMPORARY && mExitRequiredTemps[mInstructions[i + 1]->mDst.mTemp] && mInstructions[i + 1]->mCode == IC_LOAD_TEMPORARY && mExitRequiredTemps[mInstructions[i + 1]->mDst.mTemp] &&
@ -10409,6 +10532,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
changed = true; changed = true;
} }
#endif #endif
#if 1 #if 1
// Postincrement artifact // Postincrement artifact
if (mInstructions[i + 0]->mCode == IC_LOAD_TEMPORARY && mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && if (mInstructions[i + 0]->mCode == IC_LOAD_TEMPORARY && mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR &&
@ -10435,6 +10559,30 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
#endif #endif
} }
#if 1
if (i + 1 < mInstructions.Size())
{
if (
mInstructions[i + 0]->mCode == IC_LOAD_TEMPORARY &&
mInstructions[i + 1]->mCode == IC_RELATIONAL_OPERATOR && mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i + 0]->mSrc[0].mTemp && mInstructions[i + 1]->mSrc[0].mFinal
)
{
mInstructions[i + 1]->mSrc[0].mTemp = mInstructions[i + 0]->mDst.mTemp;
mInstructions[i + 1]->mSrc[0].mFinal = false;
changed = true;
}
else if (
mInstructions[i + 0]->mCode == IC_LOAD_TEMPORARY &&
mInstructions[i + 1]->mCode == IC_RELATIONAL_OPERATOR && mInstructions[i + 1]->mSrc[1].mTemp == mInstructions[i + 0]->mSrc[0].mTemp && mInstructions[i + 1]->mSrc[1].mFinal
)
{
mInstructions[i + 1]->mSrc[1].mTemp = mInstructions[i + 0]->mDst.mTemp;
mInstructions[i + 1]->mSrc[1].mFinal = false;
changed = true;
}
}
#endif
} }
} while (changed); } while (changed);
@ -10772,7 +10920,7 @@ void InterCodeProcedure::DisassembleDebug(const char* name)
Disassemble(name); Disassemble(name);
} }
void InterCodeProcedure::BuildTraces(bool expand, bool dominators) void InterCodeProcedure::BuildTraces(bool expand, bool dominators, bool compact)
{ {
// Count number of entries // Count number of entries
// //
@ -10788,7 +10936,7 @@ void InterCodeProcedure::BuildTraces(bool expand, bool dominators)
// Build traces // Build traces
// //
ResetVisited(); ResetVisited();
mEntryBlock->GenerateTraces(expand); mEntryBlock->GenerateTraces(expand, compact);
ResetVisited(); ResetVisited();
for (int i = 0; i < mBlocks.Size(); i++) for (int i = 0; i < mBlocks.Size(); i++)
@ -10827,6 +10975,9 @@ void InterCodeProcedure::BuildDataFlowSets(void)
do { do {
ResetVisited(); ResetVisited();
} while (mEntryBlock->BuildGlobalRequiredTempSet(totalRequired)); } while (mEntryBlock->BuildGlobalRequiredTempSet(totalRequired));
ResetVisited();
mEntryBlock->CollectLocalUsedTemps(numTemps);
} }
void InterCodeProcedure::RenameTemporaries(void) void InterCodeProcedure::RenameTemporaries(void)
@ -11075,6 +11226,8 @@ void InterCodeProcedure::Close(void)
RenameTemporaries(); RenameTemporaries();
BuildDataFlowSets();
TempForwarding(); TempForwarding();
int numTemps = mTemporaries.Size(); int numTemps = mTemporaries.Size();
@ -11130,6 +11283,9 @@ void InterCodeProcedure::Close(void)
} }
mTemporaries.SetSize(numTemps, true); mTemporaries.SetSize(numTemps, true);
BuildDataFlowSets();
TempForwarding(); TempForwarding();
retries--; retries--;
@ -11225,6 +11381,8 @@ void InterCodeProcedure::Close(void)
RenameTemporaries(); RenameTemporaries();
do { do {
BuildDataFlowSets();
TempForwarding(); TempForwarding();
} while (GlobalConstantPropagation()); } while (GlobalConstantPropagation());
@ -11240,9 +11398,6 @@ void InterCodeProcedure::Close(void)
} }
BuildLoopPrefix();
DisassembleDebug("added dominators");
ResetVisited(); ResetVisited();
mEntryBlock->CompactInstructions(); mEntryBlock->CompactInstructions();
@ -11266,6 +11421,9 @@ void InterCodeProcedure::Close(void)
DisassembleDebug("Peephole optimized"); DisassembleDebug("Peephole optimized");
BuildLoopPrefix();
DisassembleDebug("added dominators");
BuildDataFlowSets(); BuildDataFlowSets();
TempForwarding(); TempForwarding();
@ -11307,9 +11465,6 @@ void InterCodeProcedure::Close(void)
{ {
BuildDataFlowSets(); BuildDataFlowSets();
ResetVisited();
mEntryBlock->CollectLocalUsedTemps(mTemporaries.Size());
ResetVisited(); ResetVisited();
changed = mEntryBlock->PushSinglePathResultInstructions(); changed = mEntryBlock->PushSinglePathResultInstructions();
@ -11343,6 +11498,8 @@ void InterCodeProcedure::Close(void)
ResetVisited(); ResetVisited();
changed = mEntryBlock->MergeCommonPathInstructions(); changed = mEntryBlock->MergeCommonPathInstructions();
DisassembleDebug("Merged common path part");
if (changed) if (changed)
{ {
TempForwarding(); TempForwarding();
@ -11536,9 +11693,6 @@ void InterCodeProcedure::Close(void)
BuildDataFlowSets(); BuildDataFlowSets();
ResetVisited();
mEntryBlock->CollectLocalUsedTemps(mTemporaries.Size());
ResetVisited(); ResetVisited();
mEntryBlock->ForwardDiamondMovedTemp(); mEntryBlock->ForwardDiamondMovedTemp();
DisassembleDebug("Diamond move forwarding"); DisassembleDebug("Diamond move forwarding");
@ -11662,9 +11816,6 @@ void InterCodeProcedure::Close(void)
#if 1 #if 1
BuildDataFlowSets(); BuildDataFlowSets();
ResetVisited();
mEntryBlock->CollectLocalUsedTemps(mTemporaries.Size());
ResetVisited(); ResetVisited();
mEntryBlock->ForwardDiamondMovedTemp(); mEntryBlock->ForwardDiamondMovedTemp();
DisassembleDebug("Diamond move forwarding 2"); DisassembleDebug("Diamond move forwarding 2");
@ -11711,10 +11862,109 @@ void InterCodeProcedure::Close(void)
TempForwarding(); TempForwarding();
RemoveUnusedInstructions(); RemoveUnusedInstructions();
DisassembleDebug("Peephole optimized"); DisassembleDebug("Global Constant Prop 1");
#endif #endif
#if 1
for (int i = 0; i < 4; i++)
{
ResetVisited();
mEntryBlock->PeepholeOptimization(mModule->mGlobalVars);
DisassembleDebug("Peephole Temp Check");
ReduceTemporaries();
MergeBasicBlocks();
BuildDataFlowSets();
TempForwarding();
BuildLoopPrefix();
BuildDataFlowSets();
DisassembleDebug("Checking Unused");
RemoveUnusedInstructions();
DisassembleDebug("Checked Unused");
BuildDataFlowSets();
RenameTemporaries();
BuildDataFlowSets();
TempForwarding();
#if 1
BuildDataFlowSets();
do {
TempForwarding();
} while (GlobalConstantPropagation());
do {
GrowingInstructionPtrArray gipa(nullptr);
ResetVisited();
changed = mEntryBlock->LoadStoreForwarding(gipa, mModule->mGlobalVars);
DisassembleDebug("Load/Store forwardingX");
RemoveUnusedStoreInstructions(paramMemory);
TempForwarding();
RemoveUnusedInstructions();
DisassembleDebug("Load/Store forwarding");
} while (changed);
do
{
ResetVisited();
mEntryBlock->CompactInstructions();
BuildDataFlowSets();
ResetVisited();
changed = mEntryBlock->MergeCommonPathInstructions();
DisassembleDebug("Merged common path part");
if (changed)
{
TempForwarding();
RemoveUnusedInstructions();
}
} while (changed);
DisassembleDebug("Merged common path instructions");
#if 1
do
{
BuildDataFlowSets();
ResetVisited();
changed = mEntryBlock->PushSinglePathResultInstructions();
DisassembleDebug("Pushed single path result");
} while (changed);
#endif
TempForwarding();
RemoveUnusedInstructions();
#endif
DisassembleDebug("Global Constant Prop 2");
}
#endif
MapVariables(); MapVariables();
DisassembleDebug("mapped variabled"); DisassembleDebug("mapped variabled");
@ -11726,7 +11976,7 @@ void InterCodeProcedure::Close(void)
// Optimize for size // Optimize for size
MergeBasicBlocks(); MergeBasicBlocks();
BuildTraces(false, false); BuildTraces(false, false, true);
DisassembleDebug("Final Merged basic blocks"); DisassembleDebug("Final Merged basic blocks");
if (mSaveTempsLinkerObject && mTempSize > 16) if (mSaveTempsLinkerObject && mTempSize > 16)
@ -12007,6 +12257,9 @@ void InterCodeProcedure::BuildLoopPrefix(void)
for (int i = 0; i < mBlocks.Size(); i++) for (int i = 0; i < mBlocks.Size(); i++)
mBlocks[i]->mNumEntries = 0; mBlocks[i]->mNumEntries = 0;
mEntryBlock->CollectEntries(); mEntryBlock->CollectEntries();
ResetVisited();
mEntryBlock->BuildLoopSuffix(this);
} }
bool InterCodeProcedure::PropagateNonLocalUsedTemps(void) bool InterCodeProcedure::PropagateNonLocalUsedTemps(void)
@ -12123,6 +12376,7 @@ void InterCodeProcedure::ReduceTemporaries(void)
callerSavedTemps = freeCallerSavedTemps; callerSavedTemps = freeCallerSavedTemps;
mTempOffset.SetSize(0); mTempOffset.SetSize(0);
mTempSizes.SetSize(0);
for (int i = 0; i < mTemporaries.Size(); i++) for (int i = 0; i < mTemporaries.Size(); i++)
{ {

View File

@ -212,6 +212,7 @@ public:
void Intersect(const TempForwardingTable& table); void Intersect(const TempForwardingTable& table);
int Size(void) const;
void SetSize(int size); void SetSize(int size);
void Reset(void); void Reset(void);
@ -371,7 +372,7 @@ public:
void CollectEntries(void); void CollectEntries(void);
void CollectEntryBlocks(InterCodeBasicBlock* from); void CollectEntryBlocks(InterCodeBasicBlock* from);
void GenerateTraces(bool expand); void GenerateTraces(bool expand, bool compact);
void BuildDominatorTree(InterCodeBasicBlock * from); void BuildDominatorTree(InterCodeBasicBlock * from);
void LocalToTemp(int vindex, int temp); void LocalToTemp(int vindex, int temp);
@ -472,6 +473,7 @@ public:
void InnerLoopOptimization(const NumberSet& aliasedParams); void InnerLoopOptimization(const NumberSet& aliasedParams);
InterCodeBasicBlock* BuildLoopPrefix(InterCodeProcedure * proc); InterCodeBasicBlock* BuildLoopPrefix(InterCodeProcedure * proc);
void BuildLoopSuffix(InterCodeProcedure* proc);
void SplitBranches(InterCodeProcedure* proc); void SplitBranches(InterCodeProcedure* proc);
void FollowJumps(void); void FollowJumps(void);
@ -543,7 +545,7 @@ public:
void Disassemble(FILE* file); void Disassemble(FILE* file);
void Disassemble(const char* name, bool dumpSets = false); void Disassemble(const char* name, bool dumpSets = false);
protected: protected:
void BuildTraces(bool expand, bool dominators = true); void BuildTraces(bool expand, bool dominators = true, bool compact = false);
void BuildDataFlowSets(void); void BuildDataFlowSets(void);
void RenameTemporaries(void); void RenameTemporaries(void);
void TempForwarding(void); void TempForwarding(void);

View File

@ -5759,7 +5759,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
if (InterTypeSize[ins->mDst.mType] == 1) if (InterTypeSize[ins->mDst.mType] == 1)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
if (ainsl) if (ainsl)
{ {
if (ainsl->mType == ASMIT_ADC) if (ainsl->mType == ASMIT_ADC)
@ -5779,7 +5779,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
else if (InterTypeSize[ins->mDst.mType] == 2) else if (InterTypeSize[ins->mDst.mType] == 2)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
if (ainsl) if (ainsl)
{ {
if (ainsl->mType == ASMIT_ADC) if (ainsl->mType == ASMIT_ADC)
@ -5797,7 +5797,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
if (ainsh) mIns.Push(*ainsh); if (ainsh) mIns.Push(*ainsh);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
if (reg == areg) if (reg == areg)
@ -5812,17 +5812,17 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
else if (InterTypeSize[ins->mDst.mType] == 4) else if (InterTypeSize[ins->mDst.mType] == 4)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 2)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 3)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 3));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3));
} }
} }
@ -13280,6 +13280,7 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
} }
#endif #endif
#if 1
if (mEntryBlocks.Size() == 1) if (mEntryBlocks.Size() == 1)
{ {
NativeCodeBasicBlock* eblock = mEntryBlocks[0]; NativeCodeBasicBlock* eblock = mEntryBlocks[0];
@ -13288,11 +13289,13 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
if (mIns[0].mType == ASMIT_ORA && mIns[0].mMode == ASMIM_IMMEDIATE && mIns[0].mAddress == 0 && eblock->mIns.Last().ChangesAccuAndFlag()) if (mIns[0].mType == ASMIT_ORA && mIns[0].mMode == ASMIM_IMMEDIATE && mIns[0].mAddress == 0 && eblock->mIns.Last().ChangesAccuAndFlag())
{ {
eblock->mExitRequiredRegs += CPU_REG_Z; eblock->mExitRequiredRegs += CPU_REG_Z;
mEntryRequiredRegs += CPU_REG_Z;
mIns.Remove(0); mIns.Remove(0);
changed = true; changed = true;
} }
} }
} }
#endif
#if 1 #if 1
if (loops && mIns.Size() >= 1 && mEntryBlocks.Size() == 2) if (loops && mIns.Size() >= 1 && mEntryBlocks.Size() == 2)
{ {
@ -13837,7 +13840,7 @@ bool NativeCodeBasicBlock::CheckForwardSumYPointer(const NativeCodeBasicBlock* b
{ {
NativeCodeInstruction& ins(mIns[at]); NativeCodeInstruction& ins(mIns[at]);
if (ins.mMode == ASMIM_ZERO_PAGE && (ins.mAddress == reg || ins.mAddress == reg + 1 || ins.mAddress == index)) if (ins.mMode == ASMIM_ZERO_PAGE && (ins.mAddress == reg || ins.mAddress == reg + 1))
return false; return false;
else if (ins.mMode == ASMIM_INDIRECT_Y && ins.mAddress == reg) else if (ins.mMode == ASMIM_INDIRECT_Y && ins.mAddress == reg)
{ {
@ -14786,6 +14789,23 @@ bool NativeCodeBasicBlock::MergeXYSameValue(int from)
return false; return false;
} }
int NativeCodeBasicBlock::RetrieveYValue(int at) const
{
while (at > 0 && !mIns[at].ChangesYReg())
at--;
if (mIns[at].mType == ASMIT_LDY && mIns[at].mMode == ASMIM_IMMEDIATE)
return mIns[at].mAddress;
else
return -1;
}
void NativeCodeBasicBlock::InsertLoadYImmediate(int at, int val)
{
while (at < mIns.Size() && !mIns[at].ReferencesYReg())
at++;
mIns.Insert(at, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, val));
}
bool NativeCodeBasicBlock::PatchGlobalAdressSumYByX(int at, int reg, const NativeCodeInstruction& ains, int addr) bool NativeCodeBasicBlock::PatchGlobalAdressSumYByX(int at, int reg, const NativeCodeInstruction& ains, int addr)
{ {
int yindex = 0; int yindex = 0;
@ -14867,8 +14887,9 @@ bool NativeCodeBasicBlock::PatchDirectAddressSumY(int at, int reg, int apos, int
if (mIns[last].mLive & LIVE_CPU_REG_Y) if (mIns[last].mLive & LIVE_CPU_REG_Y)
{ {
mIns.Insert(last + 1, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, yindex)); InsertLoadYImmediate(last + 1, yindex);
mIns[last + 1].mLive |= CPU_REG_Y; // mIns.Insert(last + 1, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, yindex));
// mIns[last + 1].mLive |= CPU_REG_Y;
} }
mIns[apos].mType = ASMIT_TAY; mIns[apos].mType = ASMIT_TAY;
@ -14934,8 +14955,9 @@ bool NativeCodeBasicBlock::PatchAddressSumY(int at, int reg, int apos, int breg,
if (mIns[last].mLive & LIVE_CPU_REG_Y) if (mIns[last].mLive & LIVE_CPU_REG_Y)
{ {
mIns.Insert(last + 1, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, yindex)); InsertLoadYImmediate(last + 1, yindex);
mIns[last + 1].mLive |= CPU_REG_Y; // mIns.Insert(last + 1, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, yindex));
// mIns[last + 1].mLive |= CPU_REG_Y;
} }
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
@ -15323,9 +15345,9 @@ bool NativeCodeBasicBlock::MoveLoadIndirectTempStoreUp(int at)
mIns[j - 0].mAddress == mIns[at + 1].mAddress + 1 && mIns[j - 0].mAddress == mIns[at + 1].mAddress + 1 &&
mIns[j - 1].mAddress == mIns[j - 3].mAddress + 1) mIns[j - 1].mAddress == mIns[j - 3].mAddress + 1)
{ {
mIns[at + 0].mLive |= mIns[j].mLive;
mIns[at + 1].mLive |= mIns[j].mLive; mIns[at + 1].mLive |= mIns[j].mLive;
mIns[at + 2].mLive |= mIns[j].mLive; mIns[at + 2].mLive |= mIns[j].mLive;
mIns[at + 3].mLive |= mIns[j].mLive;
mIns[at + 1].mAddress = mIns[j - 3].mAddress; mIns[at + 1].mAddress = mIns[j - 3].mAddress;
mIns[at + 1].mLive |= LIVE_MEM; mIns[at + 1].mLive |= LIVE_MEM;
@ -15364,9 +15386,9 @@ bool NativeCodeBasicBlock::MoveLoadIndirectTempStoreUp(int at)
return false; return false;
} }
mIns[at + 0].mLive |= mIns[j].mLive;
mIns[at + 1].mLive |= mIns[j].mLive; mIns[at + 1].mLive |= mIns[j].mLive;
mIns[at + 2].mLive |= mIns[j].mLive; mIns[at + 2].mLive |= mIns[j].mLive;
mIns[at + 3].mLive |= mIns[j].mLive;
mIns[at + 1].mAddress = addr; mIns[at + 1].mAddress = addr;
mIns[at + 1].mLive |= LIVE_MEM; mIns[at + 1].mLive |= LIVE_MEM;
@ -20441,8 +20463,9 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
} }
if (mIns[i + 0].mLive & LIVE_CPU_REG_Y) if (mIns[i + 0].mLive & LIVE_CPU_REG_Y)
{ {
mIns.Insert(i + 1, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); InsertLoadYImmediate(i + 1, 0);
mIns[i + 1].mLive |= LIVE_CPU_REG_Y; // mIns.Insert(i + 1, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
// mIns[i + 1].mLive |= LIVE_CPU_REG_Y;
} }
mIns.Insert(i + 0, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, ireg)); mIns.Insert(i + 0, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, ireg));
mIns[i + 0].mLive |= LIVE_CPU_REG_Y | LIVE_MEM; mIns[i + 0].mLive |= LIVE_CPU_REG_Y | LIVE_MEM;
@ -20464,13 +20487,17 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
{ {
if (mIns[i + 0].mLive & LIVE_CPU_REG_Y) if (mIns[i + 0].mLive & LIVE_CPU_REG_Y)
{ {
mIns.Insert(i + 1, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
mIns[i + 1].mLive |= LIVE_CPU_REG_Y;
if (mIns[i + 0].mLive & LIVE_CPU_REG_Z) if (mIns[i + 0].mLive & LIVE_CPU_REG_Z)
{ {
mIns.Insert(i + 1, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
mIns[i + 1].mLive |= LIVE_CPU_REG_Y;
mIns.Insert(i + 2, NativeCodeInstruction(ASMIT_ORA, ASMIM_IMMEDIATE, 0)); mIns.Insert(i + 2, NativeCodeInstruction(ASMIT_ORA, ASMIM_IMMEDIATE, 0));
mIns[i + 2].mLive |= LIVE_CPU_REG_Y | LIVE_CPU_REG_Z; mIns[i + 2].mLive |= LIVE_CPU_REG_Y | LIVE_CPU_REG_Z;
} }
else
{
InsertLoadYImmediate(i + 1, 0);
}
} }
if (flags & LIVE_CPU_REG_Y) if (flags & LIVE_CPU_REG_Y)
@ -20557,8 +20584,9 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
#if 1 #if 1
if (mIns[i + 0].mLive & LIVE_CPU_REG_Y) if (mIns[i + 0].mLive & LIVE_CPU_REG_Y)
{ {
mIns.Insert(i + 1, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); InsertLoadYImmediate(i + 1, 0);
mIns[i + 1].mLive |= LIVE_CPU_REG_Y; // mIns.Insert(i + 1, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
// mIns[i + 1].mLive |= LIVE_CPU_REG_Y;
} }
mIns.Insert(i + 0, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, ireg)); mIns.Insert(i + 0, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, ireg));
mIns[i + 0].mLive |= LIVE_CPU_REG_Y | LIVE_MEM; mIns[i + 0].mLive |= LIVE_CPU_REG_Y | LIVE_MEM;
@ -21012,13 +21040,17 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
{ {
if (mIns[i + 1].mLive & LIVE_CPU_REG_Y) if (mIns[i + 1].mLive & LIVE_CPU_REG_Y)
{ {
mIns.Insert(i + 2, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, mIns[i + 0].mAddress));
mIns[i + 2].mLive |= LIVE_CPU_REG_Y;
if (mIns[i + 1].mLive & LIVE_CPU_REG_Z) if (mIns[i + 1].mLive & LIVE_CPU_REG_Z)
{ {
mIns.Insert(i + 2, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, mIns[i + 0].mAddress));
mIns[i + 2].mLive |= LIVE_CPU_REG_Y;
mIns.Insert(i + 3, NativeCodeInstruction(ASMIT_ORA, ASMIM_IMMEDIATE, 0)); mIns.Insert(i + 3, NativeCodeInstruction(ASMIT_ORA, ASMIM_IMMEDIATE, 0));
mIns[i + 3].mLive |= LIVE_CPU_REG_Y | LIVE_CPU_REG_Z; mIns[i + 3].mLive |= LIVE_CPU_REG_Y | LIVE_CPU_REG_Z;
} }
else
{
InsertLoadYImmediate(i + 2, 0);
}
} }
if (flags & LIVE_CPU_REG_Y) if (flags & LIVE_CPU_REG_Y)
@ -21180,8 +21212,9 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
} }
if (mIns[i + 1].mLive & LIVE_CPU_REG_Y) if (mIns[i + 1].mLive & LIVE_CPU_REG_Y)
{ {
mIns.Insert(i + 2, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); InsertLoadYImmediate(i + 2, 0);
mIns[i + 2].mLive |= LIVE_CPU_REG_Y; // mIns.Insert(i + 2, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
// mIns[i + 2].mLive |= LIVE_CPU_REG_Y;
} }
mIns.Insert(i + 0, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, ireg)); mIns.Insert(i + 0, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, ireg));
mIns[i + 0].mLive |= LIVE_CPU_REG_Y | LIVE_MEM; mIns[i + 0].mLive |= LIVE_CPU_REG_Y | LIVE_MEM;
@ -21215,8 +21248,9 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
} }
if (mIns[i + 1].mLive & LIVE_CPU_REG_Y) if (mIns[i + 1].mLive & LIVE_CPU_REG_Y)
{ {
mIns.Insert(i + 2, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, yoffset)); InsertLoadYImmediate(i + 2, 0);
mIns[i + 2].mLive |= LIVE_CPU_REG_Y; // mIns.Insert(i + 2, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, yoffset));
// mIns[i + 2].mLive |= LIVE_CPU_REG_Y;
} }
mIns[i + 0].mMode = ASMIM_ZERO_PAGE; mIns[i + 0].mMode = ASMIM_ZERO_PAGE;
@ -21302,7 +21336,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
else if ( else if (
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 2].mType == ASMIT_TAY && !(mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) && mIns[i + 2].mType == ASMIT_TAY && !(mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) &&
!mIns[i + 1].ChangesAccu() && !mIns[i + 1].RequiresAccu() && !(mIns[i + 1].mLive & LIVE_CPU_REG_Y)) !mIns[i + 1].ChangesAccu() && !mIns[i + 1].RequiresAccu() && !mIns[i + 1].RequiresYReg())
{ {
mIns[i + 0].mType = ASMIT_LDY; mIns[i + 0].mType = ASMIT_LDY;
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
@ -22135,8 +22169,9 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
} }
if (mIns[i + 2].mLive & LIVE_CPU_REG_Y) if (mIns[i + 2].mLive & LIVE_CPU_REG_Y)
{ {
mIns.Insert(i + 3, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, yoffset)); InsertLoadYImmediate(i + 3, yoffset);
mIns[i + 3].mLive |= LIVE_CPU_REG_Y; // mIns.Insert(i + 3, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, yoffset));
// mIns[i + 3].mLive |= LIVE_CPU_REG_Y;
} }
int ypos = i; int ypos = i;
@ -22897,8 +22932,9 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
} }
if (mIns[i + 3].mLive & LIVE_CPU_REG_Y) if (mIns[i + 3].mLive & LIVE_CPU_REG_Y)
{ {
mIns.Insert(i + 4, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); InsertLoadYImmediate(i + 4, 0);
mIns[i + 4].mLive |= LIVE_CPU_REG_Y; // mIns.Insert(i + 4, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
// mIns[i + 4].mLive |= LIVE_CPU_REG_Y;
} }
mIns[i + 0].mMode = ASMIM_ZERO_PAGE; mIns[i + 0].mMode = ASMIM_ZERO_PAGE;
mIns[i + 0].mAddress = ireg; mIns[i + 0].mAddress = ireg;
@ -23066,8 +23102,9 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
} }
if (mIns[i + 4].mLive & LIVE_CPU_REG_Y) if (mIns[i + 4].mLive & LIVE_CPU_REG_Y)
{ {
mIns.Insert(i + 5, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); InsertLoadYImmediate(i + 5, 0);
mIns[i + 5].mLive |= LIVE_CPU_REG_Y; // mIns.Insert(i + 5, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
// mIns[i + 5].mLive |= LIVE_CPU_REG_Y;
} }
mIns[i + 0].mMode = ASMIM_ZERO_PAGE; mIns[i + 0].mMode = ASMIM_ZERO_PAGE;
mIns[i + 0].mAddress = ireg; mIns[i + 0].mAddress = ireg;
@ -23269,9 +23306,13 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE) mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE)
{ {
int n = 3; int n = 3;
if (mIns[i + 0].mFlags & NCIF_VOLATILE)
n = 1;
if (mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) if (mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z))
n--; n--;
if (n > 0)
{
proc->ResetPatched(); proc->ResetPatched();
if (CheckSingleUseGlobalLoad(this, mIns[i + 1].mAddress, i + 2, mIns[i], n)) if (CheckSingleUseGlobalLoad(this, mIns[i + 1].mAddress, i + 2, mIns[i], n))
{ {
@ -23293,6 +23334,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
CheckLive(); CheckLive();
} }
} }
}
else if ( else if (
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ABSOLUTE) mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ABSOLUTE)
@ -23554,8 +23596,9 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 3].mAddress + 1 && mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 3].mAddress + 1 &&
!(mIns[i + 6].mLive & LIVE_CPU_REG_A)) !(mIns[i + 6].mLive & LIVE_CPU_REG_A))
{ {
int yval = RetrieveYValue(i);
proc->ResetPatched(); proc->ResetPatched();
if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, mIns[i + 2].mAddress, i + 7, -1)) if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, mIns[i + 2].mAddress, i + 7, yval))
{ {
if (mIns[i + 3].mAddress == mIns[i + 1].mAddress) if (mIns[i + 3].mAddress == mIns[i + 1].mAddress)
{ {
@ -23566,7 +23609,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
} }
proc->ResetPatched(); proc->ResetPatched();
if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, mIns[i + 2].mAddress, i + 7, -1)) if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, mIns[i + 2].mAddress, i + 7, yval))
progress = true; progress = true;
} }
} }
@ -23582,19 +23625,20 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 3].mAddress + 1 && mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 3].mAddress + 1 &&
!(mIns[i + 6].mLive & LIVE_CPU_REG_A)) !(mIns[i + 6].mLive & LIVE_CPU_REG_A))
{ {
int yval = RetrieveYValue(i);
proc->ResetPatched(); proc->ResetPatched();
if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 2].mAddress, mIns[i + 0].mAddress, i + 7, -1)) if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 2].mAddress, mIns[i + 0].mAddress, i + 7, yval))
{ {
if (mIns[i + 3].mAddress == mIns[i + 2].mAddress) if (mIns[i + 3].mAddress == mIns[i + 2].mAddress)
{ {
for (int j = 0; j < 7; j++) for (int j = 1; j < 7; j++)
{ {
mIns[i + j].mType = ASMIT_NOP; mIns[i + j].mMode = ASMIM_IMPLIED; mIns[i + j].mType = ASMIT_NOP; mIns[i + j].mMode = ASMIM_IMPLIED;
} }
} }
proc->ResetPatched(); proc->ResetPatched();
if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 2].mAddress, mIns[i + 0].mAddress, i + 7, -1)) if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 2].mAddress, mIns[i + 0].mAddress, i + 7, yval))
progress = true; progress = true;
} }
} }
@ -23770,6 +23814,8 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
} while (progress); } while (progress);
CheckLive();
int sz = mIns.Size(); int sz = mIns.Size();
#if 1 #if 1
if (sz >= 2 && if (sz >= 2 &&
@ -23807,43 +23853,47 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
#if 1 #if 1
else if (sz >= 2 && else if (sz >= 2 &&
mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_IMMEDIATE && mIns[sz - 2].mAddress == 0 && mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_IMMEDIATE && mIns[sz - 2].mAddress == 0 &&
mIns[sz - 1].mType == ASMIT_ROL && mIns[sz - 1].mMode == ASMIM_IMPLIED && !(mIns[sz - 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C))) mIns[sz - 1].mType == ASMIT_ROL && mIns[sz - 1].mMode == ASMIM_IMPLIED && !(mIns[sz - 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)) && !mExitRequiredRegs[CPU_REG_Z])
{ {
if (mBranch == ASMIT_BNE) if (mBranch == ASMIT_BNE)
{ {
mBranch = ASMIT_BCS; mBranch = ASMIT_BCS;
mIns.SetSize(sz - 2); mIns.SetSize(sz - 2);
sz -= 2;
changed = true; changed = true;
} }
else if (mBranch == ASMIT_BEQ) else if (mBranch == ASMIT_BEQ)
{ {
mBranch = ASMIT_BCC; mBranch = ASMIT_BCC;
mIns.SetSize(sz - 2); mIns.SetSize(sz - 2);
sz -= 2;
changed = true; changed = true;
} }
} }
else if (sz >= 3 && else if (sz >= 3 &&
mIns[sz - 3].mType == ASMIT_LDA && mIns[sz - 3].mMode == ASMIM_IMMEDIATE && mIns[sz - 3].mAddress == 0 && mIns[sz - 3].mType == ASMIT_LDA && mIns[sz - 3].mMode == ASMIM_IMMEDIATE && mIns[sz - 3].mAddress == 0 &&
mIns[sz - 2].mType == ASMIT_ROL && mIns[sz - 2].mMode == ASMIM_IMPLIED && mIns[sz - 2].mType == ASMIT_ROL && mIns[sz - 2].mMode == ASMIM_IMPLIED &&
mIns[sz - 1].mType == ASMIT_CMP && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && mIns[sz - 1].mAddress == 0x0 && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A)) mIns[sz - 1].mType == ASMIT_CMP && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && mIns[sz - 1].mAddress == 0x0 && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A) && !mExitRequiredRegs[CPU_REG_Z])
{ {
if (mBranch == ASMIT_BNE) if (mBranch == ASMIT_BNE)
{ {
mBranch = ASMIT_BCS; mBranch = ASMIT_BCS;
mIns.SetSize(sz - 3); mIns.SetSize(sz - 3);
sz -= 3;
changed = true; changed = true;
} }
else if (mBranch == ASMIT_BEQ) else if (mBranch == ASMIT_BEQ)
{ {
mBranch = ASMIT_BCC; mBranch = ASMIT_BCC;
mIns.SetSize(sz - 3); mIns.SetSize(sz - 3);
sz -= 3;
changed = true; changed = true;
} }
} }
else if (sz >= 2 && else if (sz >= 2 &&
mIns[sz - 2].mType == ASMIT_EOR && mIns[sz - 2].mMode == ASMIM_IMMEDIATE && mIns[sz - 2].mAddress == 0x80 && mIns[sz - 2].mType == ASMIT_EOR && mIns[sz - 2].mMode == ASMIM_IMMEDIATE && mIns[sz - 2].mAddress == 0x80 &&
mIns[sz - 1].mType == ASMIT_CMP && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && mIns[sz - 1].mAddress == 0x80 && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A)) mIns[sz - 1].mType == ASMIT_CMP && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && mIns[sz - 1].mAddress == 0x80 && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A) && !mExitRequiredRegs[CPU_REG_Z])
{ {
if (mBranch == ASMIT_BNE && mTrueJump->mIns.Size() == 0 && mTrueJump->mBranch == ASMIT_BCC) if (mBranch == ASMIT_BNE && mTrueJump->mIns.Size() == 0 && mTrueJump->mBranch == ASMIT_BCC)
{ {
@ -23865,6 +23915,8 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[sz - 2].mType = ASMIT_NOP; mIns[sz - 2].mMode = ASMIM_IMPLIED; mIns[sz - 2].mType = ASMIT_NOP; mIns[sz - 2].mMode = ASMIM_IMPLIED;
mIns[sz - 1].mType = ASMIT_ORA; mIns[sz - 1].mAddress = 0; mIns[sz - 1].mLive |= LIVE_CPU_REG_Z; mIns[sz - 1].mType = ASMIT_ORA; mIns[sz - 1].mAddress = 0; mIns[sz - 1].mLive |= LIVE_CPU_REG_Z;
CheckLive();
} }
} }
@ -23872,7 +23924,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[sz - 4].mType == ASMIT_EOR && mIns[sz - 4].mMode == ASMIM_IMMEDIATE && mIns[sz - 4].mAddress == 0x80 && mIns[sz - 4].mType == ASMIT_EOR && mIns[sz - 4].mMode == ASMIM_IMMEDIATE && mIns[sz - 4].mAddress == 0x80 &&
mIns[sz - 3].mType == ASMIT_STA && mIns[sz - 3].mMode == ASMIM_ZERO_PAGE && mIns[sz - 3].mType == ASMIT_STA && mIns[sz - 3].mMode == ASMIM_ZERO_PAGE &&
mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_IMMEDIATE && mIns[sz - 2].mAddress == 0x80 && mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_IMMEDIATE && mIns[sz - 2].mAddress == 0x80 &&
mIns[sz - 1].mType == ASMIT_CMP && mIns[sz - 1].mMode == ASMIM_ZERO_PAGE && mIns[sz - 1].mAddress == mIns[sz - 3].mAddress && !(mIns[sz - 1].mLive & (LIVE_CPU_REG_A | LIVE_MEM))) mIns[sz - 1].mType == ASMIT_CMP && mIns[sz - 1].mMode == ASMIM_ZERO_PAGE && mIns[sz - 1].mAddress == mIns[sz - 3].mAddress && !(mIns[sz - 1].mLive & (LIVE_CPU_REG_A | LIVE_MEM)) && !mExitRequiredRegs[CPU_REG_Z])
{ {
if (mBranch == ASMIT_BNE && mTrueJump->mIns.Size() == 0 && mTrueJump->mBranch == ASMIT_BCC) if (mBranch == ASMIT_BNE && mTrueJump->mIns.Size() == 0 && mTrueJump->mBranch == ASMIT_BCC)
{ {
@ -23896,12 +23948,14 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[sz - 3].mType = ASMIT_NOP; mIns[sz - 3].mMode = ASMIM_IMPLIED; mIns[sz - 3].mType = ASMIT_NOP; mIns[sz - 3].mMode = ASMIM_IMPLIED;
mIns[sz - 2].mType = ASMIT_NOP; mIns[sz - 2].mMode = ASMIM_IMPLIED; mIns[sz - 2].mType = ASMIT_NOP; mIns[sz - 2].mMode = ASMIM_IMPLIED;
mIns[sz - 1].mType = ASMIT_ORA; mIns[sz - 1].mMode = ASMIM_IMMEDIATE; mIns[sz - 1].mAddress = 0; mIns[sz - 1].mLive |= LIVE_CPU_REG_Z; mIns[sz - 1].mType = ASMIT_ORA; mIns[sz - 1].mMode = ASMIM_IMMEDIATE; mIns[sz - 1].mAddress = 0; mIns[sz - 1].mLive |= LIVE_CPU_REG_Z;
CheckLive();
} }
} }
else if (sz >= 2 && else if (sz >= 2 &&
mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_IMMEDIATE && mIns[sz - 2].mAddress == 0 && mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_IMMEDIATE && mIns[sz - 2].mAddress == 0 &&
mIns[sz - 1].mType == ASMIT_SBC && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && mIns[sz - 1].mAddress == 0 && !(mIns[sz - 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C))) mIns[sz - 1].mType == ASMIT_SBC && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && mIns[sz - 1].mAddress == 0 && !(mIns[sz - 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)) && !mExitRequiredRegs[CPU_REG_Z])
{ {
if (mBranch == ASMIT_BNE) if (mBranch == ASMIT_BNE)
{ {
@ -23915,6 +23969,9 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns.SetSize(sz - 2); mIns.SetSize(sz - 2);
changed = true; changed = true;
} }
sz -= 2;
CheckLive();
} }
if (sz >= 1 && if (sz >= 1 &&
@ -23931,16 +23988,20 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
changed = true; changed = true;
} }
#endif #endif
CheckLive();
#if 1 #if 1
if (mTrueJump && mFalseJump && !mTrueJump->mFalseJump && !mFalseJump->mFalseJump && mTrueJump->mTrueJump == mFalseJump->mTrueJump && if (mTrueJump && mFalseJump && !mTrueJump->mFalseJump && !mFalseJump->mFalseJump && mTrueJump->mTrueJump == mFalseJump->mTrueJump &&
mTrueJump->mIns.Size() == 1 && mFalseJump->mIns.Size() == 1 && mTrueJump->mIns.Size() == 1 && mFalseJump->mIns.Size() == 1 &&
mTrueJump->mIns[0].mType == ASMIT_LDA && mTrueJump->mIns[0].mMode == ASMIM_IMMEDIATE && mTrueJump->mIns[0].mType == ASMIT_LDA && mTrueJump->mIns[0].mMode == ASMIM_IMMEDIATE &&
mFalseJump->mIns[0].mType == ASMIT_LDA && mFalseJump->mIns[0].mMode == ASMIM_IMMEDIATE) mFalseJump->mIns[0].mType == ASMIT_LDA && mFalseJump->mIns[0].mMode == ASMIM_IMMEDIATE)
{ {
if (mBranch == ASMIT_BCS && mTrueJump->mIns[0].mAddress == 1 && mFalseJump->mIns[0].mAddress == 0) if (mBranch == ASMIT_BCS && mTrueJump->mIns[0].mAddress == 1 && mFalseJump->mIns[0].mAddress == 0 && !(mExitRequiredRegs[CPU_REG_C]))
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
mExitProvidedRegs += CPU_REG_A;
mBranch = ASMIT_JMP; mBranch = ASMIT_JMP;
mTrueJump = mTrueJump->mTrueJump; mTrueJump = mTrueJump->mTrueJump;
mFalseJump = nullptr; mFalseJump = nullptr;
@ -23948,10 +24009,11 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
CheckLive(); CheckLive();
} }
else if (mBranch == ASMIT_BCC && mTrueJump->mIns[0].mAddress == 0 && mFalseJump->mIns[0].mAddress == 1) else if (mBranch == ASMIT_BCC && mTrueJump->mIns[0].mAddress == 0 && mFalseJump->mIns[0].mAddress == 1 && !(mExitRequiredRegs[CPU_REG_C]))
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
mExitProvidedRegs += CPU_REG_A;
mBranch = ASMIT_JMP; mBranch = ASMIT_JMP;
mTrueJump = mTrueJump->mTrueJump; mTrueJump = mTrueJump->mTrueJump;
mFalseJump = nullptr; mFalseJump = nullptr;
@ -23959,11 +24021,12 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
CheckLive(); CheckLive();
} }
else if (mBranch == ASMIT_BCS && mTrueJump->mIns[0].mAddress == 0 && mFalseJump->mIns[0].mAddress == 1) else if (mBranch == ASMIT_BCS && mTrueJump->mIns[0].mAddress == 0 && mFalseJump->mIns[0].mAddress == 1 && !(mExitRequiredRegs[CPU_REG_C]))
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_EOR, ASMIM_IMMEDIATE, 1)); mIns.Push(NativeCodeInstruction(ASMIT_EOR, ASMIM_IMMEDIATE, 1));
mExitProvidedRegs += CPU_REG_A;
mBranch = ASMIT_JMP; mBranch = ASMIT_JMP;
mTrueJump = mTrueJump->mTrueJump; mTrueJump = mTrueJump->mTrueJump;
mFalseJump = nullptr; mFalseJump = nullptr;
@ -23971,11 +24034,12 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
CheckLive(); CheckLive();
} }
else if (mBranch == ASMIT_BCC && mTrueJump->mIns[0].mAddress == 1 && mFalseJump->mIns[0].mAddress == 0) else if (mBranch == ASMIT_BCC && mTrueJump->mIns[0].mAddress == 1 && mFalseJump->mIns[0].mAddress == 0 && !(mExitRequiredRegs[CPU_REG_C]))
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_EOR, ASMIM_IMMEDIATE, 1)); mIns.Push(NativeCodeInstruction(ASMIT_EOR, ASMIM_IMMEDIATE, 1));
mExitProvidedRegs += CPU_REG_A;
mBranch = ASMIT_JMP; mBranch = ASMIT_JMP;
mTrueJump = mTrueJump->mTrueJump; mTrueJump = mTrueJump->mTrueJump;
mFalseJump = nullptr; mFalseJump = nullptr;
@ -23990,6 +24054,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns.Insert(mIns.Size() - 1, NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); mIns.Insert(mIns.Size() - 1, NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns[mIns.Size() - 1].mType = ASMIT_CMP; mIns[mIns.Size() - 1].mLive |= LIVE_CPU_REG_C; mIns[mIns.Size() - 1].mType = ASMIT_CMP; mIns[mIns.Size() - 1].mLive |= LIVE_CPU_REG_C;
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
mExitProvidedRegs += CPU_REG_A;
mBranch = ASMIT_JMP; mBranch = ASMIT_JMP;
mTrueJump = mTrueJump->mTrueJump; mTrueJump = mTrueJump->mTrueJump;
mFalseJump = nullptr; mFalseJump = nullptr;
@ -24002,6 +24067,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns.Insert(mIns.Size() - 1, NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); mIns.Insert(mIns.Size() - 1, NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns[mIns.Size() - 1].mType = ASMIT_CMP; mIns[mIns.Size() - 1].mLive |= LIVE_CPU_REG_C; mIns[mIns.Size() - 1].mType = ASMIT_CMP; mIns[mIns.Size() - 1].mLive |= LIVE_CPU_REG_C;
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
mExitProvidedRegs += CPU_REG_A;
mBranch = ASMIT_JMP; mBranch = ASMIT_JMP;
mTrueJump = mTrueJump->mTrueJump; mTrueJump = mTrueJump->mTrueJump;
mFalseJump = nullptr; mFalseJump = nullptr;
@ -24012,6 +24078,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
} }
} }
#endif #endif
CheckLive();
#endif #endif
assert(mIndex == 1000 || mNumEntries == mEntryBlocks.Size()); assert(mIndex == 1000 || mNumEntries == mEntryBlocks.Size());
@ -24056,6 +24123,8 @@ void NativeCodeBasicBlock::CheckLive(void)
for (int j = mIns.Size() - 1; j >= 0; j--) for (int j = mIns.Size() - 1; j >= 0; j--)
{ {
assert(mIns[j].mType != ASMIT_INV);
if (mIns[j].mType != ASMIT_NOP) if (mIns[j].mType != ASMIT_NOP)
{ {
assert(!(live & ~mIns[j].mLive)); assert(!(live & ~mIns[j].mLive));
@ -25037,6 +25106,7 @@ void NativeCodeProcedure::Optimize(void)
changed = true; changed = true;
#endif #endif
#if 1 #if 1
if (step < 6) if (step < 6)
{ {
@ -25046,6 +25116,7 @@ void NativeCodeProcedure::Optimize(void)
changed = true; changed = true;
} }
} }
#if 1 #if 1
if (step == 3) if (step == 3)
{ {
@ -25067,10 +25138,11 @@ void NativeCodeProcedure::Optimize(void)
changed = true; changed = true;
} }
#endif #endif
#if 1
ResetVisited(); ResetVisited();
if (mEntryBlock->MergeBasicBlocks()) if (mEntryBlock->MergeBasicBlocks())
changed = true; changed = true;
#endif
ResetEntryBlocks(); ResetEntryBlocks();
ResetVisited(); ResetVisited();
mEntryBlock->CollectEntryBlocks(nullptr); mEntryBlock->CollectEntryBlocks(nullptr);
@ -25082,6 +25154,7 @@ void NativeCodeProcedure::Optimize(void)
changed = true; changed = true;
} }
#endif #endif
#if 1 #if 1
if (step > 2 && !changed) if (step > 2 && !changed)
{ {
@ -25108,9 +25181,9 @@ void NativeCodeProcedure::Optimize(void)
if (mEntryBlock->ReduceLocalYPressure()) if (mEntryBlock->ReduceLocalYPressure())
changed = true; changed = true;
#endif #endif
} }
#endif #endif
#if 1 #if 1
if (step == 4 || step == 5) if (step == 4 || step == 5)
{ {
@ -25262,12 +25335,12 @@ void NativeCodeProcedure::Optimize(void)
#endif #endif
#endif #endif
if (cnt > 200) if (cnt > 200)
{ {
changed = false; changed = false;
mGenerator->mErrors->Error(mInterProc->mLocation, EWARN_OPTIMIZER_LOCKED, "Optimizer locked in infinite loop", mInterProc->mIdent); mGenerator->mErrors->Error(mInterProc->mLocation, EWARN_OPTIMIZER_LOCKED, "Optimizer locked in infinite loop", mInterProc->mIdent);
} }
#if 1 #if 1
if (!changed && step < 8) if (!changed && step < 8)
{ {
@ -25275,7 +25348,10 @@ void NativeCodeProcedure::Optimize(void)
changed = true; changed = true;
} }
#endif #endif
cnt++; cnt++;
} while (changed); } while (changed);
#if 1 #if 1
@ -25650,7 +25726,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
} break; } break;
case IC_RELATIONAL_OPERATOR: case IC_RELATIONAL_OPERATOR:
if (i + 1 < iblock->mInstructions.Size() && iblock->mInstructions[i + 1]->mCode == IC_BRANCH && iblock->mInstructions[i + 1]->mSrc[0].mFinal) if (i + 1 < iblock->mInstructions.Size() && iblock->mInstructions[i + 1]->mCode == IC_BRANCH && iblock->mInstructions[i + 1]->mSrc[0].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 1]->mSrc[0].mFinal)
{ {
block->RelationalOperator(iproc, ins, this, CompileBlock(iproc, iblock->mTrueJump), CompileBlock(iproc, iblock->mFalseJump)); block->RelationalOperator(iproc, ins, this, CompileBlock(iproc, iblock->mTrueJump), CompileBlock(iproc, iblock->mFalseJump));
return; return;

View File

@ -303,6 +303,8 @@ public:
bool JoinTAYARange(int from, int to); bool JoinTAYARange(int from, int to);
bool PatchGlobalAdressSumYByX(int at, int reg, const NativeCodeInstruction& ains, int addr); bool PatchGlobalAdressSumYByX(int at, int reg, const NativeCodeInstruction& ains, int addr);
bool MergeXYSameValue(int from); bool MergeXYSameValue(int from);
void InsertLoadYImmediate(int at, int val);
int RetrieveYValue(int at) const;
bool ReverseReplaceTAX(int at); bool ReverseReplaceTAX(int at);

Binary file not shown.