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 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(); InterInstruction * oins = new InterInstruction();
oins->mCode = IC_BINARY_OPERATOR; 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[0].mTemp = vr.mTemp;
oins->mSrc[1].mType = InterTypeOf(vll.mType); oins->mSrc[1].mType = InterTypeOf(otype);
oins->mSrc[1].mTemp = vll.mTemp; 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); oins->mDst.mTemp = proc->AddTemporary(oins->mDst.mType);
if (!vll.mType->IsNumericType()) if (!vll.mType->IsNumericType())
@ -1115,9 +1125,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
} }
vr.mTemp = oins->mDst.mTemp; vr.mTemp = oins->mDst.mTemp;
vr.mType = vll.mType; vr.mType = otype;
block->Append(oins); block->Append(oins);
vr = CoerceType(proc, block, vr, vl.mType);
} }
} }
else else

View File

@ -8979,33 +8979,47 @@ bool NativeCodeBasicBlock::OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCo
return false; return false;
} }
bool NativeCodeBasicBlock::CheckInnerLoop(NativeCodeBasicBlock* head, GrowingArray<NativeCodeBasicBlock*>& blocks) void NativeCodeBasicBlock::CollectInnerLoop(NativeCodeBasicBlock* head, GrowingArray<NativeCodeBasicBlock*>& lblocks)
{ {
if (mVisited) if (mLoopHeadBlock != head)
return this == head; {
else if (mLoopHead) mLoopHeadBlock = head;
return false; lblocks.Push(this);
else if (mLoopHeadBlock != head)
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; mVisiting = true;
if (mTrueJump && mTrueJump->CheckInnerLoop(head, blocks)) NativeCodeBasicBlock* tail = nullptr;
mLoopHeadBlock = head; if (mTrueJump)
if (mFalseJump && mFalseJump->CheckInnerLoop(head, blocks)) {
mLoopHeadBlock = head; tail = mTrueJump->FindTailBlock(head);
if (tail && mFalseJump && mFalseJump->FindTailBlock(head) != tail)
tail = nullptr;
}
else if (mFalseJump)
tail = mFalseJump->FindTailBlock(head);
mVisiting = false; mVisiting = false;
if (head == mLoopHeadBlock) return tail;
{
blocks.Push(this);
return true;
} }
return false;
}
else
return true;
} }
bool NativeCodeBasicBlock::OptimizeInnerLoops(NativeCodeProcedure* proc) bool NativeCodeBasicBlock::OptimizeInnerLoops(NativeCodeProcedure* proc)
@ -9014,46 +9028,20 @@ bool NativeCodeBasicBlock::OptimizeInnerLoops(NativeCodeProcedure* proc)
if (!mVisited) if (!mVisited)
{ {
mVisited = true;
GrowingArray<NativeCodeBasicBlock*> lblocks(nullptr);
if (mLoopHead) if (mLoopHead)
{ {
lblocks.Push(this); NativeCodeBasicBlock* tail = FindTailBlock(this);
bool check = false; if (tail)
if (mTrueJump && mTrueJump->CheckInnerLoop(this, lblocks))
check = true;
if (mFalseJump && mFalseJump->CheckInnerLoop(this, lblocks))
check = true;
if (check)
{ {
// 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)) if (mTrueJump && mTrueJump->OptimizeInnerLoops(proc))
changed = true; changed = true;
@ -9656,7 +9644,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
} }
else if ( 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 + 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].mType = mIns[i + 1].mType;
mIns[i + 0].mMode = ASMIM_IMPLIED; mIns[i + 0].mMode = ASMIM_IMPLIED;
@ -9664,16 +9652,6 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
mIns[i + 1].mType = ASMIT_STA; mIns[i + 1].mType = ASMIT_STA;
progress = true; 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 #if 1
else if ( else if (
mIns[i + 0].mType == ASMIT_ASL && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && 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 OptimizeSimpleLoop(NativeCodeProcedure* proc);
bool OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCodeBasicBlock* head, NativeCodeBasicBlock* tail, GrowingArray<NativeCodeBasicBlock*>& blocks); bool OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCodeBasicBlock* head, NativeCodeBasicBlock* tail, GrowingArray<NativeCodeBasicBlock*>& blocks);
NativeCodeBasicBlock* FindTailBlock(NativeCodeBasicBlock* head);
bool OptimizeInnerLoops(NativeCodeProcedure* proc); bool OptimizeInnerLoops(NativeCodeProcedure* proc);
bool CheckInnerLoop(NativeCodeBasicBlock* head, GrowingArray<NativeCodeBasicBlock*>& blocks); void CollectInnerLoop(NativeCodeBasicBlock* head, GrowingArray<NativeCodeBasicBlock*>& lblocks);
void PutByte(uint8 code); void PutByte(uint8 code);
void PutWord(uint16 code); void PutWord(uint16 code);