Fix data dependency lost due to instruction reshuffling
This commit is contained in:
parent
002c10ad13
commit
2eeef2d71c
|
@ -4583,6 +4583,30 @@ bool InterCodeBasicBlock::PropagateNonLocalUsedConstTemps(void)
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InterCodeBasicBlock::CollectAllUsedDefinedTemps(NumberSet& defined, NumberSet& used)
|
||||||
|
{
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < mInstructions.Size(); i++)
|
||||||
|
{
|
||||||
|
InterInstruction* ins(mInstructions[i]);
|
||||||
|
|
||||||
|
if (ins->mDst.mTemp >= 0)
|
||||||
|
defined += ins->mDst.mTemp;
|
||||||
|
for (int j = 0; j < ins->mNumOperands; j++)
|
||||||
|
{
|
||||||
|
if (ins->mSrc[j].mTemp >= 0)
|
||||||
|
used += ins->mSrc[j].mTemp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump) mTrueJump->CollectAllUsedDefinedTemps(defined, used);
|
||||||
|
if (mFalseJump) mFalseJump->CollectAllUsedDefinedTemps(defined, used);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InterCodeBasicBlock::CollectLocalUsedTemps(int numTemps)
|
void InterCodeBasicBlock::CollectLocalUsedTemps(int numTemps)
|
||||||
{
|
{
|
||||||
if (!mVisited)
|
if (!mVisited)
|
||||||
|
@ -9995,6 +10019,24 @@ void InterCodeBasicBlock::CompactInstructions(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void SwapInstructions(InterInstruction* it, InterInstruction* ib)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ib->mNumOperands; i++)
|
||||||
|
{
|
||||||
|
if (ib->mSrc[i].mTemp >= 0 && ib->mSrc[i].mFinal)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < it->mNumOperands; j++)
|
||||||
|
{
|
||||||
|
if (it->mSrc[j].mTemp == ib->mSrc[i].mTemp)
|
||||||
|
{
|
||||||
|
it->mSrc[j].mFinal = true;
|
||||||
|
ib->mSrc[i].mFinal = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& staticVars)
|
void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& staticVars)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -10070,6 +10112,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
||||||
int j = i;
|
int j = i;
|
||||||
while (j < limit && CanBypass(ins, mInstructions[j + 1]))
|
while (j < limit && CanBypass(ins, mInstructions[j + 1]))
|
||||||
{
|
{
|
||||||
|
SwapInstructions(ins, mInstructions[j + 1]);
|
||||||
mInstructions[j] = mInstructions[j + 1];
|
mInstructions[j] = mInstructions[j + 1];
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
@ -10098,6 +10141,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
||||||
int j = i;
|
int j = i;
|
||||||
while (j < limit && CanBypassLoad(ins, mInstructions[j + 1]))
|
while (j < limit && CanBypassLoad(ins, mInstructions[j + 1]))
|
||||||
{
|
{
|
||||||
|
SwapInstructions(ins, mInstructions[j + 1]);
|
||||||
mInstructions[j] = mInstructions[j + 1];
|
mInstructions[j] = mInstructions[j + 1];
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
@ -10120,6 +10164,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
||||||
int j = i;
|
int j = i;
|
||||||
while (j < k)
|
while (j < k)
|
||||||
{
|
{
|
||||||
|
SwapInstructions(ins, mInstructions[j + 1]);
|
||||||
mInstructions[j] = mInstructions[j + 1];
|
mInstructions[j] = mInstructions[j + 1];
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
@ -10133,6 +10178,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
||||||
int j = i;
|
int j = i;
|
||||||
while (j < limit && CanBypass(ins, mInstructions[j + 1]))
|
while (j < limit && CanBypass(ins, mInstructions[j + 1]))
|
||||||
{
|
{
|
||||||
|
SwapInstructions(ins, mInstructions[j + 1]);
|
||||||
mInstructions[j] = mInstructions[j + 1];
|
mInstructions[j] = mInstructions[j + 1];
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
@ -10187,6 +10233,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
||||||
int j = i;
|
int j = i;
|
||||||
while (j > 0 && CanBypassStore(ins, mInstructions[j - 1]))
|
while (j > 0 && CanBypassStore(ins, mInstructions[j - 1]))
|
||||||
{
|
{
|
||||||
|
SwapInstructions(mInstructions[j - 1], ins);
|
||||||
mInstructions[j] = mInstructions[j - 1];
|
mInstructions[j] = mInstructions[j - 1];
|
||||||
j--;
|
j--;
|
||||||
}
|
}
|
||||||
|
@ -10199,6 +10246,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
||||||
int j = i;
|
int j = i;
|
||||||
while (j > 0 && CanBypassUp(ins, mInstructions[j - 1]))
|
while (j > 0 && CanBypassUp(ins, mInstructions[j - 1]))
|
||||||
{
|
{
|
||||||
|
SwapInstructions(mInstructions[j - 1], ins);
|
||||||
mInstructions[j] = mInstructions[j - 1];
|
mInstructions[j] = mInstructions[j - 1];
|
||||||
j--;
|
j--;
|
||||||
}
|
}
|
||||||
|
@ -10211,17 +10259,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
||||||
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)
|
SwapInstructions(mInstructions[j - 1], ins);
|
||||||
{
|
|
||||||
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--;
|
||||||
}
|
}
|
||||||
|
@ -10244,18 +10282,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
||||||
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)
|
SwapInstructions(ins, mInstructions[j + 1]);
|
||||||
{
|
|
||||||
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++;
|
||||||
}
|
}
|
||||||
|
@ -10268,6 +10295,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
||||||
int j = i;
|
int j = i;
|
||||||
while (j < limit && CanBypass(ins, mInstructions[j + 1]))
|
while (j < limit && CanBypass(ins, mInstructions[j + 1]))
|
||||||
{
|
{
|
||||||
|
SwapInstructions(ins, mInstructions[j + 1]);
|
||||||
mInstructions[j] = mInstructions[j + 1];
|
mInstructions[j] = mInstructions[j + 1];
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
@ -10323,6 +10351,11 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
#if _DEBUG
|
||||||
|
for (int j = i + 3; j < mInstructions.Size(); j++)
|
||||||
|
assert(!mInstructions[j]->ReferencesTemp(mInstructions[i]->mDst.mTemp));
|
||||||
|
#endif
|
||||||
|
|
||||||
int t = mInstructions[i + 0]->mDst.mTemp;
|
int t = mInstructions[i + 0]->mDst.mTemp;
|
||||||
mInstructions[i + 0]->mDst.mTemp = mInstructions[i + 1]->mDst.mTemp;
|
mInstructions[i + 0]->mDst.mTemp = mInstructions[i + 1]->mDst.mTemp;
|
||||||
mInstructions[i + 1]->mCode = IC_NONE;
|
mInstructions[i + 1]->mCode = IC_NONE;
|
||||||
|
@ -10339,6 +10372,11 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
||||||
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[1].mTemp == mInstructions[i]->mDst.mTemp && mInstructions[i + 2]->mSrc[1].mFinal)
|
(mInstructions[i + 2]->mCode == IC_RELATIONAL_OPERATOR || mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR) && mInstructions[i + 2]->mSrc[1].mTemp == mInstructions[i]->mDst.mTemp && mInstructions[i + 2]->mSrc[1].mFinal)
|
||||||
{
|
{
|
||||||
|
#if _DEBUG
|
||||||
|
for (int j = i + 3; j < mInstructions.Size(); j++)
|
||||||
|
assert(!mInstructions[j]->ReferencesTemp(mInstructions[i]->mDst.mTemp));
|
||||||
|
#endif
|
||||||
|
|
||||||
mInstructions[i + 0]->mDst.mTemp = mInstructions[i + 1]->mDst.mTemp;
|
mInstructions[i + 0]->mDst.mTemp = mInstructions[i + 1]->mDst.mTemp;
|
||||||
mInstructions[i + 1]->mCode = IC_NONE;
|
mInstructions[i + 1]->mCode = IC_NONE;
|
||||||
mInstructions[i + 2]->mSrc[1].mTemp = mInstructions[i + 1]->mDst.mTemp;
|
mInstructions[i + 2]->mSrc[1].mTemp = mInstructions[i + 1]->mDst.mTemp;
|
||||||
|
@ -11213,10 +11251,30 @@ void InterCodeProcedure::SingleAssignmentForwarding(void)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InterCodeProcedure::CheckUsedDefinedTemps(void)
|
||||||
|
{
|
||||||
|
#if _DEBUG
|
||||||
|
int numTemps = mTemporaries.Size();
|
||||||
|
|
||||||
|
NumberSet defined(numTemps), used(numTemps);
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->CollectAllUsedDefinedTemps(defined, used);
|
||||||
|
|
||||||
|
for (int i = 0; i < numTemps; i++)
|
||||||
|
{
|
||||||
|
assert(!used[i] || defined[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void InterCodeProcedure::TempForwarding(void)
|
void InterCodeProcedure::TempForwarding(void)
|
||||||
{
|
{
|
||||||
int numTemps = mTemporaries.Size();
|
int numTemps = mTemporaries.Size();
|
||||||
|
|
||||||
|
CheckUsedDefinedTemps();
|
||||||
|
|
||||||
ValueSet valueSet;
|
ValueSet valueSet;
|
||||||
FastNumberSet tvalidSet(numTemps);
|
FastNumberSet tvalidSet(numTemps);
|
||||||
|
|
||||||
|
@ -11425,10 +11483,12 @@ void InterCodeProcedure::PromoteSimpleLocalsToTemp(InterMemory paramMemory, int
|
||||||
void InterCodeProcedure::SimplifyIntegerNumeric(FastNumberSet& activeSet)
|
void InterCodeProcedure::SimplifyIntegerNumeric(FastNumberSet& activeSet)
|
||||||
{
|
{
|
||||||
GrowingInstructionPtrArray silvalues(nullptr);
|
GrowingInstructionPtrArray silvalues(nullptr);
|
||||||
int silvused;
|
int silvused = mTemporaries.Size();
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
mTemporaries.SetSize(silvused, true);
|
||||||
|
|
||||||
BuildDataFlowSets();
|
BuildDataFlowSets();
|
||||||
|
|
||||||
TempForwarding();
|
TempForwarding();
|
||||||
|
@ -11677,12 +11737,17 @@ void InterCodeProcedure::Close(void)
|
||||||
|
|
||||||
BuildDataFlowSets();
|
BuildDataFlowSets();
|
||||||
#endif
|
#endif
|
||||||
|
CheckUsedDefinedTemps();
|
||||||
|
|
||||||
SingleAssignmentForwarding();
|
SingleAssignmentForwarding();
|
||||||
|
|
||||||
|
CheckUsedDefinedTemps();
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->PeepholeOptimization(mModule->mGlobalVars);
|
mEntryBlock->PeepholeOptimization(mModule->mGlobalVars);
|
||||||
|
|
||||||
|
DisassembleDebug("Broken Peephole");
|
||||||
|
|
||||||
TempForwarding();
|
TempForwarding();
|
||||||
RemoveUnusedInstructions();
|
RemoveUnusedInstructions();
|
||||||
|
|
||||||
|
|
|
@ -377,6 +377,8 @@ public:
|
||||||
|
|
||||||
void LocalToTemp(int vindex, int temp);
|
void LocalToTemp(int vindex, int temp);
|
||||||
|
|
||||||
|
void CollectAllUsedDefinedTemps(NumberSet& defined, NumberSet& used);
|
||||||
|
|
||||||
void CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable);
|
void CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable);
|
||||||
void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams);
|
void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams);
|
||||||
|
|
||||||
|
@ -565,6 +567,7 @@ protected:
|
||||||
void LoadStoreForwarding(InterMemory paramMemory);
|
void LoadStoreForwarding(InterMemory paramMemory);
|
||||||
|
|
||||||
void MergeBasicBlocks(void);
|
void MergeBasicBlocks(void);
|
||||||
|
void CheckUsedDefinedTemps(void);
|
||||||
|
|
||||||
void DisassembleDebug(const char* name);
|
void DisassembleDebug(const char* name);
|
||||||
};
|
};
|
||||||
|
|
|
@ -6269,6 +6269,15 @@ void NativeCodeBasicBlock::ShiftRegisterLeftFromByte(InterCodeProcedure* proc, i
|
||||||
if (shift == 0)
|
if (shift == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (shift >= 8)
|
||||||
|
{
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, reg));
|
||||||
|
for (int i = 8; i < shift; i++)
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
||||||
}
|
}
|
||||||
else if (shift == 1)
|
else if (shift == 1)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue