1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00

Fixed split deferred call processor

This commit is contained in:
Brian Fiete 2022-08-24 14:49:05 -07:00
parent e09b701e9f
commit acb644830c
6 changed files with 97 additions and 8 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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<BfDeferredCallEntry*> mDeferredCallEntries;
Array<BfDeferredCallProcessorInstance> 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<BfDeferredCapture>* captures = NULL);
BfDeferredCallEntry* AddDeferredCall(const BfModuleMethodInstance& moduleMethodInstance, SizedArrayImpl<BfIRValue>& llvmArgs, BfScopeData* scope, BfAstNode* srcNode = NULL, bool bypassVirtual = false, bool doNullCheck = false);
void EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry, bool moveBlocks);
void EmitDeferredCallProcessor(SLIList<BfDeferredCallEntry*>& callEntries, BfIRValue callTail);
void EmitDeferredCall(BfScopeData* scopeData, BfDeferredCallEntry& deferredCallEntry, bool moveBlocks);
void EmitDeferredCallProcessor(BfScopeData* scopeData, SLIList<BfDeferredCallEntry*>& 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);

View file

@ -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<bool> prevHadReturn(mCurMethodState->mHadReturn, false);
SetAndRestoreValue<bool> prevInPostReturn(mCurMethodState->mInPostReturn, false);
SetAndRestoreValue<bool> 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<BfDeferredCallEntry*>& callEntries, BfIRValue callTail)
void BfModule::EmitDeferredCallProcessor(BfScopeData* scopeData, SLIList<BfDeferredCallEntry*>& callEntries, BfIRValue callTail)
{
int64 collisionId = 0;
@ -1036,7 +1073,7 @@ void BfModule::EmitDeferredCallProcessor(SLIList<BfDeferredCallEntry*>& callEntr
}
auto prevHead = callEntries.mHead;
EmitDeferredCall(*deferredCallEntry, moveBlocks);
EmitDeferredCall(scopeData, *deferredCallEntry, moveBlocks);
ValueScopeEnd(valueScopeStart);
mBfIRBuilder->CreateBr(condBB);

View file

@ -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")