Improve cross loop value propagation
This commit is contained in:
parent
d3536a718e
commit
c229a27992
|
@ -5626,6 +5626,17 @@ void InterCodeBasicBlock::BuildDominatorTree(InterCodeBasicBlock* from)
|
|||
mFalseJump->BuildDominatorTree(this);
|
||||
}
|
||||
|
||||
bool InterCodeBasicBlock::IsDominator(InterCodeBasicBlock* block)
|
||||
{
|
||||
while (block)
|
||||
{
|
||||
if (block == this)
|
||||
return true;
|
||||
block = block->mDominator;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void InterCodeBasicBlock::CollectEntries(void)
|
||||
{
|
||||
mNumEntries++;
|
||||
|
@ -11584,25 +11595,74 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
|
|||
for (int i = 0; i < mInstructions.Size(); i++)
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
if (ins->mDst.mTemp >= 0)
|
||||
int j = 0;
|
||||
while (j < mLoadStoreInstructions.Size())
|
||||
{
|
||||
int j = 0;
|
||||
while (j < mLoadStoreInstructions.Size())
|
||||
{
|
||||
if (mLoadStoreInstructions[j]->ReferencesTemp(ins->mDst.mTemp) || CollidingMem(ins, mLoadStoreInstructions[j]))
|
||||
mLoadStoreInstructions.Remove(j);
|
||||
else
|
||||
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);
|
||||
else
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
mLoadStoreInstructions.SetSize(0);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
else
|
||||
mLoadStoreInstructions.SetSize(0);
|
||||
|
||||
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
|
||||
// move loads up as far as possible to avoid false aliasing
|
||||
for (int i = 1; i < mInstructions.Size(); i++)
|
||||
|
@ -11673,17 +11733,34 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
|
|||
else
|
||||
{
|
||||
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++;
|
||||
if (j < mLoadStoreInstructions.Size())
|
||||
{
|
||||
InterInstruction* cins = mLoadStoreInstructions[j];
|
||||
|
||||
int64 offset = ins->mSrc[0].mIntConst - cins->mSrc[1].mIntConst;
|
||||
ins->mSrc[0] = cins->mSrc[0];
|
||||
ins->mSrc[0].mOperandSize = InterTypeSize[ins->mDst.mType];
|
||||
ins->mSrc[0].mIntConst += offset;
|
||||
changed = true;
|
||||
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;
|
||||
ins->mSrc[0] = cins->mSrc[0];
|
||||
ins->mSrc[0].mOperandSize = InterTypeSize[ins->mDst.mType];
|
||||
ins->mSrc[0].mIntConst += offset;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
nins = ins;
|
||||
|
@ -11776,8 +11853,31 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
|
|||
nins = ins;
|
||||
#endif
|
||||
}
|
||||
else if (ins->mCode == IC_STRCPY || ins->mCode == IC_FILL)
|
||||
flushMem = true;
|
||||
else if (ins->mCode == IC_FILL)
|
||||
{
|
||||
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)
|
||||
{
|
||||
//
|
||||
|
@ -14093,6 +14193,17 @@ bool InterCodeBasicBlock::CollidingMem(InterCodeBasicBlock* block, InterInstruct
|
|||
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)
|
||||
{
|
||||
int i = 0;
|
||||
|
@ -21381,6 +21492,8 @@ void InterCodeProcedure::ReduceRecursionTempSpilling(InterMemory paramMemory)
|
|||
|
||||
void InterCodeProcedure::LoadStoreForwarding(InterMemory paramMemory)
|
||||
{
|
||||
BuildTraces(false);
|
||||
|
||||
DisassembleDebug("Load/Store forwardingY");
|
||||
|
||||
bool changed;
|
||||
|
|
|
@ -531,6 +531,7 @@ public:
|
|||
|
||||
bool MoveTrainCrossBlock(void);
|
||||
bool HoistCommonConditionalPath(void);
|
||||
bool IsDominator(InterCodeBasicBlock* block);
|
||||
bool IsDirectDominatorBlock(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& op1, InterType type1, const InterOperand& op2, InterType type2) const;
|
||||
bool CollidingMem(InterCodeBasicBlock* block, InterInstruction* lins, int from, int to) const;
|
||||
bool InvalidatedBy(const InterInstruction* ins, const InterInstruction* by) const;
|
||||
|
||||
bool PushSinglePathResultInstructions(void);
|
||||
|
||||
|
|
Loading…
Reference in New Issue