mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 12:32:20 +02:00
Another pass at marking scoped raw arrays as deleted
This commit is contained in:
parent
81f8a95cd8
commit
76dfe97d78
5 changed files with 273 additions and 81 deletions
|
@ -505,7 +505,7 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc
|
|||
mCurMethodState->mDeferredLoopListEntryCount++;
|
||||
auto diVariable = mBfIRBuilder->DbgCreateAutoVariable(mCurMethodState->mCurScope->mDIScope,
|
||||
varName, mCurFilePosition.mFileInstance->mDIFile, mCurFilePosition.mCurLine, deferDIType);
|
||||
mBfIRBuilder->DbgInsertDeclare(deferredAlloca, diVariable);
|
||||
mBfIRBuilder->DbgInsertDeclare(deferredAlloca, diVariable);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -539,7 +539,161 @@ BfDeferredCallEntry* BfModule::AddDeferredCall(const BfModuleMethodInstance& mod
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
BF_ASSERT(llvmArgs.size() == 3);
|
||||
|
@ -659,8 +813,7 @@ void BfModule::EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry)
|
|||
RestoreScopeState();
|
||||
return;
|
||||
}
|
||||
|
||||
auto moduleMethodInstance = deferredCallEntry.mModuleMethodInstance;
|
||||
|
||||
auto args = deferredCallEntry.mScopeArgs;
|
||||
if (deferredCallEntry.mArgsNeedLoad)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue