diff --git a/include/swift/SIL/SILBuilder.h b/include/swift/SIL/SILBuilder.h index d077680d40ba2..2369d62ba4f6e 100644 --- a/include/swift/SIL/SILBuilder.h +++ b/include/swift/SIL/SILBuilder.h @@ -551,6 +551,13 @@ class SILBuilder { PartialApplyInst::OnStackKind OnStack = PartialApplyInst::OnStackKind::NotOnStack, const GenericSpecializationInformation *SpecializationInfo = nullptr) { + assert(OnStack == PartialApplyInst::OnStackKind::OnStack || + llvm::all_of(Args, + [](SILValue value) { + return value->getOwnershipKind().isCompatibleWith( + OwnershipKind::Owned); + }) && + "Must have an owned compatible object"); return insert(PartialApplyInst::create( getSILDebugLocation(Loc), Fn, Args, Subs, CalleeConvention, *F, SpecializationInfo, OnStack)); @@ -900,6 +907,8 @@ class SILBuilder { EndBorrowInst *createEndBorrow(SILLocation loc, SILValue borrowedValue) { assert(!SILArgument::isTerminatorResult(borrowedValue) && "terminator results do not have end_borrow"); + assert(!isa(borrowedValue) && + "Function arguments should never have an end_borrow"); return insert(new (getModule()) EndBorrowInst(getSILDebugLocation(loc), borrowedValue)); } diff --git a/lib/SILGen/Cleanup.cpp b/lib/SILGen/Cleanup.cpp index cbd12e73e3647..af9b51ff822fa 100644 --- a/lib/SILGen/Cleanup.cpp +++ b/lib/SILGen/Cleanup.cpp @@ -401,7 +401,9 @@ ManagedValue CleanupCloner::clone(SILValue value) const { } if (!hasCleanup) { - return ManagedValue::forUnmanaged(value); + if (value->getOwnershipKind().isCompatibleWith(OwnershipKind::Owned)) + return ManagedValue::forUnmanagedOwnedValue(value); + return ManagedValue::forBorrowedRValue(value); } if (writebackBuffer.has_value()) { @@ -436,19 +438,19 @@ CleanupCloner::cloneForTuplePackExpansionComponent(SILValue tupleAddr, } if (!hasCleanup) { - return ManagedValue::forUnmanaged(tupleAddr); + return ManagedValue::forBorrowedAddressRValue(tupleAddr); } assert(!writebackBuffer.has_value()); auto expansionTy = tupleAddr->getType().getTupleElementType(componentIndex); if (expansionTy.getPackExpansionPatternType().isTrivial(SGF.F)) - return ManagedValue::forUnmanaged(tupleAddr); + return ManagedValue::forTrivialAddressRValue(tupleAddr); auto cleanup = SGF.enterPartialDestroyRemainingTupleCleanup(tupleAddr, inducedPackType, componentIndex, /*start at */ SILValue()); - return ManagedValue(tupleAddr, cleanup); + return ManagedValue::forOwnedAddressRValue(tupleAddr, cleanup); } ManagedValue @@ -460,19 +462,19 @@ CleanupCloner::cloneForPackPackExpansionComponent(SILValue packAddr, } if (!hasCleanup) { - return ManagedValue::forUnmanaged(packAddr); + return ManagedValue::forBorrowedAddressRValue(packAddr); } assert(!writebackBuffer.has_value()); auto expansionTy = packAddr->getType().getPackElementType(componentIndex); if (expansionTy.getPackExpansionPatternType().isTrivial(SGF.F)) - return ManagedValue::forUnmanaged(packAddr); + return ManagedValue::forTrivialAddressRValue(packAddr); auto cleanup = SGF.enterPartialDestroyRemainingPackCleanup(packAddr, formalPackType, componentIndex, /*start at */ SILValue()); - return ManagedValue(packAddr, cleanup); + return ManagedValue::forOwnedAddressRValue(packAddr, cleanup); } ManagedValue @@ -484,7 +486,7 @@ CleanupCloner::cloneForRemainingPackComponents(SILValue packAddr, } if (!hasCleanup) { - return ManagedValue::forUnmanaged(packAddr); + return ManagedValue::forBorrowedAddressRValue(packAddr); } assert(!writebackBuffer.has_value()); @@ -498,12 +500,12 @@ CleanupCloner::cloneForRemainingPackComponents(SILValue packAddr, } if (isTrivial) - return ManagedValue::forUnmanaged(packAddr); + return ManagedValue::forTrivialAddressRValue(packAddr); auto cleanup = SGF.enterDestroyRemainingPackComponentsCleanup(packAddr, formalPackType, firstComponentIndex); - return ManagedValue(packAddr, cleanup); + return ManagedValue::forOwnedAddressRValue(packAddr, cleanup); } ManagedValue @@ -515,7 +517,7 @@ CleanupCloner::cloneForRemainingTupleComponents(SILValue tupleAddr, } if (!hasCleanup) { - return ManagedValue::forUnmanaged(tupleAddr); + return ManagedValue::forBorrowedAddressRValue(tupleAddr); } assert(!writebackBuffer.has_value()); @@ -529,11 +531,11 @@ CleanupCloner::cloneForRemainingTupleComponents(SILValue tupleAddr, } if (isTrivial) - return ManagedValue::forUnmanaged(tupleAddr); + return ManagedValue::forTrivialAddressRValue(tupleAddr); auto cleanup = SGF.enterDestroyRemainingTupleElementsCleanup(tupleAddr, inducedPackType, firstComponentIndex); - return ManagedValue(tupleAddr, cleanup); + return ManagedValue::forOwnedAddressRValue(tupleAddr, cleanup); } diff --git a/lib/SILGen/Initialization.h b/lib/SILGen/Initialization.h index a944dd96e2b9b..3da73dbf72aae 100644 --- a/lib/SILGen/Initialization.h +++ b/lib/SILGen/Initialization.h @@ -323,7 +323,8 @@ class TemporaryInitialization : public SingleBufferInitialization { CleanupHandle getInitializedCleanup() const { return Cleanup; } ManagedValue getManagedAddress() const { - return ManagedValue(getAddress(), getInitializedCleanup()); + return ManagedValue::forOwnedAddressRValue(getAddress(), + getInitializedCleanup()); } }; diff --git a/lib/SILGen/ManagedValue.h b/lib/SILGen/ManagedValue.h index c5229ae461eee..4fcdc50d8c11f 100644 --- a/lib/SILGen/ManagedValue.h +++ b/lib/SILGen/ManagedValue.h @@ -66,16 +66,22 @@ class ManagedValue { : valueAndFlag(value, isLValue), cleanup(cleanup) { } -public: - - ManagedValue() = default; + /// Create a managed value for a +0 rvalue. + /// + /// Please do not introduce new uses of this method! Instead use one of the + /// static constructors below! + static ManagedValue forUnmanaged(SILValue value) { + assert(value && "No value specified"); + return ManagedValue(value, false, CleanupHandle::invalid()); + } /// Create a managed value for a +1 rvalue. /// /// Please do not introduce new uses of this method! Instead use one of the /// static constructors below. - ManagedValue(SILValue value, CleanupHandle cleanup) - : valueAndFlag(value, false), cleanup(cleanup) { + explicit ManagedValue(SILValue value, + CleanupHandle cleanup = CleanupHandle::invalid()) + : valueAndFlag(value, false), cleanup(cleanup) { assert(value && "No value specified?!"); assert((!getType().isObject() || value->getOwnershipKind() != OwnershipKind::None || @@ -83,13 +89,32 @@ class ManagedValue { "Objects with trivial ownership should never have a cleanup"); } - /// Create a managed value for a +0 rvalue. +public: + ManagedValue() = default; + + /// Sometimes SILGen wants to represent an owned value or owned address + /// without a cleanup as a +0 value that must be copied to be consumed. /// - /// Please do not introduce new uses of this method! Instead use one of the - /// static constructors below! - static ManagedValue forUnmanaged(SILValue value) { - assert(value && "No value specified"); - return ManagedValue(value, false, CleanupHandle::invalid()); + /// Please do not introduce new uses of this. + /// + /// DISCUSSION: We purposely provide a specific API for code paths that use + /// owned values (and assert the values are owned) so that users do not + /// attempt to use this for borrowed values. All borrowed values need to use + /// the borrowed value APIs. + static ManagedValue forUnmanagedOwnedValue(SILValue value) { + assert(value); + assert(!value->getType().isObject() || + value->getOwnershipKind().isCompatibleWith(OwnershipKind::Owned)); + return ManagedValue(value); + } + + /// Wrap a value with OwnershipKind::Unowned in a ManagedValue. This must be + /// copied before it is used. + static ManagedValue forUnownedObjectValue(SILValue value) { + assert(value); + assert(value->getType().isObject()); + assert(value->getOwnershipKind().isCompatibleWith(OwnershipKind::Unowned)); + return ManagedValue(value); } enum class ScopeKind { @@ -97,19 +122,6 @@ class ManagedValue { FormalAccess, }; - /// Given a value \p value, create a copy of it and return the relevant - /// ManagedValue. - static ManagedValue forCopyOwnedObjectRValue(SILGenFunction &SGF, - SILLocation loc, SILValue value, - ScopeKind kind) { - assert(value && "No value specified"); - assert(value->getType().isObject()); - auto mv = ManagedValue::forUnmanaged(value); - if (kind == ScopeKind::Lexical) - return mv.copy(SGF, loc); - return mv.formalAccessCopy(SGF, loc); - } - /// Create a managed value for a SILValue whose ownership is /// forwarded. Creates a new cleanup for +1 values. Forwarded +0 values /// require no cleanup. @@ -160,7 +172,10 @@ class ManagedValue { assert(value && "No value specified"); assert(value->getType().isObject() && "Expected borrowed rvalues to be objects"); - assert(value->getOwnershipKind() != OwnershipKind::None); + if (value->getOwnershipKind() == OwnershipKind::None) { + return forObjectRValueWithoutOwnership(value); + } + assert(value->getOwnershipKind() == OwnershipKind::Guaranteed); return ManagedValue(value, false, CleanupHandle::invalid()); } @@ -169,6 +184,13 @@ class ManagedValue { forBorrowedAddressRValue(SILValue value) { assert(value && "No value specified"); assert(value->getType().isAddress() && "Expected value to be an address"); + // We check for value->getFunction() here since we /could/ be passed + // SILUndef here. + if (auto *f = value->getFunction()) { + if (value->getType().isTrivial(f)) { + return forTrivialAddressRValue(value); + } + } assert(value->getOwnershipKind() == OwnershipKind::None && "Addresses always have trivial ownership"); return ManagedValue(value, false, CleanupHandle::invalid()); @@ -193,6 +215,16 @@ class ManagedValue { static ManagedValue forTrivialAddressRValue(SILValue value) { assert(value->getType().isAddress() && "Expected an address"); assert(value->getOwnershipKind() == OwnershipKind::None); + + // TODO: Add an assert that we have a trivial type here. + // + // DISCUSSION: We cannot do this today since we have problems along certain + // materialization paths where we want to emit a borrow operation. To handle + // those cases, we have loosened the rules of OSSA by allowing for store + // [trivial] to take non-trivial .none parameters. This has hidden bugs + // where SILGen emits a borrow to materialize a parameter for an @in + // parameter. It just coincidently works since when we emit the + // store_borrow, we use the store [trivial] instead. This should be fixed. return ManagedValue(value, false, CleanupHandle::invalid()); } @@ -476,8 +508,8 @@ class ConsumableManagedValue { /// /// You probably should not be using this; it's here to make it easy /// to find code that is probably wrong. - ManagedValue asUnmanagedValue() const { - return ManagedValue::forUnmanaged(Value.getValue()); + ManagedValue asUnmanagedOwnedValue() const { + return ManagedValue::forUnmanagedOwnedValue(Value.getValue()); } /// Return the consumption rules appropriate for the final use of @@ -489,15 +521,19 @@ class ConsumableManagedValue { ConsumableManagedValue asBorrowedOperand(SILGenFunction &SGF, SILLocation loc) const { if (getType().isAddress()) - return {asUnmanagedValue(), CastConsumptionKind::CopyOnSuccess}; - return {asUnmanagedValue().borrow(SGF, loc), + return {asUnmanagedOwnedValue(), CastConsumptionKind::CopyOnSuccess}; + + if (Value.getOwnershipKind() == OwnershipKind::Guaranteed) + return {Value, CastConsumptionKind::BorrowAlways}; + + return {asUnmanagedOwnedValue().borrow(SGF, loc), CastConsumptionKind::BorrowAlways}; } /// Return a managed value that's appropriate for copying this value and /// always consuming it. ConsumableManagedValue copy(SILGenFunction &SGF, SILLocation loc) const { - return ConsumableManagedValue::forOwned(asUnmanagedValue().copy(SGF, loc)); + return ConsumableManagedValue::forOwned(Value.copy(SGF, loc)); } }; diff --git a/lib/SILGen/ResultPlan.cpp b/lib/SILGen/ResultPlan.cpp index a25ec5f923d02..397cadc780ac0 100644 --- a/lib/SILGen/ResultPlan.cpp +++ b/lib/SILGen/ResultPlan.cpp @@ -810,11 +810,13 @@ class ForeignAsyncInitializationPlan final : public ResultPlan { if (handlerIsOptional) { block = SGF.B.createOptionalSome(loc, block, impTy); } - + // We don't need to manage the block because it's still on the stack. We // know we won't escape it locally so the callee can be responsible for // _Block_copy-ing it. - return ManagedValue::forUnmanaged(block); + // + // InitBlockStorageHeader always has Unowned ownership. + return ManagedValue::forUnownedObjectValue(block); } void deferExecutorBreadcrumb(ExecutorBreadcrumb &&crumb) override { @@ -899,9 +901,9 @@ class ForeignAsyncInitializationPlan final : public ResultPlan { SILValue(wrappedContinuation)); SGF.emitApplyOfLibraryIntrinsic( loc, errorIntrinsic, subs, - {continuationMV, ManagedValue::forCopyOwnedObjectRValue( - SGF, loc, bridgedForeignError, - ManagedValue::ScopeKind::Lexical)}, + {continuationMV, + SGF.B.copyOwnedObjectRValue(loc, bridgedForeignError, + ManagedValue::ScopeKind::Lexical)}, SGFContext()); // Second, emit a branch from the end of the foreign error block to the diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp index 859c811cbfcdb..f5add11f01df6 100644 --- a/lib/SILGen/SILGenApply.cpp +++ b/lib/SILGen/SILGenApply.cpp @@ -1360,12 +1360,13 @@ class SILGenApply : public Lowering::ExprVisitor { // we installed. Install a new special cleanup. if (superMV.getValue() != SGF.InitDelegationSelf.getValue()) { SILValue underlyingSelf = SGF.InitDelegationSelf.getValue(); - SGF.InitDelegationSelf = ManagedValue::forUnmanaged(underlyingSelf); + SGF.InitDelegationSelf = + ManagedValue::forUnmanagedOwnedValue(underlyingSelf); CleanupHandle newWriteback = SGF.enterOwnedValueWritebackCleanup( SGF.InitDelegationLoc.value(), SGF.InitDelegationSelfBox, superMV.forward(SGF)); - SGF.SuperInitDelegationSelf = - ManagedValue(superMV.getValue(), newWriteback); + SGF.SuperInitDelegationSelf = ManagedValue::forOwnedObjectRValue( + superMV.getValue(), newWriteback); super = RValue(SGF, SGF.InitDelegationLoc.value(), superFormalType, SGF.SuperInitDelegationSelf); } @@ -4328,7 +4329,7 @@ static void emitBorrowedLValueRecursive(SILGenFunction &SGF, value = SGF.B.createFormalAccessLoadCopy(loc, value); // Strip off the cleanup from the load [copy] since we do not want the // cleanup to be forwarded. - value = ManagedValue::forUnmanaged(value.getValue()); + value = ManagedValue::forUnmanagedOwnedValue(value.getValue()); } else { value = SGF.B.createFormalAccessLoadBorrow(loc, value); } @@ -4507,7 +4508,7 @@ class BoxInitialization : public SingleBufferInitialization { } ManagedValue getManagedBox() const { - return ManagedValue(box, initCleanup); + return ManagedValue::forOwnedObjectRValue(box, initCleanup); } }; @@ -6224,7 +6225,7 @@ void SILGenFunction::emitUninitializedArrayDeallocation(SILLocation loc, auto subMap = arrayTy->getContextSubstitutionMap(SGM.M.getSwiftModule(), Ctx.getArrayDecl()); emitApplyOfLibraryIntrinsic(loc, deallocate, subMap, - ManagedValue::forUnmanaged(array), + ManagedValue::forUnmanagedOwnedValue(array), SGFContext()); } @@ -6247,9 +6248,9 @@ ManagedValue SILGenFunction::emitUninitializedArrayFinalization(SILLocation loc, // Invoke the intrinsic. auto subMap = arrayTy->getContextSubstitutionMap(SGM.M.getSwiftModule(), Ctx.getArrayDecl()); - RValue result = emitApplyOfLibraryIntrinsic(loc, finalize, subMap, - ManagedValue::forUnmanaged(arrayVal), - SGFContext()); + RValue result = emitApplyOfLibraryIntrinsic( + loc, finalize, subMap, ManagedValue::forUnmanagedOwnedValue(arrayVal), + SGFContext()); return std::move(result).getScalarValue(); } diff --git a/lib/SILGen/SILGenBackDeploy.cpp b/lib/SILGen/SILGenBackDeploy.cpp index cf6ff21728108..402cbeba4770e 100644 --- a/lib/SILGen/SILGenBackDeploy.cpp +++ b/lib/SILGen/SILGenBackDeploy.cpp @@ -143,9 +143,9 @@ static void emitBackDeployForwardApplyAndReturnOrThrow( // Emit error block. SGF.B.emitBlock(errorBB); - SILValue error = errorBB->createPhiArgument( - SGF.F.mapTypeIntoContext(fnConv.getSILErrorType(TEC)), - OwnershipKind::Owned); + ManagedValue error = + SGF.B.createPhi(SGF.F.mapTypeIntoContext(fnConv.getSILErrorType(TEC)), + OwnershipKind::Owned); SGF.B.createBranch(loc, SGF.ThrowDest.getBlock(), {error}); // Emit normal block. diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp index 2c99b9ee7e38e..f11bc67422be3 100644 --- a/lib/SILGen/SILGenBridging.cpp +++ b/lib/SILGen/SILGenBridging.cpp @@ -308,20 +308,21 @@ static ManagedValue emitManagedParameter(SILGenFunction &SGF, SILLocation loc, case ParameterConvention::Direct_Guaranteed: // If we have a guaranteed parameter, the object should not need to be // retained or have a cleanup. - return ManagedValue::forUnmanaged(value); + return ManagedValue::forBorrowedObjectRValue(value); case ParameterConvention::Direct_Unowned: // We need to independently retain the value. - return SGF.emitManagedRetain(loc, value, valueTL); + return SGF.emitManagedCopy(loc, value, valueTL); case ParameterConvention::Indirect_Inout: return ManagedValue::forLValue(value); case ParameterConvention::Indirect_In_Guaranteed: if (valueTL.isLoadable()) { - return SGF.B.createLoadBorrow(loc, ManagedValue::forUnmanaged(value)); + return SGF.B.createLoadBorrow( + loc, ManagedValue::forBorrowedAddressRValue(value)); } else { - return ManagedValue::forUnmanaged(value); + return ManagedValue::forBorrowedAddressRValue(value); } case ParameterConvention::Indirect_In: @@ -904,7 +905,7 @@ static void buildBlockToFuncThunkBody(SILGenFunction &SGF, // Add the block argument. SILValue blockV = entry->createFunctionArgument(SILType::getPrimitiveObjectType(blockTy)); - ManagedValue block = ManagedValue::forUnmanaged(blockV); + ManagedValue block = ManagedValue::forBorrowedObjectRValue(blockV); CanType formalResultType = formalFuncTy.getResult(); @@ -1098,7 +1099,7 @@ static ManagedValue emitCBridgedToNativeValue( // when they are converted to an object via objc_metatype_to_object. assert(!v.hasCleanup() && "Metatypes are trivial and should not have " "cleanups"); - return ManagedValue::forUnmanaged(native); + return ManagedValue::forUnmanagedOwnedValue(native); } } @@ -2180,7 +2181,7 @@ void SILGenFunction::emitForeignToNativeThunk(SILDeclRef thunk) { break; case ParameterConvention::Direct_Guaranteed: case ParameterConvention::Direct_Unowned: - param = emitManagedRetain(fd, paramValue); + param = emitManagedCopy(fd, paramValue); break; case ParameterConvention::Indirect_Inout: case ParameterConvention::Indirect_InoutAliasable: diff --git a/lib/SILGen/SILGenBuilder.cpp b/lib/SILGen/SILGenBuilder.cpp index 92533cd42940f..52aea2c1279d5 100644 --- a/lib/SILGen/SILGenBuilder.cpp +++ b/lib/SILGen/SILGenBuilder.cpp @@ -137,7 +137,7 @@ ManagedValue SILGenBuilder::createStructExtract(SILLocation loc, VarDecl *decl) { ManagedValue borrowedBase = base.formalAccessBorrow(SGF, loc); SILValue extract = createStructExtract(loc, borrowedBase.getValue(), decl); - return ManagedValue::forUnmanaged(extract); + return ManagedValue::forBorrowedRValue(extract); } ManagedValue SILGenBuilder::createRefElementAddr(SILLocation loc, @@ -146,7 +146,7 @@ ManagedValue SILGenBuilder::createRefElementAddr(SILLocation loc, SILType resultTy) { operand = operand.formalAccessBorrow(SGF, loc); SILValue result = createRefElementAddr(loc, operand.getValue(), field); - return ManagedValue::forUnmanaged(result); + return ManagedValue::forBorrowedRValue(result); } ManagedValue SILGenBuilder::createCopyValue(SILLocation loc, @@ -249,7 +249,7 @@ ManagedValue SILGenBuilder::createPhi(SILType type, return ManagedValue::forObjectRValueWithoutOwnership(arg); case OwnershipKind::Unowned: - return ManagedValue::forUnmanaged(arg); + return ManagedValue::forUnownedObjectValue(arg); } } @@ -292,7 +292,7 @@ ManagedValue SILGenBuilder::createTupleExtract(SILLocation loc, ManagedValue borrowedBase = SGF.emitManagedBeginBorrow(loc, base.getValue()); SILValue extract = createTupleExtract(loc, borrowedBase.getValue(), index, type); - return ManagedValue::forUnmanaged(extract); + return ManagedValue::forBorrowedRValue(extract); } ManagedValue SILGenBuilder::createTupleExtract(SILLocation loc, @@ -306,7 +306,7 @@ ManagedValue SILGenBuilder::createLoadBorrow(SILLocation loc, ManagedValue base) { if (SGF.getTypeLowering(base.getType()).isTrivial()) { auto *i = createLoad(loc, base.getValue(), LoadOwnershipQualifier::Trivial); - return ManagedValue::forUnmanaged(i); + return ManagedValue::forBorrowedRValue(i); } auto *i = createLoadBorrow(loc, base.getValue()); @@ -317,7 +317,7 @@ ManagedValue SILGenBuilder::createFormalAccessLoadBorrow(SILLocation loc, ManagedValue base) { if (SGF.getTypeLowering(base.getType()).isTrivial()) { auto *i = createLoad(loc, base.getValue(), LoadOwnershipQualifier::Trivial); - return ManagedValue::forUnmanaged(i); + return ManagedValue::forBorrowedRValue(i); } SILValue baseValue = base.getValue(); @@ -531,15 +531,15 @@ static ManagedValue createInputFunctionArgument( case SILArgumentConvention::Direct_Guaranteed: case SILArgumentConvention::Pack_Guaranteed: // Guaranteed parameters are passed at +0. - return ManagedValue::forUnmanaged(arg); + return ManagedValue::forBorrowedRValue(arg); case SILArgumentConvention::Direct_Unowned: // Unowned parameters are only guaranteed at the instant of the call, so we // must retain them even if we're in a context that can accept a +0 value. // // NOTE: If we have a trivial value, the copy will do nothing, so this is // just a convenient way to avoid writing conditional code. - return ManagedValue::forCopyOwnedObjectRValue( - SGF, loc, arg, ManagedValue::ScopeKind::Lexical); + return SGF.B.copyOwnedObjectRValue(loc, arg, + ManagedValue::ScopeKind::Lexical); case SILArgumentConvention::Direct_Owned: return SGF.emitManagedRValueWithCleanup(arg); @@ -659,7 +659,7 @@ ManagedValue SILGenBuilder::createOptionalSome(SILLocation loc, SGF.emitInjectOptionalValueInto( loc, std::move(argValue), tempResult, SGF.getTypeLowering(tempResult->getType())); - return ManagedValue::forUnmanaged(tempResult); + return ManagedValue::forBorrowedAddressRValue(tempResult); } ManagedValue SILGenBuilder::createManagedOptionalNone(SILLocation loc, @@ -688,7 +688,7 @@ ManagedValue SILGenBuilder::createTupleElementAddr(SILLocation Loc, SILType Type) { SILValue TupleEltAddr = createTupleElementAddr(Loc, Base.getValue(), Index, Type); - return ManagedValue::forUnmanaged(TupleEltAddr); + return ManagedValue::forBorrowedAddressRValue(TupleEltAddr); } ManagedValue SILGenBuilder::createTupleElementAddr(SILLocation Loc, @@ -729,8 +729,8 @@ ManagedValue SILGenBuilder::createUncheckedBitCast(SILLocation loc, // identity implying that we need a copy of the casted value to be returned so // that the inputs/outputs of the case have separate ownership. if (isa(cast)) { - return ManagedValue::forCopyOwnedObjectRValue( - SGF, loc, cast, ManagedValue::ScopeKind::Lexical); + return SGF.B.copyOwnedObjectRValue(loc, cast, + ManagedValue::ScopeKind::Lexical); } // Otherwise, we forward the cleanup of the input value and place the cleanup @@ -754,7 +754,7 @@ ManagedValue SILGenBuilder::createOpenExistentialValue(SILLocation loc, ManagedValue borrowedExistential = original.formalAccessBorrow(SGF, loc); SILValue openedExistential = createOpenExistentialValue(loc, borrowedExistential.getValue(), type); - return ManagedValue::forUnmanaged(openedExistential); + return ManagedValue::forBorrowedObjectRValue(openedExistential); } ManagedValue SILGenBuilder::createOpenExistentialBoxValue(SILLocation loc, @@ -763,7 +763,7 @@ ManagedValue SILGenBuilder::createOpenExistentialBoxValue(SILLocation loc, ManagedValue borrowedExistential = original.formalAccessBorrow(SGF, loc); SILValue openedExistential = createOpenExistentialBoxValue(loc, borrowedExistential.getValue(), type); - return ManagedValue::forUnmanaged(openedExistential); + return ManagedValue::forBorrowedObjectRValue(openedExistential); } ManagedValue SILGenBuilder::createOpenExistentialBox(SILLocation loc, @@ -772,7 +772,7 @@ ManagedValue SILGenBuilder::createOpenExistentialBox(SILLocation loc, ManagedValue borrowedExistential = original.formalAccessBorrow(SGF, loc); SILValue openedExistentialAddr = createOpenExistentialBox(loc, borrowedExistential.getValue(), type); - return ManagedValue::forUnmanaged(openedExistentialAddr); + return ManagedValue::forBorrowedAddressRValue(openedExistentialAddr); } ManagedValue SILGenBuilder::createOpenExistentialMetatype(SILLocation loc, @@ -822,7 +822,7 @@ ManagedValue SILGenBuilder::createStoreBorrow(SILLocation loc, assert(value.getOwnershipKind() == OwnershipKind::Guaranteed); auto *sbi = createStoreBorrow(loc, value.getValue(), address); SGF.Cleanups.pushCleanup(sbi); - return ManagedValue(sbi, CleanupHandle::invalid()); + return ManagedValue::forBorrowedAddressRValue(sbi); } ManagedValue SILGenBuilder::createFormalAccessStoreBorrow(SILLocation loc, @@ -839,7 +839,7 @@ ManagedValue SILGenBuilder::createStoreBorrowOrTrivial(SILLocation loc, SILValue address) { if (value.getOwnershipKind() == OwnershipKind::None) { createStore(loc, value, address, StoreOwnershipQualifier::Trivial); - return ManagedValue(address, CleanupHandle::invalid()); + return ManagedValue::forTrivialAddressRValue(address); } return createStoreBorrow(loc, value, address); @@ -1002,7 +1002,7 @@ void SILGenBuilder::emitDestructureAddressOperation( ManagedValue SILGenBuilder::createProjectBox(SILLocation loc, ManagedValue mv, unsigned index) { auto *pbi = createProjectBox(loc, mv.getValue(), index); - return ManagedValue::forUnmanaged(pbi); + return ManagedValue::forBorrowedAddressRValue(pbi); } ManagedValue SILGenBuilder::createMarkDependence(SILLocation loc, @@ -1020,7 +1020,7 @@ ManagedValue SILGenBuilder::createBeginBorrow(SILLocation loc, auto *newValue = SILBuilder::createBeginBorrow(loc, value.getValue(), isLexical); SGF.emitManagedBorrowedRValueWithCleanup(newValue); - return ManagedValue::forUnmanaged(newValue); + return ManagedValue::forBorrowedObjectRValue(newValue); } ManagedValue SILGenBuilder::createMoveValue(SILLocation loc, ManagedValue value, @@ -1047,7 +1047,7 @@ ManagedValue SILGenBuilder::createGuaranteedMoveOnlyWrapperToCopyableValue( auto *mdi = createGuaranteedMoveOnlyWrapperToCopyableValue(loc, value.getValue()); assert(mdi->getOperand()->getType().isObject() && "Expected an object?!"); - return ManagedValue::forUnmanaged(mdi); + return ManagedValue::forBorrowedObjectRValue(mdi); } ManagedValue @@ -1065,7 +1065,7 @@ ManagedValue SILGenBuilder::createGuaranteedCopyableToMoveOnlyWrapperValue( auto *mdi = createGuaranteedCopyableToMoveOnlyWrapperValue(loc, value.getValue()); assert(mdi->getOperand()->getType().isObject() && "Expected an object?!"); - return ManagedValue::forUnmanaged(mdi); + return ManagedValue::forBorrowedObjectRValue(mdi); } ManagedValue @@ -1101,3 +1101,25 @@ ManagedValue SILGenBuilder::createExplicitCopyValue(SILLocation loc, auto cvi = SILBuilder::createExplicitCopyValue(loc, operand.getValue()); return SGF.emitManagedRValueWithCleanup(cvi); } + +ManagedValue +SILGenBuilder::copyOwnedObjectRValue(SILLocation loc, SILValue value, + ManagedValue::ScopeKind kind) { + assert(value && "No value specified"); + assert(value->getType().isObject()); + if (kind == ManagedValue::ScopeKind::Lexical) { + return SGF.emitManagedCopy(loc, value); + } + return SGF.emitManagedFormalEvaluationCopy(loc, value); +} + +ManagedValue SILGenBuilder::borrowObjectRValue(SILGenFunction &SGF, + SILLocation loc, SILValue value, + ManagedValue::ScopeKind kind) { + assert(value && "No value specified"); + assert(value->getType().isObject()); + if (kind == ManagedValue::ScopeKind::Lexical) { + return SGF.emitManagedBeginBorrow(loc, value); + } + return SGF.emitFormalEvaluationManagedBeginBorrow(loc, value); +} diff --git a/lib/SILGen/SILGenBuilder.h b/lib/SILGen/SILGenBuilder.h index 2891f7cc689e2..e1f3a4df2a473 100644 --- a/lib/SILGen/SILGenBuilder.h +++ b/lib/SILGen/SILGenBuilder.h @@ -64,6 +64,14 @@ class SILGenBuilder : public SILBuilder { SILGenModule &getSILGenModule() const; SILGenFunction &getSILGenFunction() const { return SGF; } + /// Given a value \p value, create a copy of it and return the relevant + /// ManagedValue. + ManagedValue copyOwnedObjectRValue(SILLocation loc, SILValue value, + ManagedValue::ScopeKind kind); + + ManagedValue borrowObjectRValue(SILGenFunction &SGF, SILLocation loc, + SILValue value, ManagedValue::ScopeKind kind); + SILDebugLocation getSILDebugLocation(SILLocation Loc, bool ForMetaInstruction = false) override; @@ -489,6 +497,11 @@ class SILGenBuilder : public SILBuilder { void emitCopyAddrOperation(SILLocation loc, SILValue srcAddr, SILValue destAddr, IsTake_t isTake, IsInitialization_t isInitialize); + + using SILBuilder::createEndLifetime; + void createEndLifetime(SILLocation loc, ManagedValue selfValue) { + createEndLifetime(loc, selfValue.forward(SGF)); + } }; } // namespace Lowering diff --git a/lib/SILGen/SILGenBuiltin.cpp b/lib/SILGen/SILGenBuiltin.cpp index d3b3833aef385..2dbcde3be080a 100644 --- a/lib/SILGen/SILGenBuiltin.cpp +++ b/lib/SILGen/SILGenBuiltin.cpp @@ -406,7 +406,7 @@ static ManagedValue emitBuiltinBridgeFromRawPointer(SILGenFunction &SGF, SILValue result = SGF.B.createRawPointerToRef(loc, args[0].getUnmanagedValue(), destType); // The result has ownership semantics, so retain it with a cleanup. - return SGF.emitManagedRetain(loc, result, destLowering); + return SGF.emitManagedCopy(loc, result, destLowering); } static ManagedValue emitBuiltinAddressOfBuiltins(SILGenFunction &SGF, @@ -486,7 +486,7 @@ static ManagedValue emitBuiltinAddressOfBorrowBuiltins(SILGenFunction &SGF, : context.getIdentifier("unprotectedAddressOfBorrowOpaque"); auto builtin = SGF.B.createBuiltin(loc, identifier, rawPointerType, substitutions, {borrow.getValue()}); - return ManagedValue::forUnmanaged(builtin); + return ManagedValue::forObjectRValueWithoutOwnership(builtin); } if (!borrow.isPlusZero() || !borrow.getType().isAddress()) { @@ -799,7 +799,7 @@ static ManagedValue emitBuiltinReinterpretCast(SILGenFunction &SGF, } // Leave the cleanup on the original value. if (toTL.isTrivial()) - return ManagedValue::forUnmanaged(toAddr); + return ManagedValue::forTrivialAddressRValue(toAddr); // Initialize the +1 result buffer without taking the incoming value. The // source and destination cleanups will be independent. @@ -924,7 +924,7 @@ static ManagedValue emitBuiltinValueToBridgeObject(SILGenFunction &SGF, } SILValue result = SGF.B.createValueToBridgeObject(loc, args[0].getValue()); - return SGF.emitManagedRetain(loc, result); + return SGF.emitManagedCopy(loc, result); } // This should only accept as an operand type single-refcounted-pointer types, diff --git a/lib/SILGen/SILGenConstructor.cpp b/lib/SILGen/SILGenConstructor.cpp index 922b4e5ea9113..89372fcee1867 100644 --- a/lib/SILGen/SILGenConstructor.cpp +++ b/lib/SILGen/SILGenConstructor.cpp @@ -86,7 +86,7 @@ static ManagedValue emitManagedParameter(SILGenFunction &SGF, if (isOwned) { return SGF.emitManagedRValueWithCleanup(value); } else { - return ManagedValue::forUnmanaged(value); + return ManagedValue::forBorrowedRValue(value); } } @@ -1272,7 +1272,7 @@ void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) { // method. if (NeedsBoxForSelf) { ManagedValue storedSelf = - ManagedValue::forUnmanaged(VarLocs[selfDecl].value); + ManagedValue::forBorrowedAddressRValue(VarLocs[selfDecl].value); selfArg = B.createLoadCopy(cleanupLoc, storedSelf); } else { // We have to do a retain because we are returning the pointer +1. @@ -1504,7 +1504,7 @@ void SILGenFunction::emitMemberInitializationViaInitAccessor( SILAccessEnforcement::Unknown, /*noNestedConflict=*/false, /*fromBuiltin=*/false); - selfRef = ManagedValue::forUnmanaged(accessToSelf); + selfRef = ManagedValue::forBorrowedAddressRValue(accessToSelf); } emitAssignOrInit(loc, selfRef, var, diff --git a/lib/SILGen/SILGenConvert.cpp b/lib/SILGen/SILGenConvert.cpp index e25a1b1f15f46..0b3d285347036 100644 --- a/lib/SILGen/SILGenConvert.cpp +++ b/lib/SILGen/SILGenConvert.cpp @@ -262,7 +262,7 @@ SILGenFunction::emitPreconditionOptionalHasValue(SILLocation loc, return ManagedValue::forLValue(result.forward(*this)); } - return ManagedValue::forUnmanaged(result.forward(*this)); + return ManagedValue::forBorrowedRValue(result.forward(*this)); } SILValue SILGenFunction::emitDoesOptionalHaveValue(SILLocation loc, @@ -959,7 +959,7 @@ SILGenFunction::emitOpenExistential( SILValue archetypeValue = B.createOpenExistentialAddr(loc, existentialValue.getValue(), loweredOpenedType, allowedAccess); - return ManagedValue::forUnmanaged(archetypeValue); + return ManagedValue::forBorrowedAddressRValue(archetypeValue); } else { // borrow the existential and return an unmanaged opened value. return B.createOpenExistentialValue( diff --git a/lib/SILGen/SILGenDecl.cpp b/lib/SILGen/SILGenDecl.cpp index fe83addaf14bc..eaf3cfd596247 100644 --- a/lib/SILGen/SILGenDecl.cpp +++ b/lib/SILGen/SILGenDecl.cpp @@ -100,7 +100,12 @@ static void copyOrInitPackExpansionInto(SILGenFunction &SGF, formalPackType, componentIndex, indexWithinComponent); } - auto eltMV = ManagedValue(elt, eltCleanup); + ManagedValue eltMV; + if (eltCleanup == CleanupHandle::invalid()) { + eltMV = ManagedValue::forRValueWithoutOwnership(elt); + } else { + eltMV = ManagedValue::forOwnedRValue(elt, eltCleanup); + } // Perform the initialization. If this doesn't consume the // element value, that's fine, we'll just destroy it as part of @@ -1190,7 +1195,8 @@ void EnumElementPatternInitialization::emitEnumMatch( UnenforcedAccess access; SILValue accessAddress = access.beginAccess( SGF, loc, boxedValue.getValue(), SILAccessKind::Read); - auto mvAccessAddress = ManagedValue::forUnmanaged(accessAddress); + auto mvAccessAddress = + ManagedValue::forBorrowedAddressRValue(accessAddress); { Scope loadScope(SGF, loc); ManagedValue borrowedVal = @@ -1850,7 +1856,7 @@ class EndLifetimeCleanup : public Cleanup { ManagedValue SILGenFunction::emitManagedRValueWithEndLifetimeCleanup( SILValue value) { Cleanups.pushCleanup(value); - return ManagedValue::forUnmanaged(value); + return ManagedValue::forUnmanagedOwnedValue(value); } namespace { @@ -2072,13 +2078,13 @@ SILGenFunction::emitFormalAccessManagedBufferWithCleanup(SILLocation loc, assert(isInFormalEvaluationScope() && "Must be in formal evaluation scope"); auto &lowering = getTypeLowering(addr->getType()); if (lowering.isTrivial()) - return ManagedValue::forUnmanaged(addr); + return ManagedValue::forTrivialAddressRValue(addr); auto &cleanup = Cleanups.pushCleanup(); CleanupHandle handle = Cleanups.getTopCleanup(); FormalEvalContext.push(loc, handle, addr); cleanup.Depth = FormalEvalContext.stable_begin(); - return ManagedValue(addr, handle); + return ManagedValue::forOwnedAddressRValue(addr, handle); } ManagedValue @@ -2087,13 +2093,13 @@ SILGenFunction::emitFormalAccessManagedRValueWithCleanup(SILLocation loc, assert(isInFormalEvaluationScope() && "Must be in formal evaluation scope"); auto &lowering = getTypeLowering(value->getType()); if (lowering.isTrivial()) - return ManagedValue::forObjectRValueWithoutOwnership(value); + return ManagedValue::forRValueWithoutOwnership(value); auto &cleanup = Cleanups.pushCleanup(); CleanupHandle handle = Cleanups.getTopCleanup(); FormalEvalContext.push(loc, handle, value); cleanup.Depth = FormalEvalContext.stable_begin(); - return ManagedValue(value, handle); + return ManagedValue::forOwnedRValue(value, handle); } CleanupHandle SILGenFunction::enterDormantFormalAccessTemporaryCleanup( diff --git a/lib/SILGen/SILGenDestructor.cpp b/lib/SILGen/SILGenDestructor.cpp index cde5b030195c0..9c46adb531712 100644 --- a/lib/SILGen/SILGenDestructor.cpp +++ b/lib/SILGen/SILGenDestructor.cpp @@ -131,8 +131,8 @@ void SILGenFunction::emitDestroyingDestructor(DestructorDecl *dd) { } ArgumentScope S(*this, Loc); - ManagedValue borrowedValue = - ManagedValue::forUnmanaged(resultSelfValue).borrow(*this, cleanupLoc); + ManagedValue borrowedValue = B.borrowObjectRValue( + *this, cleanupLoc, resultSelfValue, ManagedValue::ScopeKind::Lexical); if (classTy != borrowedValue.getType()) { borrowedValue = @@ -273,8 +273,17 @@ void SILGenFunction::emitIVarDestroyer(SILDeclRef ivarDestroyer) { RegularLocation loc(cd); loc.markAutoGenerated(); - ManagedValue selfValue = ManagedValue::forUnmanaged( - emitSelfDeclForDestructor(cd->getDestructor()->getImplicitSelfDecl())); + ManagedValue selfValue; + { + SILValue rawSelfValue = + emitSelfDeclForDestructor(cd->getDestructor()->getImplicitSelfDecl()); + if (rawSelfValue->getOwnershipKind() == OwnershipKind::Unowned) { + selfValue = ManagedValue::forUnownedObjectValue(rawSelfValue); + } else { + selfValue = ManagedValue::forBorrowedRValue(rawSelfValue); + } + } + assert(selfValue); auto cleanupLoc = CleanupLocation(loc); prepareEpilog(llvm::None, false, cleanupLoc); @@ -383,8 +392,7 @@ void SILGenFunction::emitRecursiveChainDestruction(ManagedValue selfValue, // while iter != nil { { B.emitBlock(loopBB); - auto iterBorrow = - ManagedValue::forUnmanaged(iterAddr).borrow(*this, cleanupLoc); + auto iterBorrow = ManagedValue::forBorrowedAddressRValue(iterAddr); SwitchEnumBuilder switchBuilder(B, cleanupLoc, iterBorrow); switchBuilder.addOptionalSomeCase(someBB); switchBuilder.addOptionalNoneCase(noneBB); diff --git a/lib/SILGen/SILGenDistributed.cpp b/lib/SILGen/SILGenDistributed.cpp index 99cfbedf2fa0b..9d79696bb89a7 100644 --- a/lib/SILGen/SILGenDistributed.cpp +++ b/lib/SILGen/SILGenDistributed.cpp @@ -371,7 +371,7 @@ void SILGenFunction::emitDistributedActorFactory(FuncDecl *fd) { // TODO(distrib SILArgument *actorSystemArg = F.getArgument(1); SILValue selfArgValue = F.getSelfArgument(); - ManagedValue selfArg = ManagedValue::forUnmanaged(selfArgValue); + ManagedValue selfArg = ManagedValue::forBorrowedObjectRValue(selfArgValue); // type: SpecificDistributedActor.Type auto selfArgType = selfArg.getType().getASTType(); diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index 03dfb379fb46d..e03262cbe7cee 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -60,15 +60,13 @@ using namespace swift; using namespace Lowering; -ManagedValue SILGenFunction::emitManagedRetain(SILLocation loc, - SILValue v) { +ManagedValue SILGenFunction::emitManagedCopy(SILLocation loc, SILValue v) { auto &lowering = getTypeLowering(v->getType()); - return emitManagedRetain(loc, v, lowering); + return emitManagedCopy(loc, v, lowering); } -ManagedValue SILGenFunction::emitManagedRetain(SILLocation loc, - SILValue v, - const TypeLowering &lowering) { +ManagedValue SILGenFunction::emitManagedCopy(SILLocation loc, SILValue v, + const TypeLowering &lowering) { assert(lowering.getLoweredType() == v->getType()); if (lowering.isTrivial()) return ManagedValue::forRValueWithoutOwnership(v); @@ -81,6 +79,28 @@ ManagedValue SILGenFunction::emitManagedRetain(SILLocation loc, return emitManagedRValueWithCleanup(v, lowering); } +ManagedValue SILGenFunction::emitManagedFormalEvaluationCopy(SILLocation loc, + SILValue v) { + auto &lowering = getTypeLowering(v->getType()); + return emitManagedFormalEvaluationCopy(loc, v, lowering); +} + +ManagedValue +SILGenFunction::emitManagedFormalEvaluationCopy(SILLocation loc, SILValue v, + const TypeLowering &lowering) { + assert(lowering.getLoweredType() == v->getType()); + assert(isInFormalEvaluationScope() && "Must be in formal evaluation scope"); + if (lowering.isTrivial()) + return ManagedValue::forRValueWithoutOwnership(v); + if (v->getType().isObject() && v->getOwnershipKind() == OwnershipKind::None) + return ManagedValue::forObjectRValueWithoutOwnership(v); + assert((!lowering.isAddressOnly() || !silConv.useLoweredAddresses()) && + "cannot retain an unloadable type"); + + v = lowering.emitCopyValue(B, loc, v); + return emitFormalAccessManagedRValueWithCleanup(loc, v); +} + ManagedValue SILGenFunction::emitManagedLoadCopy(SILLocation loc, SILValue v) { auto &lowering = getTypeLowering(v->getType()); return emitManagedLoadCopy(loc, v, lowering); @@ -137,7 +157,7 @@ ManagedValue SILGenFunction::emitManagedStoreBorrow( "cannot retain an unloadable type"); auto *sbi = B.createStoreBorrow(loc, v, addr); Cleanups.pushCleanup(sbi); - return ManagedValue(sbi, CleanupHandle::invalid()); + return ManagedValue::forBorrowedAddressRValue(sbi); } ManagedValue SILGenFunction::emitManagedBeginBorrow(SILLocation loc, @@ -154,11 +174,14 @@ SILGenFunction::emitManagedBeginBorrow(SILLocation loc, SILValue v, if (lowering.isTrivial()) return ManagedValue::forRValueWithoutOwnership(v); + if (v->getType().isAddress()) + return ManagedValue::forBorrowedAddressRValue(v); + if (v->getOwnershipKind() == OwnershipKind::None) return ManagedValue::forRValueWithoutOwnership(v); if (v->getOwnershipKind() == OwnershipKind::Guaranteed) - return ManagedValue::forUnmanaged(v); + return ManagedValue::forBorrowedObjectRValue(v); auto *bbi = B.createBeginBorrow(loc, v); return emitManagedBorrowedRValueWithCleanup(v, bbi, lowering); @@ -168,6 +191,8 @@ EndBorrowCleanup::EndBorrowCleanup(SILValue borrowedValue) : borrowedValue(borrowedValue) { assert(!SILArgument::isTerminatorResult(borrowedValue) && "Transforming terminators do not have end_borrow"); + assert(!isa(borrowedValue) && + "SILFunctionArguments cannot have an end_borrow"); } void EndBorrowCleanup::emit(SILGenFunction &SGF, CleanupLocation l, @@ -224,7 +249,7 @@ ManagedValue SILGenFunction::emitFormalEvaluationManagedBeginBorrow(SILLocation loc, SILValue v) { if (v->getOwnershipKind() == OwnershipKind::Guaranteed) - return ManagedValue::forUnmanaged(v); + return ManagedValue::forBorrowedObjectRValue(v); auto &lowering = getTypeLowering(v->getType()); return emitFormalEvaluationManagedBeginBorrow(loc, v, lowering); } @@ -234,9 +259,9 @@ ManagedValue SILGenFunction::emitFormalEvaluationManagedBeginBorrow( assert(lowering.getLoweredType().getObjectType() == v->getType().getObjectType()); if (lowering.isTrivial()) - return ManagedValue::forUnmanaged(v); + return ManagedValue::forRValueWithoutOwnership(v); if (v->getOwnershipKind() == OwnershipKind::Guaranteed) - return ManagedValue::forUnmanaged(v); + return ManagedValue::forBorrowedRValue(v); auto *bbi = B.createBeginBorrow(loc, v); return emitFormalEvaluationManagedBorrowedRValueWithCleanup(loc, v, bbi, lowering); @@ -269,7 +294,7 @@ SILGenFunction::emitFormalEvaluationManagedBorrowedRValueWithCleanup( assert(lowering.getLoweredType().getObjectType() == original->getType().getObjectType()); if (lowering.isTrivial()) - return ManagedValue::forUnmanaged(borrowed); + return ManagedValue::forRValueWithoutOwnership(borrowed); assert(isInFormalEvaluationScope() && "Must be in formal evaluation scope"); auto &cleanup = Cleanups.pushCleanup(); @@ -277,19 +302,19 @@ SILGenFunction::emitFormalEvaluationManagedBorrowedRValueWithCleanup( FormalEvalContext.push(loc, handle, original, borrowed); cleanup.Depth = FormalEvalContext.stable_begin(); - return ManagedValue(borrowed, CleanupHandle::invalid()); + return ManagedValue::forBorrowedRValue(borrowed); } ManagedValue SILGenFunction::emitManagedBorrowedArgumentWithCleanup(SILPhiArgument *arg) { if (arg->getOwnershipKind() == OwnershipKind::None || arg->getType().isTrivial(F)) { - return ManagedValue::forUnmanaged(arg); + return ManagedValue::forRValueWithoutOwnership(arg); } assert(arg->getOwnershipKind() == OwnershipKind::Guaranteed); Cleanups.pushCleanup(arg); - return ManagedValue(arg, CleanupHandle::invalid()); + return ManagedValue::forBorrowedObjectRValue(arg); } ManagedValue @@ -322,7 +347,7 @@ ManagedValue SILGenFunction::emitManagedBorrowedRValueWithCleanup( Cleanups.pushCleanup(borrowed); } - return ManagedValue(borrowed, CleanupHandle::invalid()); + return ManagedValue::forBorrowedRValue(borrowed); } ManagedValue SILGenFunction::emitManagedBorrowedRValueWithCleanup( @@ -337,7 +362,7 @@ ManagedValue SILGenFunction::emitManagedBorrowedRValueWithCleanup( return ManagedValue::forObjectRValueWithoutOwnership(borrowed); Cleanups.pushCleanup(borrowed); - return ManagedValue(borrowed, CleanupHandle::invalid()); + return ManagedValue::forBorrowedRValue(borrowed); } ManagedValue SILGenFunction::emitManagedRValueWithCleanup(SILValue v) { @@ -354,7 +379,7 @@ ManagedValue SILGenFunction::emitManagedRValueWithCleanup(SILValue v, if (v->getType().isObject() && v->getOwnershipKind() == OwnershipKind::None) { return ManagedValue::forRValueWithoutOwnership(v); } - return ManagedValue(v, enterDestroyCleanup(v)); + return ManagedValue::forOwnedRValue(v, enterDestroyCleanup(v)); } ManagedValue SILGenFunction::emitManagedBufferWithCleanup(SILValue v) { @@ -367,9 +392,9 @@ ManagedValue SILGenFunction::emitManagedBufferWithCleanup(SILValue v, assert(lowering.getLoweredType().getAddressType() == v->getType() || !silConv.useLoweredAddresses()); if (lowering.isTrivial()) - return ManagedValue::forUnmanaged(v); + return ManagedValue::forTrivialAddressRValue(v); - return ManagedValue(v, enterDestroyCleanup(v)); + return ManagedValue::forOwnedAddressRValue(v, enterDestroyCleanup(v)); } void SILGenFunction::emitExprInto(Expr *E, Initialization *I, @@ -816,7 +841,7 @@ RValue SILGenFunction::emitRValueForSelfInDelegationInit(SILLocation loc, "This should only be called if guaranteed plus zero is ok"); SelfInitDelegationState = SILGenFunction::DidSharedBorrowSelf; ManagedValue result = - B.createLoadBorrow(loc, ManagedValue::forUnmanaged(addr)); + B.createLoadBorrow(loc, ManagedValue::forBorrowedAddressRValue(addr)); return RValue(*this, loc, refType, result); } @@ -826,7 +851,7 @@ RValue SILGenFunction::emitRValueForSelfInDelegationInit(SILLocation loc, assert(C.isGuaranteedPlusZeroOk() && "This should only be called if guaranteed plus zero is ok"); ManagedValue result = - B.createLoadBorrow(loc, ManagedValue::forUnmanaged(addr)); + B.createLoadBorrow(loc, ManagedValue::forBorrowedAddressRValue(addr)); return RValue(*this, loc, refType, result); } @@ -879,8 +904,8 @@ RValue SILGenFunction::emitFormalEvaluationRValueForSelfInDelegationInit( assert(C.isGuaranteedPlusZeroOk() && "This should only be called if guaranteed plus zero is ok"); SelfInitDelegationState = SILGenFunction::DidSharedBorrowSelf; - ManagedValue result = - B.createFormalAccessLoadBorrow(loc, ManagedValue::forUnmanaged(addr)); + ManagedValue result = B.createFormalAccessLoadBorrow( + loc, ManagedValue::forBorrowedAddressRValue(addr)); return RValue(*this, loc, refType, result); } @@ -889,8 +914,8 @@ RValue SILGenFunction::emitFormalEvaluationRValueForSelfInDelegationInit( if (SelfInitDelegationState == SILGenFunction::DidSharedBorrowSelf) { assert(C.isGuaranteedPlusZeroOk() && "This should only be called if guaranteed plus zero is ok"); - ManagedValue result = - B.createFormalAccessLoadBorrow(loc, ManagedValue::forUnmanaged(addr)); + ManagedValue result = B.createFormalAccessLoadBorrow( + loc, ManagedValue::forBorrowedAddressRValue(addr)); return RValue(*this, loc, refType, result); } @@ -1108,9 +1133,10 @@ manageBufferForExprResult(SILValue buffer, const TypeLowering &bufferTL, // Add a cleanup for the temporary we allocated. if (bufferTL.isTrivial()) - return ManagedValue::forUnmanaged(buffer); + return ManagedValue::forTrivialAddressRValue(buffer); - return ManagedValue(buffer, enterDestroyCleanup(buffer)); + return ManagedValue::forOwnedAddressRValue(buffer, + enterDestroyCleanup(buffer)); } SILGenFunction::ForceTryEmission::ForceTryEmission(SILGenFunction &SGF, @@ -1740,7 +1766,7 @@ static ManagedValue convertFunctionRepresentation(SILGenFunction &SGF, sourceTy->getWithRepresentation( SILFunctionTypeRepresentation::Thick))); // FIXME: what if other reabstraction is required? - return ManagedValue(v, source.getCleanup()); + return ManagedValue::forOwnedRValue(v, source.getCleanup()); } case SILFunctionType::Representation::Thick: llvm_unreachable("should not try thick-to-thick repr change"); @@ -1768,7 +1794,7 @@ static ManagedValue convertFunctionRepresentation(SILGenFunction &SGF, SILType::getPrimitiveObjectType( sourceTy->getWithRepresentation( SILFunctionTypeRepresentation::Thick))); - source = ManagedValue(v, source.getCleanup()); + source = ManagedValue::forOwnedRValue(v, source.getCleanup()); LLVM_FALLTHROUGH; } case SILFunctionType::Representation::Thick: @@ -2081,7 +2107,7 @@ ManagedValue SILGenFunction::getManagedValue(SILLocation loc, // If the type is trivial, it's always +1. if (valueTL.isTrivial()) - return ManagedValue::forUnmanaged(value.getValue()); + return ManagedValue::forRValueWithoutOwnership(value.getValue()); // If it's an object... if (valueTy.isObject()) { @@ -5325,7 +5351,8 @@ void SILGenFunction::emitOptionalEvaluation(SILLocation loc, Type optType, if (!resultTy.getOptionalObjectType()) { resultTy = SILType::getOptionalType(resultTy); value = B.createOptionalSome(loc, value, resultTy); - result = ManagedValue::forUnmanaged(value); + // This is really unprincipled. + result = ManagedValue::forUnmanagedOwnedValue(value); } } @@ -5710,7 +5737,7 @@ class AutoreleasingWritebackComponent : public LogicalPathComponent { auto strongType = SILType::getPrimitiveObjectType( unowned->getType().castTo().getReferentType()); auto owned = SGF.B.createUnmanagedToRef(loc, unowned, strongType); - auto ownedMV = SGF.emitManagedRetain(loc, owned); + auto ownedMV = SGF.emitManagedCopy(loc, owned); // Then create a mark dependence in between the base and the ownedMV. This // is important to ensure that the destroy of the assign is not hoisted @@ -5737,7 +5764,7 @@ class AutoreleasingWritebackComponent : public LogicalPathComponent { loc, loadedBase.getUnmanagedValue(), unownedType); // A reference type should never be exploded. - return RValue(SGF, ManagedValue::forUnmanaged(unowned), refType); + return RValue(SGF, ManagedValue::forUnownedObjectValue(unowned), refType); } llvm::Optional getAccessStorage() const override { @@ -6475,5 +6502,5 @@ ManagedValue SILGenFunction::emitUndef(Type type) { ManagedValue SILGenFunction::emitUndef(SILType type) { SILValue undef = SILUndef::get(type, F); - return ManagedValue::forUnmanaged(undef); + return ManagedValue::forRValueWithoutOwnership(undef); } diff --git a/lib/SILGen/SILGenForeignError.cpp b/lib/SILGen/SILGenForeignError.cpp index 9f8ba4864f94c..74b0eed8bdce7 100644 --- a/lib/SILGen/SILGenForeignError.cpp +++ b/lib/SILGen/SILGenForeignError.cpp @@ -97,12 +97,10 @@ static void emitStoreToForeignErrorSlot(SILGenFunction &SGF, } // Otherwise, do a normal assignment. - LValue lvalue = - SGF.emitPropertyLValue(loc, ManagedValue::forUnmanaged(foreignErrorSlot), - bridgedErrorPtrType, pointeeProperty, - LValueOptions(), - SGFAccessKind::Write, - AccessSemantics::Ordinary); + LValue lvalue = SGF.emitPropertyLValue( + loc, ManagedValue::forRValueWithoutOwnership(foreignErrorSlot), + bridgedErrorPtrType, pointeeProperty, LValueOptions(), + SGFAccessKind::Write, AccessSemantics::Ordinary); RValue rvalue(SGF, loc, bridgedErrorProto, SGF.emitManagedRValueWithCleanup(bridgedError)); SGF.emitAssignToLValue(loc, std::move(rvalue), std::move(lvalue)); diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp index 21ea94f43ffb9..1a5c557e16089 100644 --- a/lib/SILGen/SILGenFunction.cpp +++ b/lib/SILGen/SILGenFunction.cpp @@ -715,7 +715,8 @@ void SILGenFunction::emitCaptures(SILLocation loc, // Our 'let' binding can guarantee the lifetime for the callee, // if we don't need to do anything more to it. if (canGuarantee && !vd->getInterfaceType()->is()) { - auto guaranteed = ManagedValue::forUnmanaged(val).borrow(*this, loc); + auto guaranteed = B.borrowObjectRValue( + *this, loc, val, ManagedValue::ScopeKind::Lexical); if (eliminateMoveOnlyWrapper) guaranteed = B.createGuaranteedMoveOnlyWrapperToCopyableValue( loc, guaranteed); @@ -758,8 +759,8 @@ void SILGenFunction::emitCaptures(SILLocation loc, capturedArgs.push_back(ManagedValue::forBorrowedRValue(addr)); } else if (!silConv.useLoweredAddresses()) { - capturedArgs.push_back( - B.createCopyValue(loc, ManagedValue::forUnmanaged(val))); + capturedArgs.push_back(B.copyOwnedObjectRValue( + loc, val, ManagedValue::ScopeKind::Lexical)); } else { auto addr = getAddressValue(val, /*forceCopy=*/true); // If our address is move only wrapped, unwrap it. @@ -798,13 +799,16 @@ void SILGenFunction::emitCaptures(SILLocation loc, // If this is a boxed variable, we can use it directly. if (Entry.box && val->getType().getASTType() == minimalLoweredType) { - auto box = ManagedValue::forBorrowedObjectRValue(Entry.box); + ManagedValue box; // We can guarantee our own box to the callee. if (canGuarantee) { - box = box.borrow(*this, loc); + box = B.borrowObjectRValue(*this, loc, Entry.box, + ManagedValue::ScopeKind::Lexical); } else { - box = box.copy(*this, loc); + box = B.copyOwnedObjectRValue(loc, Entry.box, + ManagedValue::ScopeKind::Lexical); } + assert(box); // If our captured value is a box with a moveonlywrapped type inside, // unwrap it. @@ -861,10 +865,10 @@ void SILGenFunction::emitCaptures(SILLocation loc, val->getType().getASTType() == minimalLoweredType) { // We can guarantee our own box to the callee. if (canGuarantee) { - capturedArgs.push_back( - ManagedValue::forUnmanaged(Entry.box).borrow(*this, loc)); + capturedArgs.push_back(B.borrowObjectRValue( + *this, loc, Entry.box, ManagedValue::ScopeKind::Lexical)); } else { - capturedArgs.push_back(emitManagedRetain(loc, Entry.box)); + capturedArgs.push_back(emitManagedCopy(loc, Entry.box)); } if (captureCanEscape) escapesToMark.push_back(val); diff --git a/lib/SILGen/SILGenFunction.h b/lib/SILGen/SILGenFunction.h index 1b36fb0d822de..4198cc4d6d5c7 100644 --- a/lib/SILGen/SILGenFunction.h +++ b/lib/SILGen/SILGenFunction.h @@ -22,6 +22,7 @@ #include "SILGen.h" #include "SILGenBuilder.h" #include "swift/AST/AnyFunctionRef.h" +#include "swift/Basic/NoDiscard.h" #include "swift/Basic/ProfileCounter.h" #include "swift/Basic/Statistic.h" #include "swift/SIL/SILBuilder.h" @@ -1697,9 +1698,13 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction Type resultType, RValue &&operand); - ManagedValue emitManagedRetain(SILLocation loc, SILValue v); - ManagedValue emitManagedRetain(SILLocation loc, SILValue v, - const TypeLowering &lowering); + ManagedValue emitManagedCopy(SILLocation loc, SILValue v); + ManagedValue emitManagedCopy(SILLocation loc, SILValue v, + const TypeLowering &lowering); + + ManagedValue emitManagedFormalEvaluationCopy(SILLocation loc, SILValue v); + ManagedValue emitManagedFormalEvaluationCopy(SILLocation loc, SILValue v, + const TypeLowering &lowering); ManagedValue emitManagedLoadCopy(SILLocation loc, SILValue v); ManagedValue emitManagedLoadCopy(SILLocation loc, SILValue v, diff --git a/lib/SILGen/SILGenLValue.cpp b/lib/SILGen/SILGenLValue.cpp index f9736f0d012e7..978e35e9d2ba8 100644 --- a/lib/SILGen/SILGenLValue.cpp +++ b/lib/SILGen/SILGenLValue.cpp @@ -452,7 +452,13 @@ void LogicalPathComponent::writeback(SILGenFunction &SGF, SILLocation loc, RValue rvalue(SGF, loc, getSubstFormalType(), temporary); // Don't consume cleanups on the base if this isn't final. - if (base && !isFinal) { base = ManagedValue::forUnmanaged(base.getValue()); } + if (base && !isFinal) { + if (base.getOwnershipKind() == OwnershipKind::Guaranteed) { + base = ManagedValue::forBorrowedRValue(base.getValue()); + } else { + base = ManagedValue::forUnmanagedOwnedValue(base.getValue()); + } + } // Clone the component if this isn't final. std::unique_ptr clonedComponent = @@ -3340,11 +3346,16 @@ SILGenFunction::maybeEmitValueOfLocalVarDecl( if (ptr->getType().isAddress()) return ManagedValue::forLValue(ptr); - // Otherwise, it is an RValue let. Uses of it are borrows, but we don't - // want to proactively emit a borrow here. + // Otherwise, it is an RValue let. SILGen is inconsistent here and may store + // either an "unmanaged borrowed" owned value that must be borrowed before + // use /or/ it may store an already borrowed value. In the case of the + // former, we don't want to proactively emit a borrow here. + // // TODO: integrate this with how callers want these values so we can do - // something more semantic than just forUnmanaged. - return ManagedValue::forUnmanaged(ptr); + // something more semantic than just forUnmanagedOwnedValue. + if (ptr->getOwnershipKind().isCompatibleWith(OwnershipKind::Guaranteed)) + return ManagedValue::forBorrowedRValue(ptr); + return ManagedValue::forUnmanagedOwnedValue(ptr); } // Otherwise, it's non-local or not stored. @@ -4398,10 +4409,10 @@ ManagedValue SILGenFunction::emitLoad(SILLocation loc, SILValue addr, SILType addrType = addrTL.getLoweredType(); if (!rvalueType.isMoveOnlyWrapped() && addrType.isMoveOnlyWrapped()) { SILValue value = B.createMoveOnlyWrapperToCopyableAddr(loc, addr); - return ManagedValue::forUnmanaged(value); + return ManagedValue::forBorrowedAddressRValue(value); } if (rvalueTL.getLoweredType() == addrTL.getLoweredType()) { - return ManagedValue::forUnmanaged(addr); + return ManagedValue::forBorrowedAddressRValue(addr); } } @@ -4423,7 +4434,8 @@ ManagedValue SILGenFunction::emitLoad(SILLocation loc, SILValue addr, // we can perform a +0 load of the address instead of materializing a +1 // value. if (isPlusZeroOk && addrTL.getLoweredType() == rvalueTL.getLoweredType()) { - return B.createLoadBorrow(loc, ManagedValue::forUnmanaged(addr)); + return B.createLoadBorrow(loc, + ManagedValue::forBorrowedAddressRValue(addr)); } // Load the loadable value, and retain it if we aren't taking it. @@ -4460,7 +4472,7 @@ ManagedValue SILGenFunction::emitFormalAccessLoad(SILLocation loc, // type, and there are no conversions, then we can return this as a +0 // address RValue. if (isPlusZeroOk && rvalueTL.getLoweredType() == addrTL.getLoweredType()) - return ManagedValue::forUnmanaged(addr); + return ManagedValue::forBorrowedAddressRValue(addr); // Copy the address-only value. return B.formalAccessBufferForExpr( @@ -4482,8 +4494,8 @@ ManagedValue SILGenFunction::emitFormalAccessLoad(SILLocation loc, // we can perform a +0 load of the address instead of materializing a +1 // value. if (isPlusZeroOk && addrTL.getLoweredType() == rvalueTL.getLoweredType()) { - return B.createFormalAccessLoadBorrow(loc, - ManagedValue::forUnmanaged(addr)); + return B.createFormalAccessLoadBorrow( + loc, ManagedValue::forBorrowedAddressRValue(addr)); } // Load the loadable value, and retain it if we aren't taking it. diff --git a/lib/SILGen/SILGenPack.cpp b/lib/SILGen/SILGenPack.cpp index 6d48a00c04a6a..64ab8caaea71f 100644 --- a/lib/SILGen/SILGenPack.cpp +++ b/lib/SILGen/SILGenPack.cpp @@ -34,8 +34,8 @@ class DeallocPackCleanup : public Cleanup { void dump(SILGenFunction &) const override { #ifndef NDEBUG llvm::errs() << "DeallocPackCleanup\n" - << "State:" << getState() << "\n" - << "Addr:" << Addr << "\n"; + << "State: " << getState() << "\n" + << "Addr: " << Addr << "\n"; #endif } }; @@ -59,9 +59,8 @@ class DestroyPackCleanup : public Cleanup { void dump(SILGenFunction &) const override { #ifndef NDEBUG llvm::errs() << "DestroyPackCleanup\n" - << "State:" << getState() << "\n" - << "Addr:" << Addr << "\n" - << "FormalPackType:" << FormalPackType + << "State: " << getState() << "\n" + << "Addr: " << Addr << "FormalPackType: " << FormalPackType << "FirstComponentIndex:" << FirstComponentIndex << "\n"; #endif } @@ -72,16 +71,17 @@ class DestroyPackCleanup : public Cleanup { class PartialDestroyPackCleanup : public Cleanup { SILValue Addr; unsigned PackComponentIndex; + + /// NOTE: It is expected that LimitWithinComponent maybe an empty SILValue. SILValue LimitWithinComponent; CanPackType FormalPackType; public: - PartialDestroyPackCleanup(SILValue addr, - CanPackType formalPackType, + PartialDestroyPackCleanup(SILValue addr, CanPackType formalPackType, unsigned packComponentIndex, SILValue limitWithinComponent) - : Addr(addr), PackComponentIndex(packComponentIndex), - LimitWithinComponent(limitWithinComponent), - FormalPackType(formalPackType) {} + : Addr(addr), PackComponentIndex(packComponentIndex), + LimitWithinComponent(limitWithinComponent), + FormalPackType(formalPackType) {} void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override { @@ -92,11 +92,15 @@ class PartialDestroyPackCleanup : public Cleanup { void dump(SILGenFunction &) const override { #ifndef NDEBUG llvm::errs() << "PartialDestroyPackCleanup\n" - << "State:" << getState() << "\n" - << "Addr:" << Addr << "\n" - << "FormalPackType:" << FormalPackType << "\n" - << "ComponentIndex:" << PackComponentIndex << "\n" - << "LimitWithinComponent:" << LimitWithinComponent << "\n"; + << "State: " << getState() << "\n" + << "Addr: " << Addr << "FormalPackType: " << FormalPackType + << "\n" + << "ComponentIndex: " << PackComponentIndex << "\n" + << "LimitWithinComponent: "; + if (LimitWithinComponent) + llvm::errs() << LimitWithinComponent; + else + llvm::errs() << "None\n"; #endif } }; @@ -127,11 +131,11 @@ class PartialDestroyRemainingPackCleanup : public Cleanup { void dump(SILGenFunction &) const override { #ifndef NDEBUG llvm::errs() << "PartialDestroyRemainingPackCleanup\n" - << "State:" << getState() << "\n" - << "Addr:" << Addr << "\n" - << "FormalPackType:" << FormalPackType << "\n" - << "ComponentIndex:" << ComponentIndex << "\n" - << "CurrentIndexWithinComponent:" + << "State: " << getState() << "\n" + << "Addr: " << Addr << "FormalPackType: " << FormalPackType + << "\n" + << "ComponentIndex: " << ComponentIndex << "\n" + << "CurrentIndexWithinComponent: " << CurrentIndexWithinComponent << "\n"; #endif } @@ -162,11 +166,11 @@ class PartialDestroyTupleCleanup : public Cleanup { void dump(SILGenFunction &) const override { #ifndef NDEBUG llvm::errs() << "PartialDestroyTupleCleanup\n" - << "State:" << getState() << "\n" - << "Addr:" << Addr << "\n" - << "InducedPackType:" << InducedPackType << "\n" - << "ComponentIndex:" << ComponentIndex << "\n" - << "LimitWithinComponent:" << LimitWithinComponent << "\n"; + << "State: " << getState() << "\n" + << "Addr: " << Addr << "InducedPackType: " << InducedPackType + << "\n" + << "ComponentIndex: " << ComponentIndex << '\n' + << "LimitWithinComponent: " << LimitWithinComponent << '\n'; #endif } }; @@ -197,12 +201,12 @@ class PartialDestroyRemainingTupleCleanup : public Cleanup { void dump(SILGenFunction &) const override { #ifndef NDEBUG llvm::errs() << "PartialDestroyRemainingTupleCleanup\n" - << "State:" << getState() << "\n" - << "Addr:" << Addr << "\n" - << "InducedPackType:" << InducedPackType << "\n" - << "ComponentIndex:" << ComponentIndex << "\n" - << "CurrentIndexWithinComponent:" - << CurrentIndexWithinComponent << "\n"; + << "State: " << getState() << "\n" + << "Addr: " << Addr << "InducedPackType: " << InducedPackType + << "\n" + << "ComponentIndex: " << ComponentIndex << "\n" + << "CurrentIndexWithinComponent: " + << CurrentIndexWithinComponent; #endif } }; @@ -229,10 +233,10 @@ class DestroyRemainingTupleElementsCleanup : public Cleanup { void dump(SILGenFunction &) const override { #ifndef NDEBUG llvm::errs() << "DestroyRemainingTupleElementsCleanup\n" - << "State:" << getState() << "\n" - << "Addr:" << Addr << "\n" - << "InducedPackType:" << InducedPackType << "\n" - << "ComponentIndex:" << ComponentIndex << "\n"; + << "State: " << getState() << "\n" + << "Addr: " << Addr << "InducedPackType: " << InducedPackType + << "\n" + << "ComponentIndex: " << ComponentIndex << "\n"; #endif } }; diff --git a/lib/SILGen/SILGenPattern.cpp b/lib/SILGen/SILGenPattern.cpp index 383651def92bd..7375765498e03 100644 --- a/lib/SILGen/SILGenPattern.cpp +++ b/lib/SILGen/SILGenPattern.cpp @@ -1392,7 +1392,7 @@ getManagedSubobject(SILGenFunction &SGF, SILValue value, switch (consumption) { case CastConsumptionKind::BorrowAlways: case CastConsumptionKind::CopyOnSuccess: - return {ManagedValue::forUnmanaged(value), consumption}; + return {ManagedValue::forBorrowedRValue(value), consumption}; case CastConsumptionKind::TakeAlways: case CastConsumptionKind::TakeOnSuccess: return {SGF.emitManagedRValueWithCleanup(value, valueTL), consumption}; @@ -1553,7 +1553,7 @@ emitTupleDispatch(ArrayRef rows, ConsumableManagedValue src, // If we have a loadable type, then we have a loadable sub-type of the // underlying address only tuple. - auto memberMV = ManagedValue::forUnmanaged(member); + auto memberMV = ManagedValue::forBorrowedAddressRValue(member); switch (src.getFinalConsumption()) { case CastConsumptionKind::TakeAlways: { // If our original source value is take always, perform a load [take]. @@ -1577,7 +1577,7 @@ emitTupleDispatch(ArrayRef rows, ConsumableManagedValue src, } case CastConsumptionKind::CopyOnSuccess: { // We translate copy_on_success => borrow_always. - auto memberMV = ManagedValue::forUnmanaged(member); + auto memberMV = ManagedValue::forBorrowedAddressRValue(member); return {SGF.B.createLoadBorrow(loc, memberMV), CastConsumptionKind::BorrowAlways}; } @@ -2079,8 +2079,9 @@ void PatternMatchEmission::emitEnumElementDispatch( if (!blocks.hasAnyRefutableCase()) break; - src = ConsumableManagedValue(ManagedValue::forUnmanaged(src.getValue()), - CastConsumptionKind::CopyOnSuccess); + src = ConsumableManagedValue( + ManagedValue::forUnmanagedOwnedValue(src.getValue()), + CastConsumptionKind::CopyOnSuccess); break; } diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp index 474aa96286e38..6ec4ef9210474 100644 --- a/lib/SILGen/SILGenPoly.cpp +++ b/lib/SILGen/SILGenPoly.cpp @@ -686,12 +686,22 @@ static void explodeTuple(SILGenFunction &SGF, SILLocation loc, } for (auto element : elements) { - if (!isPlusOne) - out.push_back(ManagedValue::forUnmanaged(element)); - else if (element->getType().isAddress()) + if (element->getType().isTrivial(SGF.F)) { + out.push_back(ManagedValue::forRValueWithoutOwnership(element)); + continue; + } + + if (!isPlusOne) { + out.push_back(ManagedValue::forBorrowedRValue(element)); + continue; + } + + if (element->getType().isAddress()) { out.push_back(SGF.emitManagedBufferWithCleanup(element)); - else - out.push_back(SGF.emitManagedRValueWithCleanup(element)); + continue; + } + + out.push_back(SGF.emitManagedRValueWithCleanup(element)); } } @@ -1491,8 +1501,9 @@ class TranslateArguments : public ExpanderBase { auto tuple = SGF.B.createTuple(Loc, loweredInnerTy, forwarded); if (tuple->getOwnershipKind() == OwnershipKind::Owned) return SGF.emitManagedRValueWithCleanup(tuple); - - return ManagedValue::forUnmanaged(tuple); + if (tuple->getType().isTrivial(SGF.F)) + return ManagedValue::forRValueWithoutOwnership(tuple); + return ManagedValue::forBorrowedRValue(tuple); } @@ -1537,7 +1548,9 @@ class TranslateArguments : public ExpanderBase { payload.forward(SGF); return SGF.emitManagedBufferWithCleanup(optionalBuf); } - return ManagedValue::forUnmanaged(optionalBuf); + if (optionalBuf->getType().isTrivial(SGF.F)) + return ManagedValue::forTrivialAddressRValue(optionalBuf); + return ManagedValue::forBorrowedAddressRValue(optionalBuf); } } @@ -1756,7 +1769,7 @@ class TranslateArguments : public ExpanderBase { // initially owned. if (inner.getOwnershipKind() == OwnershipKind::Unowned) { assert(!inner.hasCleanup()); - inner = SGF.emitManagedRetain(Loc, inner.getValue()); + inner = SGF.emitManagedCopy(Loc, inner.getValue()); } // If the inner is unowned or owned, create a borrow. @@ -4366,7 +4379,7 @@ void ResultPlanner::execute(SmallVectorImpl &innerDirectResultStack, "reabstraction of returns_inner_pointer function"); LLVM_FALLTHROUGH; case ResultConvention::Unowned: - return SGF.emitManagedRetain(Loc, resultValue, resultTL); + return SGF.emitManagedCopy(Loc, resultValue, resultTL); } llvm_unreachable("bad result convention!"); }; diff --git a/lib/SILGen/SILGenProlog.cpp b/lib/SILGen/SILGenProlog.cpp index e210b18b31b48..6f9a514525563 100644 --- a/lib/SILGen/SILGenProlog.cpp +++ b/lib/SILGen/SILGenProlog.cpp @@ -456,9 +456,10 @@ class EmitBBArguments : public CanTypeVisitorgetOwnershipKind() == OwnershipKind::None) + return ManagedValue::forObjectRValueWithoutOwnership(tupleValue); + return canBeGuaranteed ? ManagedValue::forBorrowedObjectRValue(tupleValue) + : SGF.emitManagedRValueWithCleanup(tupleValue); } else { // If the type is address-only, we need to move or copy the elements into // a tuple in memory. @@ -1068,7 +1069,7 @@ static void emitCaptureArguments(SILGenFunction &SGF, auto *fArg = SGF.F.begin()->createFunctionArgument(ty, VD); fArg->setClosureCapture(true); - ManagedValue val = ManagedValue::forUnmanaged(fArg); + ManagedValue val = ManagedValue::forBorrowedRValue(fArg); // If the original variable was settable, then Sema will have treated the // VarDecl as an lvalue, even in the closure's use. As such, we need to @@ -1220,12 +1221,21 @@ void SILGenFunction::emitProlog( auto &lowering = getTypeLowering(type); SILType ty = lowering.getLoweredType(); SILValue val = F.begin()->createFunctionArgument(ty); - OpaqueValues[opaqueValue] = ManagedValue::forUnmanaged(val); // Opaque values are always passed 'owned', so add a clean up if needed. + // + // TODO: Should this be tied to the mv? if (!lowering.isTrivial()) enterDestroyCleanup(val); + ManagedValue mv; + if (lowering.isTrivial()) + mv = ManagedValue::forObjectRValueWithoutOwnership(val); + else + mv = ManagedValue::forUnmanagedOwnedValue(val); + + OpaqueValues[opaqueValue] = mv; + continue; } @@ -1318,7 +1328,14 @@ void SILGenFunction::emitProlog( ManagedValue actorArg; if (actorIsolation.getActorInstanceParameter() == 0) { assert(selfParam && "no self parameter for ActorInstance isolation"); - auto selfArg = ManagedValue::forUnmanaged(F.getSelfArgument()); + ManagedValue selfArg; + if (F.getSelfArgument()->getOwnershipKind() == + OwnershipKind::Guaranteed) { + selfArg = ManagedValue::forBorrowedRValue(F.getSelfArgument()); + } else { + selfArg = + ManagedValue::forUnmanagedOwnedValue(F.getSelfArgument()); + } ExpectedExecutor = emitLoadActorExecutor(loc, selfArg); } else { unsigned isolatedParamIdx = diff --git a/lib/SILGen/SwitchEnumBuilder.cpp b/lib/SILGen/SwitchEnumBuilder.cpp index d50db70c6081b..a3301f57c527c 100644 --- a/lib/SILGen/SwitchEnumBuilder.cpp +++ b/lib/SILGen/SwitchEnumBuilder.cpp @@ -91,7 +91,7 @@ void SwitchEnumBuilder::emit() && { ArrayRef caseBlockCountsRef = caseBlockCounts; if (isAddressOnly) { if (subjectExprOperand.getType().isMoveOnlyWrapped()) { - subjectExprOperand = ManagedValue::forUnmanaged( + subjectExprOperand = ManagedValue::forBorrowedAddressRValue( builder.createMoveOnlyWrapperToCopyableAddr( loc, subjectExprOperand.getValue())); }