diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index ba65777..91c2dc4 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -806,6 +806,262 @@ void ValueSet::InsertValue(InterInstruction * ins) mInstructions[mNum++] = ins; } +static bool CanBypassLoad(const InterInstruction* lins, const InterInstruction* bins) +{ + // Check ambiguity + if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY) + return false; + + // Side effects + if (bins->mCode == IC_CALL || bins->mCode == IC_CALL_NATIVE || bins->mCode == IC_ASSEMBLER) + return false; + + // True data dependency + if (bins->UsesTemp(lins->mDst.mTemp)) + return false; + + if (bins->mCode == IC_STORE) + { + if (lins->mVolatile) + return false; + else if (lins->mSrc[0].mTemp >= 0 || bins->mSrc[1].mTemp >= 0) + return false; + else if (lins->mSrc[0].mMemory != bins->mSrc[1].mMemory) + return true; + else if (lins->mSrc[0].mMemory == IM_GLOBAL) + { + return lins->mSrc[0].mLinkerObject != bins->mSrc[1].mLinkerObject || + lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst || + lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize; + } + else if (lins->mSrc[0].mMemory == IM_ABSOLUTE) + { + return + lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst || + lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize; + } + else if (lins->mSrc[0].mMemory == IM_LOCAL) + { + return lins->mSrc[0].mVarIndex != bins->mSrc[1].mVarIndex || + lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst || + lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize; + } + else + return false; + } + + // False data dependency + if (lins->mSrc[0].mTemp >= 0 && lins->mSrc[0].mTemp == bins->mDst.mTemp) + return false; + + return true; +} + +static bool CanBypass(const InterInstruction* lins, const InterInstruction* bins) +{ + if (lins->mDst.mTemp >= 0) + { + if (lins->mDst.mTemp == bins->mDst.mTemp) + return false; + + for (int i = 0; i < bins->mNumOperands; i++) + if (lins->mDst.mTemp == bins->mSrc[i].mTemp) + return false; + } + if (bins->mDst.mTemp >= 0) + { + for (int i = 0; i < lins->mNumOperands; i++) + if (bins->mDst.mTemp == lins->mSrc[i].mTemp) + 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) + return false; + } + + return true; +} + +static bool CanBypassUp(const InterInstruction* lins, const InterInstruction* bins) +{ + if (lins->mDst.mTemp >= 0) + { + if (lins->mDst.mTemp == bins->mDst.mTemp) + return false; + + for (int i = 0; i < bins->mNumOperands; i++) + if (lins->mDst.mTemp == bins->mSrc[i].mTemp) + return false; + } + if (bins->mDst.mTemp >= 0) + { + for (int i = 0; i < lins->mNumOperands; i++) + if (bins->mDst.mTemp == lins->mSrc[i].mTemp) + 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) + return false; + } + + return true; +} + +static bool CanBypassLoadUp(const InterInstruction* lins, const InterInstruction* bins) +{ + // Check ambiguity + if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY) + return false; + + // Side effects + if (bins->mCode == IC_CALL || bins->mCode == IC_CALL_NATIVE || bins->mCode == IC_ASSEMBLER) + return false; + + // False data dependency + if (bins->UsesTemp(lins->mDst.mTemp) || bins->mDst.mTemp == lins->mDst.mTemp) + return false; + + // True data dependency + if (lins->mSrc[0].mTemp >= 0 && lins->mSrc[0].mTemp == bins->mDst.mTemp) + return false; + + if (bins->mCode == IC_STORE) + { + if (lins->mVolatile) + return false; + else if (lins->mSrc[0].mTemp >= 0 || bins->mSrc[1].mTemp >= 0) + return false; + else if (lins->mSrc[0].mMemory != bins->mSrc[1].mMemory) + return true; + else if (lins->mSrc[0].mMemory == IM_GLOBAL) + { + return lins->mSrc[0].mLinkerObject != bins->mSrc[1].mLinkerObject || + lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst || + lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize; + } + else if (lins->mSrc[0].mMemory == IM_ABSOLUTE) + { + return + lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst || + lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize; + } + else if (lins->mSrc[0].mMemory == IM_LOCAL) + { + return lins->mSrc[0].mVarIndex != bins->mSrc[1].mVarIndex || + lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst || + lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize; + } + else + return false; + } + + return true; +} + + +static bool IsChained(const InterInstruction* ins, const InterInstruction* nins) +{ + if (ins->mDst.mTemp >= 0) + { + for (int i = 0; i < nins->mNumOperands; i++) + if (ins->mDst.mTemp == nins->mSrc[i].mTemp) + return true; + } + + return false; +} + +static bool CanBypassStore(const InterInstruction* sins, const InterInstruction* bins) +{ + if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY || bins->mCode == IC_PUSH_FRAME) + return false; + + InterMemory sm = IM_NONE, bm = IM_NONE; + int bi = -1, si = -1, bt = -1, st = -1, bo = 0, so = 0, bz = 1, sz = 1; + if (sins->mCode == IC_LOAD) + { + sm = sins->mSrc[0].mMemory; + si = sins->mSrc[0].mVarIndex; + st = sins->mSrc[0].mTemp; + so = sins->mSrc[0].mIntConst; + sz = InterTypeSize[sins->mDst.mType]; + } + else if (sins->mCode == IC_LEA || sins->mCode == IC_STORE) + { + sm = sins->mSrc[1].mMemory; + si = sins->mSrc[1].mVarIndex; + st = sins->mSrc[1].mTemp; + so = sins->mSrc[1].mIntConst; + sz = InterTypeSize[sins->mSrc[0].mType]; + } + + if (bins->mCode == IC_LOAD) + { + bm = bins->mSrc[0].mMemory; + bi = bins->mSrc[0].mVarIndex; + bt = sins->mSrc[0].mTemp; + bo = sins->mSrc[0].mIntConst; + bz = InterTypeSize[sins->mDst.mType]; + } + else if (bins->mCode == IC_LEA || bins->mCode == IC_STORE) + { + bm = bins->mSrc[1].mMemory; + bi = bins->mSrc[1].mVarIndex; + bt = sins->mSrc[1].mTemp; + bo = sins->mSrc[1].mIntConst; + bz = InterTypeSize[sins->mSrc[0].mType]; + } + + // Check ambiguity + if (bins->mCode == IC_STORE || bins->mCode == IC_LOAD) + { + if (sm == IM_LOCAL) + { + if (bm == IM_PARAM || bm == IM_GLOBAL || bm == IM_FPARAM) + ; + else if (bm == IM_LOCAL) + { + if (bi == si) + return false; + } + else + return false; + } + else if (sm == IM_FRAME || sm == IM_FFRAME) + ; + else if (sm == IM_FPARAM) + { + if (bi == si) + return false; + } + else if (sm == IM_INDIRECT && bm == IM_INDIRECT && st == bt) + { + return so + sz <= bz || bo + bz <= so; + } + else + return false; + } + + if (sm == IM_FRAME && (bins->mCode == IC_PUSH_FRAME || bins->mCode == IC_POP_FRAME)) + return false; + + // Side effects + if (bins->mCode == IC_CALL || bins->mCode == IC_CALL_NATIVE || bins->mCode == IC_ASSEMBLER) + return false; + + // True data dependency + if (bins->mDst.mTemp >= 0) + { + for (int i = 0; i < sins->mNumOperands; i++) + if (bins->mDst.mTemp == sins->mSrc[i].mTemp) + return false; + } + + return true; +} + static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* sins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, const GrowingVariableArray& staticVars) { InterMemory lmem, smem; @@ -3902,6 +4158,35 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI ins->mSrc[1].mTemp = pins->mSrc[1].mTemp; } } + else if (ins->mOperator == IA_SUB && pins->mOperator == IA_SUB) + { + if (pins->mSrc[0].mTemp < 0) + { + ins->mSrc[0].mIntConst = ConstantFolding(IA_ADD, ins->mDst.mType, ins->mSrc[0].mIntConst, pins->mSrc[0].mIntConst); + ins->mSrc[1].mTemp = pins->mSrc[1].mTemp; + } + } + else if (ins->mOperator == IA_ADD && pins->mOperator == IA_SUB) + { + if (pins->mSrc[0].mTemp < 0) + { + ins->mSrc[0].mIntConst = ConstantFolding(IA_SUB, ins->mDst.mType, ins->mSrc[0].mIntConst, pins->mSrc[0].mIntConst); + ins->mSrc[1].mTemp = pins->mSrc[1].mTemp; + } + } + else if (ins->mOperator == IA_SUB && pins->mOperator == IA_ADD) + { + if (pins->mSrc[1].mTemp < 0) + { + ins->mSrc[0].mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, ins->mSrc[0].mIntConst, pins->mSrc[1].mIntConst); + ins->mSrc[1].mTemp = pins->mSrc[0].mTemp; + } + else if (pins->mSrc[0].mTemp < 0) + { + ins->mSrc[0].mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, ins->mSrc[0].mIntConst, pins->mSrc[0].mIntConst); + ins->mSrc[1].mTemp = pins->mSrc[1].mTemp; + } + } else if (ins->mOperator == IA_SHL && (pins->mOperator == IA_SHR || pins->mOperator == IA_SAR) && pins->mSrc[0].mTemp < 0 && ins->mSrc[0].mIntConst == pins->mSrc[0].mIntConst) { ins->mOperator = IA_AND; @@ -4111,11 +4396,14 @@ void InterCodeBasicBlock::CollectLocalUsedTemps(int numTemps) mVisited = true; mLocalUsedTemps.Reset(numTemps); + mLocalModifiedTemps.Reset(numTemps); for (int i = 0; i < mInstructions.Size(); i++) { InterInstruction* ins(mInstructions[i]); + if (ins->mDst.mTemp >= 0) + mLocalModifiedTemps += ins->mDst.mTemp; for (int j = 0; j < ins->mNumOperands; j++) { if (ins->mSrc[j].mTemp >= 0) @@ -6774,9 +7062,19 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void) if (mTrueJump && mFalseJump) { + InterCodeBasicBlock* joinedBlock = nullptr; + + NumberSet trueExitRequiredTemps(mTrueJump->mEntryRequiredTemps), falseExitRequiredTems(mFalseJump->mEntryRequiredTemps); NumberSet providedTemps(mExitRequiredTemps.Size()), requiredTemps(mExitRequiredTemps.Size()); + if (mTrueJump->mTrueJump && mFalseJump->mTrueJump && !mTrueJump->mFalseJump && !mFalseJump->mFalseJump && + mTrueJump->mNumEntries == 1 && mFalseJump->mNumEntries == 1 && + mTrueJump->mTrueJump == mFalseJump->mTrueJump && mTrueJump->mTrueJump->mNumEntries == 2) + { + joinedBlock = mTrueJump->mTrueJump; + } + bool hadStore = false; int i = mInstructions.Size(); @@ -6785,9 +7083,10 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void) i--; InterInstruction* ins(mInstructions[i]); + int dtemp = ins->mDst.mTemp; bool moved = false; - if (ins->mDst.mTemp >= 0 && !providedTemps[ins->mDst.mTemp] && !requiredTemps[ins->mDst.mTemp]) + if (dtemp >= 0 && !providedTemps[dtemp] && !requiredTemps[dtemp]) { int j = 0; while (j < ins->mNumOperands && (ins->mSrc[j].mTemp < 0 || !(providedTemps[ins->mSrc[j].mTemp] || IsTempModifiedOnPath(ins->mSrc[j].mTemp, i + 1)))) @@ -6795,7 +7094,7 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void) if (j == ins->mNumOperands && IsMoveable(ins->mCode) && (ins->mCode != IC_LOAD || !hadStore)) { - if (mTrueJump->mNumEntries == 1 && trueExitRequiredTemps[ins->mDst.mTemp] && !falseExitRequiredTems[ins->mDst.mTemp]) + if (mTrueJump->mNumEntries == 1 && trueExitRequiredTemps[dtemp] && !falseExitRequiredTems[dtemp]) { for (int j = 0; j < ins->mNumOperands; j++) { @@ -6807,7 +7106,7 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void) moved = true; changed = true; } - else if (mFalseJump->mNumEntries == 1 && !trueExitRequiredTemps[ins->mDst.mTemp] && falseExitRequiredTems[ins->mDst.mTemp]) + else if (mFalseJump->mNumEntries == 1 && !trueExitRequiredTemps[dtemp] && falseExitRequiredTems[dtemp]) { for (int j = 0; j < ins->mNumOperands; j++) { @@ -6819,6 +7118,53 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void) moved = true; changed = true; } +#if 1 + else if (joinedBlock && !HasSideEffect(ins->mCode) && + !mFalseJump->mLocalUsedTemps[dtemp] && !mFalseJump->mLocalModifiedTemps[dtemp] && + !mTrueJump->mLocalUsedTemps[dtemp] && !mTrueJump->mLocalModifiedTemps[dtemp]) + { + int j = 0; + while (j < ins->mNumOperands && !(ins->mSrc[j].mTemp >= 0 && (mFalseJump->mLocalModifiedTemps[dtemp] || mTrueJump->mLocalModifiedTemps[dtemp]))) + j++; + + if (j == ins->mNumOperands) + { + if (ins->mCode == IC_LOAD) + { + j = 0; + while (j < mTrueJump->mInstructions.Size() && CanBypassLoad(ins, mTrueJump->mInstructions[j])) + j++; + } + if (ins->mCode != IC_LOAD || j == mTrueJump->mInstructions.Size()) + { + if (ins->mCode == IC_LOAD) + { + j = 0; + while (j < mFalseJump->mInstructions.Size() && CanBypassLoad(ins, mFalseJump->mInstructions[j])) + j++; + } + + if (ins->mCode != IC_LOAD || j == mFalseJump->mInstructions.Size()) + { + for (int j = 0; j < ins->mNumOperands; j++) + { + if (ins->mSrc[j].mTemp >= 0) + { + trueExitRequiredTemps += ins->mSrc[j].mTemp; + falseExitRequiredTems += ins->mSrc[j].mTemp; + joinedBlock->mEntryRequiredTemps += ins->mSrc[j].mTemp; + } + } + + joinedBlock->mInstructions.Insert(0, ins); + mInstructions.Remove(i); + moved = true; + changed = true; + } + } + } + } +#endif } providedTemps += ins->mDst.mTemp; @@ -6939,261 +7285,6 @@ bool InterCodeBasicBlock::IsLeafProcedure(void) return true; } -static bool CanBypassLoad(const InterInstruction * lins, const InterInstruction * bins) -{ - // Check ambiguity - if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY) - return false; - - // Side effects - if (bins->mCode == IC_CALL || bins->mCode == IC_CALL_NATIVE || bins->mCode == IC_ASSEMBLER) - return false; - - // True data dependency - if (bins->UsesTemp(lins->mDst.mTemp)) - return false; - - if (bins->mCode == IC_STORE) - { - if (lins->mVolatile) - return false; - else if (lins->mSrc[0].mTemp >= 0 || bins->mSrc[1].mTemp >= 0) - return false; - else if (lins->mSrc[0].mMemory != bins->mSrc[1].mMemory) - return true; - else if (lins->mSrc[0].mMemory == IM_GLOBAL) - { - return lins->mSrc[0].mLinkerObject != bins->mSrc[1].mLinkerObject || - lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst || - lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize; - } - else if (lins->mSrc[0].mMemory == IM_ABSOLUTE) - { - return - lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst || - lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize; - } - else if (lins->mSrc[0].mMemory == IM_LOCAL) - { - return lins->mSrc[0].mVarIndex != bins->mSrc[1].mVarIndex || - lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst || - lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize; - } - else - return false; - } - - // False data dependency - if (lins->mSrc[0].mTemp >= 0 && lins->mSrc[0].mTemp == bins->mDst.mTemp) - return false; - - return true; -} - -static bool CanBypass(const InterInstruction* lins, const InterInstruction* bins) -{ - if (lins->mDst.mTemp >= 0) - { - if (lins->mDst.mTemp == bins->mDst.mTemp) - return false; - - for (int i = 0; i < bins->mNumOperands; i++) - if (lins->mDst.mTemp == bins->mSrc[i].mTemp) - return false; - } - if (bins->mDst.mTemp >= 0) - { - for (int i = 0; i < lins->mNumOperands; i++) - if (bins->mDst.mTemp == lins->mSrc[i].mTemp) - 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) - return false; - } - - return true; -} - -static bool CanBypassUp(const InterInstruction* lins, const InterInstruction* bins) -{ - if (lins->mDst.mTemp >= 0) - { - if (lins->mDst.mTemp == bins->mDst.mTemp) - return false; - - for (int i = 0; i < bins->mNumOperands; i++) - if (lins->mDst.mTemp == bins->mSrc[i].mTemp) - return false; - } - if (bins->mDst.mTemp >= 0) - { - for (int i = 0; i < lins->mNumOperands; i++) - if (bins->mDst.mTemp == lins->mSrc[i].mTemp) - 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) - return false; - } - - return true; -} - -static bool CanBypassLoadUp(const InterInstruction* lins, const InterInstruction* bins) -{ - // Check ambiguity - if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY) - return false; - - // Side effects - if (bins->mCode == IC_CALL || bins->mCode == IC_CALL_NATIVE || bins->mCode == IC_ASSEMBLER) - return false; - - // False data dependency - if (bins->UsesTemp(lins->mDst.mTemp) || bins->mDst.mTemp == lins->mDst.mTemp) - return false; - - // True data dependency - if (lins->mSrc[0].mTemp >= 0 && lins->mSrc[0].mTemp == bins->mDst.mTemp) - return false; - - if (bins->mCode == IC_STORE) - { - if (lins->mVolatile) - return false; - else if (lins->mSrc[0].mTemp >= 0 || bins->mSrc[1].mTemp >= 0) - return false; - else if (lins->mSrc[0].mMemory != bins->mSrc[1].mMemory) - return true; - else if (lins->mSrc[0].mMemory == IM_GLOBAL) - { - return lins->mSrc[0].mLinkerObject != bins->mSrc[1].mLinkerObject || - lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst || - lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize; - } - else if (lins->mSrc[0].mMemory == IM_ABSOLUTE) - { - return - lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst || - lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize; - } - else if (lins->mSrc[0].mMemory == IM_LOCAL) - { - return lins->mSrc[0].mVarIndex != bins->mSrc[1].mVarIndex || - lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst || - lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize; - } - else - return false; - } - - return true; -} - - -static bool IsChained(const InterInstruction* ins, const InterInstruction* nins) -{ - if (ins->mDst.mTemp >= 0) - { - for (int i = 0; i < nins->mNumOperands; i++) - if (ins->mDst.mTemp == nins->mSrc[i].mTemp) - return true; - } - - return false; -} - -static bool CanBypassStore(const InterInstruction * sins, const InterInstruction * bins) -{ - if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY || bins->mCode == IC_PUSH_FRAME) - return false; - - InterMemory sm = IM_NONE, bm = IM_NONE; - int bi = -1, si = -1, bt = -1, st = -1, bo = 0, so = 0, bz = 1, sz = 1; - if (sins->mCode == IC_LOAD) - { - sm = sins->mSrc[0].mMemory; - si = sins->mSrc[0].mVarIndex; - st = sins->mSrc[0].mTemp; - so = sins->mSrc[0].mIntConst; - sz = InterTypeSize[sins->mDst.mType]; - } - else if (sins->mCode == IC_LEA || sins->mCode == IC_STORE) - { - sm = sins->mSrc[1].mMemory; - si = sins->mSrc[1].mVarIndex; - st = sins->mSrc[1].mTemp; - so = sins->mSrc[1].mIntConst; - sz = InterTypeSize[sins->mSrc[0].mType]; - } - - if (bins->mCode == IC_LOAD) - { - bm = bins->mSrc[0].mMemory; - bi = bins->mSrc[0].mVarIndex; - bt = sins->mSrc[0].mTemp; - bo = sins->mSrc[0].mIntConst; - bz = InterTypeSize[sins->mDst.mType]; - } - else if (bins->mCode == IC_LEA || bins->mCode == IC_STORE) - { - bm = bins->mSrc[1].mMemory; - bi = bins->mSrc[1].mVarIndex; - bt = sins->mSrc[1].mTemp; - bo = sins->mSrc[1].mIntConst; - bz = InterTypeSize[sins->mSrc[0].mType]; - } - - // Check ambiguity - if (bins->mCode == IC_STORE || bins->mCode == IC_LOAD) - { - if (sm == IM_LOCAL) - { - if (bm == IM_PARAM || bm == IM_GLOBAL || bm == IM_FPARAM) - ; - else if (bm == IM_LOCAL) - { - if (bi == si) - return false; - } - else - return false; - } - else if (sm == IM_FRAME || sm == IM_FFRAME) - ; - else if (sm == IM_FPARAM) - { - if (bi == si) - return false; - } - else if (sm == IM_INDIRECT && bm == IM_INDIRECT && st == bt) - { - return so + sz <= bz || bo + bz <= so; - } - else - return false; - } - - if (sm == IM_FRAME && (bins->mCode == IC_PUSH_FRAME || bins->mCode == IC_POP_FRAME)) - return false; - - // Side effects - if (bins->mCode == IC_CALL || bins->mCode == IC_CALL_NATIVE || bins->mCode == IC_ASSEMBLER) - return false; - - // True data dependency - if (bins->mDst.mTemp >= 0) - { - for (int i = 0; i < sins->mNumOperands; i++) - if (bins->mDst.mTemp == sins->mSrc[i].mTemp) - return false; - } - - return true; -} void InterCodeBasicBlock::SplitBranches(InterCodeProcedure* proc) { @@ -8702,7 +8793,7 @@ void InterCodeBasicBlock::PeepholeOptimization(void) #if 1 else if ( mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 0]->mOperator == IA_SHR && mInstructions[i + 0]->mSrc[0].mTemp < 0 && - mInstructions[i + 1]->mCode == IC_CONVERSION_OPERATOR && mInstructions[i + 1]->mOperator == IA_EXT8TO16U && + mInstructions[i + 1]->mCode == IC_CONVERSION_OPERATOR && mInstructions[i + 1]->mOperator == IA_EXT8TO16U && mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 2]->mOperator == IA_MUL && mInstructions[i + 2]->mSrc[0].mTemp < 0 && mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[0].mFinal && mInstructions[i + 2]->mSrc[1].mTemp == mInstructions[i + 1]->mDst.mTemp && mInstructions[i + 2]->mSrc[1].mFinal && @@ -8744,7 +8835,7 @@ void InterCodeBasicBlock::PeepholeOptimization(void) else if ( mInstructions[i + 1]->mCode == IC_LOAD_TEMPORARY && mExitRequiredTemps[mInstructions[i + 1]->mDst.mTemp] && (!mExitRequiredTemps[mInstructions[i + 1]->mSrc[0].mTemp] || - (mEntryRequiredTemps[mInstructions[i + 1]->mDst.mTemp] && !mEntryRequiredTemps[mInstructions[i + 1]->mSrc[0].mTemp])) && + (mEntryRequiredTemps[mInstructions[i + 1]->mDst.mTemp] && !mEntryRequiredTemps[mInstructions[i + 1]->mSrc[0].mTemp])) && mInstructions[i + 0]->mDst.mTemp == mInstructions[i + 1]->mSrc[0].mTemp) { mInstructions[i + 0]->mDst.mTemp = mInstructions[i + 1]->mDst.mTemp; @@ -8791,6 +8882,51 @@ void InterCodeBasicBlock::PeepholeOptimization(void) mInstructions[i + 1]->mSrc[1] = mInstructions[i + 0]->mDst; changed = true; } + else if ( + mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 0]->mOperator == IA_ADD && mInstructions[i + 0]->mSrc[1].mTemp < 0 && mInstructions[i + 0]->mSrc[0].mType == IT_INT16 && + mInstructions[i + 1]->mCode == IC_CONVERSION_OPERATOR && mInstructions[i + 1]->mOperator == IA_EXT8TO16U && + mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[0].mFinal && + mInstructions[i + 1]->mSrc[0].IsUByte() && + mInstructions[i + 2]->mCode == IC_LEA && mInstructions[i + 2]->mSrc[0].mTemp == mInstructions[i + 1]->mDst.mTemp && mInstructions[i + 2]->mSrc[0].mFinal && + mInstructions[i + 2]->mSrc[1].mTemp < 0) + { + mInstructions[i + 2]->mSrc[0] = mInstructions[i + 0]->mSrc[0]; + mInstructions[i + 2]->mSrc[1].mIntConst += mInstructions[i + 0]->mSrc[1].mIntConst; + + mInstructions[i + 0]->mCode = IC_NONE; mInstructions[i + 0]->mNumOperands = 0; + mInstructions[i + 1]->mCode = IC_NONE; mInstructions[i + 1]->mNumOperands = 0; + changed = true; + } + else if ( + mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 0]->mOperator == IA_ADD && mInstructions[i + 0]->mSrc[0].mTemp < 0 && mInstructions[i + 0]->mSrc[1].mType == IT_INT16 && + mInstructions[i + 1]->mCode == IC_CONVERSION_OPERATOR && mInstructions[i + 1]->mOperator == IA_EXT8TO16U && + mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[0].mFinal && + mInstructions[i + 1]->mSrc[0].IsUByte() && + mInstructions[i + 2]->mCode == IC_LEA && mInstructions[i + 2]->mSrc[0].mTemp == mInstructions[i + 1]->mDst.mTemp && mInstructions[i + 2]->mSrc[0].mFinal && + mInstructions[i + 2]->mSrc[1].mTemp < 0) + { + mInstructions[i + 2]->mSrc[0] = mInstructions[i + 0]->mSrc[1]; + mInstructions[i + 2]->mSrc[1].mIntConst += mInstructions[i + 0]->mSrc[0].mIntConst; + + mInstructions[i + 0]->mCode = IC_NONE; mInstructions[i + 0]->mNumOperands = 0; + mInstructions[i + 1]->mCode = IC_NONE; mInstructions[i + 1]->mNumOperands = 0; + changed = true; + } + else if ( + mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 0]->mOperator == IA_SUB && mInstructions[i + 0]->mSrc[0].mTemp < 0 && mInstructions[i + 0]->mSrc[1].mType == IT_INT16 && + mInstructions[i + 1]->mCode == IC_CONVERSION_OPERATOR && mInstructions[i + 1]->mOperator == IA_EXT8TO16U && + mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[0].mFinal && + mInstructions[i + 1]->mSrc[0].IsUByte() && + mInstructions[i + 2]->mCode == IC_LEA && mInstructions[i + 2]->mSrc[0].mTemp == mInstructions[i + 1]->mDst.mTemp && mInstructions[i + 2]->mSrc[0].mFinal && + mInstructions[i + 2]->mSrc[1].mTemp < 0) + { + mInstructions[i + 2]->mSrc[0] = mInstructions[i + 0]->mSrc[1]; + mInstructions[i + 2]->mSrc[1].mIntConst -= mInstructions[i + 0]->mSrc[0].mIntConst; + + mInstructions[i + 0]->mCode = IC_NONE; mInstructions[i + 0]->mNumOperands = 0; + mInstructions[i + 1]->mCode = IC_NONE; mInstructions[i + 1]->mNumOperands = 0; + changed = true; + } #if 1 // Postincrement artifact @@ -9636,6 +9772,9 @@ void InterCodeProcedure::Close(void) { BuildDataFlowSets(); + ResetVisited(); + mEntryBlock->CollectLocalUsedTemps(mTemporaries.Size()); + ResetVisited(); changed = mEntryBlock->PushSinglePathResultInstructions(); diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index 45c7e30..34092bf 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -326,7 +326,7 @@ public: bool mVisited, mInPath, mLoopHead, mChecked, mConditionBlockTrue, mUnreachable, mLoopPath; - NumberSet mLocalUsedTemps; + NumberSet mLocalUsedTemps, mLocalModifiedTemps; NumberSet mLocalRequiredTemps, mLocalProvidedTemps; NumberSet mEntryRequiredTemps, mEntryProvidedTemps; NumberSet mExitRequiredTemps, mExitProvidedTemps; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index e4f8920..0491168 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -9915,6 +9915,9 @@ bool NativeCodeBasicBlock::CanReplaceYRegWithXReg(int start, int end) if (ins.mMode == ASMIM_INDIRECT_Y) return false; + + if (ins.mMode == ASMIM_ABSOLUTE_Y && !HasAsmInstructionMode(ins.mType, ASMIM_ABSOLUTE_X)) + return false; } return true; @@ -9931,6 +9934,10 @@ bool NativeCodeBasicBlock::CanReplaceXRegWithYReg(int start, int end) if (ins.mMode == ASMIM_INDIRECT_X) return false; + + if (ins.mMode == ASMIM_ABSOLUTE_X && !HasAsmInstructionMode(ins.mType, ASMIM_ABSOLUTE_Y)) + return false; + } return true;