Code size reduction for jmp to rts

This commit is contained in:
drmortalwombat 2022-10-22 18:21:45 +02:00
parent 7271106397
commit 0aee1ad452
7 changed files with 102 additions and 45 deletions

View File

@ -3550,7 +3550,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
dec->mLinkerObject->mTempSizes[0] = BC_REG_FPARAMS_END - BC_REG_FPARAMS; dec->mLinkerObject->mTempSizes[0] = BC_REG_FPARAMS_END - BC_REG_FPARAMS;
} }
if (dec->mBase->mBase->mType != DT_TYPE_VOID) if (dec->mBase->mBase->mType != DT_TYPE_VOID && dec->mBase->mBase->mType != DT_TYPE_STRUCT)
proc->mValueReturn = true; proc->mValueReturn = true;
InterCodeBasicBlock* entryBlock = new InterCodeBasicBlock(); InterCodeBasicBlock* entryBlock = new InterCodeBasicBlock();
@ -3569,7 +3569,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
else else
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mIdent->mString); mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mIdent->mString);
InterInstruction * ins = new InterInstruction(exp->mLocation, IC_RETURN); InterInstruction * ins = new InterInstruction(exp ? exp->mLocation : dec->mLocation, IC_RETURN);
exitBlock->Append(ins); exitBlock->Append(ins);
exitBlock->Close(nullptr, nullptr); exitBlock->Close(nullptr, nullptr);

View File

