Improve cross loop value propagation

This commit is contained in:
drmortalwombat 2024-07-16 08:36:52 +02:00
parent d3536a718e
commit c229a27992
2 changed files with 130 additions and 15 deletions

View File

@ -5626,6 +5626,17 @@ void InterCodeBasicBlock::BuildDominatorTree(InterCodeBasicBlock* from)
mFalseJump->BuildDominatorTree(this); mFalseJump->BuildDominatorTree(this);
} }
bool InterCodeBasicBlock::IsDominator(InterCodeBasicBlock* block)
{
while (block)
{
if (block == this)
return true;
block = block->mDominator;
}
return false;
}
void InterCodeBasicBlock::CollectEntries(void) void InterCodeBasicBlock::CollectEntries(void)
{ {
mNumEntries++; mNumEntries++;
@ -11584,12 +11595,46 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
for (int i = 0; i < mInstructions.Size(); i++) for (int i = 0; i < mInstructions.Size(); i++)
{ {
InterInstruction* ins(mInstructions[i]); InterInstruction* ins(mInstructions[i]);
if (ins->mDst.mTemp >= 0)
{
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])) if (InvalidatedBy(mLoadStoreInstructions[j], ins))
mLoadStoreInstructions.Remove(j);
else
j++;
}
}
}
#if 1
else if (tvalue.Size() > 0)
{
ExpandingArray<InterCodeBasicBlock*> body;
body.Push(this);
bool innerLoop = true;
int n = 1;
for (int i = 0; i < mEntryBlocks.Size(); i++)
{
if (IsDominator( mEntryBlocks[i] ))
{
n++;
if (!mEntryBlocks[i]->CollectLoopBodyRecursive(this, body))
innerLoop = false;
}
}
if (innerLoop && n == mEntryBlocks.Size() )
{
mLoadStoreInstructions = tvalue;
for (int j = 0; j < body.Size(); j++)
{
for (int i = 0; i < body[j]->mInstructions.Size(); i++)
{
InterInstruction* ins(body[j]->mInstructions[i]);
int j = 0;
while (j < mLoadStoreInstructions.Size())
{
if (InvalidatedBy(mLoadStoreInstructions[j], ins))
mLoadStoreInstructions.Remove(j); mLoadStoreInstructions.Remove(j);
else else
j++; j++;
@ -11597,12 +11642,27 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
} }
} }
} }
else
mLoadStoreInstructions.SetSize(0);
}
#endif
#endif #endif
else else
mLoadStoreInstructions.SetSize(0); mLoadStoreInstructions.SetSize(0);
mVisited = true; mVisited = true;
#if 0
for (int i = 0; i < mLoadStoreInstructions.Size(); i++)
{
if (mLoadStoreInstructions[i]->mCode == IC_STORE &&
mLoadStoreInstructions[i]->mSrc[1].mTemp < 0 &&
mLoadStoreInstructions[i]->mSrc[1].mMemory == IM_GLOBAL &&
mLoadStoreInstructions[i]->mSrc[1].mVarIndex == 68)
printf("I:%d\n", mIndex);
}
#endif
#if 1 #if 1
// move loads up as far as possible to avoid false aliasing // move loads up as far as possible to avoid false aliasing
for (int i = 1; i < mInstructions.Size(); i++) for (int i = 1; i < mInstructions.Size(); i++)
@ -11673,18 +11733,35 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
else else
{ {
j = 0; j = 0;
while (j < mLoadStoreInstructions.Size() && !(mLoadStoreInstructions[j]->mCode == IC_COPY && SameMemSegment(mLoadStoreInstructions[j]->mSrc[1], ins->mSrc[0]))) while (j < mLoadStoreInstructions.Size() && !(
mLoadStoreInstructions[j]->mCode == IC_COPY && SameMemSegment(mLoadStoreInstructions[j]->mSrc[1], ins->mSrc[0]) ||
mLoadStoreInstructions[j]->mCode == IC_FILL && SameMemSegment(mLoadStoreInstructions[j]->mSrc[1], ins->mSrc[0])))
j++; j++;
if (j < mLoadStoreInstructions.Size()) if (j < mLoadStoreInstructions.Size())
{ {
InterInstruction* cins = mLoadStoreInstructions[j]; InterInstruction* cins = mLoadStoreInstructions[j];
if (cins->mCode == IC_FILL)
{
int64 v = 0;
for (int j = 0; j < InterTypeSize[ins->mDst.mType]; j++)
v = (v << 8) | (cins->mSrc[0].mIntConst & 0xff);
ins->mCode = IC_CONSTANT;
ins->mConst.mType = ins->mDst.mType;
ins->mConst.mIntConst = v;
ins->mNumOperands = 0;
changed = true;
}
else
{
int64 offset = ins->mSrc[0].mIntConst - cins->mSrc[1].mIntConst; int64 offset = ins->mSrc[0].mIntConst - cins->mSrc[1].mIntConst;
ins->mSrc[0] = cins->mSrc[0]; ins->mSrc[0] = cins->mSrc[0];
ins->mSrc[0].mOperandSize = InterTypeSize[ins->mDst.mType]; ins->mSrc[0].mOperandSize = InterTypeSize[ins->mDst.mType];
ins->mSrc[0].mIntConst += offset; ins->mSrc[0].mIntConst += offset;
changed = true; changed = true;
} }
}
else else
nins = ins; nins = ins;
} }
@ -11776,8 +11853,31 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
nins = ins; nins = ins;
#endif #endif
} }
else if (ins->mCode == IC_STRCPY || ins->mCode == IC_FILL) else if (ins->mCode == IC_FILL)
flushMem = true; {
int j = 0, k = 0;
while (j < mLoadStoreInstructions.Size())
{
if (!DestroyingMem(mLoadStoreInstructions[j], ins))
mLoadStoreInstructions[k++] = mLoadStoreInstructions[j];
j++;
}
mLoadStoreInstructions.SetSize(k);
if (!ins->mVolatile && ins->mSrc[1].mStride == 1 && ins->mSrc[0].mTemp < 0)
nins = ins;
}
else if (ins->mCode == IC_STRCPY)
{
int j = 0, k = 0;
while (j < mLoadStoreInstructions.Size())
{
if (!DestroyingMem(mLoadStoreInstructions[j], ins))
mLoadStoreInstructions[k++] = mLoadStoreInstructions[j];
j++;
}
mLoadStoreInstructions.SetSize(k);
}
else if (ins->mCode == IC_LEA || ins->mCode == IC_UNARY_OPERATOR || ins->mCode == IC_BINARY_OPERATOR || ins->mCode == IC_RELATIONAL_OPERATOR || ins->mCode == IC_CONVERSION_OPERATOR) else if (ins->mCode == IC_LEA || ins->mCode == IC_UNARY_OPERATOR || ins->mCode == IC_BINARY_OPERATOR || ins->mCode == IC_RELATIONAL_OPERATOR || ins->mCode == IC_CONVERSION_OPERATOR)
{ {
// //
@ -14093,6 +14193,17 @@ bool InterCodeBasicBlock::CollidingMem(InterCodeBasicBlock* block, InterInstruct
return false; return false;
} }
bool InterCodeBasicBlock::InvalidatedBy(const InterInstruction* ins, const InterInstruction* by) const
{
if (by->mDst.mTemp >= 0 && ins->ReferencesTemp(by->mDst.mTemp))
return true;
else if (ins->mCode == IC_STORE || ins->mCode == IC_LOAD)
return DestroyingMem(ins, by);
else
return CollidingMem(by, ins);
}
bool InterCodeBasicBlock::CollectSingleHeadLoopBody(InterCodeBasicBlock* head, InterCodeBasicBlock* tail, GrowingArray<InterCodeBasicBlock*>& body) bool InterCodeBasicBlock::CollectSingleHeadLoopBody(InterCodeBasicBlock* head, InterCodeBasicBlock* tail, GrowingArray<InterCodeBasicBlock*>& body)
{ {
int i = 0; int i = 0;
@ -21381,6 +21492,8 @@ void InterCodeProcedure::ReduceRecursionTempSpilling(InterMemory paramMemory)
void InterCodeProcedure::LoadStoreForwarding(InterMemory paramMemory) void InterCodeProcedure::LoadStoreForwarding(InterMemory paramMemory)
{ {
BuildTraces(false);
DisassembleDebug("Load/Store forwardingY"); DisassembleDebug("Load/Store forwardingY");
bool changed; bool changed;

View File

@ -531,6 +531,7 @@ public:
bool MoveTrainCrossBlock(void); bool MoveTrainCrossBlock(void);
bool HoistCommonConditionalPath(void); bool HoistCommonConditionalPath(void);
bool IsDominator(InterCodeBasicBlock* block);
bool IsDirectDominatorBlock(InterCodeBasicBlock* block); bool IsDirectDominatorBlock(InterCodeBasicBlock* block);
bool IsDirectLoopPathBlock(InterCodeBasicBlock* block); bool IsDirectLoopPathBlock(InterCodeBasicBlock* block);
@ -546,6 +547,7 @@ public:
bool CollidingMem(const InterOperand& op, InterType type, const InterInstruction* ins) 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(const InterOperand& op1, InterType type1, const InterOperand& op2, InterType type2) const;
bool CollidingMem(InterCodeBasicBlock* block, InterInstruction* lins, int from, int to) const; bool CollidingMem(InterCodeBasicBlock* block, InterInstruction* lins, int from, int to) const;
bool InvalidatedBy(const InterInstruction* ins, const InterInstruction* by) const;
bool PushSinglePathResultInstructions(void); bool PushSinglePathResultInstructions(void);