From acb644830c93b995f71477805f85a9f6af3972a2 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Wed, 24 Aug 2022 14:49:05 -0700 Subject: [PATCH] Fixed split deferred call processor --- IDE/src/BuildContext.bf | 4 +++ IDEHelper/Backend/BeMCContext.cpp | 3 ++ IDEHelper/Compiler/BfModule.cpp | 10 ++++-- IDEHelper/Compiler/BfModule.h | 16 +++++++-- IDEHelper/Compiler/BfStmtEvaluator.cpp | 45 +++++++++++++++++++++++--- IDEHelper/Tests/src/Scopes.bf | 27 ++++++++++++++++ 6 files changed, 97 insertions(+), 8 deletions(-) diff --git a/IDE/src/BuildContext.bf b/IDE/src/BuildContext.bf index 20ed2542..c426c6ea 100644 --- a/IDE/src/BuildContext.bf +++ b/IDE/src/BuildContext.bf @@ -801,6 +801,8 @@ namespace IDE IDEUtils.FixFilePath(libPath); libPaths.Add(libPath); } + else + delete libPath; } @@ -813,6 +815,8 @@ namespace IDE IDEUtils.FixFilePath(depPath); depPaths.Add(depPath); } + else + delete depPath; } for (let libPath in options.mBuildOptions.mLibPaths) diff --git a/IDEHelper/Backend/BeMCContext.cpp b/IDEHelper/Backend/BeMCContext.cpp index e6cb6228..ed5166b3 100644 --- a/IDEHelper/Backend/BeMCContext.cpp +++ b/IDEHelper/Backend/BeMCContext.cpp @@ -8453,6 +8453,9 @@ void BeMCContext::DoFrameObjPass() // If we're doing UseBP, we have to allocate these at call time int homeSize = BF_ALIGN(BF_MAX(mMaxCallParamCount, 4) * 8, 16); + if (mMaxCallParamCount == -1) + homeSize = 0; + mStackSize = 0; if (mUseBP) diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 3bb075ad..8d4a1f77 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -2006,9 +2006,12 @@ void BfModule::RestoreScopeState() } } + mCurMethodState->mCurScope->mDone = true; if (!mCurMethodState->mLeftBlockUncond) EmitDeferredScopeCalls(true, mCurMethodState->mCurScope); + EmitDeferredCallProcessorInstances(mCurMethodState->mCurScope); + RestoreScoreState_LocalVariables(); if (mCurMethodState->mCurScope->mValueScopeStart) @@ -16017,7 +16020,7 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa } auto prevHead = checkScope->mDeferredCallEntries.mHead; - EmitDeferredCall(*deferredCallEntry, true); + EmitDeferredCall(checkScope, *deferredCallEntry, true); if (prevHead != checkScope->mDeferredCallEntries.mHead) { // The list changed, start over and ignore anything we've already handled @@ -16028,7 +16031,7 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa } else { - EmitDeferredCall(*deferredCallEntry, true); + EmitDeferredCall(checkScope, *deferredCallEntry, true); deferredCallEntry = deferredCallEntry->mNext; } } @@ -21819,12 +21822,15 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, AssertErrorState(); } + mCurMethodState->mHeadScope.mDone = true; if (!mCurMethodState->mHadReturn) { // Clear off the stackallocs that have occurred after a scopeData break EmitDeferredScopeCalls(false, &mCurMethodState->mHeadScope, mCurMethodState->mIRExitBlock); } + EmitDeferredCallProcessorInstances(&mCurMethodState->mHeadScope); + if (mCurMethodState->mIRExitBlock) { for (auto preExitBlock : mCurMethodState->mHeadScope.mAtEndBlocks) diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index c3a6c099..3c288f38 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -425,6 +425,14 @@ enum BfScopeKind BfScopeKind_StatementTarget_Conditional, }; +class BfDeferredCallProcessorInstance +{ +public: + BfDeferredCallEntry* mDeferredCallEntry; + BfIRBlock mProcessorBlock; + BfIRBlock mContinueBlock; +}; + // "Looped" means this scope will execute zero to many times, "Conditional" means zero or one. // Looped and Conditional are mutually exclusive. "Dyn" means Looped OR Conditional. class BfScopeData @@ -454,11 +462,13 @@ public: bool mSupressNextUnreachable; bool mInConstIgnore; bool mIsSharedTempBlock; + bool mDone; BfMixinState* mMixinState; BfBlock* mAstBlock; BfAstNode* mCloseNode; BfExprEvaluator* mExprEvaluator; SLIList mDeferredCallEntries; + Array mDeferredCallProcessorInstances; BfIRValue mBlock; BfIRValue mValueScopeStart; BfIRValue mSavedStack; @@ -495,6 +505,7 @@ public: mInInitBlock = false; mInConstIgnore = false; mIsSharedTempBlock = false; + mDone = false; mMixinDepth = 0; mScopeDepth = 0; mScopeLocalId = -1; @@ -1688,8 +1699,9 @@ public: bool AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfScopeData* scope); BfDeferredCallEntry* AddDeferredBlock(BfBlock* block, BfScopeData* scope, Array* captures = NULL); BfDeferredCallEntry* AddDeferredCall(const BfModuleMethodInstance& moduleMethodInstance, SizedArrayImpl& llvmArgs, BfScopeData* scope, BfAstNode* srcNode = NULL, bool bypassVirtual = false, bool doNullCheck = false); - void EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry, bool moveBlocks); - void EmitDeferredCallProcessor(SLIList& callEntries, BfIRValue callTail); + void EmitDeferredCall(BfScopeData* scopeData, BfDeferredCallEntry& deferredCallEntry, bool moveBlocks); + void EmitDeferredCallProcessor(BfScopeData* scopeData, SLIList& callEntries, BfIRValue callTail); + void EmitDeferredCallProcessorInstances(BfScopeData* scopeData); bool CanCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags = BfCastFlags_None); bool AreSplatsCompatible(BfType* fromType, BfType* toType, bool* outNeedsMemberCasting); BfType* GetClosestNumericCastType(const BfTypedValue& typedVal, BfType* wantType); diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index 7ea10734..167a3901 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -801,7 +801,28 @@ void BfModule::EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, Siz } } -void BfModule::EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry, bool moveBlocks) +void BfModule::EmitDeferredCallProcessorInstances(BfScopeData* scopeData) +{ + BF_ASSERT(scopeData->mDone); + + for (auto& deferredProcessor : scopeData->mDeferredCallProcessorInstances) + { + SetAndRestoreValue prevHadReturn(mCurMethodState->mHadReturn, false); + SetAndRestoreValue prevInPostReturn(mCurMethodState->mInPostReturn, false); + SetAndRestoreValue prevLeftBlockUncond(mCurMethodState->mLeftBlockUncond, false); + + auto prevBlock = mBfIRBuilder->GetInsertBlock(); + + mBfIRBuilder->AddBlock(deferredProcessor.mProcessorBlock); + mBfIRBuilder->SetInsertPoint(deferredProcessor.mProcessorBlock); + EmitDeferredCallProcessor(scopeData, deferredProcessor.mDeferredCallEntry->mDynList, deferredProcessor.mDeferredCallEntry->mDynCallTail); + mBfIRBuilder->CreateBr(deferredProcessor.mContinueBlock); + + mBfIRBuilder->SetInsertPoint(prevBlock); + } +} + +void BfModule::EmitDeferredCall(BfScopeData* scopeData, BfDeferredCallEntry& deferredCallEntry, bool moveBlocks) { if ((mCompiler->mIsResolveOnly) && (!mIsComptimeModule) && (deferredCallEntry.mHandlerCount > 0)) { @@ -813,7 +834,23 @@ void BfModule::EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry, bool mov if (deferredCallEntry.IsDynList()) { - EmitDeferredCallProcessor(deferredCallEntry.mDynList, deferredCallEntry.mDynCallTail); + if (scopeData->mDone) + { + EmitDeferredCallProcessor(scopeData, deferredCallEntry.mDynList, deferredCallEntry.mDynCallTail); + } + else + { + BfDeferredCallProcessorInstance deferredProcessor; + deferredProcessor.mProcessorBlock = mBfIRBuilder->CreateBlock("dyn.processor"); + deferredProcessor.mContinueBlock = mBfIRBuilder->CreateBlock("dyn.continue"); + deferredProcessor.mDeferredCallEntry = &deferredCallEntry; + scopeData->mDeferredCallProcessorInstances.Add(deferredProcessor); + mBfIRBuilder->CreateBr(deferredProcessor.mProcessorBlock); + + mBfIRBuilder->AddBlock(deferredProcessor.mContinueBlock); + mBfIRBuilder->SetInsertPoint(deferredProcessor.mContinueBlock); + } + return; } @@ -877,7 +914,7 @@ void BfModule::EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry, bool mov EmitDeferredCall(deferredCallEntry.mModuleMethodInstance, args, flags); } -void BfModule::EmitDeferredCallProcessor(SLIList& callEntries, BfIRValue callTail) +void BfModule::EmitDeferredCallProcessor(BfScopeData* scopeData, SLIList& callEntries, BfIRValue callTail) { int64 collisionId = 0; @@ -1036,7 +1073,7 @@ void BfModule::EmitDeferredCallProcessor(SLIList& callEntr } auto prevHead = callEntries.mHead; - EmitDeferredCall(*deferredCallEntry, moveBlocks); + EmitDeferredCall(scopeData, *deferredCallEntry, moveBlocks); ValueScopeEnd(valueScopeStart); mBfIRBuilder->CreateBr(condBB); diff --git a/IDEHelper/Tests/src/Scopes.bf b/IDEHelper/Tests/src/Scopes.bf index 26080274..93a91407 100644 --- a/IDEHelper/Tests/src/Scopes.bf +++ b/IDEHelper/Tests/src/Scopes.bf @@ -43,6 +43,33 @@ namespace Tests str.Contains('T'); }*/ + public static void Defer0(ref int val) + { + for (int i < 10) + { + defer:: + { + val += 100; + } + + if (i == 2) + return; + + defer:: + { + val++; + } + } + } + + [Test] + public static void TestBasics() + { + int a = 0; + Defer0(ref a); + Test.Assert(a == 302); + } + public static mixin GetStr() { scope:mixin String("TestString")