@ -4175,13 +4175,17 @@ int NativeCodeBasicBlock::PutJump(NativeCodeProcedure* proc, NativeCodeBasicBloc
return 3; return 3;
} }
int NativeCodeBasicBlock::BranchByteSize(int from, int to) int NativeCodeBasicBlock::BranchByteSize(NativeCodeBasicBlock* target, int from, int to)
{ {
if (to - from >= -126 && to - from <= 129) if (to - from >= -126 && to - from <= 129)
return 2; return 2;
else else
{
if (target->mIns.Size() == 1 && target->mIns[0].mType == ASMIT_RTS)
return 3;
return 5; return 5;
} }
}
int NativeCodeBasicBlock::JumpByteSize(NativeCodeBasicBlock* target, int offset) int NativeCodeBasicBlock::JumpByteSize(NativeCodeBasicBlock* target, int offset)
{ {
@ -4208,7 +4212,7 @@ int NativeCodeBasicBlock::JumpByteSize(NativeCodeBasicBlock* target, int offset)
} }
int NativeCodeBasicBlock::PutBranch(NativeCodeProcedure* proc, AsmInsType code, int offset) int NativeCodeBasicBlock::PutBranch(NativeCodeProcedure* proc, NativeCodeBasicBlock* target, AsmInsType code, int offset)
{ {
if (offset >= -126 && offset <= 129) if (offset >= -126 && offset <= 129)
{ {
@ -4219,6 +4223,15 @@ int NativeCodeBasicBlock::PutBranch(NativeCodeProcedure* proc, AsmInsType code,
else else
{ {
PutByte(AsmInsOpcodes[InvertBranchCondition(code)][ASMIM_RELATIVE]); PutByte(AsmInsOpcodes[InvertBranchCondition(code)][ASMIM_RELATIVE]);
if (target->mIns.Size() == 1 && target->mIns[0].mType == ASMIT_RTS)
{
PutByte(1);
PutByte(0x60);
return 3;
}
else
{
PutByte(3); PutByte(3);
PutByte(0x4c); PutByte(0x4c);
@ -4234,6 +4247,7 @@ int NativeCodeBasicBlock::PutBranch(NativeCodeProcedure* proc, AsmInsType code,
return 5; return 5;
} }
} }
}
void NativeCodeBasicBlock::LoadConstantToReg(InterCodeProcedure * proc, const InterInstruction * ins, InterType type, int reg) void NativeCodeBasicBlock::LoadConstantToReg(InterCodeProcedure * proc, const InterInstruction * ins, InterType type, int reg)
{ {
@ -16134,7 +16148,7 @@ bool NativeCodeBasicBlock::CrossBlockXYPreservation(void)
{ {
NativeCodeBasicBlock* tblock = mTrueJump, * fblock = mFalseJump; NativeCodeBasicBlock* tblock = mTrueJump, * fblock = mFalseJump;
if (!mExitRequiredRegs[CPU_REG_Y] && !fblock->mEntryRequiredRegs[CPU_REG_X] && mExitRequiredRegs[CPU_REG_X]) if (!mExitRequiredRegs[CPU_REG_Y] && !fblock->mEntryRequiredRegs[CPU_REG_X])
{ {
int si = mIns.Size() - 1; int si = mIns.Size() - 1;
while (si >= 0 && !mIns[si].ChangesXReg()) while (si >= 0 && !mIns[si].ChangesXReg())
@ -16260,6 +16274,9 @@ bool NativeCodeBasicBlock::FindImmediateStore(int at, int reg, const NativeCodeI
bool NativeCodeBasicBlock::CheckPatchFailUse(void) bool NativeCodeBasicBlock::CheckPatchFailUse(void)
{ {
if (mPatchStart)
return true;
if (mPatchChecked) if (mPatchChecked)
return false; return false;
@ -16642,6 +16659,8 @@ bool NativeCodeBasicBlock::CheckGlobalAddressSumYPointer(const NativeCodeBasicBl
yval = -1; yval = -1;
} }
} }
else
mPatchStart = true;
while (at < mIns.Size()) while (at < mIns.Size())
{ {
@ -23255,7 +23274,7 @@ bool NativeCodeBasicBlock::BlockSizeCopyReduction(NativeCodeProcedure* proc, int
// Size reduction violating various assumptions such as no branches in basic blocks // Size reduction violating various assumptions such as no branches in basic blocks
// must be last step before actual assembly // must be last step before actual assembly
void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc) void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc, int xenter, int yenter)
{ {
if (!mVisited) if (!mVisited)
{ {
@ -23711,6 +23730,21 @@ void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc)
#if 1 #if 1
bool yimm = false, ximm = false, aimm = false, afail = false; bool yimm = false, ximm = false, aimm = false, afail = false;
int yval = 0, xval = 0, aval = 0; int yval = 0, xval = 0, aval = 0;
if (mNumEntries == 1)
{
if (yenter >= 0)
{
yval = yenter;
yimm = true;
}
if (xenter >= 0)
{
xval = xenter;
ximm = true;
}
}
for(int i = 0; i < mIns.Size(); i++) for(int i = 0; i < mIns.Size(); i++)
{ {
if (afail) if (afail)
@ -24167,9 +24201,9 @@ void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc)
#endif #endif
if (mTrueJump) if (mTrueJump)
mTrueJump->BlockSizeReduction(proc); mTrueJump->BlockSizeReduction(proc, ximm ? xval : -1, yimm ? yval: -1);
if (mFalseJump) if (mFalseJump)
mFalseJump->BlockSizeReduction(proc); mFalseJump->BlockSizeReduction(proc, ximm ? xval : -1, yimm ? yval : -1);
} }
} }
@ -26486,6 +26520,18 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
progress = true; progress = true;
} }
else if (
mIns[i + 0].mType == ASMIT_ASL && mIns[i + 0].mMode == ASMIM_IMPLIED &&
mIns[i + 1].mType == ASMIT_CLC &&
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1)
{
mIns[i + 0].mType = ASMIT_SEC; mIns[i + 0].mLive |= LIVE_CPU_REG_C;
mIns[i + 1].mType = ASMIT_ROL;
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true;
}
else if ( else if (
mIns[i + 0].mType == ASMIT_STA && !(mIns[i + 0].mFlags & NCIF_VOLATILE) && mIns[i + 0].mType == ASMIT_STA && !(mIns[i + 0].mFlags & NCIF_VOLATILE) &&
mIns[i + 2].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 2]) && mIns[i + 2].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 2]) &&
@ -28661,6 +28707,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 3].mAddress + 1 && mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 3].mAddress + 1 &&
!(mIns[i + 6].mLive & LIVE_CPU_REG_A)) !(mIns[i + 6].mLive & LIVE_CPU_REG_A))
{ {
int reg = mIns[i + 3].mAddress;
proc->ResetPatched(); proc->ResetPatched();
if (CheckGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, i + 7, -1)) if (CheckGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, i + 7, -1))
{ {
@ -29623,19 +29670,19 @@ bool NativeCodeBasicBlock::CalculateOffset(int& total)
if (mFalseJump) if (mFalseJump)
{ {
if (mFalseJump->mPlace == mPlace + 1) if (mFalseJump->mPlace == mPlace + 1)
total += BranchByteSize(total, mTrueJump->mOffset); total += BranchByteSize(mTrueJump, total, mTrueJump->mOffset);
else if (mTrueJump->mPlace == mPlace + 1) else if (mTrueJump->mPlace == mPlace + 1)
total += BranchByteSize(total, mFalseJump->mOffset); total += BranchByteSize(mFalseJump, total, mFalseJump->mOffset);
else if ( else if (
mFalseJump->mPlace > mTrueJump->mPlace && mFalseJump->mPlace < mPlace || mFalseJump->mPlace > mTrueJump->mPlace && mFalseJump->mPlace < mPlace ||
mFalseJump->mPlace < mTrueJump->mPlace && mFalseJump->mPlace > mPlace) mFalseJump->mPlace < mTrueJump->mPlace && mFalseJump->mPlace > mPlace)
{ {
total += BranchByteSize(total, mFalseJump->mOffset); total += BranchByteSize(mFalseJump, total, mFalseJump->mOffset);
total += JumpByteSize(mTrueJump, mTrueJump->mOffset - total); total += JumpByteSize(mTrueJump, mTrueJump->mOffset - total);
} }
else else
{ {
total += BranchByteSize(total, mTrueJump->mOffset); total += BranchByteSize(mTrueJump, total, mTrueJump->mOffset);
total += JumpByteSize(mFalseJump, mFalseJump->mOffset - total); total += JumpByteSize(mFalseJump, mFalseJump->mOffset - total);
} }
} }
@ -29690,19 +29737,19 @@ void NativeCodeBasicBlock::CopyCode(NativeCodeProcedure * proc, uint8* target)
if (mFalseJump) if (mFalseJump)
{ {
if (mFalseJump->mPlace == mPlace + 1) if (mFalseJump->mPlace == mPlace + 1)
end += PutBranch(proc, mBranch, mTrueJump->mOffset - end); end += PutBranch(proc, mTrueJump, mBranch, mTrueJump->mOffset - end);
else if (mTrueJump->mPlace == mPlace + 1) else if (mTrueJump->mPlace == mPlace + 1)
end += PutBranch(proc, InvertBranchCondition(mBranch), mFalseJump->mOffset - end); end += PutBranch(proc, mFalseJump, InvertBranchCondition(mBranch), mFalseJump->mOffset - end);
else if ( else if (
mFalseJump->mPlace > mTrueJump->mPlace && mFalseJump->mPlace < mPlace || mFalseJump->mPlace > mTrueJump->mPlace && mFalseJump->mPlace < mPlace ||
mFalseJump->mPlace < mTrueJump->mPlace && mFalseJump->mPlace > mPlace) mFalseJump->mPlace < mTrueJump->mPlace && mFalseJump->mPlace > mPlace)
{ {
end += PutBranch(proc, InvertBranchCondition(mBranch), mFalseJump->mOffset - end); end += PutBranch(proc, mFalseJump, InvertBranchCondition(mBranch), mFalseJump->mOffset - end);
end += PutJump(proc, mTrueJump, mTrueJump->mOffset - end); end += PutJump(proc, mTrueJump, mTrueJump->mOffset - end);
} }
else else
{ {
end += PutBranch(proc, mBranch, mTrueJump->mOffset - end); end += PutBranch(proc, mTrueJump, mBranch, mTrueJump->mOffset - end);
end += PutJump(proc, mFalseJump, mFalseJump->mOffset - end); end += PutJump(proc, mFalseJump, mFalseJump->mOffset - end);
} }
} }
@ -30425,7 +30472,7 @@ void NativeCodeProcedure::RebuildEntry(void)
void NativeCodeProcedure::Optimize(void) void NativeCodeProcedure::Optimize(void)
{ {
CheckFunc = !strcmp(mInterProc->mIdent->mString, "test"); CheckFunc = !strcmp(mInterProc->mIdent->mString, "display_explosion");
#if 1 #if 1
int step = 0; int step = 0;
@ -30545,7 +30592,6 @@ void NativeCodeProcedure::Optimize(void)
changed = true; changed = true;
#endif #endif
// if (cnt == 2) // if (cnt == 2)
// return; // return;
#if 1 #if 1
@ -30929,7 +30975,7 @@ void NativeCodeProcedure::Optimize(void)
#if 1 #if 1
ResetVisited(); ResetVisited();
mEntryBlock->BlockSizeReduction(this); mEntryBlock->BlockSizeReduction(this, -1, -1);
#endif #endif
#endif #endif
@ -31002,6 +31048,7 @@ void NativeCodeProcedure::ResetPatched(void)
mBlocks[i]->mPatched = false; mBlocks[i]->mPatched = false;
mBlocks[i]->mPatchFail = false; mBlocks[i]->mPatchFail = false;
mBlocks[i]->mPatchChecked = false; mBlocks[i]->mPatchChecked = false;
mBlocks[i]->mPatchStart = false;
} }
} }

View File

@ -170,17 +170,17 @@ public:
GrowingArray<NativeCodeBasicBlock*> mEntryBlocks; GrowingArray<NativeCodeBasicBlock*> mEntryBlocks;
int mOffset, mSize, mPlace, mNumEntries, mNumEntered, mFrameOffset, mTemp; int mOffset, mSize, mPlace, mNumEntries, mNumEntered, mFrameOffset, mTemp;
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting, mLocked, mPatched, mPatchFail, mPatchChecked; bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting, mLocked, mPatched, mPatchFail, mPatchChecked, mPatchStart;
NativeCodeBasicBlock * mDominator, * mSameBlock; NativeCodeBasicBlock * mDominator, * mSameBlock;
NativeCodeBasicBlock* mLoopHeadBlock, * mLoopTailBlock; NativeCodeBasicBlock* mLoopHeadBlock, * mLoopTailBlock;
NativeRegisterDataSet mDataSet, mNDataSet, mFDataSet; NativeRegisterDataSet mDataSet, mNDataSet, mFDataSet;
int PutBranch(NativeCodeProcedure* proc, AsmInsType code, int offset); int PutBranch(NativeCodeProcedure* proc, NativeCodeBasicBlock* target, AsmInsType code, int offset);
int PutJump(NativeCodeProcedure* proc, NativeCodeBasicBlock* target, int offset); int PutJump(NativeCodeProcedure* proc, NativeCodeBasicBlock* target, int offset);
int JumpByteSize(NativeCodeBasicBlock * target, int offset); int JumpByteSize(NativeCodeBasicBlock * target, int offset);
int BranchByteSize(int from, int to); int BranchByteSize(NativeCodeBasicBlock* target, int from, int to);
NativeCodeBasicBlock* BypassEmptyBlocks(void); NativeCodeBasicBlock* BypassEmptyBlocks(void);
void RemoveEntryBlock(NativeCodeBasicBlock* block); void RemoveEntryBlock(NativeCodeBasicBlock* block);
@ -198,7 +198,7 @@ public:
bool RemoveNops(void); bool RemoveNops(void);
bool PeepHoleOptimizer(NativeCodeProcedure* proc, int pass); bool PeepHoleOptimizer(NativeCodeProcedure* proc, int pass);
void BlockSizeReduction(NativeCodeProcedure* proc); void BlockSizeReduction(NativeCodeProcedure* proc, int xenter, int yenter);
bool BlockSizeCopyReduction(NativeCodeProcedure* proc, int & si, int & di); bool BlockSizeCopyReduction(NativeCodeProcedure* proc, int & si, int & di);
bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc); bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc);

View File

@ -74,7 +74,7 @@ int main2(int argc, const char** argv)
#else #else
strcpy(strProductName, "oscar64"); strcpy(strProductName, "oscar64");
strcpy(strProductVersion, "1.10.166"); strcpy(strProductVersion, "1.10.167");
#ifdef __APPLE__ #ifdef __APPLE__
uint32_t length = sizeof(basePath); uint32_t length = sizeof(basePath);
@ -301,6 +301,16 @@ int main2(int argc, const char** argv)
} }
#ifdef WIN32
#ifndef _DEBUG
int seh_filter(unsigned int code, struct _EXCEPTION_POINTERS* info)
{
printf("oscar64 crashed. %08x %08x", info->ExceptionRecord->ExceptionCode, (uint32)(info->ExceptionRecord->ExceptionAddress));
return EXCEPTION_EXECUTE_HANDLER;
}
#endif
#endif
int main(int argc, const char** argv) int main(int argc, const char** argv)
{ {
#if 1 #if 1
@ -317,9 +327,8 @@ int main(int argc, const char** argv)
#ifdef _WIN32 #ifdef _WIN32
#ifndef _DEBUG #ifndef _DEBUG
} }
__except (EXCEPTION_EXECUTE_HANDLER) __except (seh_filter(GetExceptionCode(), GetExceptionInformation()))
{ {
printf("oscar64 crashed.");
return 30; return 30;
} }
#endif #endif

