From ecf8e69cf20d695bbe9beb50a127ee4edb3aa476 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Fri, 13 Oct 2023 11:18:16 +0200 Subject: [PATCH] Add restricted pointer attribute to newly allocated memory --- autotest/opp_string.cpp | 13 +- oscar64/InterCode.cpp | 278 +++++++++++++++++++++++++++++--- oscar64/InterCode.h | 13 +- oscar64/InterCodeGenerator.cpp | 2 + oscar64/NativeCodeGenerator.cpp | 27 +++- oscar64/NativeCodeGenerator.h | 1 + 6 files changed, 306 insertions(+), 28 deletions(-) diff --git a/autotest/opp_string.cpp b/autotest/opp_string.cpp index bf2b789..3a52312 100644 --- a/autotest/opp_string.cpp +++ b/autotest/opp_string.cpp @@ -10,7 +10,7 @@ static const char AndBeyond[] = "And Beyond"; static const char And[] = "And"; static const char HelloWorldAndBeyond[] = "Hello World And Beyond"; -void test_create(void) +__noinline void test_create(void) { string s1(); string s2(HelloWorld); @@ -22,7 +22,7 @@ void test_create(void) assert(s4.size() == 1 && s4[0] == 'a'); } -void test_concat(void) +__noinline void test_concat(void) { string s1(); string s2(HelloWorld); @@ -51,7 +51,7 @@ __noinline void test_find(void) assert(s1.find(' ', 6) == 11); } -void test_assign(void) +__noinline void test_assign(void) { string s1(HelloWorld); string s2(AndBeyond); @@ -77,9 +77,12 @@ void test_assign(void) assert(!strcmp(s3.tocstr(), HelloWorld)); } +static char * test; + int main(void) { - char * p = new char; + test = new char; + unsigned avail = heapfree(); test_create(); @@ -94,5 +97,7 @@ int main(void) test_assign(); assert(avail == heapfree()); + delete test; + return 0; } diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 87e17d8..ee838e9 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -5,6 +5,7 @@ #include static bool CheckFunc; +static bool CheckCase; int InterTypeSize[] = { 0, @@ -445,7 +446,9 @@ bool InterCodeBasicBlock::CollidingMem(const InterOperand& op1, InterType type1, { if (op1.mMemory == IM_INDIRECT) { - if (op2.mMemory == IM_GLOBAL) + if (op1.mRestricted) + return false; + else if (op2.mMemory == IM_GLOBAL) return mProc->mModule->mGlobalVars[op2.mVarIndex]->mAliased; else if (op2.mMemory == IM_FPARAM || op2.mMemory == IM_FFRAME) return false; @@ -456,7 +459,9 @@ bool InterCodeBasicBlock::CollidingMem(const InterOperand& op1, InterType type1, } else if (op2.mMemory == IM_INDIRECT) { - if (op1.mMemory == IM_GLOBAL) + if (op2.mRestricted) + return false; + else if (op1.mMemory == IM_GLOBAL) return mProc->mModule->mGlobalVars[op1.mVarIndex]->mAliased; else if (op1.mMemory == IM_FPARAM || op1.mMemory == IM_FFRAME) return false; @@ -487,6 +492,8 @@ bool InterCodeBasicBlock::CollidingMem(const InterOperand& op1, InterType type1, return op1.mIntConst < op2.mIntConst + op2.mOperandSize && op2.mIntConst < op1.mIntConst + op1.mOperandSize; else if (op1.mLinkerObject && op2.mLinkerObject && op1.mLinkerObject != op2.mLinkerObject) return false; + else if (op1.mRestricted && op2.mRestricted && op1.mRestricted != op2.mRestricted) + return false; else return CollidingMemType(type1, type2); default: @@ -1235,12 +1242,12 @@ void ValueSet::InsertValue(InterInstruction * ins) static bool HasSideEffect(InterCode code) { - return code == IC_CALL || code == IC_CALL_NATIVE || code == IC_ASSEMBLER || code == IC_MALLOC || code == IC_FREE; + return code == IC_CALL || code == IC_CALL_NATIVE || code == IC_ASSEMBLER || code == IC_DISPATCH /* || code == IC_MALLOC || code == IC_FREE */; } static bool IsObservable(InterCode code) { - return code == IC_CALL || code == IC_CALL_NATIVE || code == IC_ASSEMBLER || code == IC_STORE || code == IC_COPY || code == IC_STRCPY || code == IC_MALLOC || code == IC_FREE; + return code == IC_CALL || code == IC_CALL_NATIVE || code == IC_ASSEMBLER || code == IC_DISPATCH || code == IC_STORE || code == IC_COPY || code == IC_STRCPY || code == IC_MALLOC || code == IC_FREE; } static bool IsMoveable(InterCode code) @@ -2900,7 +2907,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr InterOperand::InterOperand(void) - : mTemp(INVALID_TEMPORARY), mType(IT_NONE), mFinal(false), mIntConst(0), mFloatConst(0), mVarIndex(-1), mOperandSize(0), mLinkerObject(nullptr), mMemory(IM_NONE), mStride(1) + : mTemp(INVALID_TEMPORARY), mType(IT_NONE), mFinal(false), mIntConst(0), mFloatConst(0), mVarIndex(-1), mOperandSize(0), mLinkerObject(nullptr), mMemory(IM_NONE), mStride(1), mRestricted(0) {} bool InterOperand::IsNotUByte(void) const @@ -2967,6 +2974,7 @@ void InterOperand::ForwardMem(const InterOperand& op) mType = op.mType; mRange = op.mRange; mStride = op.mStride; + mRestricted = op.mRestricted; mFinal = false; } @@ -4335,7 +4343,12 @@ void InterOperand::Disassemble(FILE* file, InterCodeProcedure* proc) fprintf(file, "R%d(%c)", mTemp, typechars[mType]); if (mType == IT_POINTER && mMemory == IM_INDIRECT) + { fprintf(file, "+%d", int(mIntConst)); + } + + if (mRestricted) + fprintf(file, "{%d}", mRestricted); if (mRange.mMinState >= IntegerValueRange::S_WEAK || mRange.mMaxState >= IntegerValueRange::S_WEAK) { @@ -4811,6 +4824,22 @@ void InterCodeBasicBlock::GenerateTraces(bool expand, bool compact) // Limit number of contractions for (int i = 0; i < 100; i++) { + int sz = mInstructions.Size(); + + if (mFalseJump && sz > 0 && mInstructions[sz - 1]->mCode == IC_BRANCH && mInstructions[sz - 1]->mSrc[0].mType == IT_BOOL && mInstructions[sz - 1]->mSrc[0].mTemp < 0) + { + mInstructions[sz - 1]->mCode = IC_JUMP; + mInstructions[sz - 1]->mNumOperands = 0; + if (!mInstructions[sz - 1]->mSrc[0].mIntConst) + { + mTrueJump->mNumEntries--; + mTrueJump = mFalseJump; + } + else + mFalseJump->mNumEntries--; + mFalseJump = nullptr; + } + if (mTrueJump && mTrueJump->mInstructions.Size() == 1 && mTrueJump->mInstructions[0]->mCode == IC_JUMP && !mTrueJump->mLoopHead && mTrueJump->mTraceIndex != mIndex) { mTrueJump->mTraceIndex = mIndex; @@ -5123,6 +5152,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI break; } } + break; case IC_LOAD: @@ -5149,6 +5179,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI break; } } + OptimizeAddress(ins, tvalue, 1); break; case IC_COPY: @@ -6204,6 +6235,10 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void) { constFalse = true; } + else if (cins->mSrc[1].IsUnsigned() && cins->mSrc[1].mRange.mMaxValue == 0) + { + constFalse = true; + } else if (cins->mSrc[1].IsUnsigned() && cins->mSrc[0].IsUnsigned()) { if (cins->mSrc[1].mRange.mMinValue > cins->mSrc[0].mRange.mMaxValue) @@ -10172,6 +10207,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray& { ins->mCode = IC_LOAD_TEMPORARY; ins->mSrc[0] = lins->mDst; + ins->mSrc[0].mRestricted = ins->mDst.mRestricted = lins->mDst.mRestricted; ins->mNumOperands = 1; assert(ins->mSrc[0].mTemp >= 0); changed = true; @@ -10189,6 +10225,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray& { ins->mCode = IC_LOAD_TEMPORARY; ins->mSrc[0] = lins->mSrc[0]; + ins->mSrc[0].mRestricted = ins->mDst.mRestricted = lins->mSrc[0].mRestricted; ins->mDst.mRange.Limit(ins->mSrc[0].mRange); ins->mNumOperands = 1; assert(ins->mSrc[0].mTemp >= 0); @@ -10252,6 +10289,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray& assert(lins->mDst.mTemp >= 0); ins->mCode = IC_LOAD_TEMPORARY; ins->mSrc[0] = lins->mDst; + ins->mSrc[0].mRestricted = ins->mDst.mRestricted = lins->mDst.mRestricted; ins->mDst.mRange.Limit(ins->mSrc[0].mRange); ins->mNumOperands = 1; changed = true; @@ -10396,6 +10434,8 @@ void InterCodeBasicBlock::LocalRenameRegister(const GrowingIntArray& renameTable } } + RenameValueRanges(mEntryRenameTable, num); + for (i = 0; i < mInstructions.Size(); i++) { mInstructions[i]->LocalRenameRegister(mExitRenameTable, num); @@ -10440,11 +10480,29 @@ void InterCodeBasicBlock::GlobalRenameRegister(const GrowingIntArray& renameTabl mInstructions[i]->GlobalRenameRegister(renameTable, temporaries); } + RenameValueRanges(renameTable, temporaries.Size()); + if (mTrueJump) mTrueJump->GlobalRenameRegister(renameTable, temporaries); if (mFalseJump) mFalseJump->GlobalRenameRegister(renameTable, temporaries); } } +void InterCodeBasicBlock::RenameValueRanges(const GrowingIntArray& renameTable, int numTemps) +{ + if (mEntryValueRange.Size() > 0) + { + mLocalValueRange = mEntryValueRange; + mEntryValueRange.SetSize(numTemps, true); + for (int i = 0; i < mLocalValueRange.Size(); i++) + { + if (renameTable[i] >= 0) + { + mEntryValueRange[renameTable[i]].Limit(mLocalValueRange[i]); + } + } + } +} + void InterCodeBasicBlock::BuildCollisionTable(NumberSet* collisionSets) { if (!mVisited) @@ -13235,6 +13293,139 @@ bool InterCodeBasicBlock::CheapInlining(int & numTemps) return changed; } +void InterCodeBasicBlock::RemoveUnusedMallocs(void) +{ + if (!mVisited) + { + mVisited = true; + + for (int i = 0; i < mInstructions.Size(); i++) + { + InterInstruction* mins = mInstructions[i]; + if (mins->mCode == IC_MALLOC) + { + int mtemp = mins->mDst.mTemp; + bool used = false; + int j = i + 1; + while (j < mInstructions.Size() && !used) + { + InterInstruction* fins = mInstructions[j]; + if (fins->mCode == IC_FREE && fins->mSrc[0].mTemp == mtemp) + break; + if (fins->ReferencesTemp(mtemp)) + { + if (fins->mCode != IC_STORE || fins->mSrc[1].mTemp != mtemp) + used = true; + } + j++; + } + + if (j < mInstructions.Size() && !used) + { + mins->mCode = IC_NONE; mins->mNumOperands = 0; + for (int k = i + 1; k <= j; k++) + { + InterInstruction* lins = mInstructions[k]; + if (lins->UsesTemp(mtemp)) + { + lins->mCode = IC_NONE; + lins->mNumOperands = 0; + } + } + } + } + } + + if (mTrueJump) mTrueJump->RemoveUnusedMallocs(); + if (mFalseJump) mFalseJump->RemoveUnusedMallocs(); + } +} + +void InterCodeBasicBlock::PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue) +{ + if (!mVisited) + { + GrowingInstructionPtrArray ltvalue(tvalue); + + if (mLoopHead) + { + if (mNumEntries == 2 && (mTrueJump == this || mFalseJump == this)) + { + for (int i = 0; i < ltvalue.Size(); i++) + { + if (ltvalue[i]) + { + for (int j = 0; j < mInstructions.Size(); j++) + { + if (mInstructions[j]->mDst.mTemp == i) + { + if (mInstructions[j]->mCode == IC_LEA && mInstructions[j]->mSrc[1].mTemp == i) + ; + else + { + ltvalue[i] = nullptr; + break; + } + } + } + } + } + } + else + ltvalue.Clear(); + } + else if (mNumEntries > 0) + { + if (mNumEntered > 0) + { + for (int i = 0; i < ltvalue.Size(); i++) + { + if (mMergeTValues[i] != ltvalue[i]) + ltvalue[i] = nullptr; + } + } + + mNumEntered++; + + if (mNumEntered < mNumEntries) + { + mMergeTValues = ltvalue; + return; + } + } + + mVisited = true; + + for (int i = 0; i < mInstructions.Size(); i++) + { + InterInstruction* ins = mInstructions[i]; + + for (int j = 0; j < ins->mNumOperands; j++) + { + if (ins->mSrc[j].mTemp > 0 && ltvalue[ins->mSrc[j].mTemp] && ins->mSrc[j].mType == IT_POINTER) + ins->mSrc[j].mRestricted = ltvalue[ins->mSrc[j].mTemp]->mDst.mRestricted; + } + + if (ins->mDst.mTemp >= 0) + { + if (ins->mDst.mRestricted) + ltvalue[ins->mDst.mTemp] = ins; + else + ltvalue[ins->mDst.mTemp] = nullptr; + } + + if (ins->mCode == IC_LEA) + ins->mDst.mRestricted = ins->mSrc[1].mRestricted; + else if (ins->mCode == IC_LOAD_TEMPORARY) + ins->mDst.mRestricted = ins->mSrc[0].mRestricted; + } + + + if (mTrueJump) mTrueJump->PropagateMemoryAliasingInfo(ltvalue); + if (mFalseJump) mFalseJump->PropagateMemoryAliasingInfo(ltvalue); + } +} + void InterCodeBasicBlock::PushMoveOutOfLoop(void) { @@ -16570,7 +16761,8 @@ InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & l mInterrupt(false), mHardwareInterrupt(false), mCompiled(false), mInterruptCalled(false), mDynamicStack(false), mAssembled(false), mSaveTempsLinkerObject(nullptr), mValueReturn(false), mFramePointer(false), mCheckUnreachable(true), mReturnType(IT_NONE), mCheapInline(false), - mDeclaration(nullptr), mGlobalsChecked(false), mDispatchedCall(false) + mDeclaration(nullptr), mGlobalsChecked(false), mDispatchedCall(false), + mNumRestricted(1) { mID = mModule->mProcedures.Size(); mModule->mProcedures.Push(this); @@ -16636,6 +16828,11 @@ int InterCodeProcedure::AddTemporary(InterType type) return temp; } +int InterCodeProcedure::AddRestricted(void) +{ + return mNumRestricted++; +} + void InterCodeProcedure::CheckBlocks(void) { ResetVisited(); @@ -16699,6 +16896,10 @@ void InterCodeProcedure::BuildTraces(bool expand, bool dominators, bool compact) mBlocks[i]->mNumEntries = 0; mEntryBlock->CollectEntries(); + ResetEntryBlocks(); + ResetVisited(); + mEntryBlock->CollectEntryBlocks(nullptr); + ResetVisited(); for (int i = 0; i < mBlocks.Size(); i++) mBlocks[i]->mDominator = nullptr; @@ -16875,6 +17076,17 @@ void InterCodeProcedure::CheckUsedDefinedTemps(void) #endif } +void InterCodeProcedure::PropagateMemoryAliasingInfo(void) +{ + GrowingInstructionPtrArray tvalue(nullptr); + + ResetVisited(); + mEntryBlock->PropagateMemoryAliasingInfo(tvalue); + + Disassemble("PropagateMemoryAliasingInfo"); +} + + void InterCodeProcedure::WarnUsedUndefinedVariables(void) { ResetEntryBlocks(); @@ -17350,6 +17562,8 @@ void InterCodeProcedure::LoadStoreForwarding(InterMemory paramMemory) bool changed; do { + PropagateMemoryAliasingInfo(); + GrowingInstructionPtrArray gipa(nullptr); ResetVisited(); changed = mEntryBlock->LoadStoreForwarding(gipa, mModule->mGlobalVars); @@ -17358,11 +17572,15 @@ void InterCodeProcedure::LoadStoreForwarding(InterMemory paramMemory) RemoveUnusedStoreInstructions(paramMemory); + GlobalConstantPropagation(); + RemoveUnusedMallocs(); + TempForwarding(); RemoveUnusedInstructions(); DisassembleDebug("Load/Store forwarding"); } while (changed); + } void InterCodeProcedure::CombineIndirectAddressing(void) @@ -17434,7 +17652,8 @@ void InterCodeProcedure::Close(void) { GrowingTypeArray tstack(IT_NONE); - CheckFunc = !strcmp(mIdent->mString, "main"); + CheckFunc = !strcmp(mIdent->mString, "atoi"); + CheckCase = false; mEntryBlock = mBlocks[0]; @@ -17589,6 +17808,8 @@ void InterCodeProcedure::Close(void) BuildDataFlowSets(); + LoadStoreForwarding(paramMemory); + ResetVisited(); mEntryBlock->OptimizeIntervalCompare(); @@ -17725,6 +17946,9 @@ void InterCodeProcedure::Close(void) Disassemble("gcp-"); #endif + BuildTraces(false); + DisassembleDebug("Rebuilt traces"); + BuildDataFlowSets(); TempForwarding(); @@ -17762,16 +17986,12 @@ void InterCodeProcedure::Close(void) ResetVisited(); mEntryBlock->SimplifyIntegerRangeRelops(); - DisassembleDebug("Simplified range limited relational ops"); + DisassembleDebug("Simplified range limited relational ops 1"); #endif BuildTraces(false); DisassembleDebug("Rebuilt traces"); - ResetEntryBlocks(); - ResetVisited(); - mEntryBlock->CollectEntryBlocks(nullptr); - #if 1 SimplifyIntegerNumeric(activeSet); @@ -17844,9 +18064,6 @@ void InterCodeProcedure::Close(void) #endif BuildTraces(false); - ResetEntryBlocks(); - ResetVisited(); - mEntryBlock->CollectEntryBlocks(nullptr); #if 1 SingleBlockLoopPointerSplit(activeSet); @@ -17927,7 +18144,7 @@ void InterCodeProcedure::Close(void) ResetVisited(); mEntryBlock->SimplifyIntegerRangeRelops(); - DisassembleDebug("Simplified range limited relational ops"); + DisassembleDebug("Simplified range limited relational ops 2"); #endif #if 1 @@ -17980,6 +18197,10 @@ void InterCodeProcedure::Close(void) LoadStoreForwarding(paramMemory); + CheckCase = true; + + RebuildIntegerRangeSet(); + #if 1 BuildLoopPrefix(); DisassembleDebug("added dominators"); @@ -18046,6 +18267,8 @@ void InterCodeProcedure::Close(void) mEntryBlock->CollectEntryBlocks(nullptr); BuildTraces(false); + BuildDataFlowSets(); + BuildTraces(false); #endif PropagateConstOperationsUp(); @@ -18057,6 +18280,11 @@ void InterCodeProcedure::Close(void) #endif + ResetVisited(); + mEntryBlock->SimplifyIntegerRangeRelops(); + + DisassembleDebug("Simplified range limited relational ops 3"); + #if 1 BuildDataFlowSets(); @@ -18111,7 +18339,7 @@ void InterCodeProcedure::Close(void) ResetVisited(); mEntryBlock->SingleBlockLoopOptimisation(mParamAliasedSet, mModule->mGlobalVars); - DisassembleDebug("single block loop opt 3"); + DisassembleDebug("single block loop opt 4"); BuildDataFlowSets(); @@ -18130,6 +18358,8 @@ void InterCodeProcedure::Close(void) TempForwarding(); } while (GlobalConstantPropagation()); + BuildTraces(false); + DisassembleDebug("Rebuilt traces"); PeepholeOptimization(); TempForwarding(); @@ -18158,8 +18388,14 @@ void InterCodeProcedure::Close(void) CombineIndirectAddressing(); #if 1 - for (int i = 0; i < 4; i++) + for (int i = 0; i < 8; i++) { + BuildTraces(false); + + LoadStoreForwarding(paramMemory); + + RebuildIntegerRangeSet(); + PeepholeOptimization(); DisassembleDebug("Peephole Temp Check"); @@ -18793,6 +19029,12 @@ bool InterCodeProcedure::GlobalConstantPropagation(void) return mEntryBlock->PropagateConstTemps(ctemps); } +void InterCodeProcedure::RemoveUnusedMallocs(void) +{ + ResetVisited(); + mEntryBlock->RemoveUnusedMallocs(); +} + void InterCodeProcedure::HoistCommonConditionalPath(void) { for(;;) diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index 4699e7d..a38b802 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -265,7 +265,7 @@ public: bool mFinal; int64 mIntConst; double mFloatConst; - int mVarIndex, mOperandSize, mStride; + int mVarIndex, mOperandSize, mStride, mRestricted; LinkerObject * mLinkerObject; InterMemory mMemory; IntegerValueRange mRange; @@ -457,6 +457,7 @@ public: void LocalRenameRegister(const GrowingIntArray& renameTable, int& num); void BuildGlobalRenameRegisterTable(const GrowingIntArray& renameTable, GrowingIntArray& globalRenameTable); void GlobalRenameRegister(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries); + void RenameValueRanges(const GrowingIntArray& renameTable, int numTemps); void CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const GrowingVariableArray& staticVars, FastNumberSet& fsingle); void PerformTempForwarding(const TempForwardingTable& forwardingTable, bool reverse, bool checkloops); @@ -555,7 +556,10 @@ public: void CollectLoopPath(const GrowingArray& body, GrowingArray& path); void InnerLoopOptimization(const NumberSet& aliasedParams); void PushMoveOutOfLoop(void); - + + void PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue); + void RemoveUnusedMallocs(void); + bool CollectSingleHeadLoopBody(InterCodeBasicBlock* head, InterCodeBasicBlock* tail, GrowingArray& body); bool SingleTailLoopOptimization(const NumberSet& aliasedParams, const GrowingVariableArray& staticVars); @@ -603,7 +607,7 @@ public: GrowingInterCodeBasicBlockPtrArray mBlocks; GrowingTypeArray mTemporaries; GrowingIntArray mTempOffset, mTempSizes; - int mTempSize, mCommonFrameSize, mCallerSavedTemps, mFreeCallerSavedTemps, mFastCallBase; + int mTempSize, mCommonFrameSize, mCallerSavedTemps, mFreeCallerSavedTemps, mFastCallBase, mNumRestricted; bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode, mFastCallProcedure; bool mInterrupt, mHardwareInterrupt, mCompiled, mInterruptCalled, mValueReturn, mFramePointer, mDynamicStack, mAssembled; bool mDispatchedCall; @@ -633,6 +637,7 @@ public: ~InterCodeProcedure(void); int AddTemporary(InterType type); + int AddRestricted(void); void Close(void); @@ -682,10 +687,12 @@ protected: void CombineIndirectAddressing(void); void SingleTailLoopOptimization(InterMemory paramMemory); void HoistCommonConditionalPath(void); + void RemoveUnusedMallocs(void); void MergeBasicBlocks(void); void CheckUsedDefinedTemps(void); void WarnUsedUndefinedVariables(void); + void PropagateMemoryAliasingInfo(void); void PeepholeOptimization(void); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index f3ecaa6..28cd27c 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -2916,6 +2916,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* ins->mSrc[0].mTemp = vl.mTemp; ins->mDst.mType = IT_POINTER; ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType); + ins->mDst.mRestricted = proc->AddRestricted(); block->Append(ins); return ExValue(exp->mDecType, ins->mDst.mTemp, 0); @@ -3141,6 +3142,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* ins->mNumOperands = 1; ins->mDst.mType = IT_POINTER; ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType); + ins->mDst.mRestricted = proc->AddRestricted(); block->Append(ins); return ExValue(TheVoidPointerTypeDeclaration, ins->mDst.mTemp); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 642b288..8797913 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -32138,7 +32138,7 @@ bool NativeCodeBasicBlock::OptimizeGenericLoop(NativeCodeProcedure* proc) ExpandingArray lblocks; proc->ResetPatched(); - if (CollectGenericLoop(proc, lblocks)) + if (CollectSingleEntryGenericLoop(proc, lblocks)) { int yreg = -1, xreg = -1, areg = -1; int zyreg[NUM_REGS], zxreg[NUM_REGS], zareg[NUM_REGS]; @@ -32777,6 +32777,28 @@ bool NativeCodeBasicBlock::CollectGenericLoop(NativeCodeProcedure* proc, Expandi return lblocks.Size() > 0; } +bool NativeCodeBasicBlock::CollectSingleEntryGenericLoop(NativeCodeProcedure* proc, ExpandingArray& lblocks) +{ + if (CollectGenericLoop(proc, lblocks)) + { + for (int i = 0; i < lblocks.Size(); i++) + { + NativeCodeBasicBlock* block = lblocks[i]; + + if (block != this) + { + for (int j = 0; j < block->mEntryBlocks.Size(); j++) + if (!lblocks.Contains(block->mEntryBlocks[j])) + return false; + } + } + + return true; + } + else + return false; +} + bool NativeCodeBasicBlock::OptimizeFindLoop(NativeCodeProcedure* proc) { bool changed = false; @@ -41426,7 +41448,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) { mInterProc = proc; - CheckFunc = !strcmp(mInterProc->mIdent->mString, "fill_row"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "atoi"); int nblocks = proc->mBlocks.Size(); tblocks = new NativeCodeBasicBlock * [nblocks]; @@ -42276,7 +42298,6 @@ void NativeCodeProcedure::Optimize(void) if (mEntryBlock->RemoveDoubleZPStore()) changed = true; } - if (step == 3 || step == 5 || step == 9) { ResetVisited(); diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index 5975eaf..6ec4307 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -307,6 +307,7 @@ public: bool OptimizeGenericLoop(NativeCodeProcedure* proc); bool CollectGenericLoop(NativeCodeProcedure* proc, ExpandingArray& lblocks); + bool CollectSingleEntryGenericLoop(NativeCodeProcedure* proc, ExpandingArray& lblocks); void CollectReachable(ExpandingArray& lblock); bool OptimizeFindLoop(NativeCodeProcedure* proc);