Fix native code inner loop detection
This commit is contained in:
parent
931c4d875a
commit
5cce611659
|
@ -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
|
||||||
|
|
|
@ -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 &&
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue