diff --git a/IDEHelper/Backend/BeIRCodeGen.cpp b/IDEHelper/Backend/BeIRCodeGen.cpp index 89da21bd..ab3091cf 100644 --- a/IDEHelper/Backend/BeIRCodeGen.cpp +++ b/IDEHelper/Backend/BeIRCodeGen.cpp @@ -1424,6 +1424,9 @@ void BeIRCodeGen::HandleNextCmd() case BfIRCmd_LifetimeEnd: { CMD_PARAM(BeValue*, val); +#ifdef _DEBUG + val->mLifetimeEnded = true; +#endif auto inst = mBeModule->AllocInst(); inst->mPtr = val; SetResult(curId, inst); @@ -3045,6 +3048,9 @@ BeValue* BeIRCodeGen::GetBeValue(int id) { auto& result = mResults[id]; BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Value); +#ifdef _DEBUG + BF_ASSERT(!result.mBeValue->mLifetimeEnded); +#endif return result.mBeValue; } diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index d8a33fb6..36565494 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -12043,7 +12043,8 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo value = newLocalVar->mConstValue; auto aliasValue = mModule->mBfIRBuilder->CreateAliasValue(value); - scopeData.mDeferredLifetimeEnds.Add(aliasValue); + if (mModule->WantsLifetimes()) + scopeData.mDeferredLifetimeEnds.Add(aliasValue); if (newLocalVar->mAddr) mModule->mBfIRBuilder->DbgInsertDeclare(aliasValue, diVariable); @@ -15156,7 +15157,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) auto startCheckTypeInst = target.mType->ToTypeInstance(); for (int pass = 0; pass < 2; pass++) - { + { bool isFailurePass = pass == 1; auto curCheckType = startCheckTypeInst; @@ -15318,6 +15319,16 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) } } + if (indexArgument.mType->IsPrimitiveType()) + { + auto primType = (BfPrimitiveType*)indexArgument.mType; + if ((!primType->IsSigned()) && (primType->mSize < 8)) + { + // GEP will always do a signed upcast so we need to cast manually if we are unsigned + indexArgument = BfTypedValue(mModule->mBfIRBuilder->CreateNumericCast(indexArgument.mValue, false, BfTypeCode_IntPtr), mModule->GetPrimitiveType(BfTypeCode_IntPtr)); + } + } + mModule->PopulateType(target.mType); if (target.mType->IsSizedArray()) { diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index b1e18cc4..ffa8fab4 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -1788,7 +1788,7 @@ BfIRValue BfModule::CreateAlloca(BfType* type, bool addLifetime, const char* nam if (name != NULL) mBfIRBuilder->SetName(allocaInst, name); mBfIRBuilder->SetInsertPoint(prevInsertBlock); - if (addLifetime) + if ((addLifetime) && (WantsLifetimes())) { auto lifetimeStart = mBfIRBuilder->CreateLifetimeStart(allocaInst); mBfIRBuilder->ClearDebugLocation(lifetimeStart); @@ -1812,7 +1812,7 @@ BfIRValue BfModule::CreateAllocaInst(BfTypeInstance* typeInst, bool addLifetime, if (name != NULL) mBfIRBuilder->SetName(allocaInst, name); mBfIRBuilder->SetInsertPoint(prevInsertBlock); - if (addLifetime) + if ((addLifetime) && (WantsLifetimes())) { auto lifetimeStart = mBfIRBuilder->CreateLifetimeStart(allocaInst); mBfIRBuilder->ClearDebugLocation(lifetimeStart); @@ -7456,8 +7456,11 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget castedVal = mBfIRBuilder->CreateBitCast(allocaInst, mBfIRBuilder->MapTypeInstPtr(typeInstance)); mBfIRBuilder->ClearDebugLocation(castedVal); mBfIRBuilder->SetInsertPoint(prevBlock); - mBfIRBuilder->CreateLifetimeStart(allocaInst); - scopeData->mDeferredLifetimeEnds.push_back(allocaInst); + if (WantsLifetimes()) + { + mBfIRBuilder->CreateLifetimeStart(allocaInst); + scopeData->mDeferredLifetimeEnds.push_back(allocaInst); + } } else { @@ -7507,8 +7510,11 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget { mBfIRBuilder->ClearDebugLocation(allocaInst); mBfIRBuilder->SetInsertPoint(prevBlock); - mBfIRBuilder->CreateLifetimeStart(allocaInst); - scopeData->mDeferredLifetimeEnds.push_back(allocaInst); + if (WantsLifetimes()) + { + mBfIRBuilder->CreateLifetimeStart(allocaInst); + scopeData->mDeferredLifetimeEnds.push_back(allocaInst); + } } if (!noDtorCall) AddStackAlloc(typedVal, NULL, scopeData, false, true); @@ -7937,8 +7943,15 @@ bool BfModule::IsOptimized() bool BfModule::IsTargetingBeefBackend() { if (mProject == NULL) - return false; - return GetModuleOptions().mOptLevel == BfOptLevel_OgPlus; + return false; + return GetModuleOptions().mOptLevel == BfOptLevel_OgPlus; +} + +bool BfModule::WantsLifetimes() +{ + if (mProject == NULL) + return false; + return GetModuleOptions().mOptLevel == BfOptLevel_OgPlus; } bool BfModule::HasCompiledOutput() @@ -11793,7 +11806,7 @@ BfIRValue BfModule::AllocLocalVariable(BfType* type, const StringImpl& name, boo return mBfIRBuilder->GetFakeVal(); auto allocaInst = CreateAlloca(type, doLifetimeEnd, name.c_str()); - if (!doLifetimeEnd) + if ((!doLifetimeEnd) && (WantsLifetimes())) { auto lifetimeStart = mBfIRBuilder->CreateLifetimeStart(allocaInst); mBfIRBuilder->ClearDebugLocation(lifetimeStart); @@ -15969,7 +15982,8 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) mBfIRBuilder->SetAllocaAlignment(allocaInst, checkType->mAlign); if (!paramVar->mAddr) paramVar->mAddr = allocaInst; - mCurMethodState->mCurScope->mDeferredLifetimeEnds.push_back(allocaInst); + if (WantsLifetimes()) + mCurMethodState->mCurScope->mDeferredLifetimeEnds.push_back(allocaInst); splatAddrValues.push_back(allocaInst); }, paramVar->mResolvedType); mBfIRBuilder->SetInsertPoint(prevInsert); @@ -15989,7 +16003,8 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) mBfIRBuilder->SetName(allocaInst, paramVar->mName + ".addr"); mBfIRBuilder->SetAllocaAlignment(allocaInst, thisType->mAlign); paramVar->mAddr = allocaInst; - mCurMethodState->mCurScope->mDeferredLifetimeEnds.push_back(allocaInst); + if (WantsLifetimes()) + mCurMethodState->mCurScope->mDeferredLifetimeEnds.push_back(allocaInst); } } else @@ -16007,7 +16022,8 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) mBfIRBuilder->SetName(allocaInst, paramVar->mName + ".addr"); mBfIRBuilder->SetAllocaAlignment(allocaInst, mSystem->mPtrSize); paramVar->mAddr = allocaInst; - mCurMethodState->mCurScope->mDeferredLifetimeEnds.push_back(allocaInst); + if (WantsLifetimes()) + mCurMethodState->mCurScope->mDeferredLifetimeEnds.push_back(allocaInst); } mBfIRBuilder->SetInsertPoint(prevInsert); } @@ -16046,7 +16062,8 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) mBfIRBuilder->SetAllocaAlignment(allocaInst, alignSize); paramVar->mAddr = allocaInst; mBfIRBuilder->SetInsertPoint(prevInsert); - mCurMethodState->mCurScope->mDeferredLifetimeEnds.push_back(allocaInst); + if (WantsLifetimes()) + mCurMethodState->mCurScope->mDeferredLifetimeEnds.push_back(allocaInst); } } else if (wantsAddr) diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index b07dab01..4d723428 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1460,6 +1460,7 @@ public: void EmitAppendAlign(int align, int sizeMultiple = 0); BfIRValue AppendAllocFromType(BfType* type, BfIRValue appendSizeValue = BfIRValue(), int appendAllocAlign = 0, BfIRValue arraySize = BfIRValue(), int arrayDim = 0, bool isRawArrayAlloc = false, bool zeroMemory = true); bool IsTargetingBeefBackend(); + bool WantsLifetimes(); bool HasCompiledOutput(); void SkipObjectAccessCheck(BfTypedValue typedVal); void EmitObjectAccessCheck(BfTypedValue typedVal); diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index ba220de1..c74f8fa8 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -84,10 +84,12 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc auto allocaInst = mBfIRBuilder->CreateAlloca(origParamTypes[paramIdx]); mBfIRBuilder->ClearDebugLocation(allocaInst); mBfIRBuilder->SetInsertPoint(prevInsertBlock); - mBfIRBuilder->CreateLifetimeStart(allocaInst); + if (WantsLifetimes()) + mBfIRBuilder->CreateLifetimeStart(allocaInst); mBfIRBuilder->CreateStore(scopeArg, allocaInst); deferredCallEntry->mScopeArgs[paramIdx] = allocaInst; - scopeData->mDeferredLifetimeEnds.push_back(allocaInst); + if (WantsLifetimes()) + scopeData->mDeferredLifetimeEnds.push_back(allocaInst); } deferredCallEntry->mArgsNeedLoad = true; } @@ -120,7 +122,8 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc if (!mBfIRBuilder->mIgnoreWrites) { listEntry->mDynCallTail = CreateAlloca(deferredCallEntryTypePtr, false, "deferredCallTail"); - scopeData->mDeferredLifetimeEnds.push_back(listEntry->mDynCallTail); + if (WantsLifetimes()) + scopeData->mDeferredLifetimeEnds.push_back(listEntry->mDynCallTail); auto prevInsertBlock = mBfIRBuilder->GetInsertBlock(); mBfIRBuilder->SaveDebugLocation(); @@ -129,7 +132,8 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc auto scopeHead = &mCurMethodState->mHeadScope; mBfIRBuilder->SetCurrentDebugLocation(mCurFilePosition.mCurLine + 1, 0, scopeHead->mDIScope, BfIRMDNode()); - mBfIRBuilder->CreateLifetimeStart(listEntry->mDynCallTail); + if (WantsLifetimes()) + mBfIRBuilder->CreateLifetimeStart(listEntry->mDynCallTail); auto storeInst = mBfIRBuilder->CreateStore(GetDefaultValue(deferredCallEntryTypePtr), listEntry->mDynCallTail); mBfIRBuilder->ClearDebugLocation(storeInst); @@ -1590,7 +1594,8 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD if (localDef->mIsReadOnly) localDef->mValue = mBfIRBuilder->CreateLoad(localDef->mAddr); } - mCurMethodState->mCurScope->mDeferredLifetimeEnds.push_back(localDef->mAddr); + if (WantsLifetimes()) + mCurMethodState->mCurScope->mDeferredLifetimeEnds.push_back(localDef->mAddr); } if ((!localDef->mAddr) && (!isConst) && ((!localDef->mIsReadOnly) || (localNeedsAddr)))