From 8de4bef4365487911554c0b49db6df4107e1ad2a Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sun, 12 Sep 2021 22:32:31 +0200 Subject: [PATCH] Improved value forwarding across conditiona branches --- oscar64/Array.h | 8 ++ oscar64/ByteCodeGenerator.cpp | 83 ++++++++---- oscar64/InterCode.cpp | 229 ++++++++++++++++++++++++-------- oscar64/InterCode.h | 30 +++-- oscar64/NativeCodeGenerator.cpp | 55 +++++++- oscar64/NativeCodeGenerator.h | 1 + oscar64/Parser.cpp | 1 + 7 files changed, 305 insertions(+), 102 deletions(-) diff --git a/oscar64/Array.h b/oscar64/Array.h index cba8bc9..5cc0e0e 100644 --- a/oscar64/Array.h +++ b/oscar64/Array.h @@ -199,6 +199,14 @@ public: for (i = 0; i < size; i++) array[i] = a.array[i]; } + GrowingArray & operator=(const GrowingArray& a) + { + Grow(a.size, true); + int i; + for (i = 0; i < size; i++) array[i] = a.array[i]; + return *this; + } + ~GrowingArray(void) { delete[] array; diff --git a/oscar64/ByteCodeGenerator.cpp b/oscar64/ByteCodeGenerator.cpp index 282d44b..8a3b806 100644 --- a/oscar64/ByteCodeGenerator.cpp +++ b/oscar64/ByteCodeGenerator.cpp @@ -55,38 +55,11 @@ bool ByteCodeInstruction::IsStore(void) const bool ByteCodeInstruction::ChangesAccu(void) const { - if (mCode == BC_LOAD_REG_16 || mCode == BC_LOAD_REG_32) - return true; - if (mCode >= BC_BINOP_ADDR_16 && mCode <= BC_BINOP_SHRR_I16) - return true; - if (mCode >= BC_BINOP_CMPUR_16 && mCode <= BC_BINOP_CMPSI_16) - return true; - if (mCode >= BC_OP_NEGATE_16 && mCode <= BC_OP_INVERT_16) - return true; - if (mCode >= BC_BINOP_ADD_F32 && mCode <= BC_OP_CEIL_F32) - return true; - if (mCode >= BC_CONV_U16_F32 && mCode <= BC_CONV_F32_I16) - return true; - if (mCode >= BC_BINOP_SHLI_16 && mCode <= BC_BINOP_SHRI_U16) - return true; - if (mCode >= BC_SET_EQ && mCode <= BC_SET_LE) - return true; - if (mCode == BC_JSR || mCode == BC_CALL) - return true; - return ChangesRegister(BC_REG_ACCU); - } bool ByteCodeInstruction::ChangesAddr(void) const { - if (mCode == BC_ADDR_REG) - return true; - if (mCode >= BC_LOAD_ABS_U8 && mCode <= BC_STORE_ABS_32) - return true; - if (mCode == BC_JSR || mCode == BC_CALL) - return true; - return ChangesRegister(BC_REG_ADDR); } @@ -160,6 +133,38 @@ bool ByteCodeInstruction::ChangesRegister(uint32 reg) const return true; } + if (reg == BC_REG_ACCU) + { + if (mCode == BC_LOAD_REG_16 || mCode == BC_LOAD_REG_32) + return true; + if (mCode >= BC_BINOP_ADDR_16 && mCode <= BC_BINOP_SHRR_I16) + return true; + if (mCode >= BC_BINOP_CMPUR_16 && mCode <= BC_BINOP_CMPSI_16) + return true; + if (mCode >= BC_OP_NEGATE_16 && mCode <= BC_OP_INVERT_16) + return true; + if (mCode >= BC_BINOP_ADD_F32 && mCode <= BC_OP_CEIL_F32) + return true; + if (mCode >= BC_CONV_U16_F32 && mCode <= BC_CONV_F32_I16) + return true; + if (mCode >= BC_BINOP_SHLI_16 && mCode <= BC_BINOP_SHRI_U16) + return true; + if (mCode >= BC_SET_EQ && mCode <= BC_SET_LE) + return true; + if (mCode == BC_JSR || mCode == BC_CALL) + return true; + } + + if (reg == BC_REG_ADDR) + { + if (mCode == BC_ADDR_REG) + return true; + if (mCode >= BC_LOAD_ABS_U8 && mCode <= BC_STORE_ABS_32) + return true; + if (mCode == BC_JSR || mCode == BC_CALL) + return true; + } + return false; } @@ -2537,6 +2542,16 @@ void ByteCodeBasicBlock::PeepHoleOptimizer(void) mIns[i + 0].mCode = BC_NOP; mBranch = TransposeBranchCondition(mBranch); } + else if (mIns[i + 0].mCode == BC_LOAD_REG_16 && + mIns[i + 1].mCode == BC_STORE_REG_16 && + mIns[i + 2].mCode == BC_LOAD_REG_16 && mIns[i + 0].mRegister == mIns[i + 2].mRegister) + { + mIns[i + 2].mCode = BC_NOP; + } + else if (mIns[i + 0].mCode == BC_CONST_16 && mIns[i + 2].mCode == BC_CONST_16 && mIns[i + 0].mRegister == mIns[i + 2].mRegister && mIns[i + 0].mValue == mIns[i + 2].mValue && !mIns[i + 1].ChangesRegister(mIns[i + 0].mRegister)) + { + mIns[i + 2].mCode = BC_NOP; + } } if (i + 1 < mIns.Size()) { @@ -2601,6 +2616,13 @@ void ByteCodeBasicBlock::PeepHoleOptimizer(void) mIns[i + 1].mCode = BC_NOP; progress = true; } + else if (mIns[i].mCode == BC_LOAD_LOCAL_16 && mIns[i + 1].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal) + { + mIns[i].mRegister = BC_REG_ADDR; + mIns[i + 1].mCode = BC_NOP; + progress = true; + } + } if ((mIns[i].mCode == BC_LOAD_REG_16 || mIns[i].mCode == BC_STORE_REG_16 || mIns[i].mCode == BC_LOAD_REG_32 || mIns[i].mCode == BC_STORE_REG_32) && accuTemp == mIns[i].mRegister) @@ -2948,9 +2970,12 @@ const char* ByteCodeProcedure::TempName(uint8 tmp, char* buffer, InterCodeProced else if (tmp >= BC_REG_TMP && tmp < BC_REG_TMP + proc->mTempSize) { int i = 0; - while (i + 1 < proc->mTempOffset.Size() && proc->mTempOffset[i + 1] <= tmp - BC_REG_TMP) + while (i < proc->mTempOffset.Size() && proc->mTempOffset[i] != tmp - BC_REG_TMP) i++; - sprintf_s(buffer, 10, "T%d", i); + if (i < proc->mTempOffset.Size()) + sprintf_s(buffer, 10, "T%d", i); + else + sprintf_s(buffer, 10, "$%02x", tmp); return buffer; } else diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index bd7fcdf..28e834e 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -24,6 +24,24 @@ ValueSet::ValueSet(const ValueSet& values) mInstructions[i] = values.mInstructions[i]; } +ValueSet& ValueSet::operator=(const ValueSet& values) +{ + int i; + + mNum = values.mNum; + if (mSize != values.mSize) + { + delete[] mInstructions; + mSize = values.mSize; + mInstructions = new InterInstructionPtr[mSize]; + } + + for (i = 0; i < mNum; i++) + mInstructions[i] = values.mInstructions[i]; + + return *this; +} + ValueSet::~ValueSet(void) { delete[] mInstructions; @@ -265,7 +283,7 @@ static bool MemRange(const InterInstruction * ins, const GrowingInstructionPtrAr return false; } -static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* sins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals) +static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* sins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams) { InterMemory lmem, smem; int lvindex, svindex; @@ -286,12 +304,31 @@ static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* if (lmem == IM_LOCAL) return aliasedLocals[lvindex]; + else if (lmem == IM_PARAM) + return aliasedParams[lvindex]; } return true; } -void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals) +void ValueSet::Intersect(ValueSet& set) +{ + int k = 0; + for(int i=0; imCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], &ins, tvalue, aliasedLocals)) + if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], &ins, tvalue, aliasedLocals, aliasedParams)) { mNum--; if (mNum > 0) @@ -399,7 +436,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr i = 0; while (i < mNum) { - if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], &ins, tvalue, aliasedLocals)) + if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], &ins, tvalue, aliasedLocals, aliasedParams)) { mNum--; if (mNum > 0) @@ -556,7 +593,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr ins.mSTemp[0] = -1; ins.mSTemp[1] = -1; - UpdateValue(ins, tvalue, aliasedLocals); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); return; } @@ -575,7 +612,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr ins.mSTemp[1] = -1; assert(ins.mSTemp[0] >= 0); - UpdateValue(ins, tvalue, aliasedLocals); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); return; } @@ -586,7 +623,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr ins.mSTemp[0] = -1; ins.mSTemp[1] = -1; - UpdateValue(ins, tvalue, aliasedLocals); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); return; } @@ -601,7 +638,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr ins.mSTemp[1] = -1; assert(ins.mSTemp[0] >= 0); - UpdateValue(ins, tvalue, aliasedLocals); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); return; } @@ -613,7 +650,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr ins.mSTemp[0] = -1; ins.mSTemp[1] = -1; - UpdateValue(ins, tvalue, aliasedLocals); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); return; } @@ -623,7 +660,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr ins.mOperator = IA_NEG; ins.mSTemp[1] = -1; - UpdateValue(ins, tvalue, aliasedLocals); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); return; } @@ -637,7 +674,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr ins.mSTemp[0] = -1; ins.mSTemp[1] = -1; - UpdateValue(ins, tvalue, aliasedLocals); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); return; } @@ -647,7 +684,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr ins.mSTemp[1] = -1; assert(ins.mSTemp[0] >= 0); - UpdateValue(ins, tvalue, aliasedLocals); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); return; } @@ -864,7 +901,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr ins.mSTemp[0] = -1; ins.mSTemp[1] = -1; - UpdateValue(ins, tvalue, aliasedLocals); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); } break; case IT_POINTER: @@ -878,7 +915,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr ins.mSTemp[0] = -1; ins.mSTemp[1] = -1; - UpdateValue(ins, tvalue, aliasedLocals); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); } else if (ins.mSTemp[1] == ins.mSTemp[0]) { @@ -904,7 +941,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr ins.mSTemp[0] = -1; ins.mSTemp[1] = -1; - UpdateValue(ins, tvalue, aliasedLocals); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); } break; } @@ -1006,31 +1043,39 @@ static void FilterTempDefineUsage(NumberSet& requiredTemps, NumberSet& providedT } } -void InterInstruction::CollectLocalAddressTemps(GrowingIntArray& localTable) +void InterInstruction::CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable) { if (mCode == IC_CONSTANT) { if (mTType == IT_POINTER && mMemory == IM_LOCAL) localTable[mTTemp] = mVarIndex; + else if (mTType == IT_POINTER && mMemory == IM_PARAM) + paramTable[mTTemp] = mVarIndex; } else if (mCode == IC_LEA) { if (mMemory == IM_LOCAL) localTable[mTTemp] = localTable[mSTemp[1]]; + else if (mMemory == IM_PARAM) + paramTable[mTTemp] = paramTable[mSTemp[1]]; } else if (mCode == IC_LOAD_TEMPORARY) { localTable[mTTemp] = localTable[mSTemp[0]]; + paramTable[mTTemp] = paramTable[mSTemp[0]]; } } -void InterInstruction::MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals) +void InterInstruction::MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams) { if (mCode == IC_STORE) { int l = localTable[mSTemp[0]]; if (l >= 0) aliasedLocals += l; + l = paramTable[mSTemp[0]]; + if (l >= 0) + aliasedParams += l; } } @@ -1156,7 +1201,7 @@ void InterInstruction::BuildCallerSaveTempSet(NumberSet& requiredTemps, NumberSe if (mSTemp[2] >= 0) requiredTemps += mSTemp[2]; } -bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, InterInstruction* pre, NumberSet& requiredTemps) +bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, NumberSet& requiredTemps) { bool changed = false; @@ -1328,7 +1373,7 @@ void InterInstruction::ShrinkActiveTemporaries(FastNumberSet& set, GrowingTypeAr if (mSTemp[2] >= 0) mSTemp[2] = set.Index(mSTemp[2]); } -void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray& localTypes) +void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray& localTypes, FastNumberSet& complexParams, FastNumberSet& simpleParams, GrowingTypeArray& paramTypes) { switch (mCode) { @@ -1341,6 +1386,14 @@ void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNum else complexLocals += mVarIndex; } + else if (mMemory == IM_PARAM && mSTemp[0] < 0) + { + paramTypes[mVarIndex] = mTType; + if (mOperandSize == 2) + simpleParams += mVarIndex; + else + complexParams += mVarIndex; + } break; case IC_STORE: if (mMemory == IM_LOCAL && mSTemp[1] < 0) @@ -1351,14 +1404,26 @@ void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNum else complexLocals += mVarIndex; } + else if (mMemory == IM_PARAM && mSTemp[1] < 0) + { + paramTypes[mVarIndex] = mSType[0]; + if (mOperandSize == 2) + simpleParams += mVarIndex; + else + complexParams += mVarIndex; + } break; case IC_LEA: if (mMemory == IM_LOCAL && mSTemp[1] < 0) complexLocals += mVarIndex; + else if (mMemory == IM_PARAM && mSTemp[1] < 0) + complexParams += mVarIndex; break; case IC_CONSTANT: if (mTType == IT_POINTER && mMemory == IM_LOCAL) complexLocals += mVarIndex; + else if (mTType == IT_POINTER && mMemory == IM_PARAM) + complexParams += mVarIndex; break; } } @@ -1476,8 +1541,14 @@ void InterInstruction::Disassemble(FILE* file) if (mTTemp >= 0) fprintf(file, "R%d(%c)", mTTemp, typechars[mTType]); fprintf(file, "\t<-\t"); if (mSTemp[2] >= 0) fprintf(file, "R%d(%c%c), ", mSTemp[2], typechars[mSType[2]], mSFinal[2] ? 'F' : '-'); - if (mSTemp[1] >= 0) fprintf(file, "R%d(%c%c), ", mSTemp[1], typechars[mSType[1]], mSFinal[1] ? 'F' : '-'); - if (mSTemp[0] >= 0) fprintf(file, "R%d(%c%c)", mSTemp[0], typechars[mSType[0]], mSFinal[0] ? 'F' : '-'); + if (mSTemp[1] >= 0) + fprintf(file, "R%d(%c%c), ", mSTemp[1], typechars[mSType[1]], mSFinal[1] ? 'F' : '-'); + else if (this->mCode == IC_STORE) + fprintf(file, "V%d+%d, ", mVarIndex, mSIntConst[1]); + if (mSTemp[0] >= 0) + fprintf(file, "R%d(%c%c)", mSTemp[0], typechars[mSType[0]], mSFinal[0] ? 'F' : '-'); + else if (this->mCode == IC_LOAD) + fprintf(file, "V%d+%d", mVarIndex, mSIntConst[0]); if (this->mCode == IC_CONSTANT) { if (mTType == IT_POINTER) @@ -1495,8 +1566,10 @@ void InterInstruction::Disassemble(FILE* file) } InterCodeBasicBlock::InterCodeBasicBlock(void) - : mInstructions(InterInstruction()), mEntryRenameTable(-1), mExitRenameTable(-1) + : mInstructions(InterInstruction()), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr) { + mInPath = false; + mLoopHead = false; } InterCodeBasicBlock::~InterCodeBasicBlock(void) @@ -1533,9 +1606,13 @@ void InterCodeBasicBlock::GenerateTraces(void) { int i; + if (mInPath) + mLoopHead = true; + if (!mVisited) { mVisited = true; + mInPath = true; for (;;) { @@ -1575,6 +1652,8 @@ void InterCodeBasicBlock::GenerateTraces(void) if (mTrueJump) mTrueJump->GenerateTraces(); if (mFalseJump) mFalseJump->GenerateTraces(); + + mInPath = false; } } @@ -2076,7 +2155,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn } -void InterCodeBasicBlock::CollectLocalAddressTemps(GrowingIntArray& localTable) +void InterCodeBasicBlock::CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable) { int i; @@ -2085,14 +2164,14 @@ void InterCodeBasicBlock::CollectLocalAddressTemps(GrowingIntArray& localTable) mVisited = true; for (i = 0; i < mInstructions.Size(); i++) - mInstructions[i].CollectLocalAddressTemps(localTable); + mInstructions[i].CollectLocalAddressTemps(localTable, paramTable); - if (mTrueJump) mTrueJump->CollectLocalAddressTemps(localTable); - if (mFalseJump) mFalseJump->CollectLocalAddressTemps(localTable); + if (mTrueJump) mTrueJump->CollectLocalAddressTemps(localTable, paramTable); + if (mFalseJump) mFalseJump->CollectLocalAddressTemps(localTable, paramTable); } } -void InterCodeBasicBlock::MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals) +void InterCodeBasicBlock::MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams) { int i; @@ -2101,10 +2180,10 @@ void InterCodeBasicBlock::MarkAliasedLocalTemps(const GrowingIntArray& localTabl mVisited = true; for (i = 0; i < mInstructions.Size(); i++) - mInstructions[i].MarkAliasedLocalTemps(localTable, aliasedLocals); + mInstructions[i].MarkAliasedLocalTemps(localTable, aliasedLocals, paramTable, aliasedParams); - if (mTrueJump) mTrueJump->MarkAliasedLocalTemps(localTable, aliasedLocals); - if (mFalseJump) mFalseJump->MarkAliasedLocalTemps(localTable, aliasedLocals); + if (mTrueJump) mTrueJump->MarkAliasedLocalTemps(localTable, aliasedLocals, paramTable, aliasedParams); + if (mFalseJump) mFalseJump->MarkAliasedLocalTemps(localTable, aliasedLocals, paramTable, aliasedParams); } } @@ -2351,13 +2430,11 @@ bool InterCodeBasicBlock::RemoveUnusedStoreInstructions(const GrowingVariableArr NumberSet requiredVars(mExitRequiredVars); int i; - for (i = mInstructions.Size() - 1; i > 0; i--) + for (i = mInstructions.Size() - 1; i >= 0; i--) { - if (mInstructions[i].RemoveUnusedStoreInstructions(localVars, &(mInstructions[i - 1]), requiredVars)) + if (mInstructions[i].RemoveUnusedStoreInstructions(localVars, requiredVars)) changed = true; } - if (mInstructions[0].RemoveUnusedStoreInstructions(localVars, nullptr, requiredVars)) - changed = true; if (mTrueJump) { @@ -2375,7 +2452,7 @@ bool InterCodeBasicBlock::RemoveUnusedStoreInstructions(const GrowingVariableArr } -void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals) +void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams) { int i; @@ -2384,32 +2461,57 @@ void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArra GrowingInstructionPtrArray ltvalue(tvalue); ValueSet lvalues(values); - mVisited = true; - - tvalid.Clear(); - - if (mNumEntries != 1) + if (mLoopHead) { lvalues.FlushAll(); ltvalue.Clear(); } - else +#if 0 + else if (mNumEntries > 1) { - for (i = 0; i < ltvalue.Size(); i++) + lvalues.FlushAll(); + ltvalue.Clear(); + } +#endif + else if (mNumEntries > 0) + { + if (mNumEntered > 0) { - if (ltvalue[i]) - tvalid += i; + lvalues.Intersect(mMergeValues); + for (int i = 0; i < ltvalue.Size(); i++) + { + if (mMergeTValues[i] != ltvalue[i]) + ltvalue[i] = nullptr; + } } + + mNumEntered++; + + if (mNumEntered < mNumEntries) + { + mMergeTValues = ltvalue; + mMergeValues = lvalues; + return; + } + } + + mVisited = true; + + tvalid.Clear(); + for (i = 0; i < ltvalue.Size(); i++) + { + if (ltvalue[i]) + tvalid += i; } for (i = 0; i < mInstructions.Size(); i++) { - lvalues.UpdateValue(mInstructions[i], ltvalue, aliasedLocals); + lvalues.UpdateValue(mInstructions[i], ltvalue, aliasedLocals, aliasedParams); mInstructions[i].PerformValueForwarding(ltvalue, tvalid); } - if (mTrueJump) mTrueJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals); - if (mFalseJump) mFalseJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals); + if (mTrueJump) mTrueJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams); + if (mFalseJump) mFalseJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams); } } @@ -2974,7 +3076,7 @@ void InterCodeBasicBlock::CollectVariables(GrowingVariableArray& globalVars, Gro } } -void InterCodeBasicBlock::CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray& localTypes) +void InterCodeBasicBlock::CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray& localTypes, FastNumberSet& complexParams, FastNumberSet& simpleParams, GrowingTypeArray& paramTypes) { int i; @@ -2984,11 +3086,11 @@ void InterCodeBasicBlock::CollectSimpleLocals(FastNumberSet& complexLocals, Fast for (i = 0; i < mInstructions.Size(); i++) { - mInstructions[i].CollectSimpleLocals(complexLocals, simpleLocals, localTypes); + mInstructions[i].CollectSimpleLocals(complexLocals, simpleLocals, localTypes, complexParams, simpleParams, paramTypes); } - if (mTrueJump) mTrueJump->CollectSimpleLocals(complexLocals, simpleLocals, localTypes); - if (mFalseJump) mFalseJump->CollectSimpleLocals(complexLocals, simpleLocals, localTypes); + if (mTrueJump) mTrueJump->CollectSimpleLocals(complexLocals, simpleLocals, localTypes, complexParams, simpleParams, paramTypes); + if (mFalseJump) mFalseJump->CollectSimpleLocals(complexLocals, simpleLocals, localTypes, complexParams, simpleParams, paramTypes); } } @@ -3055,7 +3157,8 @@ void InterCodeBasicBlock::Disassemble(FILE* file, bool dumpSets) { mVisited = true; - fprintf(file, "L%d: (%d)\n", mIndex, mNumEntries); + const char* s = mLoopHead ? "Head" : ""; + fprintf(file, "L%d: (%d) %s\n", mIndex, mNumEntries, s); if (dumpSets) { @@ -3106,7 +3209,10 @@ void InterCodeProcedure::ResetVisited(void) int i; for (i = 0; i < mBlocks.Size(); i++) + { mBlocks[i]->mVisited = false; + mBlocks[i]->mNumEntered = 0; + } } void InterCodeProcedure::Append(InterCodeBasicBlock* block) @@ -3331,18 +3437,22 @@ void InterCodeProcedure::Close(void) // // Find all local variables that are never aliased // - GrowingIntArray localTable(-1); + GrowingIntArray localTable(-1), paramTable(-1); ResetVisited(); - mBlocks[0]->CollectLocalAddressTemps(localTable); + mBlocks[0]->CollectLocalAddressTemps(localTable, paramTable); - int nlocals = 0; + int nlocals = 0, nparams = 0; for (int i = 0; i < localTable.Size(); i++) if (localTable[i] + 1 > nlocals) nlocals = localTable[i] + 1; + for (int i = 0; i < paramTable.Size(); i++) + if (paramTable[i] + 1 > nparams) + nparams = paramTable[i] + 1; mLocalAliasedSet.Reset(nlocals); + mParamAliasedSet.Reset(nparams); ResetVisited(); - mBlocks[0]->MarkAliasedLocalTemps(localTable, mLocalAliasedSet); + mBlocks[0]->MarkAliasedLocalTemps(localTable, mLocalAliasedSet, paramTable, mParamAliasedSet); // // Now forward constant values @@ -3353,7 +3463,7 @@ void InterCodeProcedure::Close(void) mValueForwardingTable.SetSize(numTemps, true); ResetVisited(); - mBlocks[0]->PerformValueForwarding(mValueForwardingTable, valueSet, tvalidSet, mLocalAliasedSet); + mBlocks[0]->PerformValueForwarding(mValueForwardingTable, valueSet, tvalidSet, mLocalAliasedSet, mParamAliasedSet); DisassembleDebug("value forwarding"); @@ -3441,8 +3551,11 @@ void InterCodeProcedure::Close(void) FastNumberSet simpleLocals(nlocals), complexLocals(nlocals); GrowingTypeArray localTypes(IT_NONE); + FastNumberSet simpleParams(nparams), complexParams(nparams); + GrowingTypeArray paramTypes(IT_NONE); + ResetVisited(); - mBlocks[0]->CollectSimpleLocals(complexLocals, simpleLocals, localTypes); + mBlocks[0]->CollectSimpleLocals(complexLocals, simpleLocals, localTypes, complexParams, simpleParams, paramTypes); for (int i = 0; i < simpleLocals.Num(); i++) { diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index ef9c21f..b727581 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -123,13 +123,16 @@ public: ValueSet(const ValueSet& values); ~ValueSet(void); + ValueSet& operator=(const ValueSet& values); + void FlushAll(void); void FlushCallAliases(void); void RemoveValue(int index); void InsertValue(InterInstruction& ins); - void UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals); + void UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams); + void Intersect(ValueSet& set); }; class TempForwardingTable @@ -276,13 +279,13 @@ public: InterInstruction(void); void SetCode(const Location & loc, InterCode code); - void CollectLocalAddressTemps(GrowingIntArray& localTable); - void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals); + void CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable); + void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams); void FilterTempUsage(NumberSet& requiredVars, NumberSet& providedVars); void FilterVarsUsage(const GrowingVariableArray& localVars, NumberSet& requiredTemps, NumberSet& providedTemps); bool RemoveUnusedResultInstructions(InterInstruction* pre, NumberSet& requiredTemps, int numStaticTemps); - bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, InterInstruction* pre, NumberSet& requiredTemps); + bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, NumberSet& requiredTemps); void PerformValueForwarding(GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid); void BuildCallerSaveTempSet(NumberSet& requiredTemps, NumberSet& callerSaveTemps); @@ -297,7 +300,7 @@ public: void CollectActiveTemporaries(FastNumberSet& set); void ShrinkActiveTemporaries(FastNumberSet& set, GrowingTypeArray& temporaries); - void CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray& localTypes); + void CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray& localTypes, FastNumberSet& complexParams, FastNumberSet& simpleParams, GrowingTypeArray& paramTypes); void SimpleLocalToTemp(int vindex, int temp); void Disassemble(FILE* file); @@ -351,11 +354,11 @@ public: class InterCodeBasicBlock { public: - int mIndex, mNumEntries; + int mIndex, mNumEntries, mNumEntered; InterCodeBasicBlock* mTrueJump, * mFalseJump; GrowingInstructionArray mInstructions; - bool mVisited; + bool mVisited, mInPath, mLoopHead; NumberSet mLocalRequiredTemps, mLocalProvidedTemps; NumberSet mEntryRequiredTemps, mEntryProvidedTemps; @@ -365,6 +368,9 @@ public: NumberSet mEntryRequiredVars, mEntryProvidedVars; NumberSet mExitRequiredVars, mExitProvidedVars; + GrowingInstructionPtrArray mMergeTValues; + ValueSet mMergeValues; + InterCodeBasicBlock(void); ~InterCodeBasicBlock(void); @@ -376,8 +382,8 @@ public: void LocalToTemp(int vindex, int temp); - void CollectLocalAddressTemps(GrowingIntArray& localTable); - void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals); + void CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable); + void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams); void BuildLocalTempSets(int num, int numFixed); void BuildGlobalProvidedTempSet(NumberSet fromProvidedTemps); @@ -399,13 +405,13 @@ public: void CheckValueUsage(InterInstruction& ins, const GrowingInstructionPtrArray& tvalue); void PerformTempForwarding(TempForwardingTable& forwardingTable); - void PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals); + void PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams); void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid); void BuildCollisionTable(NumberSet* collisionSets); void ReduceTemporaries(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries); - void CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray & localTypes); + void CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray & localTypes, FastNumberSet& complexParams, FastNumberSet& simpleParams, GrowingTypeArray& paramTypes); void SimpleLocalToTemp(int vindex, int temp); void CollectActiveTemporaries(FastNumberSet& set); @@ -434,7 +440,7 @@ protected: TempForwardingTable mTempForwardingTable; GrowingInstructionPtrArray mValueForwardingTable; int numFixedTemporaries; - NumberSet mLocalAliasedSet; + NumberSet mLocalAliasedSet, mParamAliasedSet; void ResetVisited(void); public: diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 8f2d7ba..3f3d881 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -445,6 +445,28 @@ bool NativeCodeInstruction::ChangesAddress(void) const } +bool NativeCodeInstruction::SameEffectiveAddress(const NativeCodeInstruction& ins) const +{ + if (mMode != ins.mMode) + return false; + + switch (mMode) + { + case ASMIM_ZERO_PAGE: + case ASMIM_ZERO_PAGE_X: + case ASMIM_ZERO_PAGE_Y: + case ASMIM_INDIRECT_X: + case ASMIM_INDIRECT_Y: + return ins.mAddress == mAddress; + case ASMIM_ABSOLUTE: + case ASMIM_ABSOLUTE_X: + case ASMIM_ABSOLUTE_Y: + return (ins.mVarIndex == mVarIndex && ins.mAddress == mAddress && ins.mFunction == mFunction && ins.mRuntime == mRuntime); + default: + return false; + } +} + bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) { bool changed = false; @@ -2645,10 +2667,10 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI { if (sins0) { - insl = NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, treg); - insh = NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, treg + 1); + insl = NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_WORK + 0); + insh = NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_WORK + 1); - LoadValueToReg(proc, *sins0, treg, nullptr, nullptr); + LoadValueToReg(proc, *sins0, BC_REG_WORK, nullptr, nullptr); } else { @@ -3784,8 +3806,35 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void) mIns[i].mType = ASMIT_NOP; progress = true; } + else if (mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && + mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == mIns[i + 2].mAddress && + mIns[i + 1].mType == ASMIT_INC && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == mIns[i + 1].mAddress && (mIns[i + 2].mLive & LIVE_CPU_REG_C) == 0) + { + mIns[i + 0].mType = ASMIT_CLC; + mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_ADC; + mIns[i + 1].mMode = ASMIM_IMMEDIATE; + mIns[i + 1].mAddress = 1; + mIns[i + 2].mType = ASMIT_STA; + progress = true; + } } + if (i + 3 < mIns.Size()) + { + if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) && + 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].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) && + (mIns[i + 3].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_A)) == 0) + { + mIns[i + 0].mType = ASMIT_NOP; + mIns[i + 1].mType = ASMIT_NOP; + mIns[i + 2].mType = ASMIT_NOP; + mIns[i + 3].mType = ASMIT_INC; + } + } + + if (i + 4 < mIns.Size()) { if (mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index a656a2a..8822f0d 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -46,6 +46,7 @@ public: bool LoadsAccu(void) const; bool ChangesAddress(void) const; + bool SameEffectiveAddress(const NativeCodeInstruction& ins) const; }; class NativeCodeBasicBlock diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index c7eff3e..5128cdf 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -549,6 +549,7 @@ Expression* Parser::ParseInitExpression(Declaration* dtype) { dtype->mFlags |= DTF_DEFINED; dtype->mSize = index; + dec->mSize = index; } } else