From 94a3097ba79f2a2004f1219fd808b3b9bcbfd540 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Wed, 21 Feb 2024 15:05:17 +0100 Subject: [PATCH] Fix find loop optimization with mirrored condition --- oscar64/InterCode.cpp | 4 +- oscar64/NativeCodeGenerator.cpp | 292 ++++++++++++++++--------------- oscar64setup/oscar64setup.vdproj | 82 ++++++++- 3 files changed, 232 insertions(+), 146 deletions(-) diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 616a6d9..7bd8e47 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -5033,7 +5033,7 @@ void InterOperand::Disassemble(FILE* file, InterCodeProcedure* proc) } else if (mMemoryBase == IM_PROCEDURE) { - if (proc->mModule->mProcedures[mVarIndex]) + if (mVarIndex >= 0 && proc->mModule->mProcedures[mVarIndex]) vname = proc->mModule->mProcedures[mVarIndex]->mIdent->mString; else if (mLinkerObject && mLinkerObject->mIdent) vname = mLinkerObject->mIdent->mString; @@ -5108,7 +5108,7 @@ void InterOperand::Disassemble(FILE* file, InterCodeProcedure* proc) } else if (mMemory == IM_PROCEDURE) { - if (proc->mModule->mProcedures[mVarIndex]) + if (mVarIndex >= 0 && proc->mModule->mProcedures[mVarIndex]) vname = proc->mModule->mProcedures[mVarIndex]->mIdent->mString; else if (mLinkerObject && mLinkerObject->mIdent) vname = mLinkerObject->mIdent->mString; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 8f603b8..cf622bc 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -36413,31 +36413,101 @@ bool NativeCodeBasicBlock::OptimizeFindLoop(NativeCodeProcedure* proc) if (succ) { NativeCodeBasicBlock* pred = mEntryBlocks[0]; - if (pred == mFalseJump) - pred = mEntryBlocks[0]; + if (pred == body) + pred = mEntryBlocks[1]; - if (mIns.Size() > 0 && body->mIns.Size() > 0) + if (!pred->mFalseJump) { - int fsz = body->mIns.Size(); - - if (mIns[0].mType == ASMIT_LDY && mIns[0].mMode == ASMIM_ZERO_PAGE && - body->mIns[fsz - 1].mType == ASMIT_INC && body->mIns[fsz - 1].SameEffectiveAddress(mIns[0])) + if (mIns.Size() > 0 && body->mIns.Size() > 0) { - int i = 1; - while (i < mIns.Size() && !mIns[i].ChangesYReg() && !mIns[i].ReferencesZeroPage(mIns[0].mAddress)) - i++; - if (i == mIns.Size()) + int fsz = body->mIns.Size(); + + if (mIns[0].mType == ASMIT_LDY && mIns[0].mMode == ASMIM_ZERO_PAGE && + body->mIns[fsz - 1].mType == ASMIT_INC && body->mIns[fsz - 1].SameEffectiveAddress(mIns[0])) { - i = 0; - while (i + 1 < fsz && !body->mIns[i].ChangesYReg() && !body->mIns[i].ReferencesZeroPage(mIns[0].mAddress)) + int i = 1; + while (i < mIns.Size() && !mIns[i].ChangesYReg() && !mIns[i].ReferencesZeroPage(mIns[0].mAddress)) i++; - if (i + 1 == fsz) + if (i == mIns.Size()) { - pred->mIns.Push(mIns[0]); - succ->mIns.Insert(0, NativeCodeInstruction(mIns[0].mIns, ASMIT_STY, mIns[0])); - body->mIns[fsz - 1].mType = ASMIT_INY; - body->mIns[fsz - 1].mMode = ASMIM_IMPLIED; - mIns.Remove(0); + i = 0; + while (i + 1 < fsz && !body->mIns[i].ChangesYReg() && !body->mIns[i].ReferencesZeroPage(mIns[0].mAddress)) + i++; + if (i + 1 == fsz) + { + pred->mIns.Push(mIns[0]); + succ->mIns.Insert(0, NativeCodeInstruction(mIns[0].mIns, ASMIT_STY, mIns[0])); + body->mIns[fsz - 1].mType = ASMIT_INY; + body->mIns[fsz - 1].mMode = ASMIM_IMPLIED; + mIns.Remove(0); + + body->mEntryRequiredRegs += CPU_REG_Y; + body->mExitRequiredRegs += CPU_REG_Y; + mEntryRequiredRegs += CPU_REG_Y; + mExitRequiredRegs += CPU_REG_Y; + succ->mEntryRequiredRegs += CPU_REG_Y; + + for (int i = 0; i < mIns.Size(); i++) + mIns[i].mLive |= LIVE_CPU_REG_Y; + for (int i = 0; i < fsz; i++) + body->mIns[i].mLive |= LIVE_CPU_REG_Y; + + changed = true; + } + } + } + } + + if (!ReferencesYReg() && body->mIns.Size() > 0 && body->mIns[0].mType == ASMIT_LDY && body->mIns[0].mMode == ASMIM_ZERO_PAGE && !mExitRequiredRegs[CPU_REG_Y]) + { + int incdec = 0; + bool fail = false; + int addr = body->mIns[0].mAddress; + if (!ReferencesZeroPage(addr)) + { + for (int i = 1; i < body->mIns.Size(); i++) + { + const NativeCodeInstruction& bins(body->mIns[i]); + if (bins.mMode == ASMIM_ZERO_PAGE && bins.mAddress == addr) + { + if (bins.mType == ASMIT_INC) + incdec++; + else if (bins.mType == ASMIT_DEC) + incdec--; + else + { + fail = true; + break; + } + } + else if (bins.ReferencesZeroPage(addr)) + fail = true; + else if (bins.ChangesYReg()) + fail = true; + } + + if (!fail) + { + pred->mIns.Push(NativeCodeInstruction(body->mIns[0].mIns, ASMIT_LDY, ASMIM_ZERO_PAGE, addr)); + body->mIns.Remove(0); + while (incdec > 0) + { + body->mIns.Push(NativeCodeInstruction(body->mIns[0].mIns, ASMIT_INY)); + incdec--; + } + while (incdec < 0) + { + body->mIns.Push(NativeCodeInstruction(body->mIns[0].mIns, ASMIT_DEY)); + incdec++; + } + for (int i = 0; i < body->mIns.Size(); i++) + { + if (body->mIns[i].mMode == ASMIM_ZERO_PAGE && body->mIns[i].mAddress == addr) + { + body->mIns[i].mType = ASMIT_NOP; body->mIns[i].mMode = ASMIM_IMPLIED; + } + } + succ->mIns.Insert(0, NativeCodeInstruction(body->mIns[0].mIns, ASMIT_STY, ASMIM_ZERO_PAGE, addr)); body->mEntryRequiredRegs += CPU_REG_Y; body->mExitRequiredRegs += CPU_REG_Y; @@ -36447,148 +36517,80 @@ bool NativeCodeBasicBlock::OptimizeFindLoop(NativeCodeProcedure* proc) for (int i = 0; i < mIns.Size(); i++) mIns[i].mLive |= LIVE_CPU_REG_Y; - for (int i = 0; i < fsz; i++) + for (int i = 0; i < body->mIns.Size(); i++) body->mIns[i].mLive |= LIVE_CPU_REG_Y; changed = true; } } } - } - - if (!ReferencesYReg() && body->mIns.Size() > 0 && body->mIns[0].mType == ASMIT_LDY && body->mIns[0].mMode == ASMIM_ZERO_PAGE && !mExitRequiredRegs[CPU_REG_Y]) - { - int incdec = 0; - bool fail = false; - int addr = body->mIns[0].mAddress; - if (!ReferencesZeroPage(addr)) + else if (!ReferencesXReg() && body->mIns.Size() > 0 && body->mIns[0].mType == ASMIT_LDX && body->mIns[0].mMode == ASMIM_ZERO_PAGE && !mExitRequiredRegs[CPU_REG_X]) { - for (int i = 1; i < body->mIns.Size(); i++) + int incdec = 0; + bool fail = false; + int addr = body->mIns[0].mAddress; + if (!ReferencesZeroPage(addr)) { - const NativeCodeInstruction& bins(body->mIns[i]); - if (bins.mMode == ASMIM_ZERO_PAGE && bins.mAddress == addr) + for (int i = 1; i < body->mIns.Size(); i++) { - if (bins.mType == ASMIT_INC) - incdec++; - else if (bins.mType == ASMIT_DEC) - incdec--; - else + const NativeCodeInstruction& bins(body->mIns[i]); + if (bins.mMode == ASMIM_ZERO_PAGE && bins.mAddress == addr) { + if (bins.mType == ASMIT_INC) + incdec++; + else if (bins.mType == ASMIT_DEC) + incdec--; + else + { + fail = true; + break; + } + } + else if (bins.ReferencesZeroPage(addr)) + fail = true; + else if (bins.ChangesXReg()) fail = true; - break; - } } - else if (bins.ReferencesZeroPage(addr)) - fail = true; - else if (bins.ChangesYReg()) - fail = true; - } - if (!fail) - { - pred->mIns.Push(NativeCodeInstruction(body->mIns[0].mIns, ASMIT_LDY, ASMIM_ZERO_PAGE, addr)); - body->mIns.Remove(0); - while (incdec > 0) + if (!fail) { - body->mIns.Push(NativeCodeInstruction(body->mIns[0].mIns, ASMIT_INY)); - incdec--; - } - while (incdec < 0) - { - body->mIns.Push(NativeCodeInstruction(body->mIns[0].mIns, ASMIT_DEY)); - incdec++; - } - for (int i = 0; i < body->mIns.Size(); i++) - { - if (body->mIns[i].mMode == ASMIM_ZERO_PAGE && body->mIns[i].mAddress == addr) + pred->mIns.Push(NativeCodeInstruction(body->mIns[0].mIns, ASMIT_LDX, ASMIM_ZERO_PAGE, addr)); + body->mIns.Remove(0); + while (incdec > 0) { - body->mIns[i].mType = ASMIT_NOP; body->mIns[i].mMode = ASMIM_IMPLIED; + body->mIns.Push(NativeCodeInstruction(body->mIns[0].mIns, ASMIT_INX)); + incdec--; } + while (incdec < 0) + { + body->mIns.Push(NativeCodeInstruction(body->mIns[0].mIns, ASMIT_DEX)); + incdec++; + } + for (int i = 0; i < body->mIns.Size(); i++) + { + if (body->mIns[i].mMode == ASMIM_ZERO_PAGE && body->mIns[i].mAddress == addr) + { + body->mIns[i].mType = ASMIT_NOP; body->mIns[i].mMode = ASMIM_IMPLIED; + } + } + succ->mIns.Insert(0, NativeCodeInstruction(body->mIns[0].mIns, ASMIT_STX, ASMIM_ZERO_PAGE, addr)); + + body->mEntryRequiredRegs += CPU_REG_X; + body->mExitRequiredRegs += CPU_REG_X; + mEntryRequiredRegs += CPU_REG_X; + mExitRequiredRegs += CPU_REG_X; + succ->mEntryRequiredRegs += CPU_REG_X; + + for (int i = 0; i < mIns.Size(); i++) + mIns[i].mLive |= LIVE_CPU_REG_X; + for (int i = 0; i < body->mIns.Size(); i++) + body->mIns[i].mLive |= LIVE_CPU_REG_X; + + changed = true; } - succ->mIns.Insert(0, NativeCodeInstruction(body->mIns[0].mIns, ASMIT_STY, ASMIM_ZERO_PAGE, addr)); - - body->mEntryRequiredRegs += CPU_REG_Y; - body->mExitRequiredRegs += CPU_REG_Y; - mEntryRequiredRegs += CPU_REG_Y; - mExitRequiredRegs += CPU_REG_Y; - succ->mEntryRequiredRegs += CPU_REG_Y; - - for (int i = 0; i < mIns.Size(); i++) - mIns[i].mLive |= LIVE_CPU_REG_Y; - for (int i = 0; i < body->mIns.Size(); i++) - body->mIns[i].mLive |= LIVE_CPU_REG_Y; - - changed = true; } } } - else if (!ReferencesXReg() && body->mIns.Size() > 0 && body->mIns[0].mType == ASMIT_LDX && body->mIns[0].mMode == ASMIM_ZERO_PAGE && !mExitRequiredRegs[CPU_REG_X]) - { - int incdec = 0; - bool fail = false; - int addr = body->mIns[0].mAddress; - if (!ReferencesZeroPage(addr)) - { - for (int i = 1; i < body->mIns.Size(); i++) - { - const NativeCodeInstruction& bins(body->mIns[i]); - if (bins.mMode == ASMIM_ZERO_PAGE && bins.mAddress == addr) - { - if (bins.mType == ASMIT_INC) - incdec++; - else if (bins.mType == ASMIT_DEC) - incdec--; - else - { - fail = true; - break; - } - } - else if (bins.ReferencesZeroPage(addr)) - fail = true; - else if (bins.ChangesXReg()) - fail = true; - } - - if (!fail) - { - pred->mIns.Push(NativeCodeInstruction(body->mIns[0].mIns, ASMIT_LDX, ASMIM_ZERO_PAGE, addr)); - body->mIns.Remove(0); - while (incdec > 0) - { - body->mIns.Push(NativeCodeInstruction(body->mIns[0].mIns, ASMIT_INX)); - incdec--; - } - while (incdec < 0) - { - body->mIns.Push(NativeCodeInstruction(body->mIns[0].mIns, ASMIT_DEX)); - incdec++; - } - for (int i = 0; i < body->mIns.Size(); i++) - { - if (body->mIns[i].mMode == ASMIM_ZERO_PAGE && body->mIns[i].mAddress == addr) - { - body->mIns[i].mType = ASMIT_NOP; body->mIns[i].mMode = ASMIM_IMPLIED; - } - } - succ->mIns.Insert(0, NativeCodeInstruction(body->mIns[0].mIns, ASMIT_STX, ASMIM_ZERO_PAGE, addr)); - - body->mEntryRequiredRegs += CPU_REG_X; - body->mExitRequiredRegs += CPU_REG_X; - mEntryRequiredRegs += CPU_REG_X; - mExitRequiredRegs += CPU_REG_X; - succ->mEntryRequiredRegs += CPU_REG_X; - - for (int i = 0; i < mIns.Size(); i++) - mIns[i].mLive |= LIVE_CPU_REG_X; - for (int i = 0; i < body->mIns.Size(); i++) - body->mIns[i].mLive |= LIVE_CPU_REG_X; - - changed = true; - } - } - } - } } } @@ -45948,7 +45950,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) { mInterProc = proc; - CheckFunc = !strcmp(mInterProc->mIdent->mString, "sieve"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "manager_show_status"); int nblocks = proc->mBlocks.Size(); tblocks = new NativeCodeBasicBlock * [nblocks]; @@ -46946,6 +46948,12 @@ void NativeCodeProcedure::Optimize(void) if (mEntryBlock->OptimizeFindLoop(this)) changed = true; #endif + +#if _DEBUG + ResetVisited(); + mEntryBlock->CheckBlocks(true); +#endif + #if 1 ResetVisited(); if (mEntryBlock->ReduceLocalYPressure()) diff --git a/oscar64setup/oscar64setup.vdproj b/oscar64setup/oscar64setup.vdproj index 7eb2db0..fd681f8 100644 --- a/oscar64setup/oscar64setup.vdproj +++ b/oscar64setup/oscar64setup.vdproj @@ -220,6 +220,12 @@ } "Entry" { + "MsmKey" = "8:_28CED61D2559486D87F70EC821B89525" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_29ED5D9B606D45DA80CFF329A7643DC8" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -832,6 +838,12 @@ } "Entry" { + "MsmKey" = "8:_A7796DF7A31E4292ADF6BECCF2604081" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_A8820F3446B9408E88692E85817C1B07" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -982,6 +994,12 @@ } "Entry" { + "MsmKey" = "8:_C6CAE25C0BCA43E58CF2062C2700F12F" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_C72E9CB8EC154F9BA499FAC968B83A93" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -2083,6 +2101,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_28CED61D2559486D87F70EC821B89525" + { + "SourcePath" = "8:..\\include\\iso646.h" + "TargetName" = "8:iso646.h" + "Tag" = "8:" + "Folder" = "8:_7C0D28C244F14A21B5F72213BBE59B6F" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_29ED5D9B606D45DA80CFF329A7643DC8" { "SourcePath" = "8:..\\samples\\kernalio\\diskdir.c" @@ -4123,6 +4161,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A7796DF7A31E4292ADF6BECCF2604081" + { + "SourcePath" = "8:..\\include\\inttypes.c" + "TargetName" = "8:inttypes.c" + "Tag" = "8:" + "Folder" = "8:_7C0D28C244F14A21B5F72213BBE59B6F" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A8820F3446B9408E88692E85817C1B07" { "SourcePath" = "8:..\\samples\\make.bat" @@ -4623,6 +4681,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C6CAE25C0BCA43E58CF2062C2700F12F" + { + "SourcePath" = "8:..\\include\\inttypes.h" + "TargetName" = "8:inttypes.h" + "Tag" = "8:" + "Folder" = "8:_7C0D28C244F14A21B5F72213BBE59B6F" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C72E9CB8EC154F9BA499FAC968B83A93" { "SourcePath" = "8:..\\include\\c64\\rasterirq.h" @@ -6077,7 +6155,7 @@ "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:oscar64" "ProductCode" = "8:{48CA0A06-57AB-4F70-8BE8-4FA70116E175}" - "PackageCode" = "8:{8D1D153B-0A1B-4DC9-A05E-AB40E1BD5AD2}" + "PackageCode" = "8:{F0372634-9B36-46D2-95AF-3DD2B414BF99}" "UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}" "AspNetVersion" = "8:2.0.50727.0" "RestartWWWService" = "11:FALSE" @@ -6598,7 +6676,7 @@ { "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_FB2E467BC172457785F4279BB0BFE8B6" { - "SourcePath" = "8:..\\Releasex64\\oscar64.exe" + "SourcePath" = "8:..\\Debugx64\\oscar64.exe" "TargetName" = "8:" "Tag" = "8:" "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"