Add loop sinking optimization
This commit is contained in:
parent
f5dff9620b
commit
d2fdbd29f5
|
@ -16106,6 +16106,73 @@ bool InterCodeBasicBlock::SingleTailLoopOptimization(const NumberSet& aliasedPar
|
||||||
return modified;
|
return modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InterCodeBasicBlock::EmptyLoopOptimization(void)
|
||||||
|
{
|
||||||
|
bool modified = false;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
if (mLoopHead && mNumEntries == 2 && (mTrueJump == this || mFalseJump == this))
|
||||||
|
{
|
||||||
|
if (mInstructions.Size() == 3)
|
||||||
|
{
|
||||||
|
InterInstruction* ai = mInstructions[0];
|
||||||
|
InterInstruction* ci = mInstructions[1];
|
||||||
|
InterInstruction* bi = mInstructions[2];
|
||||||
|
|
||||||
|
if (ai->mCode == IC_BINARY_OPERATOR && ai->mOperator == IA_ADD && ai->mSrc[0].mTemp < 0 && ai->mDst.mTemp == ai->mSrc[1].mTemp && ai->mSrc[0].mIntConst == 1 && IsIntegerType(ai->mDst.mType) &&
|
||||||
|
ci->mCode == IC_RELATIONAL_OPERATOR && ci->mOperator == IA_CMPLU && ci->mSrc[1].mTemp == ai->mDst.mTemp &&
|
||||||
|
bi->mCode == IC_BRANCH && bi->mSrc[0].mTemp == ci->mDst.mTemp)
|
||||||
|
{
|
||||||
|
InterInstruction* mi = nullptr;
|
||||||
|
|
||||||
|
InterInstruction* si = FindSourceInstruction(mLoopPrefix, ai->mSrc[1].mTemp);
|
||||||
|
if (si && si->mDst.mRange.mMaxState == IntegerValueRange::S_BOUND &&
|
||||||
|
ci->mSrc[0].mRange.mMinState == IntegerValueRange::S_BOUND &&
|
||||||
|
si->mDst.mRange.mMaxValue < ci->mSrc[0].mRange.mMinValue)
|
||||||
|
{
|
||||||
|
if (ci->mSrc[0].mTemp >= 0)
|
||||||
|
{
|
||||||
|
mi = new InterInstruction(ai->mLocation, IC_LOAD_TEMPORARY);
|
||||||
|
mi->mDst = ai->mDst;
|
||||||
|
mi->mSrc[0] = ci->mSrc[0];
|
||||||
|
mi->mDst.mRange = mi->mSrc[0].mRange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mi)
|
||||||
|
{
|
||||||
|
mInstructions.SetSize(0);
|
||||||
|
mInstructions.Push(mi);
|
||||||
|
|
||||||
|
if (mFalseJump != this)
|
||||||
|
mTrueJump = mFalseJump;
|
||||||
|
mFalseJump = nullptr;
|
||||||
|
mLoopHead = false;
|
||||||
|
mNumEntries = 1;
|
||||||
|
mEntryBlocks.SetSize(0);
|
||||||
|
mEntryBlocks.Push(mLoopPrefix);
|
||||||
|
|
||||||
|
InterInstruction* ins = new InterInstruction(mi->mLocation, IC_JUMP);
|
||||||
|
mInstructions.Push(ins);
|
||||||
|
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump && mTrueJump->EmptyLoopOptimization())
|
||||||
|
modified = true;
|
||||||
|
if (mFalseJump && mFalseJump->EmptyLoopOptimization())
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
void InterCodeBasicBlock::ConstLoopOptimization(void)
|
void InterCodeBasicBlock::ConstLoopOptimization(void)
|
||||||
{
|
{
|
||||||
if (!mVisited)
|
if (!mVisited)
|
||||||
|
@ -17929,6 +17996,66 @@ bool InterCodeBasicBlock::CheckSingleBlockLimitedLoop(InterCodeBasicBlock*& pbl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool InterCodeBasicBlock::SingleBlockLoopSinking(int& spareTemps)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
if (mLoopHead && mNumEntries == 2 && mFalseJump && (mTrueJump == this || mFalseJump == this) && mInstructions.Size() > 3)
|
||||||
|
{
|
||||||
|
InterCodeBasicBlock* pblock = mEntryBlocks[0], * eblock = mFalseJump;
|
||||||
|
if (pblock == this)
|
||||||
|
pblock = mEntryBlocks[1];
|
||||||
|
if (eblock == this)
|
||||||
|
eblock = mTrueJump;
|
||||||
|
|
||||||
|
if (eblock->mNumEntries == 1)
|
||||||
|
{
|
||||||
|
int j = mInstructions.Size() - 1;
|
||||||
|
while (j >= 0)
|
||||||
|
{
|
||||||
|
InterInstruction* ins = mInstructions[j];
|
||||||
|
|
||||||
|
if (ins->mCode != IC_LOAD_TEMPORARY && !HasSideEffect(ins->mCode) && ins->mDst.mTemp >= 0 && !IsTempUsedInRange(0, mInstructions.Size(), ins->mDst.mTemp) && !ins->mVolatile)
|
||||||
|
{
|
||||||
|
if (spareTemps + ins->mNumOperands >= mEntryRequiredTemps.Size() + 16)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
mInstructions.Remove(j);
|
||||||
|
eblock->mInstructions.Insert(0, ins);
|
||||||
|
|
||||||
|
for (int i = 0; i < ins->mNumOperands; i++)
|
||||||
|
{
|
||||||
|
if (ins->mSrc[i].mTemp >= 0 && IsTempModifiedInRange(j, mInstructions.Size(), ins->mSrc[i].mTemp))
|
||||||
|
{
|
||||||
|
InterInstruction* tins = new InterInstruction(ins->mLocation, IC_LOAD_TEMPORARY);
|
||||||
|
tins->mSrc[0] = ins->mSrc[i];
|
||||||
|
tins->mDst = tins->mSrc[0];
|
||||||
|
tins->mDst.mTemp = spareTemps++;
|
||||||
|
ins->mSrc[i] = tins->mDst;
|
||||||
|
mInstructions.Insert(j, tins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump && mTrueJump->SingleBlockLoopSinking(spareTemps))
|
||||||
|
changed = true;
|
||||||
|
if (mFalseJump && mFalseJump->SingleBlockLoopSinking(spareTemps))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
bool InterCodeBasicBlock::SingleBlockLoopPointerToByte(int& spareTemps)
|
bool InterCodeBasicBlock::SingleBlockLoopPointerToByte(int& spareTemps)
|
||||||
{
|
{
|
||||||
|
@ -22832,6 +22959,55 @@ void InterCodeProcedure::SingleBlockLoopPointerSplit(FastNumberSet& activeSet)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InterCodeProcedure::SingleBlockLoopSinking(FastNumberSet& activeSet)
|
||||||
|
{
|
||||||
|
int silvused = mTemporaries.Size();
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->BuildLoopSuffix();
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
mTemporaries.SetSize(silvused, true);
|
||||||
|
|
||||||
|
DisassembleDebug("SingleBlockLoopSinkingA");
|
||||||
|
|
||||||
|
BuildDataFlowSets();
|
||||||
|
|
||||||
|
DisassembleDebug("SingleBlockLoopSinkingB");
|
||||||
|
|
||||||
|
TempForwarding();
|
||||||
|
RemoveUnusedInstructions();
|
||||||
|
|
||||||
|
DisassembleDebug("SingleBlockLoopSinkingC");
|
||||||
|
|
||||||
|
activeSet.Clear();
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->CollectActiveTemporaries(activeSet);
|
||||||
|
|
||||||
|
silvused = activeSet.Num();
|
||||||
|
if (silvused != mTemporaries.Size())
|
||||||
|
{
|
||||||
|
mTemporaries.SetSize(activeSet.Num(), true);
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->ShrinkActiveTemporaries(activeSet, mTemporaries);
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->RemapActiveTemporaries(activeSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
} while (mEntryBlock->SingleBlockLoopSinking(silvused));
|
||||||
|
|
||||||
|
assert(silvused == mTemporaries.Size());
|
||||||
|
|
||||||
|
DisassembleDebug("SingleBlockLoopSinking");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void InterCodeProcedure::SimplifyIntegerNumeric(FastNumberSet& activeSet)
|
void InterCodeProcedure::SimplifyIntegerNumeric(FastNumberSet& activeSet)
|
||||||
{
|
{
|
||||||
GrowingInstructionPtrArray silvalues(nullptr);
|
GrowingInstructionPtrArray silvalues(nullptr);
|
||||||
|
@ -23417,6 +23593,8 @@ void InterCodeProcedure::Close(void)
|
||||||
|
|
||||||
SingleBlockLoopPointerToByte(activeSet);
|
SingleBlockLoopPointerToByte(activeSet);
|
||||||
|
|
||||||
|
SingleBlockLoopSinking(activeSet);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
DisassembleDebug("PreMoveTrainCrossBlockA");
|
DisassembleDebug("PreMoveTrainCrossBlockA");
|
||||||
|
|
||||||
|
@ -23844,6 +24022,9 @@ void InterCodeProcedure::Close(void)
|
||||||
|
|
||||||
ConstLoopOptimization();
|
ConstLoopOptimization();
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->EmptyLoopOptimization();
|
||||||
|
|
||||||
// CollapseDispatch();
|
// CollapseDispatch();
|
||||||
// DisassembleDebug("CollapseDispatch");
|
// DisassembleDebug("CollapseDispatch");
|
||||||
|
|
||||||
|
|
|
@ -625,11 +625,13 @@ public:
|
||||||
void SingleBlockLoopUnrolling(void);
|
void SingleBlockLoopUnrolling(void);
|
||||||
bool SingleBlockLoopPointerSplit(int& spareTemps);
|
bool SingleBlockLoopPointerSplit(int& spareTemps);
|
||||||
bool SingleBlockLoopPointerToByte(int& spareTemps);
|
bool SingleBlockLoopPointerToByte(int& spareTemps);
|
||||||
|
bool SingleBlockLoopSinking(int& spareTemps);
|
||||||
bool CollectLoopBody(InterCodeBasicBlock* head, ExpandingArray<InterCodeBasicBlock*> & body);
|
bool CollectLoopBody(InterCodeBasicBlock* head, ExpandingArray<InterCodeBasicBlock*> & body);
|
||||||
bool CollectLoopBodyRecursive(InterCodeBasicBlock* head, ExpandingArray<InterCodeBasicBlock*>& body);
|
bool CollectLoopBodyRecursive(InterCodeBasicBlock* head, ExpandingArray<InterCodeBasicBlock*>& body);
|
||||||
void CollectLoopPath(const ExpandingArray<InterCodeBasicBlock*>& body, ExpandingArray<InterCodeBasicBlock*>& path);
|
void CollectLoopPath(const ExpandingArray<InterCodeBasicBlock*>& body, ExpandingArray<InterCodeBasicBlock*>& path);
|
||||||
void InnerLoopOptimization(const NumberSet& aliasedParams);
|
void InnerLoopOptimization(const NumberSet& aliasedParams);
|
||||||
void ConstLoopOptimization(void);
|
void ConstLoopOptimization(void);
|
||||||
|
bool EmptyLoopOptimization(void);
|
||||||
void EliminateDoubleLoopCounter(void);
|
void EliminateDoubleLoopCounter(void);
|
||||||
void PushMoveOutOfLoop(void);
|
void PushMoveOutOfLoop(void);
|
||||||
bool MoveConditionOutOfLoop(void);
|
bool MoveConditionOutOfLoop(void);
|
||||||
|
@ -776,6 +778,7 @@ protected:
|
||||||
void SimplifyIntegerNumeric(FastNumberSet& activeSet);
|
void SimplifyIntegerNumeric(FastNumberSet& activeSet);
|
||||||
void SingleBlockLoopPointerSplit(FastNumberSet& activeSet);
|
void SingleBlockLoopPointerSplit(FastNumberSet& activeSet);
|
||||||
void SingleBlockLoopPointerToByte(FastNumberSet& activeSet);
|
void SingleBlockLoopPointerToByte(FastNumberSet& activeSet);
|
||||||
|
void SingleBlockLoopSinking(FastNumberSet& activeSet);
|
||||||
void MergeIndexedLoadStore(void);
|
void MergeIndexedLoadStore(void);
|
||||||
void EliminateAliasValues();
|
void EliminateAliasValues();
|
||||||
void LoadStoreForwarding(InterMemory paramMemory);
|
void LoadStoreForwarding(InterMemory paramMemory);
|
||||||
|
|
Loading…
Reference in New Issue