1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 03:52:19 +02:00

Another pass at marking scoped raw arrays as deleted

This commit is contained in:
Brian Fiete 2020-05-18 06:58:02 -07:00
parent 81f8a95cd8
commit 76dfe97d78
5 changed files with 273 additions and 81 deletions

View file

@ -140,23 +140,20 @@ namespace System
#endif #endif
} }
static void SetDeleted1(void* dest) [Error("Cannot be called directly"), SkipCall]
{ static void SetDeleted1(void* dest);
*((uint8*)dest) = 0xDD; [Error("Cannot be called directly"), SkipCall]
} static void SetDeleted4(void* dest);
static void SetDeleted4(void* dest) [Error("Cannot be called directly"), SkipCall]
{ static void SetDeleted8(void* dest);
*((uint32*)dest) = 0xDDDDDDDD; [Error("Cannot be called directly"), SkipCall]
} static void SetDeleted16(void* dest);
static void SetDeleted8(void* dest) [Error("Cannot be called directly"), SkipCall]
{ static extern void SetDeletedX(void* dest, int size);
*((uint64*)dest) = 0xDDDDDDDDDDDDDDDDUL; [Error("Cannot be called directly"), SkipCall]
} static extern void SetDeleted(void* dest, int size, int32 align, int arrayCount);
static void SetDeleted16(void* dest) [Error("Cannot be called directly"), SkipCall]
{ static extern void SetDeletedArray(void* dest, int size, int32 align, int arrayCount);
*((uint64*)dest) = 0xDDDDDDDDDDDDDDDDUL;
*((uint64*)dest + 1) = 0xDDDDDDDDDDDDDDDDUL;
}
public static int MemCmp(void* memA, void* memB, int length) public static int MemCmp(void* memA, void* memB, int length)
{ {

View file

@ -118,23 +118,20 @@ namespace System
#endif #endif
} }
static void SetDeleted1(void* dest) [Error("Cannot be called directly"), SkipCall]
{ static void SetDeleted1(void* dest);
*((uint8*)dest) = 0xDD; [Error("Cannot be called directly"), SkipCall]
} static void SetDeleted4(void* dest);
static void SetDeleted4(void* dest) [Error("Cannot be called directly"), SkipCall]
{ static void SetDeleted8(void* dest);
*((uint32*)dest) = 0xDDDDDDDD; [Error("Cannot be called directly"), SkipCall]
} static void SetDeleted16(void* dest);
static void SetDeleted8(void* dest) [Error("Cannot be called directly"), SkipCall]
{ static extern void SetDeletedX(void* dest, int size);
*((uint64*)dest) = 0xDDDDDDDDDDDDDDDDUL; [Error("Cannot be called directly"), SkipCall]
} static extern void SetDeleted(void* dest, int size, int32 align, int arrayCount);
static void SetDeleted16(void* dest) [Error("Cannot be called directly"), SkipCall]
{ static extern void SetDeletedArray(void* dest, int size, int32 align, int arrayCount);
*((uint64*)dest) = 0xDDDDDDDDDDDDDDDDUL;
*((uint64*)dest + 1) = 0xDDDDDDDDDDDDDDDDUL;
}
public static int MemCmp(void* memA, void* memB, int length) public static int MemCmp(void* memA, void* memB, int length)
{ {

View file

@ -1809,7 +1809,7 @@ BfIRValue BfModule::CreateAllocaInst(BfTypeInstance* typeInst, bool addLifetime,
return allocaInst; return allocaInst;
} }
void BfModule::AddStackAlloc(BfTypedValue val, BfAstNode* refNode, BfScopeData* scopeData, bool condAlloca, bool mayEscape) void BfModule::AddStackAlloc(BfTypedValue val, BfIRValue arraySize, BfAstNode* refNode, BfScopeData* scopeData, bool condAlloca, bool mayEscape)
{ {
//This was removed because we want the alloc to be added to the __deferred list if it's actually a "stack" //This was removed because we want the alloc to be added to the __deferred list if it's actually a "stack"
// 'stack' in a head scopeData is really the same as 'scopeData', so use the simpler scopeData handling // 'stack' in a head scopeData is really the same as 'scopeData', so use the simpler scopeData handling
@ -1869,41 +1869,84 @@ void BfModule::AddStackAlloc(BfTypedValue val, BfAstNode* refNode, BfScopeData*
//TODO: In the future we could be smarter about statically determining that our value hasn't escaped and eliding this //TODO: In the future we could be smarter about statically determining that our value hasn't escaped and eliding this
if (mayEscape) if (mayEscape)
{ {
// Is this worth it?
// if ((!IsOptimized()) && (val.mType->IsComposite()) && (!val.mType->IsValuelessType()) && (!mBfIRBuilder->mIgnoreWrites) && (!mCompiler->mIsResolveOnly)) if ((!IsOptimized()) && (!val.mType->IsValuelessType()) && (!mBfIRBuilder->mIgnoreWrites) && (!mCompiler->mIsResolveOnly))
// { {
// auto nullPtrType = GetPrimitiveType(BfTypeCode_NullPtr); auto nullPtrType = GetPrimitiveType(BfTypeCode_NullPtr);
// bool isDyn = mCurMethodState->mCurScope->IsDyn(scopeData); bool isDyn = mCurMethodState->mCurScope->IsDyn(scopeData);
// if (!isDyn) if (!isDyn)
// { {
// int clearSize = val.mType->mSize; const char* methodName = arraySize ? "SetDeletedArray" : "SetDeleted";
// BfModuleMethodInstance dtorMethodInstance = GetInternalMethod("MemSet"); BfModuleMethodInstance dtorMethodInstance = GetInternalMethod(methodName);
// BF_ASSERT(dtorMethodInstance.mMethodInstance != NULL); BF_ASSERT(dtorMethodInstance.mMethodInstance != NULL);
// SizedArray<BfIRValue, 1> llvmArgs; if (!dtorMethodInstance.mMethodInstance)
// llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(nullPtrType))); {
// llvmArgs.push_back(GetConstValue8(0xDD)); Fail(StrFormat("Unable to find %s", methodName));
// llvmArgs.push_back(GetConstValue(clearSize)); }
// llvmArgs.push_back(GetConstValue32(val.mType->mAlign)); else
// llvmArgs.push_back(mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0)); {
// AddDeferredCall(dtorMethodInstance, llvmArgs, scopeData, refNode, true); SizedArray<BfIRValue, 1> llvmArgs;
// } llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(nullPtrType)));
// else llvmArgs.push_back(GetConstValue(val.mType->mSize));
// { llvmArgs.push_back(GetConstValue32(val.mType->mAlign));
// const char* funcName = "SetDeleted1"; if (arraySize)
// if (val.mType->mSize >= 16) llvmArgs.push_back(arraySize);
// funcName = "SetDeleted16"; AddDeferredCall(dtorMethodInstance, llvmArgs, scopeData, refNode, true);
// else if (val.mType->mSize >= 8) }
// funcName = "SetDeleted8"; }
// else if (val.mType->mSize >= 4) else
// funcName = "SetDeleted4"; {
// if ((arraySize) && (!arraySize.IsConst()) && (val.mType->mSize < mSystem->mPtrSize))
// BfModuleMethodInstance dtorMethodInstance = GetInternalMethod(funcName); {
// BF_ASSERT(dtorMethodInstance.mMethodInstance != NULL); BfIRValue clearSize = arraySize;
// SizedArray<BfIRValue, 1> llvmArgs; if (val.mType->GetStride() > 1)
// llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(nullPtrType))); clearSize = mBfIRBuilder->CreateMul(clearSize, GetConstValue(val.mType->GetStride()));
// AddDeferredCall(dtorMethodInstance, llvmArgs, scopeData, refNode, true);
// } const char* methodName = "SetDeletedX";
// } BfModuleMethodInstance dtorMethodInstance = GetInternalMethod(methodName);
BF_ASSERT(dtorMethodInstance);
if (!dtorMethodInstance)
{
Fail(StrFormat("Unable to find %s", methodName));
}
else
{
SizedArray<BfIRValue, 1> llvmArgs;
llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(nullPtrType)));
llvmArgs.push_back(clearSize);
AddDeferredCall(dtorMethodInstance, llvmArgs, scopeData, refNode, true);
}
}
else
{
intptr clearSize = val.mType->mSize;
auto constant = mBfIRBuilder->GetConstant(arraySize);
if (constant != NULL)
clearSize = (intptr)(clearSize * constant->mInt64);
const char* funcName = "SetDeleted1";
if (clearSize >= 16)
funcName = "SetDeleted16";
else if (clearSize >= 8)
funcName = "SetDeleted8";
else if (clearSize >= 4)
funcName = "SetDeleted4";
BfModuleMethodInstance dtorMethodInstance = GetInternalMethod(funcName);
BF_ASSERT(dtorMethodInstance.mMethodInstance != NULL);
if (!dtorMethodInstance)
{
Fail(StrFormat("Unable to find %s", funcName));
}
else
{
SizedArray<BfIRValue, 1> llvmArgs;
llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(nullPtrType)));
AddDeferredCall(dtorMethodInstance, llvmArgs, scopeData, refNode, true);
}
}
}
}
} }
} }
@ -3904,6 +3947,8 @@ void BfModule::CreateFakeCallerMethod(const String& funcName)
{ {
if (mCurMethodInstance->mHasFailed) if (mCurMethodInstance->mHasFailed)
return; return;
if (mCurMethodInstance->mMethodDef->mIsSkipCall)
return;
BF_ASSERT(mCurMethodInstance->mIRFunction); BF_ASSERT(mCurMethodInstance->mIRFunction);
@ -7809,7 +7854,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
mBfIRBuilder->SetInsertPoint(clearBlock); mBfIRBuilder->SetInsertPoint(clearBlock);
} }
AddStackAlloc(typedVal, NULL, scopeData, false, true); AddStackAlloc(typedVal, arraySize, NULL, scopeData, false, true);
if (!isConstSize) if (!isConstSize)
{ {
@ -7839,7 +7884,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
auto loadedPtr = _CreateDynAlloc(sizeValue, arrayType->mAlign); auto loadedPtr = _CreateDynAlloc(sizeValue, arrayType->mAlign);
auto typedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(loadedPtr, mBfIRBuilder->MapType(arrayType)), arrayType); auto typedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(loadedPtr, mBfIRBuilder->MapType(arrayType)), arrayType);
if (!noDtorCall) if (!noDtorCall)
AddStackAlloc(typedVal, NULL, scopeData, false, true); AddStackAlloc(typedVal, arraySize, NULL, scopeData, false, true);
InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue); InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue);
return typedVal.mValue; return typedVal.mValue;
} }
@ -7878,7 +7923,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
if (!isDynAlloc) if (!isDynAlloc)
mBfIRBuilder->SetInsertPoint(prevBlock); mBfIRBuilder->SetInsertPoint(prevBlock);
if (!noDtorCall) if (!noDtorCall)
AddStackAlloc(typedVal, NULL, scopeData, false, true); AddStackAlloc(typedVal, arraySize, NULL, scopeData, false, true);
InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue); InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue);
return typedVal.mValue; return typedVal.mValue;
} }
@ -7898,7 +7943,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
auto loadedPtr = _CreateDynAlloc(sizeValue, typeInstance->mAlign); auto loadedPtr = _CreateDynAlloc(sizeValue, typeInstance->mAlign);
auto typedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(loadedPtr, mBfIRBuilder->MapTypeInstPtr(typeInstance)), typeInstance); auto typedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(loadedPtr, mBfIRBuilder->MapTypeInstPtr(typeInstance)), typeInstance);
if (!noDtorCall) if (!noDtorCall)
AddStackAlloc(typedVal, NULL, scopeData, mCurMethodState->mInConditionalBlock, true); AddStackAlloc(typedVal, arraySize, NULL, scopeData, mCurMethodState->mInConditionalBlock, true);
InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue); InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue);
return typedVal.mValue; return typedVal.mValue;
} }
@ -7965,7 +8010,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
bool doCondAlloca = false; bool doCondAlloca = false;
if (!IsTargetingBeefBackend()) if (!IsTargetingBeefBackend())
doCondAlloca = !wasDynAlloc && isDynAlloc && mCurMethodState->mInConditionalBlock; doCondAlloca = !wasDynAlloc && isDynAlloc && mCurMethodState->mInConditionalBlock;
AddStackAlloc(typedVal, NULL, scopeData, doCondAlloca, true); AddStackAlloc(typedVal, arraySize, NULL, scopeData, doCondAlloca, true);
} }
InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue); InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue);
@ -8009,7 +8054,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
} }
} }
if (!noDtorCall) if (!noDtorCall)
AddStackAlloc(typedVal, NULL, scopeData, false, true); AddStackAlloc(typedVal, BfIRValue(), NULL, scopeData, false, true);
if (typeInstance != NULL) if (typeInstance != NULL)
{ {
InitTypeInst(typedVal, scopeData, zeroMemory, GetConstValue(typeInstance->mInstSize)); InitTypeInst(typedVal, scopeData, zeroMemory, GetConstValue(typeInstance->mInstSize));

View file

@ -1468,7 +1468,7 @@ public:
void NewScopeState(bool createLexicalBlock = true, bool flushValueScope = true); // returns prev scope data void NewScopeState(bool createLexicalBlock = true, bool flushValueScope = true); // returns prev scope data
BfIRValue CreateAlloca(BfType* type, bool addLifetime = true, const char* name = NULL, BfIRValue arraySize = BfIRValue()); BfIRValue CreateAlloca(BfType* type, bool addLifetime = true, const char* name = NULL, BfIRValue arraySize = BfIRValue());
BfIRValue CreateAllocaInst(BfTypeInstance* typeInst, bool addLifetime = true, const char* name = NULL); BfIRValue CreateAllocaInst(BfTypeInstance* typeInst, bool addLifetime = true, const char* name = NULL);
void AddStackAlloc(BfTypedValue val, BfAstNode* refNode, BfScopeData* scope, bool condAlloca = false, bool mayEscape = false); void AddStackAlloc(BfTypedValue val, BfIRValue arraySize, BfAstNode* refNode, BfScopeData* scope, bool condAlloca = false, bool mayEscape = false);
void RestoreScoreState_LocalVariables(); void RestoreScoreState_LocalVariables();
void RestoreScopeState(); void RestoreScopeState();
void MarkDynStack(BfScopeData* scope); void MarkDynStack(BfScopeData* scope);

View file

@ -505,7 +505,7 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc
mCurMethodState->mDeferredLoopListEntryCount++; mCurMethodState->mDeferredLoopListEntryCount++;
auto diVariable = mBfIRBuilder->DbgCreateAutoVariable(mCurMethodState->mCurScope->mDIScope, auto diVariable = mBfIRBuilder->DbgCreateAutoVariable(mCurMethodState->mCurScope->mDIScope,
varName, mCurFilePosition.mFileInstance->mDIFile, mCurFilePosition.mCurLine, deferDIType); varName, mCurFilePosition.mFileInstance->mDIFile, mCurFilePosition.mCurLine, deferDIType);
mBfIRBuilder->DbgInsertDeclare(deferredAlloca, diVariable); mBfIRBuilder->DbgInsertDeclare(deferredAlloca, diVariable);
} }
return true; return true;
@ -539,7 +539,161 @@ BfDeferredCallEntry* BfModule::AddDeferredCall(const BfModuleMethodInstance& mod
} }
void BfModule::EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, SizedArrayImpl<BfIRValue>& llvmArgs, BfDeferredBlockFlags flags) void BfModule::EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, SizedArrayImpl<BfIRValue>& llvmArgs, BfDeferredBlockFlags flags)
{ {
if (moduleMethodInstance.mMethodInstance->GetOwner()->IsInstanceOf(mCompiler->mInternalTypeDef))
{
if (moduleMethodInstance.mMethodInstance->mMethodDef->mName.StartsWith("SetDeleted"))
{
intptr typeSize = 0;
intptr typeAlign = 1;
intptr clearSize = 0;
bool isDynSize = false;
bool mayBeZero = false;
auto ptrValue = llvmArgs[0];
BfIRValue arraySize;
if ((moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeleted") ||
(moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeletedArray"))
{
auto constant = mBfIRBuilder->GetConstant(llvmArgs[1]);
if (constant != NULL)
typeSize = constant->mInt64;
constant = mBfIRBuilder->GetConstant(llvmArgs[2]);
if (constant != NULL)
typeAlign = constant->mInt64;
auto arraySize = llvmArgs[3];
intptr allocSize = typeSize;
if (arraySize)
{
allocSize = BF_ALIGN(typeSize, typeAlign);
auto constant = mBfIRBuilder->GetConstant(arraySize);
if (constant != NULL)
allocSize = allocSize * (intptr)constant->mInt64;
else
{
isDynSize = true;
mayBeZero = true;
}
}
clearSize = BF_MIN(allocSize, mSystem->mPtrSize);
}
else if (moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeletedX")
{
// Note: this infers that mayBeZero is false still, because the deferred call would not have
// been added if the array size was zero
typeSize = 1;
clearSize = typeSize;
arraySize = llvmArgs[1];
isDynSize = true;
}
else if (moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeleted1")
{
clearSize = 1;
}
else if (moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeleted2")
{
clearSize = 2;
}
else if (moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeleted4")
{
clearSize = 4;
}
else if (moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeleted8")
{
clearSize = 8;
}
else if (moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeleted16")
{
clearSize = 16;
}
if (clearSize > 0)
{
BfTypeCode clearTypeCode = BfTypeCode_Int8;
if (clearSize >= mSystem->mPtrSize)
clearTypeCode = BfTypeCode_IntPtr;
else if (clearSize >= 4)
clearTypeCode = BfTypeCode_Int32;
else if (clearSize >= 2)
clearTypeCode = BfTypeCode_Int16;
auto intType = GetPrimitiveType(clearTypeCode);
auto intPtrType = CreatePointerType(intType);
if (isDynSize)
{
if (clearSize >= mSystem->mPtrSize)
{
auto ddSize1Block = mBfIRBuilder->CreateBlock("DDSize1");
auto ddDoneBlock = mBfIRBuilder->CreateBlock("DDDone");
auto cmp = mBfIRBuilder->CreateCmpGT(arraySize, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), true);
mBfIRBuilder->CreateCondBr(cmp, ddSize1Block, ddDoneBlock);
mBfIRBuilder->AddBlock(ddSize1Block);
mBfIRBuilder->SetInsertPoint(ddSize1Block);
auto intPtrVal = mBfIRBuilder->CreateBitCast(ptrValue, mBfIRBuilder->MapType(intPtrType));
mBfIRBuilder->CreateStore(mBfIRBuilder->CreateConst(clearTypeCode, 0xDDDDDDDDDDDDDDDDULL), intPtrVal);
mBfIRBuilder->CreateBr(ddDoneBlock);
mBfIRBuilder->AddBlock(ddDoneBlock);
mBfIRBuilder->SetInsertPoint(ddDoneBlock);
}
else
{
// If we allocate at least this many then we can do an IntPtr-sized marking, otherwise just one element's worth
int intPtrCount = (int)((mSystem->mPtrSize + typeSize - 1) / typeSize);
BfIRBlock ddSizePtrBlock = mBfIRBuilder->CreateBlock("DDSizePtr");
BfIRBlock ddCheck1Block = mBfIRBuilder->CreateBlock("DDCheck1");
BfIRBlock ddSize1Block;
if (mayBeZero)
ddSize1Block = mBfIRBuilder->CreateBlock("DDSize1");
BfIRBlock ddDoneBlock = mBfIRBuilder->CreateBlock("DDDone");
auto intptrType = GetPrimitiveType(BfTypeCode_IntPtr);
auto intptrPtrType = CreatePointerType(intptrType);
auto cmpPtr = mBfIRBuilder->CreateCmpGTE(arraySize, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, intPtrCount), true);
mBfIRBuilder->CreateCondBr(cmpPtr, ddSizePtrBlock, ddCheck1Block);
mBfIRBuilder->AddBlock(ddSizePtrBlock);
mBfIRBuilder->SetInsertPoint(ddSizePtrBlock);
auto intptrPtrVal = mBfIRBuilder->CreateBitCast(ptrValue, mBfIRBuilder->MapType(intptrPtrType));
mBfIRBuilder->CreateStore(mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0xDDDDDDDDDDDDDDDDULL), intptrPtrVal);
mBfIRBuilder->CreateBr(ddDoneBlock);
mBfIRBuilder->AddBlock(ddCheck1Block);
mBfIRBuilder->SetInsertPoint(ddCheck1Block);
if (mayBeZero)
{
auto cmp1 = mBfIRBuilder->CreateCmpGT(arraySize, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), true);
mBfIRBuilder->CreateCondBr(cmp1, ddSize1Block, ddDoneBlock);
mBfIRBuilder->AddBlock(ddSize1Block);
mBfIRBuilder->SetInsertPoint(ddSize1Block);
}
auto intPtrVal = mBfIRBuilder->CreateBitCast(ptrValue, mBfIRBuilder->MapType(intPtrType));
mBfIRBuilder->CreateStore(mBfIRBuilder->CreateConst(clearTypeCode, 0xDDDDDDDDDDDDDDDDULL), intPtrVal);
mBfIRBuilder->CreateBr(ddDoneBlock);
mBfIRBuilder->AddBlock(ddDoneBlock);
mBfIRBuilder->SetInsertPoint(ddDoneBlock);
}
}
else
{
auto intPtrVal = mBfIRBuilder->CreateBitCast(ptrValue, mBfIRBuilder->MapType(intPtrType));
mBfIRBuilder->CreateStore(mBfIRBuilder->CreateConst(clearTypeCode, 0xDDDDDDDDDDDDDDDDULL), intPtrVal);
}
}
return;
}
}
if (moduleMethodInstance.mMethodInstance == mContext->mValueTypeDeinitSentinel) if (moduleMethodInstance.mMethodInstance == mContext->mValueTypeDeinitSentinel)
{ {
BF_ASSERT(llvmArgs.size() == 3); BF_ASSERT(llvmArgs.size() == 3);
@ -659,8 +813,7 @@ void BfModule::EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry)
RestoreScopeState(); RestoreScopeState();
return; return;
} }
auto moduleMethodInstance = deferredCallEntry.mModuleMethodInstance;
auto args = deferredCallEntry.mScopeArgs; auto args = deferredCallEntry.mScopeArgs;
if (deferredCallEntry.mArgsNeedLoad) if (deferredCallEntry.mArgsNeedLoad)
{ {