From 0639fdc008d2afe8550997b89348f77ec39cbaf1 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sat, 6 May 2023 18:28:59 +0200 Subject: [PATCH] Unify instruction dependency check in optimizer --- include/setjmp.c | 85 +++++++-- include/setjmp.h | 9 +- oscar64/Compiler.cpp | 6 +- oscar64/Compiler.h | 2 +- oscar64/Declaration.h | 1 + oscar64/Emulator.cpp | 24 ++- oscar64/Emulator.h | 2 +- oscar64/GlobalAnalyzer.cpp | 10 +- oscar64/InterCode.cpp | 298 +++++++++++++++++++++++--------- oscar64/InterCode.h | 23 +-- oscar64/InterCodeGenerator.cpp | 117 +++++-------- oscar64/NativeCodeGenerator.cpp | 16 +- oscar64/Parser.cpp | 7 +- oscar64/Scanner.cpp | 3 + oscar64/Scanner.h | 1 + oscar64/oscar64.cpp | 6 +- samples/hires/polygon.c | 1 - 17 files changed, 400 insertions(+), 211 deletions(-) diff --git a/include/setjmp.c b/include/setjmp.c index 04401fb..27922b6 100644 --- a/include/setjmp.c +++ b/include/setjmp.c @@ -1,5 +1,56 @@ #include "setjmp.h" +int setjmpsp(jmp_buf env, void * sp) +{ + __asm + { + ldy #0 + lda sp + 0 + sta (env), y + iny + lda sp + 1 + sta (env), y + iny + + lda __ip + 0 + sta (env), y + iny + lda __ip + 1 + sta (env), y + iny + + lda __fp + 0 + sta (env), y + iny + lda __fp + 1 + sta (env), y + iny + + ldx #0 + l1: + lda __sregs, x + sta (env), y + iny + inx + cpx #32 + bne l1 + + tsx + txa + sta (env), y + + inx + l2: + iny + lda $0100, x + sta (env), y + inx + bne l2 + } + + return 0; +} + int setjmp(jmp_buf env) { __asm @@ -27,29 +78,28 @@ int setjmp(jmp_buf env) iny ldx #0 - loop: + l1: lda __sregs, x sta (env), y iny inx cpx #32 - bne loop + bne l1 tsx txa sta (env), y + + inx + l2: iny - - lda $0101, x + lda $0100, x sta (env), y - iny - - lda $0102, x - sta (env), y - iny + inx + bne l2 } - return 0 + return 0; } #pragma native(setjmp) @@ -81,26 +131,25 @@ void longjmp(jmp_buf env, int value) iny ldx #0 - loop: + l1: lda (env), y sta __sregs, x iny inx cpx #32 - bne loop + bne l1 lda (env), y tax txs - iny - lda (env), y - sta $0101, x + inx + l2: iny - lda (env), y - sta $0102, x - iny + sta $0100, x + inx + bne l2 lda value sta __accu diff --git a/include/setjmp.h b/include/setjmp.h index 4f4cc2e..663646a 100644 --- a/include/setjmp.h +++ b/include/setjmp.h @@ -5,14 +5,17 @@ struct _jmp_buf { void * sp, * ip, * fp; char tmps[32]; - char cpup, cpul, cpuh; + char cpup; + char stack[48]; }; typedef struct _jmp_buf jmp_buf[1]; -int setjmp(jmp_buf env); +__dynstack int setjmp(jmp_buf env); -void longjmp(jmp_buf env, int value); +__dynstack int setjmpsp(jmp_buf env, void * sp); + +__dynstack void longjmp(jmp_buf env, int value); #pragma compile("setjmp.c") diff --git a/oscar64/Compiler.cpp b/oscar64/Compiler.cpp index 1bc39bd..a65c1d1 100644 --- a/oscar64/Compiler.cpp +++ b/oscar64/Compiler.cpp @@ -972,7 +972,7 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64) return true; } -int Compiler::ExecuteCode(bool profile) +int Compiler::ExecuteCode(bool profile, bool trace) { Location loc; @@ -985,12 +985,12 @@ int Compiler::ExecuteCode(bool profile) memcpy(emu->mMemory + mLinker->mProgramStart, mLinker->mMemory + mLinker->mProgramStart, mLinker->mProgramEnd - mLinker->mProgramStart); emu->mMemory[0x2d] = mLinker->mProgramEnd & 0xff; emu->mMemory[0x2e] = mLinker->mProgramEnd >> 8; - ecode = emu->Emulate(2061); + ecode = emu->Emulate(2061, trace ? 2 : 0); } else if (mCompilerOptions & COPT_TARGET_CRT) { memcpy(emu->mMemory + 0x8000, mLinker->mMemory + 0x0800, 0x4000); - ecode = emu->Emulate(0x8009); + ecode = emu->Emulate(0x8009, trace ? 2 : 0); } printf("Emulation result %d\n", ecode); diff --git a/oscar64/Compiler.h b/oscar64/Compiler.h index 28af8b7..0928278 100644 --- a/oscar64/Compiler.h +++ b/oscar64/Compiler.h @@ -44,7 +44,7 @@ public: bool ParseSource(void); bool GenerateCode(void); bool WriteOutputFile(const char* targetPath, DiskImage * d64); - int ExecuteCode(bool profile); + int ExecuteCode(bool profile, bool trace); void AddDefine(const Ident* ident, const char* value); diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index 243e362..a5cf229 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -75,6 +75,7 @@ static const uint64 DTF_STACKCALL = (1ULL << 21); static const uint64 DTF_ZEROPAGE = (1ULL << 22); static const uint64 DTF_PREVENT_INLINE = (1ULL << 23); static const uint64 DTF_STRIPED = (1ULL << 24); +static const uint64 DTF_DYNSTACK = (1ULL << 25); static const uint64 DTF_FUNC_VARIABLE = (1ULL << 32); static const uint64 DTF_FUNC_ASSEMBLER = (1ULL << 33); diff --git a/oscar64/Emulator.cpp b/oscar64/Emulator.cpp index 940db68..c7f1bdf 100644 --- a/oscar64/Emulator.cpp +++ b/oscar64/Emulator.cpp @@ -321,10 +321,10 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in mIP = addr; break; case ASMIT_JSR: - mRegS--; mMemory[0x100 + mRegS] = (mIP - 1) >> 8; mRegS--; mMemory[0x100 + mRegS] = (mIP - 1) & 0xff; + mRegS--; mIP = addr; cycles += 2; break; @@ -372,23 +372,23 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in UpdateStatus(mRegA); break; case ASMIT_PHA: - mRegS--; mMemory[0x100 + mRegS] = mRegA; + mRegS--; cycles ++; break; case ASMIT_PHP: - mRegS--; mMemory[0x100 + mRegS] = mRegP; + mRegS--; cycles++; break; case ASMIT_PLA: - mRegA = mMemory[0x100 + mRegS]; mRegS++; + mRegA = mMemory[0x100 + mRegS]; cycles++; break; case ASMIT_PLP: - mRegP = mMemory[0x100 + mRegS]; mRegS++; + mRegP = mMemory[0x100 + mRegS]; cycles++; break; case ASMIT_ROL: @@ -426,7 +426,7 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in case ASMIT_RTI: break; case ASMIT_RTS: - mIP = (mMemory[0x100 + mRegS] + 256 * mMemory[0x101 + mRegS] + 1) & 0xffff; + mIP = (mMemory[0x101 + mRegS] + 256 * mMemory[0x102 + mRegS] + 1) & 0xffff; mRegS += 2; cycles += 4; break; @@ -496,10 +496,8 @@ void Emulator::DumpProfile(void) DumpCycles(); } -int Emulator::Emulate(int startIP) +int Emulator::Emulate(int startIP, int trace) { - int trace = 0; - for (int i = 0; i < 0x10000; i++) mCycles[i] = 0; @@ -508,7 +506,7 @@ int Emulator::Emulate(int startIP) mRegX = 0; mRegY = 0; mRegP = 0; - mRegS = 0xfe; + mRegS = 0xfd; mMemory[0x1fe] = 0xff; mMemory[0x1ff] = 0xff; @@ -537,14 +535,14 @@ int Emulator::Emulate(int startIP) putchar('\n'); else putchar(mRegA); - mIP = mMemory[0x100 + mRegS] + 256 * mMemory[0x101 + mRegS] + 1; + mIP = mMemory[0x101 + mRegS] + 256 * mMemory[0x102 + mRegS] + 1; mRegS += 2; } else if (mIP == 0xffcf) { int ch = getchar(); mRegA = ch; - mIP = mMemory[0x100 + mRegS] + 256 * mMemory[0x101 + mRegS] + 1; + mIP = mMemory[0x101 + mRegS] + 256 * mMemory[0x102 + mRegS] + 1; mRegS += 2; } @@ -681,7 +679,7 @@ int Emulator::Emulate(int startIP) return -1; } - if (mRegS == 0) + if (mRegS == 0xff) { #if 0 for (int i = 0; i < 256; i++) diff --git a/oscar64/Emulator.h b/oscar64/Emulator.h index a0fd4de..72d24ce 100644 --- a/oscar64/Emulator.h +++ b/oscar64/Emulator.h @@ -19,7 +19,7 @@ public: Linker* mLinker; - int Emulate(int startIP); + int Emulate(int startIP, int trace); void DumpProfile(void); bool EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, int & cycles); protected: diff --git a/oscar64/GlobalAnalyzer.cpp b/oscar64/GlobalAnalyzer.cpp index 2d245bd..86ff108 100644 --- a/oscar64/GlobalAnalyzer.cpp +++ b/oscar64/GlobalAnalyzer.cpp @@ -216,7 +216,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec) { if (!(procDec->mBase->mFlags & DTF_FASTCALL) && !(procDec->mBase->mFlags & DTF_STACKCALL) && (procDec->mType == DT_CONST_FUNCTION)) { - if (!(procDec->mBase->mFlags & DTF_VARIADIC) && !(procDec->mFlags & DTF_FUNC_VARIABLE) && !(procDec->mFlags & DTF_FUNC_RECURSIVE)) + if (!(procDec->mBase->mFlags & DTF_VARIADIC) && !(procDec->mFlags & DTF_FUNC_VARIABLE) && !(procDec->mFlags & DTF_FUNC_RECURSIVE) && !(procDec->mFlags & DTF_DYNSTACK)) { int nbase = 0; for (int i = 0; i < procDec->mCalled.Size(); i++) @@ -451,7 +451,10 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo } else if (exp->mDecValue->mType == DT_CONST_POINTER) { - RegisterProc(Analyze(exp->mDecValue->mValue, procDec, true)); + ldec = Analyze(exp->mDecValue->mValue, procDec, true); + if (ldec->mType == DT_VARIABLE) + ldec->mFlags |= DTF_VAR_ALIASING; + RegisterProc(ldec); } else if (exp->mDecValue->mType == DT_CONST_ADDRESS) { @@ -703,6 +706,9 @@ void GlobalAnalyzer::RegisterCall(Declaration* from, Declaration* to) { if (to->mType == DT_CONST_FUNCTION) { + if (to->mFlags & DTF_DYNSTACK) + from->mFlags |= DTF_DYNSTACK; + if (!(to->mFlags & DTF_FUNC_CONSTEXPR)) from->mFlags &= ~DTF_FUNC_CONSTEXPR; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 7bfefe5..0aff1e1 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -619,6 +619,95 @@ static bool SameInstruction(const InterInstruction* ins1, const InterInstruction return false; } +bool InterCodeBasicBlock::CanSwapInstructions(const InterInstruction* ins0, const InterInstruction* ins1) const +{ + // Cannot swap branches + if (ins1->mCode == IC_JUMP || ins1->mCode == IC_BRANCH) + return false; + + // Check function call + if (ins1->mCode == IC_CALL || ins1->mCode == IC_CALL_NATIVE || ins1->mCode == IC_ASSEMBLER) + { + if (ins0->mCode == IC_CALL || ins0->mCode == IC_CALL_NATIVE || ins0->mCode == IC_ASSEMBLER || + ins0->mCode == IC_RETURN || ins0->mCode == IC_RETURN_STRUCT || ins0->mCode == IC_RETURN_VALUE || + ins0->mCode == IC_PUSH_FRAME || ins0->mCode == IC_POP_FRAME) + return false; + + if (ins0->mCode == IC_LOAD || ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY) + return false; + } + if (ins0->mCode == IC_CALL || ins0->mCode == IC_CALL_NATIVE || ins0->mCode == IC_ASSEMBLER) + { + if (ins1->mCode == IC_RETURN || ins1->mCode == IC_RETURN_STRUCT || ins1->mCode == IC_RETURN_VALUE || + ins1->mCode == IC_PUSH_FRAME || ins1->mCode == IC_POP_FRAME) + return false; + + if (ins1->mCode == IC_LOAD || ins1->mCode == IC_STORE || ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY) + return false; + } + + // Check frame pointer + if (ins0->mCode == IC_PUSH_FRAME || ins0->mCode == IC_POP_FRAME) + { + if (ins1->mCode == IC_PUSH_FRAME || ins1->mCode == IC_POP_FRAME) + return false; + if (ins1->mCode == IC_CONSTANT && ins1->mDst.mType == IT_POINTER && ins1->mConst.mMemory == IM_FRAME) + return false; + if (ins1->mCode == IC_STORE && ins1->mSrc[1].mMemory == IM_FRAME) + return false; + } + if (ins1->mCode == IC_PUSH_FRAME || ins1->mCode == IC_POP_FRAME) + { + if (ins0->mCode == IC_CONSTANT && ins0->mDst.mType == IT_POINTER && ins0->mConst.mMemory == IM_FRAME) + return false; + if (ins0->mCode == IC_STORE && ins0->mSrc[1].mMemory == IM_FRAME) + return false; + } + + // False data dependency + if (ins1->mDst.mTemp >= 0) + { + if (ins1->mDst.mTemp == ins0->mDst.mTemp) + return false; + + for (int i = 0; i < ins0->mNumOperands; i++) + if (ins1->mDst.mTemp == ins0->mSrc[i].mTemp) + return false; + } + + // True data dependency + if (ins0->mDst.mTemp >= 0) + { + for (int i = 0; i < ins1->mNumOperands; i++) + if (ins0->mDst.mTemp == ins1->mSrc[i].mTemp) + return false; + } + + if ((ins0->mCode == IC_LOAD || ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY) && + (ins1->mCode == IC_LOAD || ins1->mCode == IC_STORE || ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY)) + { + if (ins0->mVolatile || ins1->mVolatile) + return false; + + if (ins0->mCode == IC_LOAD) + { + if (DestroyingMem(ins0, ins1, mProc->mModule->mGlobalVars)) + return false; + } + else if (ins1->mCode == IC_LOAD) + { + if (DestroyingMem(ins1, ins0, mProc->mModule->mGlobalVars)) + return false; + } + else if (ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY) + { + if (CollidingMem(ins0, ins1, mProc->mModule->mGlobalVars)) + return false; + } + } + + return true; +} static int64 ConstantFolding(InterOperator oper, InterType type, int64 val1, int64 val2 = 0) { @@ -1271,6 +1360,12 @@ static bool CanBypassUp(const InterInstruction* lins, const InterInstruction* bi if (bins->mDst.mTemp == lins->mSrc[i].mTemp) return false; } + if (lins->mCode == IC_STORE || lins->mCode == IC_COPY) + { + if (bins->mCode == IC_STORE || bins->mCode == IC_LOAD || bins->mCode == IC_COPY || bins->mCode == IC_CALL || bins->mCode == IC_CALL_NATIVE) + return false; + } + if (bins->mCode == IC_PUSH_FRAME || bins->mCode == IC_POP_FRAME) { if (lins->mCode == IC_CONSTANT && lins->mDst.mType == IT_POINTER && lins->mConst.mMemory == IM_FRAME) @@ -4138,8 +4233,9 @@ void InterInstruction::Disassemble(FILE* file) } } -InterCodeBasicBlock::InterCodeBasicBlock(void) - : mInstructions(nullptr), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr), mMergeAValues(nullptr), mTrueJump(nullptr), mFalseJump(nullptr), mLoopPrefix(nullptr), mDominator(nullptr), +InterCodeBasicBlock::InterCodeBasicBlock(InterCodeProcedure * proc) + : mProc(proc), + mInstructions(nullptr), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr), mMergeAValues(nullptr), mTrueJump(nullptr), mFalseJump(nullptr), mLoopPrefix(nullptr), mDominator(nullptr), mEntryValueRange(IntegerValueRange()), mTrueValueRange(IntegerValueRange()), mFalseValueRange(IntegerValueRange()), mLocalValueRange(IntegerValueRange()), mEntryParamValueRange(IntegerValueRange()), mTrueParamValueRange(IntegerValueRange()), mFalseParamValueRange(IntegerValueRange()), mLocalParamValueRange(IntegerValueRange()), mReverseValueRange(IntegerValueRange()), mEntryBlocks(nullptr), mLoadStoreInstructions(nullptr), mLoopPathBlocks(nullptr), mMemoryValueSize(0), mEntryMemoryValueSize(0) @@ -4150,6 +4246,9 @@ InterCodeBasicBlock::InterCodeBasicBlock(void) mChecked = false; mTraceIndex = -1; mUnreachable = false; + + mIndex = proc->mBlocks.Size(); + proc->mBlocks.Push(this); } InterCodeBasicBlock::~InterCodeBasicBlock(void) @@ -5554,7 +5653,7 @@ bool InterCodeBasicBlock::CombineIndirectAddressing(void) if (j < tvalue.Size()) { - int offset = lins->mSrc[1].mIntConst - tvalue[j]->mSrc[1].mIntConst; + int64 offset = lins->mSrc[1].mIntConst - tvalue[j]->mSrc[1].mIntConst; lins->mSrc[1] = tvalue[j]->mDst; lins->mSrc[0].mTemp = -1; lins->mSrc[0].mIntConst = offset; @@ -7206,7 +7305,7 @@ bool InterCodeBasicBlock::PropagateConstOperationsUp(void) int di = eb->mInstructions.Size() - 1; if (eb->mInstructions[di]->mCode == IC_BRANCH && di > 0 && eb->mInstructions[di - 1]->mDst.mTemp == eb->mInstructions[di]->mSrc[0].mTemp && - CanBypassUp(ins, eb->mInstructions[di - 1])) + CanSwapInstructions(eb->mInstructions[di - 1], ins)) { di--; } @@ -8033,7 +8132,7 @@ bool InterCodeBasicBlock::MergeIndexedLoadStore(const GrowingInstructionPtrArra if (ins->mCode == IC_LEA) { int j = i; - while (j > 0 && CanBypassUp(ins, mInstructions[j - 1])) + while (j > 0 && CanSwapInstructions(mInstructions[j - 1], ins)) { mInstructions[j] = mInstructions[j - 1]; j--; @@ -9679,6 +9778,18 @@ bool InterCodeBasicBlock::CanMoveInstructionDown(int si, int ti) const { InterInstruction* ins = mInstructions[si]; +#if 1 + if (ins->mCode == IC_COPY || ins->mCode == IC_PUSH_FRAME || ins->mCode == IC_POP_FRAME || + ins->mCode == IC_RETURN || ins->mCode == IC_RETURN_STRUCT || ins->mCode == IC_RETURN_VALUE) + return false; + + for (int i = si + 1; i < ti; i++) + if (!CanSwapInstructions(ins, mInstructions[i])) + return false; + return true; + +#else + if (ins->mCode == IC_LOAD) { for (int i = si + 1; i < ti; i++) @@ -9702,6 +9813,7 @@ bool InterCodeBasicBlock::CanMoveInstructionDown(int si, int ti) const } return true; +#endif } int InterCodeBasicBlock::FindSameInstruction(const InterInstruction* ins) const @@ -9719,6 +9831,17 @@ bool InterCodeBasicBlock::CanMoveInstructionBehindBlock(int ii) const bool InterCodeBasicBlock::CanMoveInstructionBeforeBlock(int ii, const InterInstruction* ins) const { + +#if 1 + if (ins->mCode == IC_CALL || ins->mCode == IC_CALL_NATIVE || ins->mCode == IC_COPY || ins->mCode == IC_PUSH_FRAME || ins->mCode == IC_POP_FRAME || + ins->mCode == IC_RETURN || ins->mCode == IC_RETURN_STRUCT || ins->mCode == IC_RETURN_VALUE) + return false; + + for (int i = 0; i < ii; i++) + if (!CanSwapInstructions(mInstructions[i], ins)) + return false; + return true; +#else if (ins->mCode == IC_LOAD) { for (int i = 0; i < ii; i++) @@ -9740,7 +9863,7 @@ bool InterCodeBasicBlock::CanMoveInstructionBeforeBlock(int ii, const InterInstr if (!CanBypassUp(ins, mInstructions[i])) return false; } - +#endif return true; } @@ -9781,7 +9904,9 @@ bool InterCodeBasicBlock::MergeCommonPathInstructions(void) if (mTrueJump->CanMoveInstructionBeforeBlock(ti) && mFalseJump->CanMoveInstructionBeforeBlock(fi)) { int tindex = mInstructions.Size() - 1; - if (mInstructions.Size() >= 2 && mInstructions[tindex - 1]->mDst.mTemp == mInstructions[tindex]->mSrc[0].mTemp && CanBypassUp(tins, mInstructions[tindex - 1])) + if (mInstructions.Size() >= 2 && mInstructions[tindex - 1]->mDst.mTemp == mInstructions[tindex]->mSrc[0].mTemp && + CanSwapInstructions(mInstructions[tindex - 1], tins)) +// CanBypassUp(tins, mInstructions[tindex - 1])) tindex--; mInstructions.Insert(tindex, tins); @@ -10334,7 +10459,7 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void) if (ins->mCode == IC_LOAD) { j = 0; - while (j < mTrueJump->mInstructions.Size() && CanBypassLoad(ins, mTrueJump->mInstructions[j])) + while (j < mTrueJump->mInstructions.Size() && CanSwapInstructions(ins, mTrueJump->mInstructions[j])) j++; } if (ins->mCode != IC_LOAD || j == mTrueJump->mInstructions.Size()) @@ -10342,7 +10467,7 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void) if (ins->mCode == IC_LOAD) { j = 0; - while (j < mFalseJump->mInstructions.Size() && CanBypassLoad(ins, mFalseJump->mInstructions[j])) + while (j < mFalseJump->mInstructions.Size() && CanSwapInstructions(ins, mFalseJump->mInstructions[j])) j++; } @@ -10488,7 +10613,7 @@ bool InterCodeBasicBlock::IsLeafProcedure(void) } -void InterCodeBasicBlock::ExpandSelect(InterCodeProcedure* proc) +void InterCodeBasicBlock::ExpandSelect(void) { if (!mVisited) { @@ -10502,12 +10627,9 @@ void InterCodeBasicBlock::ExpandSelect(InterCodeProcedure* proc) { InterInstruction* sins = mInstructions[i]; - InterCodeBasicBlock* tblock = new InterCodeBasicBlock(); - proc->Append(tblock); - InterCodeBasicBlock* fblock = new InterCodeBasicBlock(); - proc->Append(fblock); - InterCodeBasicBlock* eblock = new InterCodeBasicBlock(); - proc->Append(eblock); + InterCodeBasicBlock* tblock = new InterCodeBasicBlock(mProc); + InterCodeBasicBlock* fblock = new InterCodeBasicBlock(mProc); + InterCodeBasicBlock* eblock = new InterCodeBasicBlock(mProc); for (int j = i + 1; j < mInstructions.Size(); j++) eblock->mInstructions.Push(mInstructions[j]); @@ -10564,13 +10686,13 @@ void InterCodeBasicBlock::ExpandSelect(InterCodeProcedure* proc) } if (mTrueJump) - mTrueJump->ExpandSelect(proc); + mTrueJump->ExpandSelect(); if (mFalseJump) - mFalseJump->ExpandSelect(proc); + mFalseJump->ExpandSelect(); } } -void InterCodeBasicBlock::SplitBranches(InterCodeProcedure* proc) +void InterCodeBasicBlock::SplitBranches(void) { if (!mVisited) { @@ -10578,10 +10700,9 @@ void InterCodeBasicBlock::SplitBranches(InterCodeProcedure* proc) if (mTrueJump && mFalseJump && (mInstructions.Size() > 2 || mInstructions.Size() == 2 && mInstructions[0]->mCode != IC_RELATIONAL_OPERATOR)) { - InterCodeBasicBlock* block = new InterCodeBasicBlock(); + InterCodeBasicBlock* block = new InterCodeBasicBlock(mProc); InterInstruction* ins = mInstructions.Last(); - proc->Append(block); if (mInstructions[mInstructions.Size() - 2]->mCode == IC_RELATIONAL_OPERATOR) { block->mInstructions.Push(mInstructions[mInstructions.Size() - 2]); @@ -10600,14 +10721,14 @@ void InterCodeBasicBlock::SplitBranches(InterCodeProcedure* proc) mFalseJump = nullptr; block->mNumEntries = 1; - block->SplitBranches(proc); + block->SplitBranches(); } else { if (mTrueJump) - mTrueJump->SplitBranches(proc); + mTrueJump->SplitBranches(); if (mFalseJump) - mFalseJump->SplitBranches(proc); + mFalseJump->SplitBranches(); } } } @@ -10948,7 +11069,7 @@ void InterCodeBasicBlock::FollowJumps(void) } } -void InterCodeBasicBlock::BuildLoopSuffix(InterCodeProcedure* proc) +void InterCodeBasicBlock::BuildLoopSuffix(void) { if (!mVisited) { @@ -10960,8 +11081,7 @@ void InterCodeBasicBlock::BuildLoopSuffix(InterCodeProcedure* proc) { if (mFalseJump->mNumEntries > 1) { - InterCodeBasicBlock* suffix = new InterCodeBasicBlock(); - proc->Append(suffix); + InterCodeBasicBlock* suffix = new InterCodeBasicBlock(mProc); InterInstruction* jins = new InterInstruction(mInstructions[0]->mLocation, IC_JUMP); suffix->Append(jins); suffix->Close(mFalseJump, nullptr); @@ -10973,8 +11093,7 @@ void InterCodeBasicBlock::BuildLoopSuffix(InterCodeProcedure* proc) { if (mTrueJump->mNumEntries > 1) { - InterCodeBasicBlock* suffix = new InterCodeBasicBlock(); - proc->Append(suffix); + InterCodeBasicBlock* suffix = new InterCodeBasicBlock(mProc); InterInstruction* jins = new InterInstruction(mInstructions[0]->mLocation, IC_JUMP); suffix->Append(jins); suffix->Close(mTrueJump, nullptr); @@ -10985,27 +11104,26 @@ void InterCodeBasicBlock::BuildLoopSuffix(InterCodeProcedure* proc) } if (mTrueJump) - mTrueJump->BuildLoopSuffix(proc); + mTrueJump->BuildLoopSuffix(); if (mFalseJump) - mFalseJump->BuildLoopSuffix(proc); + mFalseJump->BuildLoopSuffix(); } } -InterCodeBasicBlock* InterCodeBasicBlock::BuildLoopPrefix(InterCodeProcedure* proc) +InterCodeBasicBlock* InterCodeBasicBlock::BuildLoopPrefix(void) { if (!mVisited) { mVisited = true; if (mTrueJump) - mTrueJump = mTrueJump->BuildLoopPrefix(proc); + mTrueJump = mTrueJump->BuildLoopPrefix(); if (mFalseJump) - mFalseJump = mFalseJump->BuildLoopPrefix(proc); + mFalseJump = mFalseJump->BuildLoopPrefix(); if (mLoopHead) { - mLoopPrefix = new InterCodeBasicBlock(); - proc->Append(mLoopPrefix); + mLoopPrefix = new InterCodeBasicBlock(mProc); InterInstruction* jins = new InterInstruction(mInstructions[0]->mLocation, IC_JUMP); mLoopPrefix->Append(jins); mLoopPrefix->Close(this, nullptr); @@ -13658,6 +13776,15 @@ bool InterCodeBasicBlock::PeepholeReplaceOptimization(const GrowingVariableArray mInstructions[i + 0]->mSrc[1].mFinal = false; changed = true; } + else if ( + mInstructions[i + 0]->mCode == IC_STORE && mInstructions[i + 1]->mCode == IC_STORE && + SameMemSegment(mInstructions[i + 1]->mSrc[1], mInstructions[i + 0]->mSrc[1]) && + !mInstructions[i + 0]->mVolatile && !mInstructions[i + 1]->mVolatile) + { + mInstructions[i + 0]->mCode = IC_NONE; + mInstructions[i + 0]->mNumOperands = 0; + changed = true; + } #if 1 if (i + 2 < mInstructions.Size() && @@ -13878,7 +14005,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati if (ins->mSrc[0].mTemp < 0) { int k = i; - while (k < limit && CanBypass(ins, mInstructions[k + 1])) + while (k < limit && CanSwapInstructions(ins, mInstructions[k + 1])) k++; if (k == limit) @@ -13914,7 +14041,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati { InterInstruction* ins(mInstructions[i]); int j = i; - while (j < limit && CanBypass(ins, mInstructions[j + 1])) + while (j < limit && CanSwapInstructions(ins, mInstructions[j + 1])) { SwapInstructions(ins, mInstructions[j + 1]); mInstructions[j] = mInstructions[j + 1]; @@ -13945,7 +14072,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati { InterInstruction * ins(mInstructions[i]); int j = i; - while (j < limit && CanBypassLoad(ins, mInstructions[j + 1])) + while (j < limit && CanSwapInstructions(ins, mInstructions[j + 1])) { SwapInstructions(ins, mInstructions[j + 1]); mInstructions[j] = mInstructions[j + 1]; @@ -13959,7 +14086,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati InterInstruction* ins(mInstructions[i]); int k = i; - while (k < limit && CanBypass(ins, mInstructions[k + 1])) + while (k < limit && CanSwapInstructions(ins, mInstructions[k + 1])) k++; if (k < limit) { @@ -13982,7 +14109,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati { InterInstruction* ins(mInstructions[i]); int j = i; - while (j < limit && CanBypass(ins, mInstructions[j + 1])) + while (j < limit && CanSwapInstructions(ins, mInstructions[j + 1])) { SwapInstructions(ins, mInstructions[j + 1]); mInstructions[j] = mInstructions[j + 1]; @@ -13997,6 +14124,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati CheckFinalLocal(); #endif + #if 1 // move indirect load/store pairs up i = 0; @@ -14011,8 +14139,8 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati int j = i; while (j > 0 && - CanBypassLoadUp(lins, mInstructions[j - 1]) && - CanBypassStore(sins, mInstructions[j - 1])) + CanSwapInstructions(mInstructions[j - 1], lins) && + CanSwapInstructions(mInstructions[j - 1], sins)) { SwapInstructions(mInstructions[j - 1], lins); SwapInstructions(mInstructions[j - 1], sins); @@ -14034,6 +14162,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati CheckFinalLocal(); #endif + #if 1 i = 0; while (i < mInstructions.Size()) @@ -14043,8 +14172,12 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati { InterInstruction * ins(mInstructions[i]); int j = i; - while (j > 0 && CanBypassStore(ins, mInstructions[j - 1])) + while (j > 0 && CanSwapInstructions(mInstructions[j - 1], ins)) { + if (mInstructions[j - 1]->mCode == IC_STORE && mInstructions[j - 1]->mSrc[1].mMemory == IM_INDIRECT) + { + CanSwapInstructions(mInstructions[j - 1], ins); + } SwapInstructions(mInstructions[j - 1], ins); mInstructions[j] = mInstructions[j - 1]; j--; @@ -14056,7 +14189,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati { InterInstruction* ins(mInstructions[i]); int j = i; - while (j > 0 && CanBypassUp(ins, mInstructions[j - 1])) + while (j > 0 && CanSwapInstructions(mInstructions[j - 1], ins)) { SwapInstructions(mInstructions[j - 1], ins); mInstructions[j] = mInstructions[j - 1]; @@ -14069,7 +14202,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati { InterInstruction* ins(mInstructions[i]); int j = i; - while (j > 0 && CanBypassLoadUp(ins, mInstructions[j - 1])) + while (j > 0 && CanSwapInstructions(mInstructions[j - 1], ins)) { SwapInstructions(mInstructions[j - 1], ins); mInstructions[j] = mInstructions[j - 1]; @@ -14094,7 +14227,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati { InterInstruction* ins(mInstructions[i]); int j = i; - while (j < limit && CanBypassLoad(ins, mInstructions[j + 1])) + while (j < limit && CanSwapInstructions(ins, mInstructions[j + 1])) { SwapInstructions(ins, mInstructions[j + 1]); mInstructions[j] = mInstructions[j + 1]; @@ -14107,7 +14240,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati { InterInstruction* ins(mInstructions[i]); int j = i; - while (j < limit && CanBypass(ins, mInstructions[j + 1])) + while (j < limit && CanSwapInstructions(ins, mInstructions[j + 1])) { SwapInstructions(ins, mInstructions[j + 1]); mInstructions[j] = mInstructions[j + 1]; @@ -14254,7 +14387,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati } } -void InterCodeBasicBlock::CheckValueReturn(InterCodeProcedure* proc) +void InterCodeBasicBlock::CheckValueReturn(void) { if (!mVisited) { @@ -14266,16 +14399,16 @@ void InterCodeBasicBlock::CheckValueReturn(InterCodeProcedure* proc) if (ins->mCode == IC_ASSEMBLER) return; else if (ins->mCode == IC_RETURN) - proc->mModule->mErrors->Error(ins->mLocation, EWARN_MISSING_RETURN_STATEMENT, "Missing return statement"); + mProc->mModule->mErrors->Error(ins->mLocation, EWARN_MISSING_RETURN_STATEMENT, "Missing return statement"); } - if (mTrueJump) mTrueJump->CheckValueReturn(proc); - if (mFalseJump) mFalseJump->CheckValueReturn(proc); + if (mTrueJump) mTrueJump->CheckValueReturn(); + if (mFalseJump) mFalseJump->CheckValueReturn(); } } -void InterCodeBasicBlock::WarnUsedUndefinedVariables(InterCodeProcedure* proc) +void InterCodeBasicBlock::WarnUsedUndefinedVariables(void) { if (!mVisited) { @@ -14294,22 +14427,22 @@ void InterCodeBasicBlock::WarnUsedUndefinedVariables(InterCodeProcedure* proc) int t = ins->mSrc[j].mTemp; int k = 0; - while (k < proc->mLocalVars.Size() && !(proc->mLocalVars[k] && proc->mLocalVars[k]->mTempIndex == t)) + while (k < mProc->mLocalVars.Size() && !(mProc->mLocalVars[k] && mProc->mLocalVars[k]->mTempIndex == t)) k++; if (potentialTemps[t]) { - if (k < proc->mLocalVars.Size() && proc->mLocalVars[k]->mIdent) - proc->mModule->mErrors->Error(ins->mLocation, EWARN_USE_OF_UNINITIALIZED_VARIABLE, "Use of potentially uninitialized variable", proc->mLocalVars[k]->mIdent); + if (k < mProc->mLocalVars.Size() && mProc->mLocalVars[k]->mIdent) + mProc->mModule->mErrors->Error(ins->mLocation, EWARN_USE_OF_UNINITIALIZED_VARIABLE, "Use of potentially uninitialized variable", mProc->mLocalVars[k]->mIdent); else - proc->mModule->mErrors->Error(ins->mLocation, EWARN_USE_OF_UNINITIALIZED_VARIABLE, "Use of potentially uninitialized expression"); + mProc->mModule->mErrors->Error(ins->mLocation, EWARN_USE_OF_UNINITIALIZED_VARIABLE, "Use of potentially uninitialized expression"); } else { - if (k < proc->mLocalVars.Size() && proc->mLocalVars[k]->mIdent) - proc->mModule->mErrors->Error(ins->mLocation, EWARN_USE_OF_UNINITIALIZED_VARIABLE, "Use of uninitialized variable", proc->mLocalVars[k]->mIdent); + if (k < mProc->mLocalVars.Size() && mProc->mLocalVars[k]->mIdent) + mProc->mModule->mErrors->Error(ins->mLocation, EWARN_USE_OF_UNINITIALIZED_VARIABLE, "Use of uninitialized variable", mProc->mLocalVars[k]->mIdent); else - proc->mModule->mErrors->Error(ins->mLocation, EWARN_USE_OF_UNINITIALIZED_VARIABLE, "Use of uninitialized expression"); + mProc->mModule->mErrors->Error(ins->mLocation, EWARN_USE_OF_UNINITIALIZED_VARIABLE, "Use of uninitialized expression"); if (ins->mCode == IC_LOAD_TEMPORARY) { @@ -14335,8 +14468,8 @@ void InterCodeBasicBlock::WarnUsedUndefinedVariables(InterCodeProcedure* proc) providedTemps += ins->mDst.mTemp; } - if (mTrueJump) mTrueJump->WarnUsedUndefinedVariables(proc); - if (mFalseJump) mFalseJump->WarnUsedUndefinedVariables(proc); + if (mTrueJump) mTrueJump->WarnUsedUndefinedVariables(); + if (mFalseJump) mFalseJump->WarnUsedUndefinedVariables(); } } @@ -14609,7 +14742,7 @@ InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & l mValueForwardingTable(nullptr), mLocalVars(nullptr), mParamVars(nullptr), mModule(mod), mIdent(ident), mLinkerObject(linkerObject), mNativeProcedure(false), mLeafProcedure(false), mCallsFunctionPointer(false), mCalledFunctions(nullptr), mFastCallProcedure(false), - mInterrupt(false), mHardwareInterrupt(false), mCompiled(false), mInterruptCalled(false), + mInterrupt(false), mHardwareInterrupt(false), mCompiled(false), mInterruptCalled(false), mDynamicStack(false), mSaveTempsLinkerObject(nullptr), mValueReturn(false), mFramePointer(false), mDeclaration(nullptr) { @@ -14667,12 +14800,6 @@ void InterCodeProcedure::ResetVisited(void) } } -void InterCodeProcedure::Append(InterCodeBasicBlock* block) -{ - block->mIndex = mBlocks.Size(); - mBlocks.Push(block); -} - int InterCodeProcedure::AddTemporary(InterType type) { int temp = mTemporaries.Size(); @@ -14925,7 +15052,7 @@ void InterCodeProcedure::WarnUsedUndefinedVariables(void) mEntryBlock->CollectEntryBlocks(nullptr); ResetVisited(); - mEntryBlock->WarnUsedUndefinedVariables(this); + mEntryBlock->WarnUsedUndefinedVariables(); } @@ -15327,7 +15454,7 @@ void InterCodeProcedure::ExpandSelect(void) { #if 1 ResetVisited(); - mEntryBlock->ExpandSelect(this); + mEntryBlock->ExpandSelect(); ResetVisited(); for (int i = 0; i < mBlocks.Size(); i++) @@ -15428,7 +15555,7 @@ void InterCodeProcedure::Close(void) { GrowingTypeArray tstack(IT_NONE); -// CheckFunc = !strcmp(mIdent->mString, "joy_poll"); + CheckFunc = !strcmp(mIdent->mString, "main"); mEntryBlock = mBlocks[0]; @@ -15705,6 +15832,16 @@ void InterCodeProcedure::Close(void) ResetVisited(); mEntryBlock->CollectEntryBlocks(nullptr); +#if 1 + BuildDataFlowSets(); + + do { + Disassemble("gcp+"); + TempForwarding(); + } while (GlobalConstantPropagation()); + Disassemble("gcp-"); +#endif + BuildDataFlowSets(); #if 1 @@ -15865,8 +16002,10 @@ void InterCodeProcedure::Close(void) BuildDataFlowSets(); do { + Disassemble("gcp+"); TempForwarding(); } while (GlobalConstantPropagation()); + Disassemble("gcp-"); #endif #if 1 @@ -16050,7 +16189,7 @@ void InterCodeProcedure::Close(void) #if 1 ResetVisited(); - if (!mInterruptCalled && mNativeProcedure && mEntryBlock->CheckStaticStack()) + if (!mInterruptCalled && !mDynamicStack && mNativeProcedure && mEntryBlock->CheckStaticStack()) { mLinkerObject->mFlags |= LOBJF_STATIC_STACK; mLinkerObject->mStackSection = mModule->mLinker->AddSection(mIdent->Mangle("@stack"), LST_STATIC_STACK); @@ -16209,7 +16348,7 @@ void InterCodeProcedure::Close(void) if (mValueReturn) { ResetVisited(); - mEntryBlock->CheckValueReturn(this); + mEntryBlock->CheckValueReturn(); } if (mSaveTempsLinkerObject && mTempSize > BC_REG_TMP_SAVED - BC_REG_TMP) @@ -16381,7 +16520,7 @@ void InterCodeProcedure::MergeBasicBlocks(void) mEntryBlock->FollowJumps(); ResetVisited(); - mEntryBlock->SplitBranches(this); + mEntryBlock->SplitBranches(); DisassembleDebug("PostSplit"); @@ -16483,8 +16622,7 @@ void InterCodeProcedure::MergeBasicBlocks(void) if (!allBlocks || eblocks.Size() || mblocks.IndexOf(block) != -1) { - nblock = new InterCodeBasicBlock(); - this->Append(nblock); + nblock = new InterCodeBasicBlock(this); for (int i = 0; i < mblocks.Size(); i++) mblocks[i]->mTrueJump = nblock; @@ -16532,7 +16670,7 @@ void InterCodeProcedure::BuildLoopPrefix(void) for (int i = 0; i < mBlocks.Size(); i++) mBlocks[i]->mLoopPrefix = nullptr; - mEntryBlock = mEntryBlock->BuildLoopPrefix(this); + mEntryBlock = mEntryBlock->BuildLoopPrefix(); ResetVisited(); for (int i = 0; i < mBlocks.Size(); i++) @@ -16540,7 +16678,7 @@ void InterCodeProcedure::BuildLoopPrefix(void) mEntryBlock->CollectEntries(); ResetVisited(); - mEntryBlock->BuildLoopSuffix(this); + mEntryBlock->BuildLoopSuffix(); } bool InterCodeProcedure::PropagateNonLocalUsedTemps(void) @@ -16646,7 +16784,7 @@ void InterCodeProcedure::MapCallerSavedTemps(void) int callerSavedTemps = 0, calleeSavedTemps = BC_REG_TMP_SAVED - BC_REG_TMP, freeCallerSavedTemps = 0, freeTemps = 0; - if (mCallsFunctionPointer) + if (mCallsFunctionPointer || mDynamicStack) freeCallerSavedTemps = BC_REG_TMP_SAVED - BC_REG_TMP; else { diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index fc43fe9..9d909a8 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -117,6 +117,7 @@ class InterInstruction; class InterCodeBasicBlock; class InterCodeProcedure; class InterVariable; +class InterCodeModule; typedef InterInstruction* InterInstructionPtr; typedef InterCodeBasicBlock* InterCodeBasicBlockPtr; @@ -343,6 +344,7 @@ public: class InterCodeBasicBlock { public: + InterCodeProcedure * mProc; int mIndex, mNumEntries, mNumEntered, mTraceIndex; InterCodeBasicBlock * mTrueJump, * mFalseJump, * mLoopPrefix, * mDominator; GrowingInstructionArray mInstructions; @@ -380,7 +382,7 @@ public: ValueSet mMergeValues; TempForwardingTable mMergeForwardingTable; - InterCodeBasicBlock(void); + InterCodeBasicBlock(InterCodeProcedure * proc); ~InterCodeBasicBlock(void); void Append(InterInstruction * code); @@ -492,6 +494,8 @@ public: bool IsTempReferencedOnPath(int temp, int at) const; bool PushSinglePathResultInstructions(void); + + bool CanSwapInstructions(const InterInstruction* ins0, const InterInstruction* ins1) const; bool CanMoveInstructionBeforeBlock(int ii) const; bool CanMoveInstructionBeforeBlock(int ii, const InterInstruction * ins) const; bool CanMoveInstructionBehindBlock(int ii) const; @@ -525,12 +529,12 @@ public: bool SingleTailLoopOptimization(const NumberSet& aliasedParams, const GrowingVariableArray& staticVars); - InterCodeBasicBlock* BuildLoopPrefix(InterCodeProcedure * proc); - void BuildLoopSuffix(InterCodeProcedure* proc); + InterCodeBasicBlock* BuildLoopPrefix(void); + void BuildLoopSuffix(void); - void ExpandSelect(InterCodeProcedure* proc); + void ExpandSelect(void); - void SplitBranches(InterCodeProcedure* proc); + void SplitBranches(void); void FollowJumps(void); bool IsEqual(const InterCodeBasicBlock* block) const; @@ -546,13 +550,11 @@ public: bool SameExitCode(const InterCodeBasicBlock* block) const; - void WarnUsedUndefinedVariables(InterCodeProcedure* proc); - void CheckValueReturn(InterCodeProcedure* proc); + void WarnUsedUndefinedVariables(void); + void CheckValueReturn(void); }; -class InterCodeModule; - class InterCodeProcedure { protected: @@ -570,7 +572,7 @@ public: GrowingIntArray mTempOffset, mTempSizes; int mTempSize, mCommonFrameSize, mCallerSavedTemps, mFreeCallerSavedTemps, mFastCallBase; bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode, mFastCallProcedure; - bool mInterrupt, mHardwareInterrupt, mCompiled, mInterruptCalled, mValueReturn, mFramePointer; + bool mInterrupt, mHardwareInterrupt, mCompiled, mInterruptCalled, mValueReturn, mFramePointer, mDynamicStack; GrowingInterCodeProcedurePtrArray mCalledFunctions; InterCodeModule * mModule; @@ -592,7 +594,6 @@ public: int AddTemporary(InterType type); - void Append(InterCodeBasicBlock * block); void Close(void); // void Set(InterCodeIDMapper* mapper, BitVector localStructure, Scanner scanner, bool debug); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 6b3ad28..037b61f 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -398,6 +398,9 @@ void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration* var->mDeclaration = dec; mod->mGlobalVars.Push(var); + if (dec->mFlags & DTF_VAR_ALIASING) + var->mAliased = true; + dec->mVarIndex = var->mIndex; dec->mLinkerObject = var->mLinkerObject; @@ -745,8 +748,7 @@ void InterCodeGenerator::BuildSwitchTree(InterCodeProcedure* proc, Expression* e { for (int i = left; i < right; i++) { - InterCodeBasicBlock* cblock = new InterCodeBasicBlock(); - proc->Append(cblock); + InterCodeBasicBlock* cblock = new InterCodeBasicBlock(proc); InterInstruction* vins = new InterInstruction(exp->mLocation, IC_CONSTANT); vins->mConst.mType = IT_INT16; @@ -785,14 +787,9 @@ void InterCodeGenerator::BuildSwitchTree(InterCodeProcedure* proc, Expression* e { int center = (left + right + 1) >> 1; - InterCodeBasicBlock* cblock = new InterCodeBasicBlock(); - proc->Append(cblock); - - InterCodeBasicBlock* rblock = new InterCodeBasicBlock(); - proc->Append(rblock); - - InterCodeBasicBlock* lblock = new InterCodeBasicBlock(); - proc->Append(lblock); + InterCodeBasicBlock* cblock = new InterCodeBasicBlock(proc); + InterCodeBasicBlock* rblock = new InterCodeBasicBlock(proc); + InterCodeBasicBlock* lblock = new InterCodeBasicBlock(proc); InterInstruction* vins = new InterInstruction(exp->mLocation, IC_CONSTANT); vins->mConst.mType = IT_INT16; @@ -851,13 +848,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro Declaration* ftype = fdec->mBase; InlineMapper nmapper; - nmapper.mReturn = new InterCodeBasicBlock(); + nmapper.mReturn = new InterCodeBasicBlock(proc); nmapper.mVarIndex = proc->mNumLocals; nmapper.mConstExpr = inlineConstexpr; proc->mNumLocals += fdec->mNumVars; if (inlineMapper) nmapper.mDepth = inlineMapper->mDepth + 1; - proc->Append(nmapper.mReturn); Declaration* pdec = ftype->mParams; Expression* pex = exp->mRight; @@ -1205,6 +1201,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* InterVariable * var = new InterVariable(); var->mOffset = 0; var->mSize = dec->mSize; + if (dec->mFlags & DTF_VAR_ALIASING) + var->mAliased = true; var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA, dec->mAlignment); dec->mLinkerObject = var->mLinkerObject; var->mIdent = dec->mIdent; @@ -2932,8 +2930,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* } else block->Close(nullptr, nullptr); - block = new InterCodeBasicBlock(); - proc->Append(block); + block = new InterCodeBasicBlock(proc); return ExValue(TheVoidTypeDeclaration); } @@ -2946,8 +2943,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* block->Append(jins); block->Close(breakBlock, nullptr); - block = new InterCodeBasicBlock(); - proc->Append(block); + block = new InterCodeBasicBlock(proc); } else mErrors->Error(exp->mLocation, EERR_INVALID_BREAK, "No break target"); @@ -2963,8 +2959,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* block->Append(jins); block->Close(continueBlock, nullptr); - block = new InterCodeBasicBlock(); - proc->Append(block); + block = new InterCodeBasicBlock(proc); } else mErrors->Error(exp->mLocation, EERR_INVALID_CONTINUE, "No continue target"); @@ -2975,10 +2970,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case EX_ASSUME: { #if 1 - InterCodeBasicBlock* tblock = new InterCodeBasicBlock(); - proc->Append(tblock); - InterCodeBasicBlock* fblock = new InterCodeBasicBlock(); - proc->Append(fblock); + InterCodeBasicBlock* tblock = new InterCodeBasicBlock(proc); + InterCodeBasicBlock* fblock = new InterCodeBasicBlock(proc); TranslateLogic(procType, proc, block, tblock, fblock, exp->mLeft, inlineMapper); @@ -3110,12 +3103,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* InterInstruction* jins0 = new InterInstruction(exp->mLocation, IC_JUMP); InterInstruction* jins1 = new InterInstruction(exp->mLocation, IC_JUMP); - InterCodeBasicBlock* tblock = new InterCodeBasicBlock(); - proc->Append(tblock); - InterCodeBasicBlock* fblock = new InterCodeBasicBlock(); - proc->Append(fblock); - InterCodeBasicBlock* eblock = new InterCodeBasicBlock(); - proc->Append(eblock); + InterCodeBasicBlock* tblock = new InterCodeBasicBlock(proc); + InterCodeBasicBlock* fblock = new InterCodeBasicBlock(proc); + InterCodeBasicBlock* eblock = new InterCodeBasicBlock(proc); TranslateLogic(procType, proc, block, tblock, fblock, exp->mLeft, inlineMapper); @@ -3320,13 +3310,10 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* InterInstruction* jins0 = new InterInstruction(exp->mLocation, IC_JUMP); InterInstruction* jins1 = new InterInstruction(exp->mLocation, IC_JUMP); - InterCodeBasicBlock* tblock = new InterCodeBasicBlock(); - proc->Append(tblock); - InterCodeBasicBlock* fblock = new InterCodeBasicBlock(); - proc->Append(fblock); - InterCodeBasicBlock* eblock = new InterCodeBasicBlock(); - proc->Append(eblock); - + InterCodeBasicBlock* tblock = new InterCodeBasicBlock(proc); + InterCodeBasicBlock* fblock = new InterCodeBasicBlock(proc); + InterCodeBasicBlock* eblock = new InterCodeBasicBlock(proc); + TranslateLogic(procType, proc, block, tblock, fblock, exp, inlineMapper); int ttemp = proc->AddTemporary(IT_BOOL); @@ -3360,13 +3347,10 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* InterInstruction * jins0 = new InterInstruction(exp->mLocation, IC_JUMP); InterInstruction* jins1 = new InterInstruction(exp->mLocation, IC_JUMP); - InterCodeBasicBlock* cblock = new InterCodeBasicBlock(); + InterCodeBasicBlock* cblock = new InterCodeBasicBlock(proc); InterCodeBasicBlock* lblock = cblock; - proc->Append(cblock); - InterCodeBasicBlock* bblock = new InterCodeBasicBlock(); - proc->Append(bblock); - InterCodeBasicBlock* eblock = new InterCodeBasicBlock(); - proc->Append(eblock); + InterCodeBasicBlock* bblock = new InterCodeBasicBlock(proc); + InterCodeBasicBlock* eblock = new InterCodeBasicBlock(proc); block->Append(jins0); block->Close(cblock, nullptr); @@ -3387,12 +3371,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* InterInstruction * jins0 = new InterInstruction(exp->mLocation, IC_JUMP); InterInstruction* jins1 = new InterInstruction(exp->mLocation, IC_JUMP); - InterCodeBasicBlock* tblock = new InterCodeBasicBlock(); - proc->Append(tblock); - InterCodeBasicBlock* fblock = new InterCodeBasicBlock(); - proc->Append(fblock); - InterCodeBasicBlock* eblock = new InterCodeBasicBlock(); - proc->Append(eblock); + InterCodeBasicBlock* tblock = new InterCodeBasicBlock(proc); + InterCodeBasicBlock* fblock = new InterCodeBasicBlock(proc); + InterCodeBasicBlock* eblock = new InterCodeBasicBlock(proc); TranslateLogic(procType, proc, block, tblock, fblock, exp->mLeft, inlineMapper); @@ -3421,15 +3402,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* InterInstruction* jins2 = new InterInstruction(exp->mLocation, IC_JUMP); InterInstruction* jins3 = new InterInstruction(exp->mLocation, IC_JUMP); - InterCodeBasicBlock* cblock = new InterCodeBasicBlock(); + InterCodeBasicBlock* cblock = new InterCodeBasicBlock(proc); InterCodeBasicBlock* lblock = cblock; - proc->Append(cblock); - InterCodeBasicBlock* bblock = new InterCodeBasicBlock(); - proc->Append(bblock); - InterCodeBasicBlock* iblock = new InterCodeBasicBlock(); - proc->Append(iblock); - InterCodeBasicBlock* eblock = new InterCodeBasicBlock(); - proc->Append(eblock); + InterCodeBasicBlock* bblock = new InterCodeBasicBlock(proc); + InterCodeBasicBlock* iblock = new InterCodeBasicBlock(proc); + InterCodeBasicBlock* eblock = new InterCodeBasicBlock(proc); block->Append(jins0); block->Close(cblock, nullptr); @@ -3464,11 +3441,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* { InterInstruction * jins = new InterInstruction(exp->mLocation, IC_JUMP); - InterCodeBasicBlock* cblock = new InterCodeBasicBlock(); + InterCodeBasicBlock* cblock = new InterCodeBasicBlock(proc); InterCodeBasicBlock* lblock = cblock; - proc->Append(cblock); - InterCodeBasicBlock* eblock = new InterCodeBasicBlock(); - proc->Append(eblock); + InterCodeBasicBlock* eblock = new InterCodeBasicBlock(proc); block->Append(jins); block->Close(cblock, nullptr); @@ -3493,8 +3468,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* block = nullptr; - InterCodeBasicBlock* eblock = new InterCodeBasicBlock(); - proc->Append(eblock); + InterCodeBasicBlock* eblock = new InterCodeBasicBlock(proc); SwitchNodeArray switchNodes({ 0 }); @@ -3504,8 +3478,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* Expression* cexp = sexp->mLeft; if (cexp->mType == EX_CASE) { - InterCodeBasicBlock* nblock = new InterCodeBasicBlock(); - proc->Append(nblock); + InterCodeBasicBlock* nblock = new InterCodeBasicBlock(proc); SwitchNode snode; snode.mBlock = nblock; @@ -3538,8 +3511,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* { if (!dblock) { - dblock = new InterCodeBasicBlock(); - proc->Append(dblock); + dblock = new InterCodeBasicBlock(proc); if (block) { @@ -3661,6 +3633,8 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int var->mIndex = dec->mVarIndex; var->mOffset = 0; var->mSize = dec->mSize; + if (dec->mFlags & DTF_VAR_ALIASING) + var->mAliased = true; var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA, dec->mAlignment); dec->mLinkerObject = var->mLinkerObject; var->mLinkerObject->AddData(dec->mData, dec->mSize); @@ -3727,16 +3701,14 @@ void InterCodeGenerator::TranslateLogic(Declaration* procType, InterCodeProcedur break; case EX_LOGICAL_AND: { - InterCodeBasicBlock* ablock = new InterCodeBasicBlock(); - proc->Append(ablock); + InterCodeBasicBlock* ablock = new InterCodeBasicBlock(proc); TranslateLogic(procType, proc, block, ablock, fblock, exp->mLeft, inlineMapper); TranslateLogic(procType, proc, ablock, tblock, fblock, exp->mRight, inlineMapper); break; } case EX_LOGICAL_OR: { - InterCodeBasicBlock* oblock = new InterCodeBasicBlock(); - proc->Append(oblock); + InterCodeBasicBlock* oblock = new InterCodeBasicBlock(proc); TranslateLogic(procType, proc, block, tblock, oblock, exp->mLeft, inlineMapper); TranslateLogic(procType, proc, oblock, tblock, fblock, exp->mRight, inlineMapper); break; @@ -3782,6 +3754,9 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod if (dec->mFlags & DTF_FUNC_INTRCALLED) proc->mInterruptCalled = true; + + if (dec->mFlags & DTF_DYNSTACK) + proc->mDynamicStack = true; if (dec->mBase->mFlags & DTF_FASTCALL) { @@ -3806,9 +3781,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod if (dec->mBase->mBase->mType != DT_TYPE_VOID && dec->mBase->mBase->mType != DT_TYPE_STRUCT) proc->mValueReturn = true; - InterCodeBasicBlock* entryBlock = new InterCodeBasicBlock(); - - proc->Append(entryBlock); + InterCodeBasicBlock* entryBlock = new InterCodeBasicBlock(proc); InterCodeBasicBlock* exitBlock = entryBlock; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index c739f2c..3a6c098 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -19208,7 +19208,7 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool changed = true; } } - else if (ns >= 3 && mIns[ns - 3].mType == ASMIT_LDA && mIns[ns - 3].mMode == ASMIM_ZERO_PAGE && !(mIns[ns - 2].mLive & LIVE_CPU_REG_X)) + else if (ns >= 3 && mIns[ns - 3].mType == ASMIT_LDA && mIns[ns - 3].mMode == ASMIM_ZERO_PAGE && !(mIns[ns - 2].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_A))) { if (mTrueJump->mEntryRequiredRegs[ins.mAddress] && !mFalseJump->mEntryRequiredRegs[ins.mAddress] && mTrueJump->mEntryBlocks.Size() == 1) { @@ -24671,6 +24671,8 @@ bool NativeCodeBasicBlock::EliminateUpper16BitSum(NativeCodeProcedure* nproc) { mVisited = true; + CheckLive(); + for (int i = 0; i + 2 < mIns.Size(); i++) { if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && @@ -28346,7 +28348,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc } mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; } - else if (!(mIns[i + 0].mLive & LIVE_MEM) && !(mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) && !mExitRequiredRegs[mIns[i + 1].mAddress]) + else if (j > i && !(mIns[i + 0].mLive & LIVE_MEM) && !(mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) && !mExitRequiredRegs[mIns[i + 1].mAddress]) { int j = mIns.Size() - 1; @@ -39078,7 +39080,7 @@ void NativeCodeProcedure::RebuildEntry(void) void NativeCodeProcedure::Optimize(void) { - CheckFunc = !strcmp(mInterProc->mIdent->mString, "main"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "bm_polygon_nc_fill"); #if 1 int step = 0; @@ -39330,7 +39332,10 @@ void NativeCodeProcedure::Optimize(void) { ResetVisited(); if (mEntryBlock->JoinTailCodeSequences(this, step > 4)) + { changed = true; + BuildDataFlowSets(); + } ResetVisited(); if (mEntryBlock->PropagateSinglePath()) @@ -39339,6 +39344,7 @@ void NativeCodeProcedure::Optimize(void) #endif + #if _DEBUG ResetVisited(); mEntryBlock->CheckBlocks(true); @@ -39390,6 +39396,7 @@ void NativeCodeProcedure::Optimize(void) #endif } #endif + if (step > 4 && !changed) { ResetVisited(); @@ -39704,6 +39711,7 @@ void NativeCodeProcedure::Optimize(void) mGenerator->mErrors->Error(mInterProc->mLocation, EWARN_OPTIMIZER_LOCKED, "Optimizer locked in infinite loop", mInterProc->mIdent); } + #if 1 if (!changed && step < 11) { @@ -39716,8 +39724,10 @@ void NativeCodeProcedure::Optimize(void) else cnt++; + } while (changed); + #if 1 ResetVisited(); mEntryBlock->ReduceLocalYPressure(); diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index a7841e4..aa60053 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -1051,6 +1051,11 @@ Declaration* Parser::ParseDeclaration(bool variable, bool expression) storageFlags |= DTF_EXPORT; mScanner->NextToken(); } + else if (mScanner->mToken == TK_DYNSTACK) + { + storageFlags |= DTF_DYNSTACK; + mScanner->NextToken(); + } else if (mScanner->mToken == TK_FASTCALL) { storageFlags |= DTF_FASTCALL; @@ -1818,7 +1823,7 @@ Expression* Parser::ParsePrefixExpression(void) } else if (nexp->mToken == TK_BANKOF) { - nexp->mDecType == TheUnsignedCharTypeDeclaration; + nexp->mDecType = TheUnsignedCharTypeDeclaration; } else nexp->mDecType = nexp->mLeft->mDecType; diff --git a/oscar64/Scanner.cpp b/oscar64/Scanner.cpp index 2778e97..dafe3dd 100644 --- a/oscar64/Scanner.cpp +++ b/oscar64/Scanner.cpp @@ -60,6 +60,7 @@ const char* TokenNames[] = "__zeropage", "__noinline", "__striped", + "__dynstack", "number", "char", @@ -1375,6 +1376,8 @@ void Scanner::NextRawToken(void) mToken = TK_NOINLINE; else if (!strcmp(tkident, "__striped")) mToken = TK_STRIPED; + else if (!strcmp(tkident, "__dynstack")) + mToken = TK_DYNSTACK; else { mToken = TK_IDENT; diff --git a/oscar64/Scanner.h b/oscar64/Scanner.h index 7099ca7..f06a530 100644 --- a/oscar64/Scanner.h +++ b/oscar64/Scanner.h @@ -58,6 +58,7 @@ enum Token TK_ZEROPAGE, TK_NOINLINE, TK_STRIPED, + TK_DYNSTACK, TK_NUMBER, TK_CHARACTER, diff --git a/oscar64/oscar64.cpp b/oscar64/oscar64.cpp index 161e8ab..38187c1 100644 --- a/oscar64/oscar64.cpp +++ b/oscar64/oscar64.cpp @@ -114,7 +114,7 @@ int main2(int argc, const char** argv) strcpy_s(crtPath, includePath); strcat_s(crtPath, "crt.c"); - bool emulate = false, profile = false; + bool emulate = false, profile = false, trace = false; targetPath[0] = 0; diskPath[0] = 0; @@ -203,6 +203,8 @@ int main2(int argc, const char** argv) emulate = true; if (arg[2] == 'p') profile = true; + else if (arg[2] == 't') + trace = true; } else if (arg[1] == 'd') { @@ -457,7 +459,7 @@ int main2(int argc, const char** argv) } if (emulate) - compiler->ExecuteCode(profile); + compiler->ExecuteCode(profile, trace); } } diff --git a/samples/hires/polygon.c b/samples/hires/polygon.c index 60edf3a..6b6a020 100644 --- a/samples/hires/polygon.c +++ b/samples/hires/polygon.c @@ -70,7 +70,6 @@ int main(void) } bm_polygon_nc_fill(&Screen, &cr, rpx, rpy, 10, NineShadesOfGrey[i % 9]); - for(int j=0; j<10; j++) { int k = (j + 1) % 10;