Fix inter instruction cross block move

This commit is contained in:
drmortalwombat 2023-05-26 20:16:19 +02:00
parent 5564b01d11
commit 7d3dc493c0
7 changed files with 211 additions and 23 deletions

View File

@ -227,7 +227,7 @@ void * memmove(void * dst, const void * src, int size)
if (d < s) if (d < s)
{ {
do { do {
*d++ = *s++; *d++ = *s++;
} while (--sz); } while (--sz);
} }
else if (d > s) else if (d > s)

View File

@ -10004,7 +10004,15 @@ int InterCodeBasicBlock::FindSameInstruction(const InterInstruction* ins) const
bool InterCodeBasicBlock::CanMoveInstructionBehindBlock(int ii) 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 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; return false;
@ -15791,7 +15832,7 @@ void InterCodeProcedure::Close(void)
{ {
GrowingTypeArray tstack(IT_NONE); GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "strtof"); CheckFunc = !strcmp(mIdent->mString, "main");
mEntryBlock = mBlocks[0]; mEntryBlock = mBlocks[0];

View File

@ -16634,26 +16634,30 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
int sz = mIns.Size(); int sz = mIns.Size();
if (mIns[sz - 3].mType == ASMIT_STA && mIns[sz - 3].mMode == ASMIM_ZERO_PAGE && 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 - 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 | LIVE_MEM))) 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; changed = true;
NativeCodeBasicBlock* cblock = proc->AllocateBlock(); 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 - 3].mLive |= LIVE_CPU_REG_A;
mIns[sz - 2].mType = ASMIT_NOP; mIns[sz - 2].mMode = ASMIM_IMPLIED; 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) if (mBranch == ASMIT_BCC)
{ {
mBranch = ASMIT_BNE; mTrueJump = mFalseJump;
mTrueJump = cblock; mFalseJump = cblock;
cblock->mBranch = ASMIT_BNE;
} }
else else
{ {
mBranch = ASMIT_BEQ; mFalseJump = mTrueJump;
mFalseJump = cblock; mTrueJump = cblock;
cblock->mBranch = ASMIT_BEQ;
} }
} }
} }
@ -27532,6 +27536,8 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
NativeCodeBasicBlock* lblock = proc->AllocateBlock(); NativeCodeBasicBlock* lblock = proc->AllocateBlock();
NativeCodeBasicBlock* eblock = proc->AllocateBlock(); NativeCodeBasicBlock* eblock = proc->AllocateBlock();
NativeCodeBasicBlock* xblock = mTrueJump == this ? mFalseJump : mTrueJump;
eblock->mBranch = ASMIT_JMP; eblock->mBranch = ASMIT_JMP;
eblock->mTrueJump = mFalseJump; eblock->mTrueJump = mFalseJump;
eblock->mFalseJump = nullptr; eblock->mFalseJump = nullptr;
@ -27543,8 +27549,8 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
lblock->mEntryRequiredRegs = mEntryRequiredRegs; lblock->mEntryRequiredRegs = mEntryRequiredRegs;
lblock->mExitRequiredRegs = mExitRequiredRegs; lblock->mExitRequiredRegs = mExitRequiredRegs;
eblock->mEntryRequiredRegs = mExitRequiredRegs; eblock->mEntryRequiredRegs = xblock->mEntryRequiredRegs;
eblock->mExitRequiredRegs = mExitRequiredRegs; eblock->mExitRequiredRegs = xblock->mEntryRequiredRegs;
mExitRequiredRegs = mEntryRequiredRegs; mExitRequiredRegs = mEntryRequiredRegs;
@ -27920,6 +27926,27 @@ static bool IsPointerIncAddrs(NativeCodeBasicBlock* block, int reg)
return changed; 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) bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock* prevBlock, NativeCodeBasicBlock* exitBlock, bool full)
{ {
@ -27932,6 +27959,14 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
CheckLive(); CheckLive();
if (!exitBlock)
{
if (mTrueJump == this)
exitBlock = mFalseJump;
else
exitBlock = mTrueJump;
}
int sz = mIns.Size(); 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))) 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 #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(); CheckLive();
return changed; return changed;

