Common sub expression across if

This commit is contained in:
drmortalwombat 2023-10-03 15:21:33 +02:00
parent 313b6dcf93
commit e084035a71
2 changed files with 126 additions and 2 deletions

View File

@ -10902,6 +10902,91 @@ static bool CanMoveInstructionBeforePath(const GrowingInterCodeBasicBlockPtrArra
return true;
}
bool InterCodeBasicBlock::IsDirectDominatorBlock(InterCodeBasicBlock* block)
{
if (this == block)
return true;
if (block->mLoopHead)
return false;
if (block->mEntryBlocks.Size() == 0)
return false;
for (int i = 0; i < block->mEntryBlocks.Size(); i++)
if (!IsDirectDominatorBlock(block->mEntryBlocks[i]))
return false;
return true;
}
bool InterCodeBasicBlock::HoistCommonConditionalPath(void)
{
bool changed = false;
if (!mVisited)
{
mVisited = true;
if (mFalseJump)
{
InterCodeBasicBlock* cblock = nullptr, * eblock = nullptr;
if (!mTrueJump->mFalseJump && mTrueJump->mTrueJump && IsDirectDominatorBlock(mTrueJump->mTrueJump))
{
cblock = mTrueJump;
eblock = mTrueJump->mTrueJump;
}
else if (!mFalseJump->mFalseJump && mFalseJump->mTrueJump && IsDirectDominatorBlock(mFalseJump->mTrueJump))
{
cblock = mFalseJump;
eblock = mFalseJump->mTrueJump;
}
if (cblock && cblock->mNumEntries == 1)
{
for (int i = 0; i < cblock->mInstructions.Size(); i++)
{
InterInstruction* ins = cblock->mInstructions[i];
if (cblock->CanMoveInstructionBeforeBlock(i) && !HasSideEffect(ins->mCode) && ins->mDst.mTemp >= 0 && !cblock->IsTempModifiedInRange(i + 1, cblock->mInstructions.Size(), ins->mDst.mTemp))
{
int j = 0;
while (j < eblock->mInstructions.Size() && !eblock->mInstructions[j]->IsEqualSource(ins))
j++;
if (j < eblock->mInstructions.Size() && !eblock->IsTempModifiedInRange(0, j, ins->mDst.mTemp) && eblock->CanMoveInstructionBeforeBlock(j) && cblock->CanMoveInstructionBeforeBlock(cblock->mInstructions.Size(), eblock->mInstructions[j]))
{
eblock->mInstructions[j]->mCode = IC_LOAD_TEMPORARY;
eblock->mInstructions[j]->mSrc[0] = ins->mDst;
eblock->mInstructions[j]->mNumOperands = 1;
mInstructions.Insert(mInstructions.Size() - 1, ins);
cblock->mInstructions.Remove(i);
mExitRequiredTemps += ins->mDst.mTemp;
cblock->mEntryRequiredTemps += ins->mDst.mTemp;
cblock->mExitRequiredTemps += ins->mDst.mTemp;
eblock->mEntryRequiredTemps += ins->mDst.mTemp;
i--;
changed = true;
}
}
}
}
}
if (mTrueJump && mTrueJump->HoistCommonConditionalPath())
changed = true;
if (mFalseJump && mFalseJump->HoistCommonConditionalPath())
changed = true;
}
return changed;
}
bool InterCodeBasicBlock::MoveTrainCrossBlock(void)
{
bool changed = false;
@ -15115,6 +15200,27 @@ bool InterCodeBasicBlock::PeepholeReplaceOptimization(const GrowingVariableArray
mInstructions[i + 1]->mCode = IC_NONE; mInstructions[i + 1]->mNumOperands = 0;
changed = true;
}
#endif
#if 1
else if (
mInstructions[i + 0]->mCode == IC_LEA && mInstructions[i + 0]->mSrc[0].mTemp >= 0 &&
mInstructions[i + 1]->mCode == IC_LEA && mInstructions[i + 1]->mSrc[0].mTemp >= 0 &&
mInstructions[i + 1]->mSrc[1].mTemp == mInstructions[i + 0]->mDst.mTemp &&
mInstructions[i + 1]->mSrc[1].mFinal &&
mInstructions[i + 0]->mSrc[0].IsUByte() && mInstructions[i + 1]->mSrc[0].IsUByte() && mInstructions[i + 0]->mSrc[0].mRange.mMaxValue + mInstructions[i + 1]->mSrc[0].mRange.mMaxValue < 256)
{
mInstructions[i + 1]->mSrc[1] = mInstructions[i + 0]->mSrc[1];
mInstructions[i + 0]->mCode = IC_BINARY_OPERATOR;
mInstructions[i + 0]->mOperator = IA_ADD;
mInstructions[i + 0]->mDst.mType = IT_INT16;
mInstructions[i + 0]->mSrc[1] = mInstructions[i + 1]->mSrc[0];
mInstructions[i + 0]->mDst.mRange = mInstructions[i + 0]->mSrc[0].mRange;
mInstructions[i + 0]->mDst.mRange.mMaxValue += mInstructions[i + 0]->mSrc[1].mRange.mMaxValue;
mInstructions[i + 1]->mSrc[0] = mInstructions[i + 0]->mDst;
changed = true;
}
#endif
else if (
mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 0]->mOperator == IA_ADD && mInstructions[i + 0]->mSrc[1].mTemp < 0 && mInstructions[i + 0]->mSrc[0].mType == IT_INT16 &&
@ -16129,7 +16235,6 @@ void InterCodeBasicBlock::WarnUsedUndefinedVariables(void)
}
}
void InterCodeBasicBlock::CollectVariables(GrowingVariableArray& globalVars, GrowingVariableArray& localVars, GrowingVariableArray& paramVars, InterMemory paramMemory)
{
int i;
@ -17284,7 +17389,7 @@ void InterCodeProcedure::Close(void)
{
GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "test");
CheckFunc = !strcmp(mIdent->mString, "tile_row");
mEntryBlock = mBlocks[0];
@ -17666,6 +17771,9 @@ void InterCodeProcedure::Close(void)
#endif
HoistCommonConditionalPath();
DisassembleDebug("HoistCommonConditionalPath");
#if 1
ResetVisited();
mEntryBlock->MoveLoopHeadCheckToTail();
@ -18640,6 +18748,19 @@ bool InterCodeProcedure::GlobalConstantPropagation(void)
return mEntryBlock->PropagateConstTemps(ctemps);
}
void InterCodeProcedure::HoistCommonConditionalPath(void)
{
for(;;)
{
ResetVisited();
if (!mEntryBlock->HoistCommonConditionalPath())
return;
TempForwarding();
RemoveUnusedInstructions();
}
}
void InterCodeProcedure::ReduceTemporaries(void)
{
NumberSet* collisionSet;

View File

@ -499,6 +499,8 @@ public:
bool ForwardLoopMovedTemp(void);
bool MoveTrainCrossBlock(void);
bool HoistCommonConditionalPath(void);
bool IsDirectDominatorBlock(InterCodeBasicBlock* block);
void MarkRelevantStatics(void);
void RemoveNonRelevantStatics(void);
@ -679,6 +681,7 @@ protected:
void RebuildIntegerRangeSet(void);
void CombineIndirectAddressing(void);
void SingleTailLoopOptimization(InterMemory paramMemory);
void HoistCommonConditionalPath(void);
void MergeBasicBlocks(void);
void CheckUsedDefinedTemps(void);