Fix condition hoisting side path check

This commit is contained in:
drmortalwombat 2024-09-30 13:31:31 +02:00
parent 84a8bf22e8
commit c3b46d6a78
3 changed files with 50 additions and 16 deletions

View File

@ -13291,6 +13291,26 @@ bool InterCodeBasicBlock::IsDirectDominatorBlock(InterCodeBasicBlock* block)
return true; return true;
} }
bool InterCodeBasicBlock::CollectBlocksToDominator(InterCodeBasicBlock* dblock, ExpandingArray<InterCodeBasicBlock*>& body)
{
if (this == dblock)
return true;
if (mLoopHead)
return false;
if (mEntryBlocks.Size() == 0)
return false;
body.Push(this);
for (int i = 0; i < mEntryBlocks.Size(); i++)
if (!mEntryBlocks[i]->CollectBlocksToDominator(dblock, body))
return false;
return true;
}
bool InterCodeBasicBlock::HoistCommonConditionalPath(void) bool InterCodeBasicBlock::HoistCommonConditionalPath(void)
{ {
bool changed = false; bool changed = false;
@ -13316,6 +13336,11 @@ bool InterCodeBasicBlock::HoistCommonConditionalPath(void)
if (cblock && cblock->mNumEntries == 1) if (cblock && cblock->mNumEntries == 1)
{ {
ExpandingArray<InterCodeBasicBlock*> pblocks;
eblock->CollectBlocksToDominator(this, pblocks);
pblocks.RemoveAll(cblock);
pblocks.RemoveAll(eblock);
for (int i = 0; i < cblock->mInstructions.Size(); i++) for (int i = 0; i < cblock->mInstructions.Size(); i++)
{ {
InterInstruction* ins = cblock->mInstructions[i]; InterInstruction* ins = cblock->mInstructions[i];
@ -13328,19 +13353,25 @@ bool InterCodeBasicBlock::HoistCommonConditionalPath(void)
if (j < eblock->mInstructions.Size() && !eblock->IsTempModifiedInRange(0, j, ins->mDst.mTemp) && eblock->CanMoveInstructionBeforeBlock(j) && cblock->CanMoveInstructionBeforeBlock(cblock->mInstructions.Size(), eblock->mInstructions[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; int k = 0;
eblock->mInstructions[j]->mSrc[0] = ins->mDst; while (k < pblocks.Size() && !pblocks[k]->IsTempModified(ins->mDst.mTemp))
eblock->mInstructions[j]->mNumOperands = 1; k++;
if (k == pblocks.Size())
{
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); mInstructions.Insert(mInstructions.Size() - 1, ins);
cblock->mInstructions.Remove(i); cblock->mInstructions.Remove(i);
mExitRequiredTemps += ins->mDst.mTemp; mExitRequiredTemps += ins->mDst.mTemp;
cblock->mEntryRequiredTemps += ins->mDst.mTemp; cblock->mEntryRequiredTemps += ins->mDst.mTemp;
cblock->mExitRequiredTemps += ins->mDst.mTemp; cblock->mExitRequiredTemps += ins->mDst.mTemp;
eblock->mEntryRequiredTemps += ins->mDst.mTemp; eblock->mEntryRequiredTemps += ins->mDst.mTemp;
i--; i--;
changed = true; changed = true;
}
} }
} }
} }
@ -22568,7 +22599,7 @@ void InterCodeProcedure::Close(void)
{ {
GrowingTypeArray tstack(IT_NONE); GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "foo"); CheckFunc = !strcmp(mIdent->mString, "Test::move");
CheckCase = false; CheckCase = false;
mEntryBlock = mBlocks[0]; mEntryBlock = mBlocks[0];
@ -22963,6 +22994,7 @@ void InterCodeProcedure::Close(void)
#endif #endif
DisassembleDebug("PreHoistCommonConditionalPath");
HoistCommonConditionalPath(); HoistCommonConditionalPath();
DisassembleDebug("HoistCommonConditionalPath"); DisassembleDebug("HoistCommonConditionalPath");
@ -24232,6 +24264,7 @@ void InterCodeProcedure::HoistCommonConditionalPath(void)
ResetVisited(); ResetVisited();
if (!mEntryBlock->HoistCommonConditionalPath()) if (!mEntryBlock->HoistCommonConditionalPath())
return; return;
Disassemble("InnerHoist");
TempForwarding(); TempForwarding();
RemoveUnusedInstructions(); RemoveUnusedInstructions();
} }

View File

@ -549,6 +549,7 @@ public:
bool IsDominator(InterCodeBasicBlock* block); bool IsDominator(InterCodeBasicBlock* block);
bool IsDirectDominatorBlock(InterCodeBasicBlock* block); bool IsDirectDominatorBlock(InterCodeBasicBlock* block);
bool IsDirectLoopPathBlock(InterCodeBasicBlock* block); bool IsDirectLoopPathBlock(InterCodeBasicBlock* block);
bool CollectBlocksToDominator(InterCodeBasicBlock* dblock, ExpandingArray<InterCodeBasicBlock*>& body);
void MarkRelevantStatics(void); void MarkRelevantStatics(void);
void RemoveNonRelevantStatics(void); void RemoveNonRelevantStatics(void);

View File

@ -1735,7 +1735,7 @@ Expression* Parser::ParseVarInitExpression(Expression* vexp, bool inner)
Declaration * dec = new Declaration(mScanner->mLocation, DT_CONST_DATA); Declaration * dec = new Declaration(mScanner->mLocation, DT_CONST_DATA);
dec->mBase = dtype; dec->mBase = dtype;
dec->mSize = dtype->mSize; dec->mSize = dtype->mSize;
dec->mSection = mDataSection; dec->mSection = mCodeSection;
dec->mData = d; dec->mData = d;
@ -1816,7 +1816,7 @@ Expression* Parser::ParseVarInitExpression(Expression* vexp, bool inner)
Declaration * csdec = new Declaration(mScanner->mLocation, DT_CONST_STRUCT); Declaration * csdec = new Declaration(mScanner->mLocation, DT_CONST_STRUCT);
csdec->mBase = dtype; csdec->mBase = dtype;
csdec->mSize = dtype->mSize; csdec->mSize = dtype->mSize;
csdec->mSection = mDataSection; csdec->mSection = mCodeSection;
Declaration* last = nullptr; Declaration* last = nullptr;
@ -5436,7 +5436,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
} }
else if (pthis) else if (pthis)
{ {
ndec->mFlags |= storageFlags & DTF_STATIC; ndec->mFlags |= storageFlags & (DTF_STATIC | DTF_PREVENT_INLINE);
} }
ndec->mOffset = 0; ndec->mOffset = 0;
@ -5746,7 +5746,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
ndec->mValue = ParseFunction(ndec->mBase); ndec->mValue = ParseFunction(ndec->mBase);
mFunction = nullptr; mFunction = nullptr;
if (pthis) if (pthis && !(storageFlags & DTF_PREVENT_INLINE))
ndec->mFlags |= DTF_REQUEST_INLINE; ndec->mFlags |= DTF_REQUEST_INLINE;
ndec->mFlags |= DTF_DEFINED; ndec->mFlags |= DTF_DEFINED;