From 3fddd4f396b34d809cd4c111cb3e340d5c5aebb9 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Wed, 20 Jan 2021 08:53:43 -0800 Subject: [PATCH] Better fix for direct autprop optimization --- IDEHelper/Compiler/BfAst.h | 6 ++++++ IDEHelper/Compiler/BfExprEvaluator.cpp | 20 +++++++++++--------- IDEHelper/Compiler/BfExprEvaluator.h | 2 +- IDEHelper/Compiler/BfModule.cpp | 10 +++++++++- IDEHelper/Compiler/BfModule.h | 5 +++-- IDEHelper/Tests/src/Properties.bf | 1 + 6 files changed, 31 insertions(+), 13 deletions(-) diff --git a/IDEHelper/Compiler/BfAst.h b/IDEHelper/Compiler/BfAst.h index 93fe73c1..19e0cc96 100644 --- a/IDEHelper/Compiler/BfAst.h +++ b/IDEHelper/Compiler/BfAst.h @@ -557,6 +557,7 @@ public: enum BfTypedValueKind { BfTypedValueKind_Addr, + BfTypedValueKind_CopyOnMutateAddr, BfTypedValueKind_ReadOnlyAddr, BfTypedValueKind_TempAddr, BfTypedValueKind_RestrictedTempAddr, @@ -674,6 +675,11 @@ public: return ((mKind == BfTypedValueKind_ReadOnlyTempAddr) || (mKind == BfTypedValueKind_RestrictedTempAddr) || (mKind == BfTypedValueKind_TempAddr)); } + bool IsCopyOnMutate() const + { + return (mKind == BfTypedValueKind_CopyOnMutateAddr); + } + bool IsReadOnly() const { switch (mKind) diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index d26f8470..c171aa4c 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -4573,6 +4573,9 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar target = BfTypedValue(allocaInst, primStructType, true); } + if (target.IsCopyOnMutate()) + target = mModule->CopyValue(target); + BfTypedValue targetValue; if ((isBaseLookup) && (!target.IsSplat())) { @@ -4848,12 +4851,8 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar } } - if (needsCopy) - { - result = mModule->LoadValue(result); - result = mModule->MakeAddressable(result); - result = mModule->RemoveReadOnly(result); - } + if (result.mKind == BfTypedValueKind_Addr) + result.mKind = BfTypedValueKind_CopyOnMutateAddr; mPropDef = NULL; mPropSrc = NULL; @@ -16978,8 +16977,11 @@ bool BfExprEvaluator::CheckIsBase(BfAstNode* checkNode) return true; } -bool BfExprEvaluator::CheckModifyResult(BfTypedValue typedVal, BfAstNode* refNode, const char* modifyType, bool onlyNeedsMut, bool emitWarning) +bool BfExprEvaluator::CheckModifyResult(BfTypedValue typedVal, BfAstNode* refNode, const char* modifyType, bool onlyNeedsMut, bool emitWarning, bool skipCopyOnMutate) { + if ((!skipCopyOnMutate) && (typedVal.IsCopyOnMutate())) + typedVal = mModule->CopyValue(typedVal); + BfLocalVariable* localVar = NULL; bool isCapturedLocal = false; if (mResultLocalVar != NULL) @@ -17581,11 +17583,11 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool } ResolveGenericType(); - auto ptr = mResult; + auto ptr = mResult; mResult = BfTypedValue(); if (mPropDef == NULL) { - if (!CheckModifyResult(ptr, assignExpr->mOpToken, "assign to")) + if (!CheckModifyResult(ptr, assignExpr->mOpToken, "assign to", false, false, true)) { if (assignExpr->mRight != NULL) mModule->CreateValueFromExpression(assignExpr->mRight, ptr.mType, BfEvalExprFlags_NoCast); diff --git a/IDEHelper/Compiler/BfExprEvaluator.h b/IDEHelper/Compiler/BfExprEvaluator.h index fd3af4f5..56d288c3 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.h +++ b/IDEHelper/Compiler/BfExprEvaluator.h @@ -414,7 +414,7 @@ public: void MarkResultAssigned(); void MakeResultAsValue(); bool CheckIsBase(BfAstNode* checkNode); - bool CheckModifyResult(BfTypedValue typeValue, BfAstNode* refNode, const char* modifyType, bool onlyNeedsMut = false, bool emitWarning = false); + bool CheckModifyResult(BfTypedValue typeValue, BfAstNode* refNode, const char* modifyType, bool onlyNeedsMut = false, bool emitWarning = false, bool skipCopyOnMutate = false); bool CheckGenericCtor(BfGenericParamType* genericParamType, BfResolvedArgs& argValues, BfAstNode* targetSrc); BfTypedValue LookupField(BfAstNode* targetSrc, BfTypedValue target, const StringImpl& fieldName, BfLookupFieldFlags flags = BfLookupFieldFlag_None); void CheckObjectCreateTypeRef(BfType* expectingType, BfAstNode* afterNode); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 4685784c..b50e5e5c 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -11754,7 +11754,7 @@ void BfModule::AggregateSplatIntoAddr(BfTypedValue typedValue, BfIRValue addrVal checkTypeLambda(typedValue.mType, addrVal); } -BfTypedValue BfModule::MakeAddressable(BfTypedValue typedVal) +BfTypedValue BfModule::MakeAddressable(BfTypedValue typedVal, bool forceMutable) { bool wasReadOnly = typedVal.IsReadOnly(); @@ -11775,6 +11775,9 @@ BfTypedValue BfModule::MakeAddressable(BfTypedValue typedVal) else mBfIRBuilder->CreateAlignedStore(typedVal.mValue, tempVar, type->mAlign); + if (forceMutable) + wasReadOnly = false; + return BfTypedValue(tempVar, type, typedVal.IsThis() ? (wasReadOnly ? BfTypedValueKind_ReadOnlyThisAddr : BfTypedValueKind_ThisAddr) : @@ -11790,6 +11793,11 @@ BfTypedValue BfModule::RemoveReadOnly(BfTypedValue typedValue) return typedValue; } +BfTypedValue BfModule::CopyValue(const BfTypedValue& typedValue) +{ + return MakeAddressable(LoadValue(typedValue), true); +} + BfIRValue BfModule::ExtractSplatValue(BfTypedValue typedValue, int componentIdx, BfType* wantType, bool* isAddr) { BF_ASSERT(!mIsComptimeModule); diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 727971f3..fe8d8e51 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1632,8 +1632,9 @@ public: BfTypedValue PrepareConst(BfTypedValue& typedValue); void AggregateSplatIntoAddr(BfTypedValue typedValue, BfIRValue addrVal); BfTypedValue AggregateSplat(BfTypedValue typedValue, BfIRValue* valueArrPtr = NULL); - BfTypedValue MakeAddressable(BfTypedValue typedValue); + BfTypedValue MakeAddressable(BfTypedValue typedValue, bool forceMutable = false); BfTypedValue RemoveReadOnly(BfTypedValue typedValue); + BfTypedValue CopyValue(const BfTypedValue& typedValue); BfIRValue ExtractSplatValue(BfTypedValue typedValue, int componentIdx, BfType* wantType = NULL, bool* isAddr = NULL); BfTypedValue ExtractValue(BfTypedValue typedValue, BfFieldInstance* fieldInst, int fieldIdx); BfIRValue ExtractValue(BfTypedValue typedValue, int dataIdx); @@ -1765,7 +1766,7 @@ public: BfMethodRefType* CreateMethodRefType(BfMethodInstance* methodInstance, bool mustAlreadyExist = false); BfType* FixIntUnknown(BfType* type); void FixIntUnknown(BfTypedValue& typedVal, BfType* matchType = NULL); - void FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs); + void FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs); void FixValueActualization(BfTypedValue& typedVal); bool TypeEquals(BfTypedValue& val, BfType* type); BfTypeDef* ResolveGenericInstanceDef(BfGenericInstanceTypeRef* genericTypeRef, BfType** outType = NULL, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None); diff --git a/IDEHelper/Tests/src/Properties.bf b/IDEHelper/Tests/src/Properties.bf index c412727e..6e7119b5 100644 --- a/IDEHelper/Tests/src/Properties.bf +++ b/IDEHelper/Tests/src/Properties.bf @@ -29,6 +29,7 @@ namespace Tests public this() { B = .(); + B.mA += 1000; } }