More aggressive value forwarding with local arrays

This commit is contained in:
drmortalwombat 2023-05-20 13:49:34 +02:00
parent d58e74e19a
commit e6b46a3acf
3 changed files with 193 additions and 95 deletions

View File

@ -406,25 +406,29 @@ static bool CollidingMemType(InterType type1, InterType type2)
} }
static bool CollidingMem(const InterOperand& op1, InterType type1, const InterOperand& op2, InterType type2, const GrowingVariableArray& staticVars) bool InterCodeBasicBlock::CollidingMem(const InterOperand& op1, InterType type1, const InterOperand& op2, InterType type2) const
{ {
if (op1.mMemory != op2.mMemory) if (op1.mMemory != op2.mMemory)
{ {
if (op1.mMemory == IM_INDIRECT) if (op1.mMemory == IM_INDIRECT)
{ {
if (op2.mMemory == IM_GLOBAL) if (op2.mMemory == IM_GLOBAL)
return staticVars[op2.mVarIndex]->mAliased; return mProc->mModule->mGlobalVars[op2.mVarIndex]->mAliased;
else if (op2.mMemory == IM_FPARAM || op2.mMemory == IM_FFRAME) else if (op2.mMemory == IM_FPARAM || op2.mMemory == IM_FFRAME)
return false; return false;
else if (op2.mMemory == IM_LOCAL)
return mProc->mLocalVars[op2.mVarIndex]->mAliased && CollidingMemType(type1, type2);
else else
return CollidingMemType(type1, type2); return CollidingMemType(type1, type2);
} }
else if (op2.mMemory == IM_INDIRECT) else if (op2.mMemory == IM_INDIRECT)
{ {
if (op1.mMemory == IM_GLOBAL) if (op1.mMemory == IM_GLOBAL)
return staticVars[op1.mVarIndex]->mAliased; return mProc->mModule->mGlobalVars[op1.mVarIndex]->mAliased;
else if (op1.mMemory == IM_FPARAM || op1.mMemory == IM_FFRAME) else if (op1.mMemory == IM_FPARAM || op1.mMemory == IM_FFRAME)
return false; return false;
else if (op1.mMemory == IM_LOCAL)
return mProc->mLocalVars[op1.mVarIndex]->mAliased && CollidingMemType(type1, type2);
else else
return CollidingMemType(type1, type2); return CollidingMemType(type1, type2);
} }
@ -457,38 +461,38 @@ static bool CollidingMem(const InterOperand& op1, InterType type1, const InterOp
} }
} }
static bool CollidingMem(const InterOperand& op, InterType type, const InterInstruction* ins, const GrowingVariableArray& staticVars) bool InterCodeBasicBlock::CollidingMem(const InterOperand& op, InterType type, const InterInstruction* ins) const
{ {
if (ins->mCode == IC_LOAD) if (ins->mCode == IC_LOAD)
return CollidingMem(op, type, ins->mSrc[0], ins->mDst.mType, staticVars); return CollidingMem(op, type, ins->mSrc[0], ins->mDst.mType);
else if (ins->mCode == IC_STORE) else if (ins->mCode == IC_STORE)
return CollidingMem(op, type, ins->mSrc[1], ins->mSrc[0].mType, staticVars); return CollidingMem(op, type, ins->mSrc[1], ins->mSrc[0].mType);
else if (ins->mCode == IC_COPY || ins->mCode == IC_STRCPY) else if (ins->mCode == IC_COPY || ins->mCode == IC_STRCPY)
return CollidingMem(op, type, ins->mSrc[0], IT_NONE, staticVars) || CollidingMem(op, type, ins->mSrc[1], IT_NONE, staticVars); return CollidingMem(op, type, ins->mSrc[0], IT_NONE) || CollidingMem(op, type, ins->mSrc[1], IT_NONE);
else else
return false; return false;
} }
static bool CollidingMem(const InterInstruction* ins1, const InterInstruction* ins2, const GrowingVariableArray& staticVars) bool InterCodeBasicBlock::CollidingMem(const InterInstruction* ins1, const InterInstruction* ins2) const
{ {
if (ins1->mCode == IC_LOAD) if (ins1->mCode == IC_LOAD)
return CollidingMem(ins1->mSrc[0], ins1->mDst.mType, ins2, staticVars); return CollidingMem(ins1->mSrc[0], ins1->mDst.mType, ins2);
else if (ins1->mCode == IC_STORE) else if (ins1->mCode == IC_STORE)
return CollidingMem(ins1->mSrc[1], ins1->mSrc[0].mType, ins2, staticVars); return CollidingMem(ins1->mSrc[1], ins1->mSrc[0].mType, ins2);
else if (ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY) else if (ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY)
return CollidingMem(ins1->mSrc[0], IT_NONE, ins2, staticVars) || CollidingMem(ins1->mSrc[1], IT_NONE, ins2, staticVars); return CollidingMem(ins1->mSrc[0], IT_NONE, ins2) || CollidingMem(ins1->mSrc[1], IT_NONE, ins2);
else else
return false; return false;
} }
static bool DestroyingMem(const InterInstruction* lins, const InterInstruction* sins, const GrowingVariableArray& staticVars) bool InterCodeBasicBlock::DestroyingMem(const InterInstruction* lins, const InterInstruction* sins) const
{ {
if (sins->mCode == IC_LOAD) if (sins->mCode == IC_LOAD)
return false; return false;
else if (sins->mCode == IC_STORE) else if (sins->mCode == IC_STORE)
return CollidingMem(sins->mSrc[1], sins->mSrc[0].mType, lins, staticVars); return CollidingMem(sins->mSrc[1], sins->mSrc[0].mType, lins);
else if (sins->mCode == IC_COPY || sins->mCode == IC_STRCPY) else if (sins->mCode == IC_COPY || sins->mCode == IC_STRCPY)
return CollidingMem(sins->mSrc[1], IT_NONE, lins, staticVars); return CollidingMem(sins->mSrc[1], IT_NONE, lins);
else else
return false; return false;
} }
@ -691,17 +695,17 @@ bool InterCodeBasicBlock::CanSwapInstructions(const InterInstruction* ins0, cons
if (ins0->mCode == IC_LOAD) if (ins0->mCode == IC_LOAD)
{ {
if (DestroyingMem(ins0, ins1, mProc->mModule->mGlobalVars)) if (DestroyingMem(ins0, ins1))
return false; return false;
} }
else if (ins1->mCode == IC_LOAD) else if (ins1->mCode == IC_LOAD)
{ {
if (DestroyingMem(ins1, ins0, mProc->mModule->mGlobalVars)) if (DestroyingMem(ins1, ins0))
return false; return false;
} }
else if (ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY) else if (ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY)
{ {
if (CollidingMem(ins0, ins1, mProc->mModule->mGlobalVars)) if (CollidingMem(ins0, ins1))
return false; return false;
} }
} }
@ -2949,27 +2953,80 @@ static void FilterTempDefineUsage(NumberSet& requiredTemps, NumberSet& providedT
} }
} }
void InterInstruction::CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable) void InterInstruction::CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable, int& nlocals, int& nparams)
{ {
if (mCode == IC_CONSTANT) if (mCode == IC_CONSTANT)
{ {
if (mDst.mType == IT_POINTER && mConst.mMemory == IM_LOCAL) if (mDst.mType == IT_POINTER && mConst.mMemory == IM_LOCAL)
{
localTable[mDst.mTemp] = mConst.mVarIndex; localTable[mDst.mTemp] = mConst.mVarIndex;
if (mConst.mVarIndex >= nlocals)
nlocals = mConst.mVarIndex + 1;
}
else if (mDst.mType == IT_POINTER && (mConst.mMemory == IM_PARAM || mConst.mMemory == IM_FPARAM)) else if (mDst.mType == IT_POINTER && (mConst.mMemory == IM_PARAM || mConst.mMemory == IM_FPARAM))
{
paramTable[mDst.mTemp] = mConst.mVarIndex; paramTable[mDst.mTemp] = mConst.mVarIndex;
if (mConst.mVarIndex >= nparams)
nparams = mConst.mVarIndex + 1;
}
} }
else if (mCode == IC_LEA) else if (mCode == IC_LEA)
{ {
if (mSrc[1].mMemory == IM_LOCAL) if (mSrc[1].mMemory == IM_LOCAL)
localTable[mDst.mTemp] = localTable[mSrc[1].mTemp]; {
if (mSrc[1].mTemp >= 0)
localTable[mDst.mTemp] = localTable[mSrc[1].mTemp];
else
{
localTable[mDst.mTemp] = mSrc[1].mVarIndex;
if (mSrc[1].mVarIndex >= nlocals)
nlocals = mSrc[1].mVarIndex + 1;
}
}
else if (mSrc[1].mMemory == IM_PARAM || mSrc[1].mMemory == IM_FPARAM) else if (mSrc[1].mMemory == IM_PARAM || mSrc[1].mMemory == IM_FPARAM)
paramTable[mDst.mTemp] = paramTable[mSrc[1].mTemp]; {
if (mSrc[1].mTemp >= 0)
paramTable[mDst.mTemp] = paramTable[mSrc[1].mTemp];
else
{
paramTable[mDst.mTemp] = mSrc[1].mVarIndex;
if (mSrc[1].mVarIndex >= nparams)
nparams = mSrc[1].mVarIndex + 1;
}
}
} }
else if (mCode == IC_LOAD_TEMPORARY) else if (mCode == IC_LOAD_TEMPORARY)
{ {
localTable[mDst.mTemp] = localTable[mSrc[0].mTemp]; localTable[mDst.mTemp] = localTable[mSrc[0].mTemp];
paramTable[mDst.mTemp] = paramTable[mSrc[0].mTemp]; paramTable[mDst.mTemp] = paramTable[mSrc[0].mTemp];
} }
else if (mCode == IC_STORE && mSrc[1].mTemp < 0)
{
if (mSrc[1].mMemory == IM_LOCAL)
{
if (mSrc[1].mVarIndex >= nlocals)
nlocals = mSrc[1].mVarIndex + 1;
}
else if (mSrc[1].mMemory == IM_PARAM || mSrc[1].mMemory == IM_FPARAM)
{
if (mSrc[1].mVarIndex >= nparams)
nparams = mSrc[1].mVarIndex + 1;
}
}
else if (mCode == IC_LOAD && mSrc[0].mTemp < 0)
{
if (mSrc[0].mMemory == IM_LOCAL)
{
if (mSrc[0].mVarIndex >= nlocals)
nlocals = mSrc[0].mVarIndex + 1;
}
else if (mSrc[0].mMemory == IM_PARAM || mSrc[0].mMemory == IM_FPARAM)
{
if (mSrc[0].mVarIndex >= nparams)
nparams = mSrc[0].mVarIndex + 1;
}
}
} }
void InterInstruction::MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams) void InterInstruction::MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams)
@ -3504,7 +3561,7 @@ bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray&
return changed; return changed;
} }
bool InterInstruction::RemoveUnusedStaticStoreInstructions(const GrowingVariableArray& staticVars, NumberSet& requiredVars, GrowingInstructionPtrArray& storeIns) bool InterInstruction::RemoveUnusedStaticStoreInstructions(InterCodeBasicBlock* block, const GrowingVariableArray& staticVars, NumberSet& requiredVars, GrowingInstructionPtrArray& storeIns)
{ {
bool changed = false; bool changed = false;
@ -3526,7 +3583,7 @@ bool InterInstruction::RemoveUnusedStaticStoreInstructions(const GrowingVariable
int k = 0; int k = 0;
for (int i = 0; i < storeIns.Size(); i++) for (int i = 0; i < storeIns.Size(); i++)
{ {
if (!CollidingMem(this, storeIns[i], staticVars)) if (!block->CollidingMem(this, storeIns[i]))
storeIns[k++] = storeIns[i]; storeIns[k++] = storeIns[i];
} }
storeIns.SetSize(k); storeIns.SetSize(k);
@ -3563,7 +3620,7 @@ bool InterInstruction::RemoveUnusedStaticStoreInstructions(const GrowingVariable
int k = 0; int k = 0;
for (int i = 0; i < storeIns.Size(); i++) for (int i = 0; i < storeIns.Size(); i++)
{ {
if (!CollidingMem(this, storeIns[i], staticVars)) if (!block->CollidingMem(this, storeIns[i]))
storeIns[k++] = storeIns[i]; storeIns[k++] = storeIns[i];
} }
storeIns.SetSize(k); storeIns.SetSize(k);
@ -5309,7 +5366,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
} }
void InterCodeBasicBlock::CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable) void InterCodeBasicBlock::CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable, int& nlocals, int& nparams)
{ {
int i; int i;
@ -5318,10 +5375,10 @@ void InterCodeBasicBlock::CollectLocalAddressTemps(GrowingIntArray& localTable,
mVisited = true; mVisited = true;
for (i = 0; i < mInstructions.Size(); i++) for (i = 0; i < mInstructions.Size(); i++)
mInstructions[i]->CollectLocalAddressTemps(localTable, paramTable); mInstructions[i]->CollectLocalAddressTemps(localTable, paramTable, nlocals, nparams);
if (mTrueJump) mTrueJump->CollectLocalAddressTemps(localTable, paramTable); if (mTrueJump) mTrueJump->CollectLocalAddressTemps(localTable, paramTable, nlocals, nparams);
if (mFalseJump) mFalseJump->CollectLocalAddressTemps(localTable, paramTable); if (mFalseJump) mFalseJump->CollectLocalAddressTemps(localTable, paramTable, nlocals, nparams);
} }
} }
@ -5543,7 +5600,7 @@ bool InterCodeBasicBlock::PropagateVariableCopy(const GrowingInstructionPtrArray
j = 0; j = 0;
for (int k = 0; k < ltemps.Size(); k++) for (int k = 0; k < ltemps.Size(); k++)
{ {
if (!CollidingMem(ltemps[k], ins, staticVars)) if (!CollidingMem(ltemps[k], ins))
{ {
ltemps[j++] = ltemps[k]; ltemps[j++] = ltemps[k];
} }
@ -5564,7 +5621,7 @@ bool InterCodeBasicBlock::PropagateVariableCopy(const GrowingInstructionPtrArray
j = 0; j = 0;
for (int k = 0; k < ltemps.Size(); k++) for (int k = 0; k < ltemps.Size(); k++)
{ {
if (!CollidingMem(ltemps[k], ins, staticVars)) if (!CollidingMem(ltemps[k], ins))
{ {
ltemps[j++] = ltemps[k]; ltemps[j++] = ltemps[k];
} }
@ -7960,7 +8017,7 @@ bool InterCodeBasicBlock::RemoveUnusedStaticStoreInstructions(const GrowingVaria
for (i = mInstructions.Size() - 1; i >= 0; i--) for (i = mInstructions.Size() - 1; i >= 0; i--)
{ {
if (mInstructions[i]->RemoveUnusedStaticStoreInstructions(staticVars, requiredVars, storeIns)) if (mInstructions[i]->RemoveUnusedStaticStoreInstructions(this, staticVars, requiredVars, storeIns))
changed = true; changed = true;
} }
@ -9388,7 +9445,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
int j = 0; int j = 0;
while (j < mLoadStoreInstructions.Size()) while (j < mLoadStoreInstructions.Size())
{ {
if (mLoadStoreInstructions[j]->ReferencesTemp(ins->mDst.mTemp) || CollidingMem(ins, mLoadStoreInstructions[j], staticVars)) if (mLoadStoreInstructions[j]->ReferencesTemp(ins->mDst.mTemp) || CollidingMem(ins, mLoadStoreInstructions[j]))
mLoadStoreInstructions.Remove(j); mLoadStoreInstructions.Remove(j);
else else
j++; j++;
@ -9468,7 +9525,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
j = 0; j = 0;
while (j < mLoadStoreInstructions.Size()) while (j < mLoadStoreInstructions.Size())
{ {
if (!DestroyingMem(mLoadStoreInstructions[j], ins, staticVars)) if (!DestroyingMem(mLoadStoreInstructions[j], ins))
mLoadStoreInstructions[k++] = mLoadStoreInstructions[j]; mLoadStoreInstructions[k++] = mLoadStoreInstructions[j];
j++; j++;
} }
@ -9483,7 +9540,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
int j = 0, k = 0; int j = 0, k = 0;
while (j < mLoadStoreInstructions.Size()) while (j < mLoadStoreInstructions.Size())
{ {
if (!DestroyingMem(mLoadStoreInstructions[j], ins, staticVars)) if (!DestroyingMem(mLoadStoreInstructions[j], ins))
mLoadStoreInstructions[k++] = mLoadStoreInstructions[j]; mLoadStoreInstructions[k++] = mLoadStoreInstructions[j];
j++; j++;
} }
@ -11282,12 +11339,12 @@ static bool IsMatchingStore(const InterInstruction* lins, const InterInstruction
return false; return false;
} }
static bool CollidingMem(InterCodeBasicBlock* block, InterInstruction * lins, int from, int to, const GrowingVariableArray& staticVars) bool InterCodeBasicBlock::CollidingMem(InterCodeBasicBlock* block, InterInstruction * lins, int from, int to) const
{ {
for (int i = from; i < to; i++) for (int i = from; i < to; i++)
{ {
InterInstruction* ins = block->mInstructions[i]; InterInstruction* ins = block->mInstructions[i];
if (CollidingMem(lins, ins, staticVars)) if (CollidingMem(lins, ins))
return true; return true;
} }
@ -11442,11 +11499,11 @@ bool InterCodeBasicBlock::SingleTailLoopOptimization(const NumberSet& aliasedPar
if (tail->CanMoveInstructionBehindBlock(j)) if (tail->CanMoveInstructionBehindBlock(j))
{ {
if (!CollidingMem(this, lins, i + 1, mInstructions.Size(), staticVars) && if (!CollidingMem(this, lins, i + 1, mInstructions.Size()) &&
!CollidingMem(tail, lins, 0, j, staticVars)) !CollidingMem(tail, lins, 0, j))
{ {
int k = 1; int k = 1;
while (k + 1 < body.Size() && !CollidingMem(body[k], lins, 0, body[k]->mInstructions.Size(), staticVars)) while (k + 1 < body.Size() && !CollidingMem(body[k], lins, 0, body[k]->mInstructions.Size()))
k++; k++;
if (k + 1 == body.Size()) if (k + 1 == body.Size())
@ -12473,7 +12530,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
{ {
// 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;
while (j > i && !(mInstructions[j]->mCode == IC_STORE && CollidingMem(ins, mInstructions[j], staticVars))) while (j > i && !(mInstructions[j]->mCode == IC_STORE && CollidingMem(ins, mInstructions[j])))
j--; j--;
if (j > i) if (j > i)
@ -12561,7 +12618,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
for (int j = 0; j < mInstructions.Size(); j++) for (int j = 0; j < mInstructions.Size(); j++)
{ {
InterInstruction* sins = mInstructions[j]; InterInstruction* sins = mInstructions[j];
if (sins->mCode == IC_STORE && CollidingMem(ins, sins, staticVars)) if (sins->mCode == IC_STORE && CollidingMem(ins, sins))
{ {
if (sins->mSrc[1].mTemp >= 0) if (sins->mSrc[1].mTemp >= 0)
{ {
@ -12585,7 +12642,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
ins->mInvariant = false; ins->mInvariant = false;
} }
} }
else if (CollidingMem(ins, sins, staticVars)) else if (CollidingMem(ins, sins))
{ {
ins->mInvariant = false; ins->mInvariant = false;
} }
@ -15226,17 +15283,18 @@ void InterCodeProcedure::RemoveUnusedStoreInstructions(InterMemory paramMemory)
{ {
if (mLocalVars.Size() > 0 || mParamVars.Size() > 0) if (mLocalVars.Size() > 0 || mParamVars.Size() > 0)
{ {
#if 0
for (int i = 0; i < mLocalAliasedSet.Size(); i++) for (int i = 0; i < mLocalAliasedSet.Size(); i++)
{ {
if (mLocalAliasedSet[i]) if (mLocalVars[i])
mLocalVars[i]->mAliased = true; mLocalVars[i]->mAliased = mLocalAliasedSet[i];
} }
for (int i = 0; i < mParamAliasedSet.Size(); i++) for (int i = 0; i < mParamAliasedSet.Size(); i++)
{ {
if (mParamAliasedSet[i]) if (mParamVars[i])
mParamVars[i]->mAliased = true; mParamVars[i]->mAliased = mParamAliasedSet[i];
} }
#endif
// //
// Now remove unused stores // Now remove unused stores
// //
@ -15328,15 +15386,27 @@ void InterCodeProcedure::PushSinglePathResultInstructions(void)
} while (changed); } while (changed);
} }
void InterCodeProcedure::PromoteSimpleLocalsToTemp(InterMemory paramMemory, int nlocals, int nparams) void InterCodeProcedure::CollectVariables(InterMemory paramMemory)
{ {
for (int i = 0; i < mLocalVars.Size(); i++)
if (mLocalVars[i])
mLocalVars[i]->mAliased = false;
for (int i = 0; i < mParamVars.Size(); i++)
if (mParamVars[i])
mParamVars[i]->mAliased = false;
ResetVisited(); ResetVisited();
mEntryBlock->CollectVariables(mModule->mGlobalVars, mLocalVars, mParamVars, paramMemory); mEntryBlock->CollectVariables(mModule->mGlobalVars, mLocalVars, mParamVars, paramMemory);
}
RemoveUnusedStoreInstructions(paramMemory); void InterCodeProcedure::PromoteSimpleLocalsToTemp(InterMemory paramMemory, int nlocals, int nparams)
{
for (int j = 0; j < 2; j++) for (int j = 0; j < 2; j++)
{ {
CollectVariables(paramMemory);
RemoveUnusedStoreInstructions(paramMemory);
// //
// Promote local variables to temporaries // Promote local variables to temporaries
// //
@ -15659,11 +15729,30 @@ void InterCodeProcedure::PropagateConstOperationsUp(void)
#endif #endif
} }
void InterCodeProcedure::BuildLocalAliasTable(void)
{
//
// Find all local variables that are never aliased
//
GrowingIntArray localTable(-1), paramTable(-1);
int nlocals = 0, nparams = 0;
ResetVisited();
mEntryBlock->CollectLocalAddressTemps(localTable, paramTable, nlocals, nparams);
mLocalAliasedSet.Reset(nlocals);
mParamAliasedSet.Reset(nparams);
ResetVisited();
mEntryBlock->MarkAliasedLocalTemps(localTable, mLocalAliasedSet, paramTable, mParamAliasedSet);
Disassemble("Built alias temps");
}
void InterCodeProcedure::Close(void) void InterCodeProcedure::Close(void)
{ {
GrowingTypeArray tstack(IT_NONE); GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "main"); CheckFunc = !strcmp(mIdent->mString, "sieve");
mEntryBlock = mBlocks[0]; mEntryBlock = mBlocks[0];
@ -15701,25 +15790,7 @@ void InterCodeProcedure::Close(void)
int numTemps = mTemporaries.Size(); int numTemps = mTemporaries.Size();
// BuildLocalAliasTable();
// Find all local variables that are never aliased
//
GrowingIntArray localTable(-1), paramTable(-1);
ResetVisited();
mEntryBlock->CollectLocalAddressTemps(localTable, paramTable);
int nlocals = 0, nparams = 0;
for (int i = 0; i < localTable.Size(); i++)
if (localTable[i] + 1 > nlocals)
nlocals = localTable[i] + 1;
for (int i = 0; i < paramTable.Size(); i++)
if (paramTable[i] + 1 > nparams)
nparams = paramTable[i] + 1;
mLocalAliasedSet.Reset(nlocals);
mParamAliasedSet.Reset(nparams);
ResetVisited();
mEntryBlock->MarkAliasedLocalTemps(localTable, mLocalAliasedSet, paramTable, mParamAliasedSet);
ValueSet valueSet; ValueSet valueSet;
FastNumberSet tvalidSet(numTemps + 32); FastNumberSet tvalidSet(numTemps + 32);
@ -15795,7 +15866,6 @@ void InterCodeProcedure::Close(void)
DisassembleDebug("temp forwarding 2"); DisassembleDebug("temp forwarding 2");
// //
// Now remove unused instructions // Now remove unused instructions
// //
@ -15807,12 +15877,9 @@ void InterCodeProcedure::Close(void)
InterMemory paramMemory = mFastCallProcedure ? IM_FPARAM : IM_PARAM; InterMemory paramMemory = mFastCallProcedure ? IM_FPARAM : IM_PARAM;
if (mCompilerOptions & COPT_OPTIMIZE_BASIC) if (mCompilerOptions & COPT_OPTIMIZE_BASIC)
PromoteSimpleLocalsToTemp(paramMemory, nlocals, nparams); PromoteSimpleLocalsToTemp(paramMemory, mLocalAliasedSet.Size(), mParamAliasedSet.Size());
else else
{ CollectVariables(paramMemory);
ResetVisited();
mEntryBlock->CollectVariables(mModule->mGlobalVars, mLocalVars, mParamVars, paramMemory);
}
BuildDataFlowSets(); BuildDataFlowSets();

View File

@ -307,7 +307,7 @@ public:
bool UsesTemp(int temp) const; bool UsesTemp(int temp) const;
int NumUsedTemps(void) const; int NumUsedTemps(void) const;
void CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable); void CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable, int& nlocals, int& nparams);
void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams); void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams);
void FilterTempUsage(NumberSet& requiredTemps, NumberSet& providedTemps); void FilterTempUsage(NumberSet& requiredTemps, NumberSet& providedTemps);
@ -316,7 +316,7 @@ public:
bool RemoveUnusedResultInstructions(InterInstruction* pre, NumberSet& requiredTemps); bool RemoveUnusedResultInstructions(InterInstruction* pre, NumberSet& requiredTemps);
bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, NumberSet& requiredVars, const GrowingVariableArray& params, NumberSet& requiredParams, InterMemory paramMemory); bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, NumberSet& requiredVars, const GrowingVariableArray& params, NumberSet& requiredParams, InterMemory paramMemory);
bool RemoveUnusedStaticStoreInstructions(const GrowingVariableArray& staticVars, NumberSet& requiredVars, GrowingInstructionPtrArray& storeIns); bool RemoveUnusedStaticStoreInstructions(InterCodeBasicBlock * block, const GrowingVariableArray& staticVars, NumberSet& requiredVars, GrowingInstructionPtrArray& storeIns);
void PerformValueForwarding(GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid); void PerformValueForwarding(GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid);
void BuildCallerSaveTempSet(NumberSet& requiredTemps, NumberSet& callerSaveTemps); void BuildCallerSaveTempSet(NumberSet& requiredTemps, NumberSet& callerSaveTemps);
@ -400,7 +400,7 @@ public:
void CollectAllUsedDefinedTemps(NumberSet& defined, NumberSet& used); void CollectAllUsedDefinedTemps(NumberSet& defined, NumberSet& used);
void CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable); void CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable, int & nlocals, int & nparams);
void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams); void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams);
void CollectLocalUsedTemps(int numTemps); void CollectLocalUsedTemps(int numTemps);
@ -493,6 +493,12 @@ public:
bool IsTempModifiedOnPath(int temp, int at) const; bool IsTempModifiedOnPath(int temp, int at) const;
bool IsTempReferencedOnPath(int temp, int at) const; bool IsTempReferencedOnPath(int temp, int at) const;
bool DestroyingMem(const InterInstruction* lins, const InterInstruction* sins) const;
bool CollidingMem(const InterInstruction* ins1, const InterInstruction* ins2) const;
bool CollidingMem(const InterOperand& op, InterType type, const InterInstruction* ins) const;
bool CollidingMem(const InterOperand& op1, InterType type1, const InterOperand& op2, InterType type2) const;
bool CollidingMem(InterCodeBasicBlock* block, InterInstruction* lins, int from, int to) const;
bool PushSinglePathResultInstructions(void); bool PushSinglePathResultInstructions(void);
bool CanSwapInstructions(const InterInstruction* ins0, const InterInstruction* ins1) const; bool CanSwapInstructions(const InterInstruction* ins0, const InterInstruction* ins1) const;
@ -561,7 +567,6 @@ protected:
GrowingIntArray mRenameTable, mRenameUnionTable, mGlobalRenameTable; GrowingIntArray mRenameTable, mRenameUnionTable, mGlobalRenameTable;
TempForwardingTable mTempForwardingTable; TempForwardingTable mTempForwardingTable;
GrowingInstructionPtrArray mValueForwardingTable; GrowingInstructionPtrArray mValueForwardingTable;
NumberSet mLocalAliasedSet, mParamAliasedSet;
void ResetVisited(void); void ResetVisited(void);
void ResetEntryBlocks(void); void ResetEntryBlocks(void);
@ -580,6 +585,7 @@ public:
int mLocalSize, mNumLocals; int mLocalSize, mNumLocals;
GrowingVariableArray mLocalVars, mParamVars; GrowingVariableArray mLocalVars, mParamVars;
NumberSet mLocalAliasedSet, mParamAliasedSet;
Location mLocation; Location mLocation;
const Ident * mIdent, * mSection; const Ident * mIdent, * mSection;
@ -611,6 +617,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 BuildLocalAliasTable(void);
void BuildTraces(bool expand, bool dominators = true, bool compact = false); void BuildTraces(bool expand, bool dominators = true, bool compact = false);
void BuildDataFlowSets(void); void BuildDataFlowSets(void);
void RenameTemporaries(void); void RenameTemporaries(void);
@ -623,6 +630,7 @@ protected:
void RemoveUnusedStoreInstructions(InterMemory paramMemory); void RemoveUnusedStoreInstructions(InterMemory paramMemory);
void MergeCommonPathInstructions(void); void MergeCommonPathInstructions(void);
void PushSinglePathResultInstructions(void); void PushSinglePathResultInstructions(void);
void CollectVariables(InterMemory paramMemory);
void PromoteSimpleLocalsToTemp(InterMemory paramMemory, int nlocals, int nparams); void PromoteSimpleLocalsToTemp(InterMemory paramMemory, int nlocals, int nparams);
void SimplifyIntegerNumeric(FastNumberSet& activeSet); void SimplifyIntegerNumeric(FastNumberSet& activeSet);
void SingleBlockLoopPointerSplit(FastNumberSet& activeSet); void SingleBlockLoopPointerSplit(FastNumberSet& activeSet);

View File

@ -28440,21 +28440,38 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == mIns[1].mAddress && if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == mIns[1].mAddress &&
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == mIns[0].mAddress && !(mIns[1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z))) mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == mIns[0].mAddress && !(mIns[1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)))
{ {
if (!prevBlock) if ((!mEntryRequiredRegs[CPU_REG_A] || !mEntryRequiredRegs[CPU_REG_X]) && (!mExitRequiredRegs[CPU_REG_A] || !mExitRequiredRegs[CPU_REG_X]))
return OptimizeSimpleLoopInvariant(proc, full); {
if (!prevBlock)
return OptimizeSimpleLoopInvariant(proc, full);
prevBlock->mIns.Push(mIns[0]); prevBlock->mIns.Push(mIns[0]);
prevBlock->mIns.Push(mIns[1]); prevBlock->mIns.Push(mIns[1]);
exitBlock->mIns.Insert(0, mIns[i + 0]); if (mEntryRequiredRegs[CPU_REG_A])
exitBlock->mIns.Insert(1, mIns[i + 1]); {
prevBlock->mIns[prevBlock->mIns.Size() - 2].mType = ASMIT_LDX;
prevBlock->mIns[prevBlock->mIns.Size() - 2].mLive |= LIVE_CPU_REG_X;
prevBlock->mIns[prevBlock->mIns.Size() - 1].mType = ASMIT_STX;
}
mIns.Remove(i); mIns.Remove(i); exitBlock->mIns.Insert(0, mIns[i + 0]);
mIns.Remove(0); mIns.Remove(0); exitBlock->mIns.Insert(1, mIns[i + 1]);
CheckLive(); if (mExitRequiredRegs[CPU_REG_A])
{
exitBlock->mIns[0].mType = ASMIT_LDX;
exitBlock->mIns[0].mLive |= LIVE_CPU_REG_X;
exitBlock->mIns[1].mType = ASMIT_STX;
}
return true; mIns.Remove(i); mIns.Remove(i);
mIns.Remove(0); mIns.Remove(0);
CheckLive();
return true;
}
} }
} }
} }
@ -28664,7 +28681,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
} }
#if 1 #if 1
if (mEntryRequiredRegs.Size() && (!mEntryRequiredRegs[CPU_REG_A] || !mEntryRequiredRegs[CPU_REG_X])) if (mEntryRequiredRegs.Size() && (!mEntryRequiredRegs[CPU_REG_A] || !mEntryRequiredRegs[CPU_REG_X]) && (!mExitRequiredRegs[CPU_REG_A] || !mExitRequiredRegs[CPU_REG_X]))
{ {
for (int i = 0; i + 1 < mIns.Size(); i++) for (int i = 0; i + 1 < mIns.Size(); i++)
{ {
@ -28722,8 +28739,16 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
prevBlock->mExitRequiredRegs += mIns[i + 1].mAddress; prevBlock->mExitRequiredRegs += mIns[i + 1].mAddress;
mEntryRequiredRegs += mIns[i + 1].mAddress; mEntryRequiredRegs += mIns[i + 1].mAddress;
mExitRequiredRegs += mIns[i + 1].mAddress; mExitRequiredRegs += mIns[i + 1].mAddress;
exitBlock->mIns.Insert(0, NativeCodeInstruction(mIns[i + 0].mIns, ASMIT_LDA, ASMIM_ZERO_PAGE, mIns[i + 1].mAddress)); if (!mExitRequiredRegs[CPU_REG_A])
exitBlock->mIns.Insert(1, NativeCodeInstruction(mIns[i + 1].mIns, ASMIT_STA, ASMIM_ZERO_PAGE, mIns[i + 0].mAddress)); {
exitBlock->mIns.Insert(0, NativeCodeInstruction(mIns[i + 0].mIns, ASMIT_LDA, ASMIM_ZERO_PAGE, mIns[i + 1].mAddress));
exitBlock->mIns.Insert(1, NativeCodeInstruction(mIns[i + 1].mIns, ASMIT_STA, ASMIM_ZERO_PAGE, mIns[i + 0].mAddress));
}
else
{
exitBlock->mIns.Insert(0, NativeCodeInstruction(mIns[i + 0].mIns, ASMIT_LDX, ASMIM_ZERO_PAGE, mIns[i + 1].mAddress));
exitBlock->mIns.Insert(1, NativeCodeInstruction(mIns[i + 1].mIns, ASMIT_STX, ASMIM_ZERO_PAGE, mIns[i + 0].mAddress));
}
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;
} }
@ -38921,7 +38946,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{ {
mInterProc = proc; mInterProc = proc;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "bmul"); CheckFunc = !strcmp(mInterProc->mIdent->mString, "fill_screen");
int nblocks = proc->mBlocks.Size(); int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks]; tblocks = new NativeCodeBasicBlock * [nblocks];
@ -40137,7 +40162,6 @@ void NativeCodeProcedure::Optimize(void)
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 < 11) if (!changed && step < 11)
{ {
@ -40152,7 +40176,6 @@ void NativeCodeProcedure::Optimize(void)
} while (changed); } while (changed);
#if 1 #if 1
ResetVisited(); ResetVisited();
mEntryBlock->ReduceLocalYPressure(); mEntryBlock->ReduceLocalYPressure();