View File

@ -478,6 +478,8 @@ public:
bool BypassRegisterConditionBlock(void); bool BypassRegisterConditionBlock(void);
bool FoldLoopEntry(void); bool FoldLoopEntry(void);
bool Is16BitImmSum(int at, int & val, int& reg) const;
bool Check16BitSum(int at, NativeRegisterSum16Info& info); bool Check16BitSum(int at, NativeRegisterSum16Info& info);
bool Propagate16BitSum(const ExpandingArray<NativeRegisterSum16Info>& cinfo); bool Propagate16BitSum(const ExpandingArray<NativeRegisterSum16Info>& cinfo);

View File

@ -74,7 +74,7 @@ int main2(int argc, const char** argv)
#else #else
strcpy(strProductName, "oscar64"); strcpy(strProductName, "oscar64");
strcpy(strProductVersion, "1.19.201"); strcpy(strProductVersion, "1.19.202");
#ifdef __APPLE__ #ifdef __APPLE__
uint32_t length = sizeof(basePath); uint32_t length = sizeof(basePath);

View File

@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,19,201,0 FILEVERSION 1,19,202,0
PRODUCTVERSION 1,19,201,0 PRODUCTVERSION 1,19,202,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -43,12 +43,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "oscar64" VALUE "CompanyName", "oscar64"
VALUE "FileDescription", "oscar64 compiler" VALUE "FileDescription", "oscar64 compiler"
VALUE "FileVersion", "1.19.201.0" VALUE "FileVersion", "1.19.202.0"
VALUE "InternalName", "oscar64.exe" VALUE "InternalName", "oscar64.exe"
VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "LegalCopyright", "Copyright (C) 2021"
VALUE "OriginalFilename", "oscar64.exe" VALUE "OriginalFilename", "oscar64.exe"
VALUE "ProductName", "oscar64" VALUE "ProductName", "oscar64"
VALUE "ProductVersion", "1.19.201.0" VALUE "ProductVersion", "1.19.202.0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -5233,15 +5233,15 @@
{ {
"Name" = "8:Microsoft Visual Studio" "Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:oscar64" "ProductName" = "8:oscar64"
"ProductCode" = "8:{AED61249-4A7B-4472-9783-1F5014AC87EF}" "ProductCode" = "8:{121C9EAF-FA66-4A4C-9CBB-B9CAC3B869C7}"
"PackageCode" = "8:{99957648-E168-4853-BA75-AA7B61A0AE71}" "PackageCode" = "8:{249C96D2-72FE-4889-8F29-99C7507EC96D}"
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}" "UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
"AspNetVersion" = "8:2.0.50727.0" "AspNetVersion" = "8:2.0.50727.0"
"RestartWWWService" = "11:FALSE" "RestartWWWService" = "11:FALSE"
"RemovePreviousVersions" = "11:TRUE" "RemovePreviousVersions" = "11:TRUE"
"DetectNewerInstalledVersion" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE"
"InstallAllUsers" = "11:FALSE" "InstallAllUsers" = "11:FALSE"
"ProductVersion" = "8:1.19.201" "ProductVersion" = "8:1.19.202"
"Manufacturer" = "8:oscar64" "Manufacturer" = "8:oscar64"
"ARPHELPTELEPHONE" = "8:" "ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:" "ARPHELPLINK" = "8:"
@ -5755,7 +5755,7 @@
{ {
"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_FB2E467BC172457785F4279BB0BFE8B6" "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_FB2E467BC172457785F4279BB0BFE8B6"
{ {
"SourcePath" = "8:..\\Debug\\oscar64.exe" "SourcePath" = "8:..\\Release\\oscar64.exe"
"TargetName" = "8:" "TargetName" = "8:"
"Tag" = "8:" "Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4" "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"