diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index fc261a0..1e92d7c 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -5262,7 +5262,7 @@ void InterInstruction::Disassemble(FILE* file, InterCodeProcedure* proc) { if (this->mCode != IC_NONE) { - static char memchars[] = "NPLGFPITAZZ"; + static char memchars[] = "NPLGFPITAZC"; fprintf(file, "\t"); switch (this->mCode) @@ -9973,6 +9973,10 @@ bool InterCodeBasicBlock::BuildGlobalRequiredVariableSet(const GrowingVariableAr return revisit; } + + + + bool InterCodeBasicBlock::RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory) { bool changed = false; @@ -10008,6 +10012,76 @@ bool InterCodeBasicBlock::RemoveUnusedStoreInstructions(const GrowingVariableArr } +bool InterCodeBasicBlock::RemoveUnusedArgumentStoreInstructions(void) +{ + bool changed = false; + + if (!mVisited) + { + mVisited = true; + + mEntryRequiredArgs.Reset(64, true); + + if (mTrueJump && mTrueJump == this) + { + if (mFalseJump) + { + if (mFalseJump->RemoveUnusedArgumentStoreInstructions()) + changed = true; + mEntryRequiredArgs = mFalseJump->mEntryRequiredArgs; + } + else + mEntryRequiredArgs.Reset(64, false); + } + else if (mFalseJump && mFalseJump == this) + { + if (mTrueJump->RemoveUnusedArgumentStoreInstructions()) + changed = true; + mEntryRequiredArgs = mTrueJump->mEntryRequiredArgs; + } + else + { + if (mTrueJump && mTrueJump->RemoveUnusedArgumentStoreInstructions()) + changed = true; + if (mFalseJump && mFalseJump->RemoveUnusedArgumentStoreInstructions()) + changed = true; + + if (mTrueJump) + { + mEntryRequiredArgs = mTrueJump->mEntryRequiredArgs; + if (mFalseJump) + mEntryRequiredArgs |= mTrueJump->mEntryRequiredArgs; + } + else + mEntryRequiredArgs.Reset(64, false); + } + + int i = mInstructions.Size() - 1; + while (i >= 0) + { + InterInstruction* ins(mInstructions[i]); + + if (ins->mCode == IC_CALL || ins->mCode == IC_CALL_NATIVE) + { + mEntryRequiredArgs.Fill(); + } + else if (ins->mCode == IC_STORE && ins->mSrc[1].mMemory == IM_FFRAME) + { + if (mEntryRequiredArgs.RangeClear(ins->mSrc[1].mVarIndex, InterTypeSize[ins->mSrc[0].mType])) + { + mInstructions.Remove(i); + changed = true; + } + else + mEntryRequiredArgs.SubRange(ins->mSrc[1].mVarIndex, InterTypeSize[ins->mSrc[0].mType]); + } + i--; + } + } + + return changed; +} + bool InterCodeBasicBlock::RemoveUnusedIndirectStoreInstructions(void) { bool changed = false; @@ -15237,7 +15311,7 @@ void InterCodeBasicBlock::ConstLoopOptimization(void) const InterInstruction* ins(mInstructions[i]); if (ins->mCode == IC_CONSTANT || ins->mCode == IC_BRANCH || - ins->mCode == IC_BINARY_OPERATOR || ins->mCode == IC_UNARY_OPERATOR || ins->mCode == IC_RELATIONAL_OPERATOR) + ins->mCode == IC_BINARY_OPERATOR || ins->mCode == IC_UNARY_OPERATOR || ins->mCode == IC_RELATIONAL_OPERATOR || ins->mCode == IC_LEA) { int j = 0; while (j < ins->mNumOperands && (ins->mSrc[j].mTemp < 0 || cset[ins->mSrc[j].mTemp])) @@ -17450,6 +17524,21 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa } } } + else if (ains->mCode == IC_LEA && cins->mCode == IC_RELATIONAL_OPERATOR && bins->mCode == IC_BRANCH) + { + if (ains->mSrc[1].mTemp == ains->mDst.mTemp && ains->mSrc[0].mTemp < 0 && + (cins->mSrc[1].mTemp == ains->mDst.mTemp || cins->mSrc[0].mTemp == ains->mDst.mTemp) && + bins->mSrc[0].mTemp == cins->mDst.mTemp && bins->mSrc[0].mFinal) + { + if (cins->mOperator == IA_CMPNE && mTrueJump == this && !tailBlock->mEntryRequiredTemps[ains->mDst.mTemp]) + { + cins->mCode = IC_CONSTANT; + cins->mConst.mType = IT_BOOL; + cins->mConst.mIntConst = 0; + cins->mNumOperands = 0; + } + } + } } if (!hasCall && (mProc->mCompilerOptions & COPT_OPTIMIZE_BASIC)) @@ -21793,7 +21882,7 @@ void InterCodeProcedure::Close(void) { GrowingTypeArray tstack(IT_NONE); - CheckFunc = !strcmp(mIdent->mString, "shots_move"); + CheckFunc = !strcmp(mIdent->mString, "REUArray::CacheNode::*CacheNode"); CheckCase = false; mEntryBlock = mBlocks[0]; @@ -21915,6 +22004,11 @@ void InterCodeProcedure::Close(void) } } + ResetVisited(); + mEntryBlock->RemoveUnusedArgumentStoreInstructions(); + + DisassembleDebug("RemoveUnusedArgumentStoreInstructions"); + // // // Now remove needless temporary moves, that appear due to @@ -22589,6 +22683,7 @@ void InterCodeProcedure::Close(void) mEntryBlock->ForwardShortLoadStoreOffsets(); DisassembleDebug("ForwardShortLoadStoreOffsets"); + ConstLoopOptimization(); // CollapseDispatch(); // DisassembleDebug("CollapseDispatch"); diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index ee4b39f..3566ff8 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -390,6 +390,8 @@ public: NumberSet mEntryRequiredParams, mEntryProvidedParams; NumberSet mExitRequiredParams, mExitProvidedParams; + NumberSet mEntryRequiredArgs; + GrowingInstructionArray mLoadStoreInstructions; GrowingIntegerValueRangeArray mEntryValueRange, mTrueValueRange, mFalseValueRange; @@ -451,6 +453,8 @@ public: bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory); bool RemoveUnusedIndirectStoreInstructions(void); + bool RemoveUnusedArgumentStoreInstructions(void); + void BuildStaticVariableSet(const GrowingVariableArray& staticVars); void BuildGlobalProvidedStaticVariableSet(const GrowingVariableArray& staticVars, NumberSet fromProvidedVars); bool BuildGlobalRequiredStaticVariableSet(const GrowingVariableArray& staticVars, NumberSet& fromRequiredVars); diff --git a/oscar64/NumberSet.cpp b/oscar64/NumberSet.cpp index 74b2dd8..e78d7ce 100644 --- a/oscar64/NumberSet.cpp +++ b/oscar64/NumberSet.cpp @@ -47,6 +47,26 @@ NumberSet::~NumberSet(void) delete[] bits; } +void NumberSet::Expand(int size, bool set) +{ + if (size > this->size) + { + int ndwsize = (size + 31) >> 5; + if (dwsize != ndwsize) + { + uint32 * nbits = new uint32[ndwsize]; + for (int i = 0; i < dwsize; i++) + nbits[i] = bits[i]; + for (int i = dwsize; i < ndwsize; i++) + nbits[i] = 0; + delete[] bits; + dwsize = ndwsize; + bits = nbits; + } + this->size = size; + } +} + void NumberSet::Reset(int size, bool set) { int i; diff --git a/oscar64/NumberSet.h b/oscar64/NumberSet.h index 45cea76..bb67da0 100644 --- a/oscar64/NumberSet.h +++ b/oscar64/NumberSet.h @@ -16,6 +16,7 @@ public: ~NumberSet(void); void Reset(int size, bool set = false); + void Expand(int size, bool set = false); NumberSet& operator+=(int elem); NumberSet& operator-=(int elem);