View File

@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,10,166,0 FILEVERSION 1,10,167,0
PRODUCTVERSION 1,10,166,0 PRODUCTVERSION 1,10,167,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.10.166.0" VALUE "FileVersion", "1.10.167.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.10.166.0" VALUE "ProductVersion", "1.10.167.0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -116,6 +116,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<StackReserveSize>16000000</StackReserveSize> <StackReserveSize>16000000</StackReserveSize>
<GenerateMapFile>true</GenerateMapFile>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>copy $(TargetPath) $(SolutionDir)bin</Command> <Command>copy $(TargetPath) $(SolutionDir)bin</Command>

View File

@ -4283,15 +4283,15 @@
{ {
"Name" = "8:Microsoft Visual Studio" "Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:oscar64" "ProductName" = "8:oscar64"
"ProductCode" = "8:{1BCA0ABD-960B-44D7-8540-3014B2993CE4}" "ProductCode" = "8:{CABCBC3D-0585-4368-A6E5-0D15780D3C01}"
"PackageCode" = "8:{43AAA98B-4830-4C75-9677-86C9CC444C70}" "PackageCode" = "8:{BFACC5D2-1828-414C-904E-9EF387D7E374}"
"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.10.166" "ProductVersion" = "8:1.10.167"
"Manufacturer" = "8:oscar64" "Manufacturer" = "8:oscar64"
"ARPHELPTELEPHONE" = "8:" "ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:" "ARPHELPLINK" = "8:"