Fix native code inner loop detection

This commit is contained in:
drmortalwombat 2021-11-08 08:45:43 +01:00
parent 931c4d875a
commit 5cce611659
3 changed files with 61 additions and 70 deletions

View File

@ -1055,15 +1055,25 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
}
else
{
vr = CoerceType(proc, block, vr, vll.mType);
Declaration * otype = vll.mType;
if (exp->mToken != IA_ADD && exp->mToken != IA_SUB && otype->mSize < 2)
{
if ((vll.mType->mFlags | vr.mType->mFlags) & DTF_SIGNED)
otype = TheSignedIntTypeDeclaration;
else
otype = TheUnsignedIntTypeDeclaration;
vll = CoerceType(proc, block, vll, otype);
}
vr = CoerceType(proc, block, vr, otype);
InterInstruction * oins = new InterInstruction();
oins->mCode = IC_BINARY_OPERATOR;
oins->mSrc[0].mType = InterTypeOf(vr.mType);
oins->mSrc[0].mType = InterTypeOf(otype);
oins->mSrc[0].mTemp = vr.mTemp;
oins->mSrc[1].mType = InterTypeOf(vll.mType);
oins->mSrc[1].mType = InterTypeOf(otype);
oins->mSrc[1].mTemp = vll.mTemp;
oins->mDst.mType = InterTypeOf(vll.mType);
oins->mDst.mType = InterTypeOf(otype);
oins->mDst.mTemp = proc->AddTemporary(oins->mDst.mType);
if (!vll.mType->IsNumericType())
@ -1115,9 +1125,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
}
vr.mTemp = oins->mDst.mTemp;
vr.mType = vll.mType;
vr.mType = otype;
block->Append(oins);
vr = CoerceType(proc, block, vr, vl.mType);
}
}
else

View File

@ -8979,33 +8979,47 @@ bool NativeCodeBasicBlock::OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCo
return false;
}
bool NativeCodeBasicBlock::CheckInnerLoop(NativeCodeBasicBlock* head, GrowingArray<NativeCodeBasicBlock*>& blocks)
void NativeCodeBasicBlock::CollectInnerLoop(NativeCodeBasicBlock* head, GrowingArray<NativeCodeBasicBlock*>& lblocks)
{
if (mVisited)
return this == head;
else if (mLoopHead)
return false;
else if (mLoopHeadBlock != head)
if (mLoopHeadBlock != head)
{
mLoopHeadBlock = head;
lblocks.Push(this);
if (mTrueJump != head && mFalseJump != head)
{
if (mTrueJump)
mTrueJump->CollectInnerLoop(head, lblocks);
if (mFalseJump)
mFalseJump->CollectInnerLoop(head, lblocks);
}
}
}
NativeCodeBasicBlock* NativeCodeBasicBlock::FindTailBlock(NativeCodeBasicBlock* head)
{
if (mVisiting || mVisited)
return nullptr;
else if (mTrueJump == head || mFalseJump == head)
return this;
else
{
mVisiting = true;
if (mTrueJump && mTrueJump->CheckInnerLoop(head, blocks))
mLoopHeadBlock = head;
if (mFalseJump && mFalseJump->CheckInnerLoop(head, blocks))
mLoopHeadBlock = head;
NativeCodeBasicBlock* tail = nullptr;
if (mTrueJump)
{
tail = mTrueJump->FindTailBlock(head);
if (tail && mFalseJump && mFalseJump->FindTailBlock(head) != tail)
tail = nullptr;
}
else if (mFalseJump)
tail = mFalseJump->FindTailBlock(head);
mVisiting = false;
if (head == mLoopHeadBlock)
{
blocks.Push(this);
return true;
}
return false;
}
else
return true;
return tail;
}
}
bool NativeCodeBasicBlock::OptimizeInnerLoops(NativeCodeProcedure* proc)
@ -9014,47 +9028,21 @@ bool NativeCodeBasicBlock::OptimizeInnerLoops(NativeCodeProcedure* proc)
if (!mVisited)
{
mVisited = true;
GrowingArray<NativeCodeBasicBlock*> lblocks(nullptr);
if (mLoopHead)
{
lblocks.Push(this);
NativeCodeBasicBlock* tail = FindTailBlock(this);
bool check = false;
if (mTrueJump && mTrueJump->CheckInnerLoop(this, lblocks))
check = true;
if (mFalseJump && mFalseJump->CheckInnerLoop(this, lblocks))
check = true;
if (check)
if (tail)
{
// Find tail block
GrowingArray<NativeCodeBasicBlock*> lblocks(nullptr);
CollectInnerLoop(this, lblocks);
int i = 0;
while (i < lblocks.Size() && !(lblocks[i]->mTrueJump == this || lblocks[i]->mFalseJump == this))
i++;
NativeCodeBasicBlock* tail = lblocks[i];
i++;
while (i < lblocks.Size() && !(lblocks[i]->mTrueJump == this || lblocks[i]->mFalseJump == this))
i++;
if (i < lblocks.Size())
{
// Multi tail block
}
else
{
changed = OptimizeInnerLoop(proc, this, tail, lblocks);
}
changed = OptimizeInnerLoop(proc, this, tail, lblocks);
}
}
mVisited = true;
if (mTrueJump && mTrueJump->OptimizeInnerLoops(proc))
changed = true;
if (mFalseJump && mFalseJump->OptimizeInnerLoops(proc))
@ -9656,7 +9644,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
}
else if (
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[i + 1].mAddress &&
(mIns[i + 1].mType == ASMIT_LSR || mIns[i + 1].mType == ASMIT_ASL || mIns[i + 1].mType == ASMIT_ROL || mIns[i + 1].mType == ASMIT_ROR))
(mIns[i + 1].mType == ASMIT_LSR || mIns[i + 1].mType == ASMIT_ASL || mIns[i + 1].mType == ASMIT_ROL || mIns[i + 1].mType == ASMIT_ROR) && !(mIns[i + 0].mLive & LIVE_CPU_REG_A))
{
mIns[i + 0].mType = mIns[i + 1].mType;
mIns[i + 0].mMode = ASMIM_IMPLIED;
@ -9664,16 +9652,6 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
mIns[i + 1].mType = ASMIT_STA;
progress = true;
}
else if (
mIns[i + 1].mType == ASMIT_ASL && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == mIns[i + 1].mAddress && !(mIns[i + 0].mLive & LIVE_CPU_REG_A))
{
mIns[i + 1].mType = ASMIT_STA;
mIns[i + 0].mType = ASMIT_ASL;
mIns[i + 0].mMode = ASMIM_IMPLIED;
mIns[i + 0].mLive |= LIVE_CPU_REG_A;
progress = true;
}
#if 1
else if (
mIns[i + 0].mType == ASMIT_ASL && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&

View File

@ -127,8 +127,9 @@ public:
bool OptimizeSimpleLoop(NativeCodeProcedure* proc);
bool OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCodeBasicBlock* head, NativeCodeBasicBlock* tail, GrowingArray<NativeCodeBasicBlock*>& blocks);
NativeCodeBasicBlock* FindTailBlock(NativeCodeBasicBlock* head);
bool OptimizeInnerLoops(NativeCodeProcedure* proc);
bool CheckInnerLoop(NativeCodeBasicBlock* head, GrowingArray<NativeCodeBasicBlock*>& blocks);
void CollectInnerLoop(NativeCodeBasicBlock* head, GrowingArray<NativeCodeBasicBlock*>& lblocks);
void PutByte(uint8 code);
void PutWord(uint16 code);