diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 1a5f44a..4238b5c 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -991,6 +991,16 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr break; } break; + case IC_BRANCH: + if (ins->mSTemp[0] >= 0 && tvalue[ins->mSTemp[0]] && tvalue[ins->mSTemp[0]]->mCode == IC_CONSTANT) + { + if (tvalue[ins->mSTemp[0]]->mIntValue) + ins->mCode = IC_JUMP; + else + ins->mCode = IC_JUMPF; + ins->mSTemp[0] = -1; + } + break; case IC_CALL: case IC_CALL_NATIVE: FlushCallAliases(); @@ -1617,6 +1627,9 @@ void InterInstruction::Disassemble(FILE* file) case IC_JUMP: fprintf(file, "JUMP"); break; + case IC_JUMPF: + fprintf(file, "JUMPF"); + break; case IC_PUSH_FRAME: fprintf(file, "PUSHF\t%d", int(mIntValue)); break; @@ -2786,20 +2799,41 @@ void InterCodeBasicBlock::PerformMachineSpecificValueUsageCheck(const GrowingIns if (mTrueJump) mTrueJump->PerformMachineSpecificValueUsageCheck(ltvalue, tvalid); if (mFalseJump) mFalseJump->PerformMachineSpecificValueUsageCheck(ltvalue, tvalid); + } +} - if (mInstructions.Size() > 0 && mInstructions[mInstructions.Size() - 1]->mCode == IC_BRANCH && mInstructions[mInstructions.Size() - 1]->mSTemp[0] < 0) + +bool InterCodeBasicBlock::EliminateDeadBranches(void) +{ + bool changed = false; + + if (!mVisited) + { + mVisited = true; + + if (mInstructions.Size() > 0) { - mInstructions[mInstructions.Size() - 1]->mCode = IC_JUMP; - if (!mInstructions[mInstructions.Size() - 1]->mSIntConst[0]) + if (mInstructions[mInstructions.Size() - 1]->mCode == IC_JUMP && mFalseJump) { + mFalseJump->mNumEntries--; + mFalseJump = nullptr; + changed = true; + } + else if (mInstructions[mInstructions.Size() - 1]->mCode == IC_JUMPF) + { + mInstructions[mInstructions.Size() - 1]->mCode = IC_JUMP; mTrueJump->mNumEntries--; mTrueJump = mFalseJump; + mFalseJump = nullptr; + changed = true; } - else - mFalseJump->mNumEntries--; - mFalseJump = nullptr; } + + if (mTrueJump && mTrueJump->EliminateDeadBranches()) changed = true; + if (mFalseJump && mFalseJump->EliminateDeadBranches()) changed = true; } + + return changed; } static void Union(GrowingIntArray& table, int i, int j) @@ -3886,16 +3920,33 @@ void InterCodeProcedure::Close(void) ResetVisited(); mEntryBlock->MarkAliasedLocalTemps(localTable, mLocalAliasedSet, paramTable, mParamAliasedSet); - // - // Now forward constant values - // ValueSet valueSet; FastNumberSet tvalidSet(numTemps); - mValueForwardingTable.SetSize(numTemps, true); - ResetVisited(); - mEntryBlock->PerformValueForwarding(mValueForwardingTable, valueSet, tvalidSet, mLocalAliasedSet, mParamAliasedSet); + bool eliminated; + // + // Now forward constant values + // + do { + valueSet.FlushAll(); + mValueForwardingTable.SetSize(numTemps, true); + tvalidSet.Clear(); + + ResetVisited(); + mEntryBlock->PerformValueForwarding(mValueForwardingTable, valueSet, tvalidSet, mLocalAliasedSet, mParamAliasedSet); + + ResetVisited(); + eliminated = mEntryBlock->EliminateDeadBranches(); + if (eliminated) + { + ResetVisited(); + for (int i = 0; i < mBlocks.Size(); i++) + mBlocks[i]->mNumEntries = 0; + mEntryBlock->CollectEntries(); + } + } while (eliminated); + DisassembleDebug("value forwarding"); diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index 68e9e27..d4f5fcd 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -33,7 +33,8 @@ enum InterCode IC_RETURN_VALUE, IC_RETURN_STRUCT, IC_RETURN, - IC_ASSEMBLER + IC_ASSEMBLER, + IC_JUMPF }; enum InterType @@ -442,6 +443,7 @@ public: void PerformTempForwarding(TempForwardingTable& forwardingTable); void PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams); void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid); + bool EliminateDeadBranches(void); void BuildCollisionTable(NumberSet* collisionSets); void ReduceTemporaries(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 9e34d27..bf4261e 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -1890,7 +1890,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* ins->mSType[1] = ains->mTType; ins->mSTemp[1] = ains->mTTemp; + ins->mMemory = IM_INDIRECT; ins->mCode = IC_STORE; + ins->mOperandSize = ains->mOperandSize; } else ins->mCode = IC_RETURN_VALUE;