1
0
Fork 0
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:
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

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