diff --git a/IDEHelper/Backend/BeIRCodeGen.cpp b/IDEHelper/Backend/BeIRCodeGen.cpp index b4b7e497..5dc6dca1 100644 --- a/IDEHelper/Backend/BeIRCodeGen.cpp +++ b/IDEHelper/Backend/BeIRCodeGen.cpp @@ -1754,6 +1754,14 @@ void BeIRCodeGen::HandleNextCmd() SetResult(curId, inst); } break; + case BfIRCmd_LifetimeSoftEnd: + { + CMD_PARAM(BeValue*, val); + auto inst = mBeModule->AllocInst(); + inst->mPtr = val; + SetResult(curId, inst); + } + break; case BfIRCmd_LifetimeExtend: { CMD_PARAM(BeValue*, val); diff --git a/IDEHelper/Backend/BeMCContext.cpp b/IDEHelper/Backend/BeMCContext.cpp index cde736bd..eb7b2838 100644 --- a/IDEHelper/Backend/BeMCContext.cpp +++ b/IDEHelper/Backend/BeMCContext.cpp @@ -34,11 +34,10 @@ static const char* gOpName[] = "@DefLoad", "@DefPhi", "@DbgDecl", - "@DbgRangeStart", - "@DbgRangeEnd", "@LifetimeExtend", "@LifetimeStart", "@LifetimeEnd", + "@LifetimeSoftEnd", "@ValueScopeSoftEnd", "@ValueScopeHardEnd", "@Label", @@ -13234,29 +13233,25 @@ void BeMCContext::DoCodeEmission() } } break; - case BeMCInstKind_DbgRangeStart: - { - - } - break; - case BeMCInstKind_DbgRangeEnd: - { - auto vregInfo = GetVRegInfo(inst->mArg0); - if (vregInfo->mDbgVariable != NULL) - { - auto dbgVar = vregInfo->mDbgVariable; - dbgVar->mDeclEnd = funcCodePos; - dbgVar->mDeclLifetimeExtend = false; - BF_ASSERT((uint)dbgVar->mDeclEnd >= (uint)dbgVar->mDeclStart); - } - } - break; case BeMCInstKind_LifetimeExtend: break; case BeMCInstKind_LifetimeStart: break; case BeMCInstKind_LifetimeEnd: break; + case BeMCInstKind_LifetimeSoftEnd: + { + auto vregInfo = GetVRegInfo(inst->mArg0); + if ((vregInfo != NULL) && (vregInfo->mDbgVariable != NULL)) + { + auto dbgVar = vregInfo->mDbgVariable; + dbgVar->mDeclEnd = funcCodePos; + dbgVar->mDeclLifetimeExtend = false; + dbgVar->mDbgLifeEnded = true; + BF_ASSERT((uint)dbgVar->mDeclEnd >= (uint)dbgVar->mDeclStart); + } + } + break; case BeMCInstKind_ValueScopeSoftEnd: break; case BeMCInstKind_ValueScopeHardEnd: @@ -16143,7 +16138,7 @@ void BeMCContext::Generate(BeFunction* function) mDbgPreferredRegs[32] = X64Reg_R8;*/ //mDbgPreferredRegs[8] = X64Reg_RAX; - //mDebugging = (function->mName == "?CreateEntity@ModelLoader@Content@GlitchyEngine@bf@@CA?AU?$__TUPLE_Entity_Transform@VEcsEntity@World@GlitchyEngine@bf@@PEA?AUTransformComponent@123@@4@PEAVEcsWorld@World@34@U?$Nullable@UStringView@System@bf@@@System@4@VEcsEntity@734@@Z"); + mDebugging = (function->mName == "?NumberToString@NumberFormatter@System@bf@@SAXUStringView@23@HPEAVIFormatProvider@23@PEAVString@23@@Z"); // || (function->mName == "?MethodA@TestProgram@BeefTest@bf@@CAXXZ"); // || (function->mName == "?Hey@Blurg@bf@@SAXXZ") // ; @@ -17002,6 +16997,16 @@ void BeMCContext::Generate(BeFunction* function) } } break; + case BeLifetimeSoftEndInst::TypeId: + { + auto castedInst = (BeLifetimeSoftEndInst*)inst; + auto mcPtr = GetOperand(castedInst->mPtr, false, true, true); + if (mcPtr.IsVRegAny()) + { + AllocInst(BeMCInstKind_LifetimeSoftEnd, mcPtr); + } + } + break; case BeValueScopeStartInst::TypeId: { result = BeMCOperand::FromImmediate((int)mVRegInfo.size()); diff --git a/IDEHelper/Backend/BeMCContext.h b/IDEHelper/Backend/BeMCContext.h index ecaa4692..ca743515 100644 --- a/IDEHelper/Backend/BeMCContext.h +++ b/IDEHelper/Backend/BeMCContext.h @@ -484,11 +484,10 @@ enum BeMCInstKind BeMCInstKind_DefLoad, BeMCInstKind_DefPhi, BeMCInstKind_DbgDecl, - BeMCInstKind_DbgRangeStart, - BeMCInstKind_DbgRangeEnd, // Extends life of local variables/arguments to their lexical scope end BeMCInstKind_LifetimeExtend, BeMCInstKind_LifetimeStart, BeMCInstKind_LifetimeEnd, + BeMCInstKind_LifetimeSoftEnd, BeMCInstKind_ValueScopeSoftEnd, BeMCInstKind_ValueScopeHardEnd, BeMCInstKind_Label, diff --git a/IDEHelper/Backend/BeModule.cpp b/IDEHelper/Backend/BeModule.cpp index c396624f..80a1e309 100644 --- a/IDEHelper/Backend/BeModule.cpp +++ b/IDEHelper/Backend/BeModule.cpp @@ -300,6 +300,12 @@ void BeInliner::Visit(BeLifetimeEndInst* lifetimeEndInst) destlifetimeEndInst->mPtr = Remap(lifetimeEndInst->mPtr); } +void BeInliner::Visit(BeLifetimeSoftEndInst* lifetimeEndInst) +{ + auto destlifetimeEndInst = AllocInst(lifetimeEndInst); + destlifetimeEndInst->mPtr = Remap(lifetimeEndInst->mPtr); +} + void BeInliner::Visit(BeLifetimeFenceInst* lifetimeFenceInst) { auto destlifetimeFenceInst = AllocInst(lifetimeFenceInst); @@ -2344,6 +2350,7 @@ String BeModule::ToString(BeFunction* wantFunc) DISPLAY_INST1(BeAliasValueInst, "aliasvalue", mPtr); DISPLAY_INST1(BeLifetimeStartInst, "lifetime.start", mPtr); DISPLAY_INST1(BeLifetimeEndInst, "lifetime.end", mPtr); + DISPLAY_INST1(BeLifetimeSoftEndInst, "lifetime.softEnd", mPtr); DISPLAY_INST2(BeLifetimeFenceInst, "lifetime.fence", mFenceBlock, mPtr); DISPLAY_INST0(BeValueScopeStartInst, "valueScope.start"); DISPLAY_INST1(BeValueScopeRetainInst, "valueScope.retain", mValue); diff --git a/IDEHelper/Backend/BeModule.h b/IDEHelper/Backend/BeModule.h index b5925b82..066f1062 100644 --- a/IDEHelper/Backend/BeModule.h +++ b/IDEHelper/Backend/BeModule.h @@ -36,6 +36,7 @@ class BeLifetimeExtendInst; class BeAliasValueInst; class BeLifetimeStartInst; class BeLifetimeEndInst; +class BeLifetimeSoftEndInst; class BeLifetimeFenceInst; class BeValueScopeStartInst; class BeValueScopeRetainInst; @@ -90,6 +91,7 @@ public: virtual void Visit(BeLifetimeExtendInst* lifetimeExtendInst) {} virtual void Visit(BeLifetimeStartInst* lifetimeStartInst) {} virtual void Visit(BeLifetimeEndInst* lifetimeEndInst) {} + virtual void Visit(BeLifetimeSoftEndInst* lifetimeEndInst) {} virtual void Visit(BeLifetimeFenceInst* lifetimeFenceInst) {} virtual void Visit(BeValueScopeStartInst* valueScopeStartInst) {} virtual void Visit(BeValueScopeRetainInst* valueScopeRetainInst) {} @@ -183,6 +185,7 @@ public: virtual void Visit(BeLifetimeStartInst* lifetimeStartInst) override; virtual void Visit(BeLifetimeExtendInst* lifetimeExtendInst) override; virtual void Visit(BeLifetimeEndInst* lifetimeEndInst) override; + virtual void Visit(BeLifetimeSoftEndInst* lifetimeEndInst) override; virtual void Visit(BeLifetimeFenceInst* lifetimeFenceInst) override; virtual void Visit(BeValueScopeStartInst* valueScopeStartInst) override; virtual void Visit(BeValueScopeRetainInst* valueScopeRetainInst) override; @@ -978,6 +981,20 @@ public: } }; +class BeLifetimeSoftEndInst : public BeInst +{ +public: + BE_VALUE_TYPE(BeLifetimeSoftEndInst, BeInst); + + BeValue* mPtr; + + virtual void HashInst(BeHashContext& hashCtx) override + { + hashCtx.Mixin(TypeId); + mPtr->HashReference(hashCtx); + } +}; + class BeLifetimeFenceInst : public BeInst { public: diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index cde323dc..feacf2f2 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -3402,12 +3402,6 @@ void BfExprEvaluator::Visit(BfBlock* blockExpr) } mModule->VisitEmbeddedStatement(blockExpr, this, BfNodeIsA(blockExpr) ? BfEmbeddedStatementFlags_Unscoped : BfEmbeddedStatementFlags_None); - mResult = mModule->SanitizeAddr(mResult); - if ((mResult) && (mResult.mType->IsStruct())) - { - mResult = mModule->MakeAddressable(mResult, true); - mResult.MakeTemporary(true); - } } bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requireSimpleIfExpr, bool exprMustBeTrue, bool silentFail) @@ -17193,9 +17187,14 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo mResult = BfTypedValue(BfIRValue(), mModule->GetPrimitiveType(BfTypeCode_None)); } - mResult = mModule->LoadValue(mResult); - mResult = mModule->SanitizeAddr(mResult); - + mResult = mModule->RemoveRef(mResult); + + if (mResult.IsAddr()) + { + if (mModule->mCurMethodState->mCurScope->ExtendLifetime(mResult.mValue)) + mModule->mBfIRBuilder->CreateLifetimeSoftEnd(mResult.mValue); + } + int localIdx = startLocalIdx; argExprEvaluatorItr = argExprEvaluators.begin(); @@ -17253,12 +17252,6 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo mModule->mBfIRBuilder->RestoreDebugLocation(); mModule->mBfIRBuilder->DupDebugLocation(); - - if ((mResult) && (mResult.mType->IsStruct())) - { - mResult = mModule->MakeAddressable(mResult, true); - mResult.MakeTemporary(true); - } } void BfExprEvaluator::SetMethodElementType(BfAstNode* target) @@ -19513,7 +19506,7 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool ResolveGenericType(); auto ptr = mModule->RemoveRef(mResult); mResult = BfTypedValue(); - + if (mPropDef != NULL) { bool hasLeftVal = false; @@ -21583,7 +21576,7 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, if (!mResult) return; - mResult = mModule->RemoveRef(mResult); + mResult = mModule->RemoveRef(mResult); if (mResult.mType->IsVar()) { diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index 43d6b421..250c179b 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -4907,6 +4907,13 @@ BfIRValue BfIRBuilder::CreateLifetimeEnd(BfIRValue val) return retVal; } +BfIRValue BfIRBuilder::CreateLifetimeSoftEnd(BfIRValue val) +{ + BfIRValue retVal = WriteCmd(BfIRCmd_LifetimeSoftEnd, val); + NEW_CMD_INSERTED; + return retVal; +} + BfIRValue BfIRBuilder::CreateLifetimeExtend(BfIRValue val) { BfIRValue retVal = WriteCmd(BfIRCmd_LifetimeExtend, val); diff --git a/IDEHelper/Compiler/BfIRBuilder.h b/IDEHelper/Compiler/BfIRBuilder.h index a892b11e..fe7166ca 100644 --- a/IDEHelper/Compiler/BfIRBuilder.h +++ b/IDEHelper/Compiler/BfIRBuilder.h @@ -230,7 +230,8 @@ enum BfIRCmd : uint8 BfIRCmd_AliasValue, BfIRCmd_LifetimeStart, BfIRCmd_LifetimeEnd, - BfIRCmd_LifetimeExtend, + BfIRCmd_LifetimeSoftEnd, + BfIRCmd_LifetimeExtend, BfIRCmd_ValueScopeStart, BfIRCmd_ValueScopeRetain, BfIRCmd_ValueScopeSoftEnd, @@ -1253,8 +1254,9 @@ public: void SetAllocaNoChkStkHint(BfIRValue val); void SetAllocaForceMem(BfIRValue val); BfIRValue CreateAliasValue(BfIRValue val); - BfIRValue CreateLifetimeStart(BfIRValue val); + BfIRValue CreateLifetimeStart(BfIRValue val); BfIRValue CreateLifetimeEnd(BfIRValue val); + BfIRValue CreateLifetimeSoftEnd(BfIRValue val); BfIRValue CreateLifetimeExtend(BfIRValue val); BfIRValue CreateValueScopeStart(); void CreateValueScopeRetain(BfIRValue val); // When a value is held by a variable -- don't release until we have a HardValueScopeEnd diff --git a/IDEHelper/Compiler/BfIRCodeGen.cpp b/IDEHelper/Compiler/BfIRCodeGen.cpp index 273ab80f..0755fd9c 100644 --- a/IDEHelper/Compiler/BfIRCodeGen.cpp +++ b/IDEHelper/Compiler/BfIRCodeGen.cpp @@ -2487,6 +2487,11 @@ void BfIRCodeGen::HandleNextCmd() SetResult(curId, mIRBuilder->CreateLifetimeEnd(val)); } break; + case BfIRCmd_LifetimeSoftEnd: + { + CMD_PARAM_NOTRANS(llvm::Value*, val); + } + break; case BfIRCmd_LifetimeExtend: { CMD_PARAM_NOTRANS(llvm::Value*, val); diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 1264f81b..f0dc3fc8 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -587,6 +587,17 @@ public: } return depth; } + + bool ExtendLifetime(BfIRValue irValue) + { + if (mDeferredLifetimeEnds.Remove(irValue)) + { + if (mPrevScope != NULL) + mPrevScope->mDeferredLifetimeEnds.Add(irValue); + return true; + } + return false; + } }; struct BfCaptureInfo diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index 3cb62937..09702ddf 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -3526,6 +3526,12 @@ void BfModule::VisitCodeBlock(BfBlock* block) (wasReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr)); } } + + if (exprEvaluator->mResult.IsAddr()) + { + if (mCurMethodState->mCurScope->ExtendLifetime(exprEvaluator->mResult.mValue)) + mBfIRBuilder->CreateLifetimeSoftEnd(exprEvaluator->mResult.mValue); + } } break; diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index 26426ba2..e7c393b6 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -1860,9 +1860,10 @@ void CeBuilder::Build() } switch (instType) - { - case BeNopInst::TypeId: - case BeLifetimeStartInst::TypeId: + { + case BeNopInst::TypeId: + case BeLifetimeSoftEndInst::TypeId: + case BeLifetimeStartInst::TypeId: case BeLifetimeExtendInst::TypeId: case BeValueScopeStartInst::TypeId: case BeValueScopeEndInst::TypeId: