Fix inter instruction cross block move
This commit is contained in:
parent
5564b01d11
commit
7d3dc493c0
|
@ -10004,7 +10004,15 @@ int InterCodeBasicBlock::FindSameInstruction(const InterInstruction* ins) const
|
|||
|
||||
bool InterCodeBasicBlock::CanMoveInstructionBehindBlock(int ii) const
|
||||
{
|
||||
return CanMoveInstructionDown(ii, mInstructions.Size());
|
||||
if (CanMoveInstructionDown(ii, mInstructions.Size() - 1))
|
||||
{
|
||||
InterInstruction* ins = mInstructions.Last();
|
||||
if (ins->mCode == IC_BRANCH && mInstructions[ii]->mDst.mTemp == ins->mSrc[0].mTemp)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InterCodeBasicBlock::CanMoveInstructionBeforeBlock(int ii, const InterInstruction* ins) const
|
||||
|
@ -12163,6 +12171,39 @@ bool InterCodeBasicBlock::CheckSingleBlockLimitedLoop(InterCodeBasicBlock*& pbl
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (
|
||||
mInstructions[nins - 1]->mCode == IC_BRANCH &&
|
||||
mInstructions[nins - 2]->mCode == IC_BINARY_OPERATOR && mInstructions[nins - 2]->mOperator == IA_ADD)
|
||||
{
|
||||
InterInstruction* ains = mInstructions[nins - 2];
|
||||
InterInstruction* bins = mInstructions[nins - 1];
|
||||
|
||||
if (bins->mSrc[0].mTemp == ains->mDst.mTemp &&
|
||||
ains->mSrc[1].mTemp == ains->mDst.mTemp &&
|
||||
ains->mSrc[0].mTemp < 0 &&
|
||||
ains->mSrc[0].mIntConst == -1)
|
||||
{
|
||||
int pi = pblock->mInstructions.Size() - 1;
|
||||
while (pi >= 0 && pblock->mInstructions[pi]->mDst.mTemp != ains->mDst.mTemp)
|
||||
pi--;
|
||||
|
||||
if (pi >= 0 && pblock->mInstructions[pi]->mCode == IC_CONSTANT)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < nins - 2 && mInstructions[i]->mDst.mTemp != ains->mDst.mTemp)
|
||||
i++;
|
||||
if (i == nins - 2)
|
||||
{
|
||||
nloop = pblock->mInstructions[pi]->mConst.mIntConst;
|
||||
|
||||
mLocalValueRange[ains->mDst.mTemp].LimitMin(1);
|
||||
mLocalValueRange[ains->mDst.mTemp].LimitMax(pblock->mInstructions[pi]->mConst.mIntConst);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -15791,7 +15832,7 @@ void InterCodeProcedure::Close(void)
|
|||
{
|
||||
GrowingTypeArray tstack(IT_NONE);
|
||||
|
||||
CheckFunc = !strcmp(mIdent->mString, "strtof");
|
||||
CheckFunc = !strcmp(mIdent->mString, "main");
|
||||
|
||||
mEntryBlock = mBlocks[0];
|
||||
|
||||
|
|
|
@ -16634,26 +16634,30 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
|
|||
int sz = mIns.Size();
|
||||
|
||||
if (mIns[sz - 3].mType == ASMIT_STA && mIns[sz - 3].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[sz - 1].mType == ASMIT_CMP && mIns[sz - 1].mMode == ASMIM_ZERO_PAGE && mIns[sz - 1].mAddress == mIns[sz - 3].mAddress && !(mIns[sz - 1].mLive & (LIVE_CPU_REG_A | LIVE_MEM)))
|
||||
mIns[sz - 2].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_CMP, mIns[sz - 2].mMode) &&
|
||||
mIns[sz - 1].mType == ASMIT_CMP && mIns[sz - 1].mMode == ASMIM_ZERO_PAGE && mIns[sz - 1].mAddress == mIns[sz - 3].mAddress && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A))
|
||||
{
|
||||
changed = true;
|
||||
|
||||
NativeCodeBasicBlock* cblock = proc->AllocateBlock();
|
||||
cblock->Close(mBranchIns, mFalseJump, mTrueJump, mBranch);
|
||||
cblock->Close(mBranchIns, mTrueJump, mFalseJump, mBranch);
|
||||
|
||||
mIns[sz - 1].mAddress = mIns[sz - 2].mAddress; mIns[sz - 1].mLive |= LIVE_CPU_REG_Z;
|
||||
mIns[sz - 2].mType = ASMIT_NOP; mIns[sz - 2].mMode = ASMIM_IMPLIED;
|
||||
mIns[sz - 3].mLive |= LIVE_CPU_REG_A;
|
||||
mIns[sz - 2].mType = ASMIT_CMP; mIns[sz - 2].mLive |= LIVE_CPU_REG_Z | LIVE_CPU_REG_C;
|
||||
mIns[sz - 1].mType = ASMIT_NOP; mIns[sz - 1].mMode = ASMIM_IMPLIED;
|
||||
mExitRequiredRegs += CPU_REG_Z;
|
||||
|
||||
if (mBranch == ASMIT_BCC)
|
||||
{
|
||||
mBranch = ASMIT_BNE;
|
||||
mTrueJump = cblock;
|
||||
mTrueJump = mFalseJump;
|
||||
mFalseJump = cblock;
|
||||
cblock->mBranch = ASMIT_BNE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mBranch = ASMIT_BEQ;
|
||||
mFalseJump = cblock;
|
||||
mFalseJump = mTrueJump;
|
||||
mTrueJump = cblock;
|
||||
cblock->mBranch = ASMIT_BEQ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27532,6 +27536,8 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
|||
NativeCodeBasicBlock* lblock = proc->AllocateBlock();
|
||||
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
||||
|
||||
NativeCodeBasicBlock* xblock = mTrueJump == this ? mFalseJump : mTrueJump;
|
||||
|
||||
eblock->mBranch = ASMIT_JMP;
|
||||
eblock->mTrueJump = mFalseJump;
|
||||
eblock->mFalseJump = nullptr;
|
||||
|
@ -27543,8 +27549,8 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
|||
lblock->mEntryRequiredRegs = mEntryRequiredRegs;
|
||||
lblock->mExitRequiredRegs = mExitRequiredRegs;
|
||||
|
||||
eblock->mEntryRequiredRegs = mExitRequiredRegs;
|
||||
eblock->mExitRequiredRegs = mExitRequiredRegs;
|
||||
eblock->mEntryRequiredRegs = xblock->mEntryRequiredRegs;
|
||||
eblock->mExitRequiredRegs = xblock->mEntryRequiredRegs;
|
||||
|
||||
mExitRequiredRegs = mEntryRequiredRegs;
|
||||
|
||||
|
@ -27920,6 +27926,27 @@ static bool IsPointerIncAddrs(NativeCodeBasicBlock* block, int reg)
|
|||
return changed;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::Is16BitImmSum(int at, int& val, int& reg) const
|
||||
{
|
||||
if (at + 6 < mIns.Size())
|
||||
{
|
||||
if (mIns[at + 0].mType == ASMIT_CLC &&
|
||||
mIns[at + 1].mType == ASMIT_LDA && mIns[at + 1].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[at + 2].mType == ASMIT_ADC && mIns[at + 2].mMode == ASMIM_IMMEDIATE &&
|
||||
mIns[at + 3].mType == ASMIT_STA && mIns[at + 3].mMode == ASMIM_ZERO_PAGE && mIns[at + 3].mAddress == mIns[at + 1].mAddress &&
|
||||
mIns[at + 4].mType == ASMIT_LDA && mIns[at + 4].mMode == ASMIM_ZERO_PAGE && mIns[at + 4].mAddress == mIns[at + 1].mAddress + 1 &&
|
||||
mIns[at + 5].mType == ASMIT_ADC && mIns[at + 5].mMode == ASMIM_IMMEDIATE &&
|
||||
mIns[at + 6].mType == ASMIT_STA && mIns[at + 6].mMode == ASMIM_ZERO_PAGE && mIns[at + 6].mAddress == mIns[at + 4].mAddress)
|
||||
{
|
||||
reg = mIns[at + 1].mAddress;
|
||||
val = mIns[at + 2].mAddress + 256 * mIns[at + 5].mAddress;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock* prevBlock, NativeCodeBasicBlock* exitBlock, bool full)
|
||||
{
|
||||
|
@ -27932,6 +27959,14 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
|||
|
||||
CheckLive();
|
||||
|
||||
if (!exitBlock)
|
||||
{
|
||||
if (mTrueJump == this)
|
||||
exitBlock = mFalseJump;
|
||||
else
|
||||
exitBlock = mTrueJump;
|
||||
}
|
||||
|
||||
int sz = mIns.Size();
|
||||
|
||||
if (sz == 2 && (mBranch == ASMIT_BEQ || mBranch == ASMIT_BNE) && mIns[0].mType == ASMIT_LDA && mIns[1].mType == ASMIT_CMP && !(mIns[1].mFlags & NCIF_VOLATILE) && !(mIns[1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
||||
|
@ -29004,6 +29039,116 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (mIns.Size() > 0 && (mIns.Last().mType == ASMIT_DEX || mIns.Last().mType == ASMIT_DEC || mIns.Last().mType == ASMIT_CPX))
|
||||
{
|
||||
bool yzero = false;
|
||||
|
||||
if (prevBlock)
|
||||
yzero = prevBlock->RetrieveYValue(prevBlock->mIns.Size() - 1) == 0;
|
||||
|
||||
int nregs = 0;
|
||||
int iregs[32];
|
||||
|
||||
for (int i = 0; i + 3 < mIns.Size(); i++)
|
||||
{
|
||||
if (mIns[i].mType == ASMIT_LDY && mIns[i].mMode == ASMIM_IMMEDIATE && mIns[i].mAddress == 0)
|
||||
yzero = true;
|
||||
else if (mIns[i].ChangesYReg())
|
||||
{
|
||||
nregs = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mIns[i].mMode == ASMIM_INDIRECT_Y)
|
||||
{
|
||||
if (!yzero)
|
||||
{
|
||||
nregs = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
int reg = mIns[i].mAddress;
|
||||
|
||||
if (ReferencesZeroPage(mIns[i].mAddress, 0, i) ||
|
||||
ReferencesZeroPage(mIns[i].mAddress + 1, 0, i))
|
||||
{
|
||||
nregs = 0;
|
||||
break;
|
||||
}
|
||||
if (exitBlock->mEntryRequiredRegs[reg] || exitBlock->mEntryRequiredRegs[reg + 1] || exitBlock->mEntryRequiredRegs[CPU_REG_Y])
|
||||
{
|
||||
nregs = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
int j = i + 1;
|
||||
while (j < mIns.Size() && (
|
||||
mIns[j].mMode == ASMIM_INDIRECT ||
|
||||
!(mIns[j].ReferencesZeroPage(reg) || mIns[j].ReferencesZeroPage(reg + 1))))
|
||||
j++;
|
||||
|
||||
if (j == mIns.Size())
|
||||
{
|
||||
nregs = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
int sreg, dreg, offset;
|
||||
if (Is16BitAddSubImmediate(j - 1, sreg, dreg, offset) && sreg == reg && dreg == sreg && offset == 1)
|
||||
{
|
||||
if (ReferencesZeroPage(reg, j + 6) || ReferencesZeroPage(reg + 1, j + 6))
|
||||
{
|
||||
nregs = 0;
|
||||
break;
|
||||
}
|
||||
iregs[nregs++] = sreg;
|
||||
}
|
||||
else
|
||||
{
|
||||
nregs = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nregs)
|
||||
{
|
||||
if (!prevBlock)
|
||||
return OptimizeSimpleLoopInvariant(proc, full);
|
||||
|
||||
for (int i = 0; i < mIns.Size(); i++)
|
||||
{
|
||||
if (mIns[i].mMode == ASMIM_ZERO_PAGE)
|
||||
{
|
||||
int j = 0;
|
||||
while (j < nregs && iregs[j] != mIns[i].mAddress && iregs[j] + 1 != mIns[i].mAddress)
|
||||
j++;
|
||||
if (j < nregs)
|
||||
{
|
||||
mIns[i].mType = ASMIT_NOP;
|
||||
mIns[i].mMode = ASMIM_IMPLIED;
|
||||
}
|
||||
}
|
||||
else if (mIns[i].mType == ASMIT_LDY)
|
||||
{
|
||||
mIns[i].mType = ASMIT_NOP;
|
||||
mIns[i].mMode = ASMIM_IMPLIED;
|
||||
}
|
||||
|
||||
mIns[i].mLive |= LIVE_CPU_REG_Y;
|
||||
}
|
||||
int j = mIns.Size();
|
||||
while (j > 0 && (mIns[j - 1].mLive & LIVE_CPU_REG_Z))
|
||||
j--;
|
||||
mIns.Insert(j, NativeCodeInstruction(mIns[0].mIns, ASMIT_INY));
|
||||
prevBlock->mIns.Push(NativeCodeInstruction(mIns[0].mIns, ASMIT_LDY, ASMIM_IMMEDIATE, 0));
|
||||
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CheckLive();
|
||||
|
||||
return changed;
|
||||
|
|
|
@ -478,6 +478,8 @@ public:
|
|||
bool BypassRegisterConditionBlock(void);
|
||||
bool FoldLoopEntry(void);
|
||||
|
||||
bool Is16BitImmSum(int at, int & val, int& reg) const;
|
||||
|
||||
bool Check16BitSum(int at, NativeRegisterSum16Info& info);
|
||||
bool Propagate16BitSum(const ExpandingArray<NativeRegisterSum16Info>& cinfo);
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ int main2(int argc, const char** argv)
|
|||
|
||||
#else
|
||||
strcpy(strProductName, "oscar64");
|
||||
strcpy(strProductVersion, "1.19.201");
|
||||
strcpy(strProductVersion, "1.19.202");
|
||||
|
||||
#ifdef __APPLE__
|
||||
uint32_t length = sizeof(basePath);
|
||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,19,201,0
|
||||
PRODUCTVERSION 1,19,201,0
|
||||
FILEVERSION 1,19,202,0
|
||||
PRODUCTVERSION 1,19,202,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -43,12 +43,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "oscar64"
|
||||
VALUE "FileDescription", "oscar64 compiler"
|
||||
VALUE "FileVersion", "1.19.201.0"
|
||||
VALUE "FileVersion", "1.19.202.0"
|
||||
VALUE "InternalName", "oscar64.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||
VALUE "OriginalFilename", "oscar64.exe"
|
||||
VALUE "ProductName", "oscar64"
|
||||
VALUE "ProductVersion", "1.19.201.0"
|
||||
VALUE "ProductVersion", "1.19.202.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -5233,15 +5233,15 @@
|
|||
{
|
||||
"Name" = "8:Microsoft Visual Studio"
|
||||
"ProductName" = "8:oscar64"
|
||||
"ProductCode" = "8:{AED61249-4A7B-4472-9783-1F5014AC87EF}"
|
||||
"PackageCode" = "8:{99957648-E168-4853-BA75-AA7B61A0AE71}"
|
||||
"ProductCode" = "8:{121C9EAF-FA66-4A4C-9CBB-B9CAC3B869C7}"
|
||||
"PackageCode" = "8:{249C96D2-72FE-4889-8F29-99C7507EC96D}"
|
||||
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
||||
"AspNetVersion" = "8:2.0.50727.0"
|
||||
"RestartWWWService" = "11:FALSE"
|
||||
"RemovePreviousVersions" = "11:TRUE"
|
||||
"DetectNewerInstalledVersion" = "11:TRUE"
|
||||
"InstallAllUsers" = "11:FALSE"
|
||||
"ProductVersion" = "8:1.19.201"
|
||||
"ProductVersion" = "8:1.19.202"
|
||||
"Manufacturer" = "8:oscar64"
|
||||
"ARPHELPTELEPHONE" = "8:"
|
||||
"ARPHELPLINK" = "8:"
|
||||
|
@ -5755,7 +5755,7 @@
|
|||
{
|
||||
"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
{
|
||||
"SourcePath" = "8:..\\Debug\\oscar64.exe"
|
||||
"SourcePath" = "8:..\\Release\\oscar64.exe"
|
||||
"TargetName" = "8:"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
|
|
Loading…
Reference in New Issue