From 1a06313ac9f3a84d0d5667c78f018c13a7473104 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 8 Jan 2024 11:00:33 -0500 Subject: [PATCH] SIL: Fix DynamicSelfType references from inside init accessor We need the self metatype parameter to correctly lower DynamicSelfType in IRGen, so plumb this through to all calls of init accessors, and inside the prolog of an init accessor definition. This does not break the public ABI, because init accessors are never public. Also for value types, the metatype is thin, so it should not change generated code. For classes we need the metatype in the general case because of `Self`, but hopefully in most cases the init accessor can be inlined away and the value_metatype instruction subject to dead code elimination. Fixes rdar://problem/119822466. --- lib/SIL/IR/SILFunctionType.cpp | 10 ++ lib/SILGen/SILGenConstructor.cpp | 59 +++++----- lib/SILGen/SILGenFunction.cpp | 47 ++++++-- test/IRGen/init_accessor_dynamic_self.swift | 21 ++++ test/Interpreter/init_accessors.swift | 32 +++++ .../init_accessor_raw_sil_lowering.swift | 110 +++++++++--------- test/SILOptimizer/init_accessors.swift | 99 +++++++++------- ...nit_accessors_with_indirect_newValue.swift | 4 +- 8 files changed, 244 insertions(+), 138 deletions(-) create mode 100644 test/IRGen/init_accessor_dynamic_self.swift diff --git a/lib/SIL/IR/SILFunctionType.cpp b/lib/SIL/IR/SILFunctionType.cpp index 352808d332a41..cf5c3e1409c45 100644 --- a/lib/SIL/IR/SILFunctionType.cpp +++ b/lib/SIL/IR/SILFunctionType.cpp @@ -2434,6 +2434,16 @@ static CanSILFunctionType getSILFunctionTypeForInitAccessor( ParameterConvention::Indirect_Inout)); } + // Make a new 'self' parameter. + auto selfInterfaceType = MetatypeType::get( + accessor->getDeclContext()->getSelfInterfaceType()); + AbstractionPattern origSelfType(genericSig, + selfInterfaceType->getCanonicalType()); + auto loweredSelfType = TC.getLoweredType( + origSelfType, selfInterfaceType->getCanonicalType(), context); + inputs.push_back(SILParameterInfo(loweredSelfType.getASTType(), + ParameterConvention::Direct_Unowned)); + SmallVector results; // initialized properties appear as `@out` results because they are diff --git a/lib/SILGen/SILGenConstructor.cpp b/lib/SILGen/SILGenConstructor.cpp index 714c15eb606eb..820ad973ad5a5 100644 --- a/lib/SILGen/SILGenConstructor.cpp +++ b/lib/SILGen/SILGenConstructor.cpp @@ -91,29 +91,23 @@ static ManagedValue emitManagedParameter(SILGenFunction &SGF, } static SILValue emitConstructorMetatypeArg(SILGenFunction &SGF, - ValueDecl *ctor) { + ValueDecl *decl) { // In addition to the declared arguments, the constructor implicitly takes // the metatype as its first argument, like a static function. - auto ctorFnType = ctor->getInterfaceType()->castTo(); - assert(ctorFnType->getParams().size() == 1 && - "more than one self parameter?"); - auto param = ctorFnType->getParams()[0]; - assert(!param.isVariadic() && !param.isInOut()); - Type metatype = param.getPlainType(); - auto *DC = ctor->getInnermostDeclContext(); - auto &AC = SGF.getASTContext(); + auto metatypeTy = MetatypeType::get( + decl->getDeclContext()->getSelfInterfaceType()); + auto *DC = decl->getInnermostDeclContext(); + auto &ctx = SGF.getASTContext(); auto VD = - new (AC) ParamDecl(SourceLoc(), SourceLoc(), - AC.getIdentifier("$metatype"), SourceLoc(), - AC.getIdentifier("$metatype"), DC); + new (ctx) ParamDecl(SourceLoc(), SourceLoc(), + ctx.getIdentifier("$metatype"), SourceLoc(), + ctx.getIdentifier("$metatype"), DC); VD->setSpecifier(ParamSpecifier::Default); - VD->setInterfaceType(metatype); + VD->setInterfaceType(metatypeTy); - SGF.AllocatorMetatype = SGF.F.begin()->createFunctionArgument( - SGF.getLoweredTypeForFunctionArgument(DC->mapTypeIntoContext(metatype)), + return SGF.F.begin()->createFunctionArgument( + SGF.getLoweredTypeForFunctionArgument(DC->mapTypeIntoContext(metatypeTy)), VD); - - return SGF.AllocatorMetatype; } // FIXME: Consolidate this with SILGenProlog @@ -273,7 +267,8 @@ static RValue maybeEmitPropertyWrapperInitFromValue( static void emitApplyOfInitAccessor(SILGenFunction &SGF, SILLocation loc, AccessorDecl *accessor, SILValue selfValue, - SILType selfTy, RValue &&initialValue) { + Type selfIfaceTy, SILType selfTy, + RValue &&initialValue) { SmallVector arguments; auto emitFieldReference = [&](VarDecl *field, bool forInit = false) { @@ -297,6 +292,10 @@ emitApplyOfInitAccessor(SILGenFunction &SGF, SILLocation loc, arguments.push_back(emitFieldReference(property)); } + // The `self` metatype. + auto metatypeTy = MetatypeType::get(accessor->mapTypeIntoContext(selfIfaceTy)); + arguments.push_back(SGF.B.createMetatype(loc, SGF.getLoweredType(metatypeTy))); + SubstitutionMap subs; if (auto *env = accessor->getDeclContext()->getGenericEnvironmentOfContext()) { @@ -387,7 +386,7 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF, loweredParams)); } - emitConstructorMetatypeArg(SGF, ctor); + SGF.AllocatorMetatype = emitConstructorMetatypeArg(SGF, ctor); (void) loweredParams.claimNext(); loweredParams.finish(); @@ -418,8 +417,8 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF, assert(elti != eltEnd && "number of args does not match number of fields"); - emitApplyOfInitAccessor(SGF, Loc, initAccessor, resultSlot, selfTy, - std::move(*elti)); + emitApplyOfInitAccessor(SGF, Loc, initAccessor, resultSlot, + selfIfaceTy, selfTy, std::move(*elti)); ++elti; continue; } @@ -666,7 +665,7 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) { ctor->getEffectiveThrownErrorType(), ctor->getThrowsLoc(), /*ignored parameters*/ 1); - emitConstructorMetatypeArg(*this, ctor); + AllocatorMetatype = emitConstructorMetatypeArg(*this, ctor); // Make sure we've hopped to the right global actor, if any. if (ctor->hasAsync()) { @@ -897,7 +896,7 @@ void SILGenFunction::emitEnumConstructor(EnumElementDecl *element) { } // Emit the metatype argument. - emitConstructorMetatypeArg(*this, element); + AllocatorMetatype = emitConstructorMetatypeArg(*this, element); (void) loweredParams.claimNext(); loweredParams.finish(); @@ -957,7 +956,8 @@ void SILGenFunction::emitClassConstructorAllocator(ConstructorDecl *ctor) { if (ctor->requiresUnavailableDeclABICompatibilityStubs()) emitApplyOfUnavailableCodeReached(); - SILValue selfMetaValue = emitConstructorMetatypeArg(*this, ctor); + AllocatorMetatype = emitConstructorMetatypeArg(*this, ctor); + SILValue selfMetaValue = AllocatorMetatype; // Allocate the "self" value. VarDecl *selfDecl = ctor->getImplicitSelfDecl(); @@ -1758,18 +1758,20 @@ void SILGenFunction::emitInitAccessor(AccessorDecl *accessor) { // Emit `newValue` argument. emitBasicProlog(accessor, - accessor->getParameters(), /*selfParam=*/nullptr, + accessor->getParameters(), + /*selfParam=*/nullptr, TupleType::getEmpty(F.getASTContext()), /*errorType=*/llvm::None, /*throwsLoc=*/SourceLoc(), /*ignored parameters*/ - accessedProperties.size()); + accessedProperties.size() + 1); // Emit arguments for all `accesses` properties. if (!accessedProperties.empty()) { auto propertyIter = accessedProperties.begin(); auto propertyArgs = accessorTy->getParameters().slice( - accessorTy->getNumParameters() - accessedProperties.size()); + accessorTy->getNumParameters() - accessedProperties.size() - 1, + accessedProperties.size()); for (const auto &argument : propertyArgs) { createArgument(*propertyIter, getSILTypeInContext(argument, accessorTy)); @@ -1777,6 +1779,9 @@ void SILGenFunction::emitInitAccessor(AccessorDecl *accessor) { } } + // Emit `self` argument. + emitConstructorMetatypeArg(*this, accessor); + prepareEpilog(accessor, accessor->getResultInterfaceType(), accessor->getEffectiveThrownErrorType(), diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp index d573c55777916..41eb49cd53e50 100644 --- a/lib/SILGen/SILGenFunction.cpp +++ b/lib/SILGen/SILGenFunction.cpp @@ -1882,26 +1882,49 @@ void SILGenFunction::emitAssignOrInit(SILLocation loc, ManagedValue selfValue, if (!substitutions.empty()) fieldTy = fieldTy.subst(substitutions); + auto *initAccessor = field->getOpaqueAccessor(AccessorKind::Init); + // Emit the init accessor function partially applied to the base. SILValue initFRef = emitGlobalFunctionRef( - loc, getAccessorDeclRef(field->getOpaqueAccessor(AccessorKind::Init))); + loc, getAccessorDeclRef(initAccessor)); auto initTy = initFRef->getType().castTo(); - if (!substitutions.empty()) { - // If there are substitutions we need to emit partial apply to - // apply substitutions to the init accessor reference type. - initTy = initTy->substGenericArgs(SGM.M, substitutions, - getTypeExpansionContext()); + // If there are substitutions we need to emit partial apply to + // apply substitutions to the init accessor reference type. + initTy = initTy->substGenericArgs(SGM.M, substitutions, + getTypeExpansionContext()); + + // Emit partial apply with self metatype argument to produce a substituted + // init accessor reference. + auto selfTy = selfValue.getType().getASTType(); + auto metatypeTy = MetatypeType::get(selfTy); - // Emit partial apply without argument to produce a substituted - // init accessor reference. - PartialApplyInst *initPAI = - B.createPartialApply(loc, initFRef, substitutions, ArrayRef(), - ParameterConvention::Direct_Guaranteed); - initFRef = emitManagedRValueWithCleanup(initPAI).getValue(); + SILValue selfMetatype; + if (selfTy->getClassOrBoundGenericClass()) { + selfMetatype = B.createValueMetatype(loc, getLoweredType(metatypeTy), + selfValue).getValue(); + } else { + selfMetatype = B.createMetatype(loc, getLoweredType(metatypeTy)); } + auto expectedSelfTy = initAccessor->getDeclContext()->getSelfInterfaceType() + .subst(substitutions); + + // This should only happen in the invalid case where we attempt to initialize + // superclass storage from a subclass initializer. However, we shouldn't + // crash, so emit the appropriate cast so that we can recover and diagnose + // later. + if (!expectedSelfTy->isEqual(selfTy)) { + selfMetatype = B.createUpcast(loc, selfMetatype, + getLoweredType(MetatypeType::get(expectedSelfTy))); + } + PartialApplyInst *initPAI = + B.createPartialApply(loc, initFRef, substitutions, selfMetatype, + ParameterConvention::Direct_Guaranteed, + PartialApplyInst::OnStackKind::OnStack); + initFRef = emitManagedRValueWithCleanup(initPAI).getValue(); + // Check whether value is supposed to be passed indirectly and // materialize if required. { diff --git a/test/IRGen/init_accessor_dynamic_self.swift b/test/IRGen/init_accessor_dynamic_self.swift new file mode 100644 index 0000000000000..1835ef9e0e890 --- /dev/null +++ b/test/IRGen/init_accessor_dynamic_self.swift @@ -0,0 +1,21 @@ +// RUN: %target-swift-frontend -emit-ir %s + +public class C { + private var _count: Int + + var count: Int { + @storageRestrictions(initializes: _count) + init { + print(Self.self) // crash here + _count = newValue + } + get { _count } + set { } + } + + init() { + count = 0 + } +} + +let c = C() diff --git a/test/Interpreter/init_accessors.swift b/test/Interpreter/init_accessors.swift index dcbed65b7256e..d8e2ee7c2bc64 100644 --- a/test/Interpreter/init_accessors.swift +++ b/test/Interpreter/init_accessors.swift @@ -922,3 +922,35 @@ do { // CHECK-NEXT: init accessor is called: 42 // CHECK-NEXT: nonmutating set called: 0 // CHECK-NEXT: test-nonmutating-set-4: TestNonMutatingSetCustom(_count: 42) + +do { + class Base { + var _count: Int + + var count: Int { + @storageRestrictions(initializes: _count) + init { + print("init accessor with Self = \(Self.self)") + _count = newValue + } + + get { _count } + + set {} + } + + init() { + count = 42 + } + } + + class Sub: Base {} + + print("- init accessor vs dynamic Self") + _ = Base() + _ = Sub() +} + +// CHECK-NEXT: - init accessor vs dynamic Self +// CHECK-NEXT: init accessor with Self = Base +// CHECK-NEXT: init accessor with Self = Sub \ No newline at end of file diff --git a/test/SILOptimizer/init_accessor_raw_sil_lowering.swift b/test/SILOptimizer/init_accessor_raw_sil_lowering.swift index 653eb70c552fe..44be314b81420 100644 --- a/test/SILOptimizer/init_accessor_raw_sil_lowering.swift +++ b/test/SILOptimizer/init_accessor_raw_sil_lowering.swift @@ -47,11 +47,11 @@ final class TestIndirectionThroughStorage { // CHECK: [[STORAGE_INIT:%.*]] = function_ref @$s23assign_or_init_lowering29TestIndirectionThroughStorageC8_storage33_DE106275C2F16FB3D05881E72FBD87C8LLAA0H0_pAC1TAaFPRts_XPvpfi : $@convention(thin) () -> @out any Storage // CHECK-NEXT: {{.*}} = apply [[STORAGE_INIT]]([[STORAGE_REF]]) : $@convention(thin) () -> @out any Storage // Initialization: - // CHECK: assign_or_init [init] #TestIndirectionThroughStorage.name, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $String, init {{.*}} : $@convention(thin) (@owned String, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (@owned String) -> () - // CHECK: assign_or_init [init] #TestIndirectionThroughStorage.age, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $Optional, init {{.*}} : $@convention(thin) (Optional, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (Optional) -> () + // CHECK: assign_or_init [init] #TestIndirectionThroughStorage.name, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $String, init {{.*}} : $@noescape @callee_guaranteed (@owned String, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (@owned String) -> () + // CHECK: assign_or_init [init] #TestIndirectionThroughStorage.age, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $Optional, init {{.*}} : $@noescape @callee_guaranteed (Optional, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (Optional) -> () // Explicit set: - // CHECK: assign_or_init [set] #TestIndirectionThroughStorage.name, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $String, init {{.*}} : $@convention(thin) (@owned String, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (@owned String) -> () - // CHECK: assign_or_init [set] #TestIndirectionThroughStorage.age, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $Optional, init {{.*}} : $@convention(thin) (Optional, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (Optional) -> () + // CHECK: assign_or_init [set] #TestIndirectionThroughStorage.name, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $String, init {{.*}} : $@noescape @callee_guaranteed (@owned String, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (@owned String) -> () + // CHECK: assign_or_init [set] #TestIndirectionThroughStorage.age, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $Optional, init {{.*}} : $@noescape @callee_guaranteed (Optional, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (Optional) -> () init(name: String, age: Int) { self.name = name self.age = age @@ -63,8 +63,8 @@ final class TestIndirectionThroughStorage { // CHECK: [[STORAGE_INIT:%.*]] = function_ref @$s23assign_or_init_lowering29TestIndirectionThroughStorageC8_storage33_DE106275C2F16FB3D05881E72FBD87C8LLAA0H0_pAC1TAaFPRts_XPvpfi : $@convention(thin) () -> @out any Storage // CHECK-NEXT: {{.*}} = apply [[STORAGE_INIT]]([[STORAGE_REF]]) : $@convention(thin) () -> @out any Storage // Initialization: - // CHECK: assign_or_init [init] #TestIndirectionThroughStorage.name, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $String, init {{.*}} : $@convention(thin) (@owned String, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (@owned String) -> () - // CHECK: assign_or_init [init] #TestIndirectionThroughStorage.age, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $Optional, init {{.*}} : $@convention(thin) (Optional, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (Optional) -> () + // CHECK: assign_or_init [init] #TestIndirectionThroughStorage.name, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $String, init {{.*}} : $@noescape @callee_guaranteed (@owned String, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (@owned String) -> () + // CHECK: assign_or_init [init] #TestIndirectionThroughStorage.age, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $Optional, init {{.*}} : $@noescape @callee_guaranteed (Optional, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (Optional) -> () // Explicit set: // CHECK: [[STORAGE_SETTER:%.*]] = function_ref @$s23assign_or_init_lowering29TestIndirectionThroughStorageC7storageAA0H0_pAC1TAaEPRts_XPvs : $@convention(method) (@in any Storage, @guaranteed TestIndirectionThroughStorage) -> () // CHECK-NEXT: {{.*}} = apply [[STORAGE_SETTER]]({{.*}}, [[SELF]]) : $@convention(method) (@in any Storage, @guaranteed TestIndirectionThroughStorage) -> () @@ -104,8 +104,8 @@ struct TestAccessOfOnePatternVars { // CHECK-NEXT: {{.*}} = apply [[Y_INIT]]() : $@convention(thin) () -> @owned String // CHECK-NOT: [[X_REF:%.*]] = struct_element_addr %3 : $*TestAccessOfOnePatternVars, #TestAccessOfOnePatternVars.x // CHECK-NOT: [[Y_REF:%.*]] = struct_element_addr {{.*}} : $*TestAccessOfOnePatternVars, #TestAccessOfOnePatternVars.y - // CHECK: assign_or_init [init] #TestAccessOfOnePatternVars.data, self {{.*}} : $*TestAccessOfOnePatternVars, value {{.*}} : $(Int, String), init {{.*}} : $@convention(thin) (Int, @owned String, @inout Int, @inout String) -> (), set {{.*}} : $@noescape @callee_guaranteed (Int, @owned String) -> () - // CHECK: assign_or_init [init] #TestAccessOfOnePatternVars.other, self {{.*}} : $*TestAccessOfOnePatternVars, value {{.*}} : $Bool, init {{.*}} : $@convention(thin) (Bool, @inout Int) -> (), set {{.*}} : $@noescape @callee_guaranteed (Bool) -> () + // CHECK: assign_or_init [init] #TestAccessOfOnePatternVars.data, self {{.*}} : $*TestAccessOfOnePatternVars, value {{.*}} : $(Int, String), init {{.*}} : $@noescape @callee_guaranteed (Int, @owned String, @inout Int, @inout String) -> (), set {{.*}} : $@noescape @callee_guaranteed (Int, @owned String) -> () + // CHECK: assign_or_init [init] #TestAccessOfOnePatternVars.other, self {{.*}} : $*TestAccessOfOnePatternVars, value {{.*}} : $Bool, init {{.*}} : $@noescape @callee_guaranteed (Bool, @inout Int) -> (), set {{.*}} : $@noescape @callee_guaranteed (Bool) -> () init(x: Int, y: String) { self.x = x self.y = y @@ -139,15 +139,18 @@ struct Test1 { // CHECK-LABEL: sil hidden [ossa] @$s23assign_or_init_lowering5Test1V1aACSi_tcfC : $@convention(method) (Int, @thin Test1.Type) -> @owned Test1 init(a: Int) { - // CHECK: [[INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering5Test1V1aSivi : $@convention(thin) (Int) -> @out Int - // CHECK: assign_or_init [init] #Test1.a, self {{.*}}, value [[VALUE:%.*]] : $Int, init [[INIT_REF]] : $@convention(thin) (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () + // CHECK: [[INIT_REF_FN:%.*]] = function_ref @$s23assign_or_init_lowering5Test1V1aSivi : $@convention(thin) (Int, @thin Test1.Type) -> @out Int + // CHECK: [[INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF_FN]](%1) : $@convention(thin) (Int, @thin Test1.Type) -> @out Int + // CHECK: assign_or_init [init] #Test1.a, self {{.*}}, value [[VALUE:%.*]] : $Int, init [[INIT_REF]] : $@noescape @callee_guaranteed (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () self.a = a - // CHECK: [[INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering5Test1V1bSSvi : $@convention(thin) (@owned String) -> (@out Int, @out String) - // CHECK: assign_or_init [init] [assign=0] #Test1.b, self {{.*}}, value [[VALUE:%.*]] : $String, init [[INIT_REF]] : $@convention(thin) (@owned String) -> (@out Int, @out String), set {{.*}} : $@noescape @callee_guaranteed (@owned String) -> () + // CHECK: [[INIT_REF_FN:%.*]] = function_ref @$s23assign_or_init_lowering5Test1V1bSSvi : $@convention(thin) (@owned String, @thin Test1.Type) -> (@out Int, @out String) + // CHECK: [[INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF_FN]](%1) : $@convention(thin) (@owned String, @thin Test1.Type) -> (@out Int, @out String) + // CHECK: assign_or_init [init] [assign=0] #Test1.b, self {{.*}}, value [[VALUE:%.*]] : $String, init [[INIT_REF]] : $@noescape @callee_guaranteed (@owned String) -> (@out Int, @out String), set {{.*}} : $@noescape @callee_guaranteed (@owned String) -> () self.a = -1 self.b = "" - // CHECK: [[INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering5Test1V1aSivi : $@convention(thin) (Int) -> @out Int - // CHECK: assign_or_init [set] #Test1.a, self {{.*}}, value [[VALUE:%.*]] : $Int, init [[INIT_REF]] : $@convention(thin) (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () + // CHECK: [[INIT_REF_FN:%.*]] = function_ref @$s23assign_or_init_lowering5Test1V1aSivi : $@convention(thin) (Int, @thin Test1.Type) -> @out Int + // CHECK: [[INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF_FN]](%1) : $@convention(thin) (Int, @thin Test1.Type) -> @out Int + // CHECK: assign_or_init [set] #Test1.a, self {{.*}}, value [[VALUE:%.*]] : $Int, init [[INIT_REF]] : $@noescape @callee_guaranteed (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () self.a = a } } @@ -170,18 +173,18 @@ struct Test2 { // CHECK-LABEL: sil hidden [ossa] @$s23assign_or_init_lowering5Test2V1a1bACyxGSi_xtcfC : $@convention(method) (Int, @in T, @thin Test2.Type) -> @out Test2 init(a: Int, b: T) { - // CHECK: [[INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering5Test2V4pairSi_xtvi : $@convention(thin) <τ_0_0> (Int, @in τ_0_0) -> (@out Int, @out τ_0_0) - // CHECK-NEXT: [[SUBST_INIT_REF:%.*]] = partial_apply [callee_guaranteed] [[INIT_REF]]() : $@convention(thin) <τ_0_0> (Int, @in τ_0_0) -> (@out Int, @out τ_0_0) - // CHECK: assign_or_init [init] #Test2.pair, self {{.*}}, value [[VALUE:%.*]] : $*(Int, T), init [[SUBST_INIT_REF]] : $@callee_guaranteed (Int, @in T) -> (@out Int, @out T), set {{.*}} : $@noescape @callee_guaranteed (Int, @in T) -> () + // CHECK: [[INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering5Test2V4pairSi_xtvi : $@convention(thin) <τ_0_0> (Int, @in τ_0_0, @thin Test2<τ_0_0>.Type) -> (@out Int, @out τ_0_0) + // CHECK-NEXT: [[SUBST_INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF]](%3) : $@convention(thin) <τ_0_0> (Int, @in τ_0_0, @thin Test2<τ_0_0>.Type) -> (@out Int, @out τ_0_0) + // CHECK: assign_or_init [init] #Test2.pair, self {{.*}}, value [[VALUE:%.*]] : $*(Int, T), init [[SUBST_INIT_REF]] : $@noescape @callee_guaranteed (Int, @in T) -> (@out Int, @out T), set {{.*}} : $@noescape @callee_guaranteed (Int, @in T) -> () self.pair = (a, b) - // CHECK: [[INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering5Test2V4pairSi_xtvi : $@convention(thin) <τ_0_0> (Int, @in τ_0_0) -> (@out Int, @out τ_0_0) - // CHECK-NEXT: [[SUBST_INIT_REF:%.*]] = partial_apply [callee_guaranteed] [[INIT_REF]]() : $@convention(thin) <τ_0_0> (Int, @in τ_0_0) -> (@out Int, @out τ_0_0) - // CHECK: assign_or_init [init] [assign=0] [assign=1] #Test2.pair, self {{.*}}, value [[VALUE:%.*]] : $*(Int, T), init [[SUBST_INIT_REF]] : $@callee_guaranteed (Int, @in T) -> (@out Int, @out T), set {{.*}} : $@noescape @callee_guaranteed (Int, @in T) -> () + // CHECK: [[INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering5Test2V4pairSi_xtvi : $@convention(thin) <τ_0_0> (Int, @in τ_0_0, @thin Test2<τ_0_0>.Type) -> (@out Int, @out τ_0_0) + // CHECK-NEXT: [[SUBST_INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF]](%3) : $@convention(thin) <τ_0_0> (Int, @in τ_0_0, @thin Test2<τ_0_0>.Type) -> (@out Int, @out τ_0_0) + // CHECK: assign_or_init [init] [assign=0] [assign=1] #Test2.pair, self {{.*}}, value [[VALUE:%.*]] : $*(Int, T), init [[SUBST_INIT_REF]] : $@noescape @callee_guaranteed (Int, @in T) -> (@out Int, @out T), set {{.*}} : $@noescape @callee_guaranteed (Int, @in T) -> () self.pair = (0, b) self._c = "" - // CHECK: [[INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering5Test2V4pairSi_xtvi : $@convention(thin) <τ_0_0> (Int, @in τ_0_0) -> (@out Int, @out τ_0_0) - // CHECK-NEXT: [[SUBST_INIT_REF:%.*]] = partial_apply [callee_guaranteed] [[INIT_REF]]() : $@convention(thin) <τ_0_0> (Int, @in τ_0_0) -> (@out Int, @out τ_0_0) - // CHECK: assign_or_init [set] #Test2.pair, self {{.*}}, value [[VALUE:%.*]] : $*(Int, T), init [[SUBST_INIT_REF]] : $@callee_guaranteed (Int, @in T) -> (@out Int, @out T), set {{.*}} : $@noescape @callee_guaranteed (Int, @in T) -> () + // CHECK: [[INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering5Test2V4pairSi_xtvi : $@convention(thin) <τ_0_0> (Int, @in τ_0_0, @thin Test2<τ_0_0>.Type) -> (@out Int, @out τ_0_0) + // CHECK-NEXT: [[SUBST_INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF]](%3) : $@convention(thin) <τ_0_0> (Int, @in τ_0_0, @thin Test2<τ_0_0>.Type) -> (@out Int, @out τ_0_0) + // CHECK: assign_or_init [set] #Test2.pair, self {{.*}}, value [[VALUE:%.*]] : $*(Int, T), init [[SUBST_INIT_REF]] : $@noescape @callee_guaranteed (Int, @in T) -> (@out Int, @out T), set {{.*}} : $@noescape @callee_guaranteed (Int, @in T) -> () self.pair = (1, b) } } @@ -197,8 +200,9 @@ struct Test { // CHECK-LABEL: sil hidden [ossa] @$s23assign_or_init_lowering4TestV1vACSi_tcfC : $@convention(method) (Int, @thin Test.Type) -> Test init(v: Int) { - // CHECK: [[INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering4TestV4testSivi : $@convention(thin) (Int) -> () - // CHECK: assign_or_init [init] #Test.test, self {{.*}}, value %0 : $Int, init [[INIT_REF]] : $@convention(thin) (Int) -> (), set {{.*}} : $@noescape @callee_guaranteed (Int) -> () + // CHECK: [[INIT_REF_FN:%.*]] = function_ref @$s23assign_or_init_lowering4TestV4testSivi : $@convention(thin) (Int, @thin Test.Type) -> () + // CHECK-NEXT: [[INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF_FN]](%1) : $@convention(thin) (Int, @thin Test.Type) -> () + // CHECK: assign_or_init [init] #Test.test, self {{.*}}, value %0 : $Int, init [[INIT_REF]] : $@noescape @callee_guaranteed (Int) -> (), set {{.*}} : $@noescape @callee_guaranteed (Int) -> () self.test = v } } @@ -225,10 +229,11 @@ func test_default_inits() { // CHECK: [[DEFAULT:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test1L_V1xSivpfi : $@convention(thin) () -> Int // CHECK-NEXT: [[INIT_VAL:%.*]] = apply [[DEFAULT]]() : $@convention(thin) () -> Int // CHECK-NEXT: [[SELF_REF:%.*]] = begin_access [modify] [static] [[SELF]] : $*Test1 - // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test1L_V1xSivi : $@convention(thin) (Int) -> @out Int + // CHECK: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test1L_V1xSivi : $@convention(thin) (Int, @thin Test1.Type) -> @out Int + // CHECK: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]](%0) : $@convention(thin) (Int, @thin Test1.Type) -> @out Int // CHECK: [[SETTER_REF:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test1L_V1xSivs : $@convention(method) (Int, @inout Test1) -> () // CHECK-NEXT: [[SETTER:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[SETTER_REF]]([[SELF_REF]]) : $@convention(method) (Int, @inout Test1) -> () - // CHECK-NEXT: assign_or_init [init] #Test1.x, self %2 : $*Test1, value [[INIT_VAL]] : $Int, init [[INIT_ACCESSOR]] : $@convention(thin) (Int) -> @out Int, set [[SETTER]] : $@noescape @callee_guaranteed (Int) -> () + // CHECK-NEXT: assign_or_init [init] #Test1.x, self %2 : $*Test1, value [[INIT_VAL]] : $Int, init [[INIT_ACCESSOR]] : $@noescape @callee_guaranteed (Int) -> @out Int, set [[SETTER]] : $@noescape @callee_guaranteed (Int) -> () // CHECK-NEXT: end_access [[SELF_REF]] : $*Test1 // CHECK-NEXT: destroy_value [[SETTER]] : $@noescape @callee_guaranteed (Int) -> () init() { @@ -239,14 +244,15 @@ func test_default_inits() { // CHECK: [[DEFAULT:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test1L_V1xSivpfi : $@convention(thin) () -> Int // CHECK-NEXT: [[INIT_VAL:%.*]] = apply [[DEFAULT]]() : $@convention(thin) () -> Int // CHECK-NEXT: [[SELF_REF:%.*]] = begin_access [modify] [static] [[SELF]] : $*Test1 - // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test1L_V1xSivi : $@convention(thin) (Int) -> @out Int + // CHECK: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test1L_V1xSivi : $@convention(thin) (Int, @thin Test1.Type) -> @out Int + // CHECK: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]](%1) : $@convention(thin) (Int, @thin Test1.Type) -> @out Int // CHECK: [[SETTER_REF:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test1L_V1xSivs : $@convention(method) (Int, @inout Test1) -> () // CHECK-NEXT: [[SETTER:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[SETTER_REF]]([[SELF_REF]]) : $@convention(method) (Int, @inout Test1) -> () - // CHECK-NEXT: assign_or_init [init] #Test1.x, self %3 : $*Test1, value [[INIT_VAL]] : $Int, init [[INIT_ACCESSOR]] : $@convention(thin) (Int) -> @out Int, set [[SETTER]] : $@noescape @callee_guaranteed (Int) -> () + // CHECK-NEXT: assign_or_init [init] #Test1.x, self %3 : $*Test1, value [[INIT_VAL]] : $Int, init [[INIT_ACCESSOR]] : $@noescape @callee_guaranteed (Int) -> @out Int, set [[SETTER]] : $@noescape @callee_guaranteed (Int) -> () // CHECK-NEXT: end_access [[SELF_REF]] : $*Test1 // CHECK-NEXT: destroy_value [[SETTER]] : $@noescape @callee_guaranteed (Int) -> () // - // CHECK: assign_or_init [set] #Test1.x, self {{.*}} : $*Test1, value %0 : $Int, init {{.*}} : $@convention(thin) (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () + // CHECK: assign_or_init [set] #Test1.x, self {{.*}} : $*Test1, value %0 : $Int, init {{.*}} : $@noescape @callee_guaranteed (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () init(x: Int) { self.x = x } @@ -276,13 +282,14 @@ func test_default_inits() { // CHECK-NEXT: [[NEW_VALUE_1:%.*]] = tuple_element_addr [[NEW_VALUE]] : $*(T, String), 1 // CHECK-NEXT: copy_addr [take] [[T]] to [init] [[NEW_VALUE_0]] : $*T // CHECK-NEXT: store [[STR]] to [init] [[NEW_VALUE_1]] : $*String - // CHECK: [[INIT_ACCESSOR_REF:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test2L_C1xx_SStvi : $@convention(thin) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String) -> @out (τ_0_0, String) - // CHECK-NEXT: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [[INIT_ACCESSOR_REF]]() : $@convention(thin) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String) -> @out (τ_0_0, String) + // CHECK: [[INIT_ACCESSOR_REF:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test2L_C1xx_SStvi : $@convention(thin) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String, @thick Test2<τ_0_0>.Type) -> @out (τ_0_0, String) + // CHECK-NEXT: [[METATYPE:%.*]] = value_metatype $@thick Test2.Type, {{%.*}} + // CHECK-NEXT: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_REF]]([[METATYPE]]) : $@convention(thin) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String, @thick Test2<τ_0_0>.Type) -> @out (τ_0_0, String) // CHECK: [[SETTER_REF:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test2L_C1xx_SStvs : $@convention(method) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String, @guaranteed Test2<τ_0_0>) -> () // CHECK-NEXT: [[SETTER:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[SETTER_REF]]([[SELF]]) : $@convention(method) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String, @guaranteed Test2<τ_0_0>) -> () - // CHECK-NEXT: assign_or_init [init] #Test2.x, self [[SELF]] : $Test2, value [[NEW_VALUE]] : $*(T, String), init [[INIT_ACCESSOR]] : $@callee_guaranteed (@in T, @owned String) -> @out (T, String), set [[SETTER]] : $@noescape @callee_guaranteed (@in T, @owned String) -> () + // CHECK-NEXT: assign_or_init [init] #Test2.x, self [[SELF]] : $Test2, value [[NEW_VALUE]] : $*(T, String), init [[INIT_ACCESSOR]] : $@noescape @callee_guaranteed (@in T, @owned String) -> @out (T, String), set [[SETTER]] : $@noescape @callee_guaranteed (@in T, @owned String) -> () // CHECK-NEXT: destroy_value [[SETTER]] : $@noescape @callee_guaranteed (@in T, @owned String) -> () - // CHECK-NEXT: destroy_value [[INIT_ACCESSOR]] : $@callee_guaranteed (@in T, @owned String) -> @out (T, String) + // CHECK-NEXT: destroy_value [[INIT_ACCESSOR]] : $@noescape @callee_guaranteed (@in T, @owned String) -> @out (T, String) // CHECK-NEXT: dealloc_stack [[NEW_VALUE]] : $*(T, String) // CHECK-NEXT: dealloc_stack [[T]] : $*T init() { @@ -299,19 +306,20 @@ func test_default_inits() { // CHECK-NEXT: [[NEW_VALUE_1:%.*]] = tuple_element_addr [[NEW_VALUE]] : $*(T, String), 1 // CHECK-NEXT: copy_addr [take] [[T]] to [init] [[NEW_VALUE_0]] : $*T // CHECK-NEXT: store [[STR]] to [init] [[NEW_VALUE_1]] : $*String - // CHECK: [[INIT_ACCESSOR_REF:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test2L_C1xx_SStvi : $@convention(thin) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String) -> @out (τ_0_0, String) - // CHECK-NEXT: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [[INIT_ACCESSOR_REF]]() : $@convention(thin) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String) -> @out (τ_0_0, String) + // CHECK: [[INIT_ACCESSOR_REF:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test2L_C1xx_SStvi : $@convention(thin) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String, @thick Test2<τ_0_0>.Type) -> @out (τ_0_0, String) + // CHECK-NEXT: [[METATYPE:%.*]] = value_metatype $@thick Test2.Type, {{%.*}} + // CHECK-NEXT: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_REF]]([[METATYPE]]) : $@convention(thin) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String, @thick Test2<τ_0_0>.Type) -> @out (τ_0_0, String) // CHECK: [[SETTER_REF:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test2L_C1xx_SStvs : $@convention(method) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String, @guaranteed Test2<τ_0_0>) -> () // CHECK-NEXT: [[SETTER:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[SETTER_REF]]([[SELF]]) : $@convention(method) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String, @guaranteed Test2<τ_0_0>) -> () - // CHECK-NEXT: assign_or_init [init] #Test2.x, self [[SELF]] : $Test2, value [[NEW_VALUE]] : $*(T, String), init [[INIT_ACCESSOR]] : $@callee_guaranteed (@in T, @owned String) -> @out (T, String), set [[SETTER]] : $@noescape @callee_guaranteed (@in T, @owned String) -> () + // CHECK-NEXT: assign_or_init [init] #Test2.x, self [[SELF]] : $Test2, value [[NEW_VALUE]] : $*(T, String), init [[INIT_ACCESSOR]] : $@noescape @callee_guaranteed (@in T, @owned String) -> @out (T, String), set [[SETTER]] : $@noescape @callee_guaranteed (@in T, @owned String) -> () // CHECK-NEXT: destroy_value [[SETTER]] : $@noescape @callee_guaranteed (@in T, @owned String) -> () - // CHECK-NEXT: destroy_value [[INIT_ACCESSOR]] : $@callee_guaranteed (@in T, @owned String) -> @out (T, String) + // CHECK-NEXT: destroy_value [[INIT_ACCESSOR]] : $@noescape @callee_guaranteed (@in T, @owned String) -> @out (T, String) // CHECK-NEXT: dealloc_stack [[NEW_VALUE]] : $*(T, String) // CHECK-NEXT: dealloc_stack [[T]] : $*T // - // CHECK: assign_or_init [init] [assign=0] #Test2.x, self [[SELF]] : $Test2, value {{.*}} : $*(T, String), init {{.*}} : $@callee_guaranteed (@in T, @owned String) -> @out (T, String), set {{.*}} : $@noescape @callee_guaranteed (@in T, @owned String) -> () + // CHECK: assign_or_init [init] [assign=0] #Test2.x, self [[SELF]] : $Test2, value {{.*}} : $*(T, String), init {{.*}} : $@noescape @callee_guaranteed (@in T, @owned String) -> @out (T, String), set {{.*}} : $@noescape @callee_guaranteed (@in T, @owned String) -> () // CHECK: assign %2 to [init] [[Y_REF:%.*]] : $*Int - // CHECK: assign_or_init [set] #Test2.x, self [[SELF]] : $Test2, value {{.*}} : $*(T, String), init {{.*}} : $@callee_guaranteed (@in T, @owned String) -> @out (T, String), set {{.*}} : $@noescape @callee_guaranteed (@in T, @owned String) -> () + // CHECK: assign_or_init [set] #Test2.x, self [[SELF]] : $Test2, value {{.*}} : $*(T, String), init {{.*}} : $@noescape @callee_guaranteed (@in T, @owned String) -> @out (T, String), set {{.*}} : $@noescape @callee_guaranteed (@in T, @owned String) -> () init(x: (T, String), y: Int) { self.x = x self.y = y @@ -371,10 +379,10 @@ func test_default_inits() { // CHECK: [[SL:%.*]] = mark_uninitialized [rootself] %0 // CHECK: [[X_DEFAULT:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test4L_C1xSivpfi : $@convention(thin) () -> Int // CHECK-NEXT: [[X_VALUE:%.*]] = apply [[X_DEFAULT]]() : $@convention(thin) () -> Int - // CHECK: assign_or_init [init] #Test4.x, self [[SL]] : $Test4, value [[X_VALUE]] : $Int, init {{.*}} : $@convention(thin) (Int) -> @out Int, set undef : $@convention(thin) (Int) -> @out Int + // CHECK: assign_or_init [init] #Test4.x, self [[SL]] : $Test4, value [[X_VALUE]] : $Int, init {{.*}} : $@noescape @callee_guaranteed (Int) -> @out Int, set undef : $@noescape @callee_guaranteed (Int) -> @out Int // CHECK: [[Y_DEFAULT:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test4L_C1ySSvpfi : $@convention(thin) () -> @owned String // CHECK-NEXT: [[Y_VALUE:%.*]] = apply [[Y_DEFAULT]]() : $@convention(thin) () -> @owned String - // CHECK: assign_or_init [init] #Test4.y, self [[SL]] : $Test4, value [[Y_VALUE]] : $String, init {{.*}} : $@convention(thin) (@owned String) -> @out String, set undef : $@convention(thin) (@owned String) -> @out String + // CHECK: assign_or_init [init] #Test4.y, self [[SL]] : $Test4, value [[Y_VALUE]] : $String, init {{.*}} : $@noescape @callee_guaranteed (@owned String) -> @out String, set undef : $@noescape @callee_guaranteed (@owned String) -> @out String } } @@ -423,9 +431,9 @@ func test_handling_of_nonmutating_set() { // CHECK-LABEL: sil private [ossa] @$s23assign_or_init_lowering32test_handling_of_nonmutating_setyyF4TestL_V5countADSi_tcfC : $@convention(method) (Int, @thin Test.Type) -> Test // CHECK: [[INIT_VALUE:%.*]] = function_ref @$s23assign_or_init_lowering32test_handling_of_nonmutating_setyyF4TestL_V5countSivpfi : $@convention(thin) () -> Int // CHECK-NEXT: [[VALUE:%.*]] = apply [[INIT_VALUE]]() : $@convention(thin) () -> Int - // CHECK: assign_or_init [init] #Test.count, self %3 : $*Test, value [[VALUE]] : $Int, init {{.*}} : $@convention(thin) (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () - // CHECK: assign_or_init [set] #Test.count, self %3 : $*Test, value %0 : $Int, init {{.*}} : $@convention(thin) (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () - // CHECK: assign_or_init [set] #Test.count, self %3 : $*Test, value [[ZERO:%.*]] : $Int, init {{.*}} : $@convention(thin) (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () + // CHECK: assign_or_init [init] #Test.count, self %3 : $*Test, value [[VALUE]] : $Int, init {{.*}} : $@noescape @callee_guaranteed (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () + // CHECK: assign_or_init [set] #Test.count, self %3 : $*Test, value %0 : $Int, init {{.*}} : $@noescape @callee_guaranteed (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () + // CHECK: assign_or_init [set] #Test.count, self %3 : $*Test, value [[ZERO:%.*]] : $Int, init {{.*}} : $@noescape @callee_guaranteed (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () init(count: Int) { self.count = count self.count = 0 @@ -448,9 +456,7 @@ func test_handling_of_nonmutating_set() { // CHECK: [[SELF:%.*]] = load [copy] {{.*}} : $*TestWithStored // CHECK: [[SETTER_REF:%.*]] = function_ref @$s23assign_or_init_lowering32test_handling_of_nonmutating_setyyF14TestWithStoredL_V5countSivs : $@convention(method) (Int, @guaranteed TestWithStored) -> () // CHECK-NEXT: [[SETTER_CLOSURE:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[SETTER_REF]]([[SELF]]) : $@convention(method) (Int, @guaranteed TestWithStored) -> () - // CHECK-NEXT: assign_or_init [init] #TestWithStored.count, self [[SELF_REF]] : $*TestWithStored, value %0 : $Int, init {{.*}} : $@convention(thin) (Int) -> @out Int, set [[SETTER_CLOSURE]] : $@noescape @callee_guaranteed (Int) -> () - // CHECK-NEXT: destroy_value [[SETTER_CLOSURE]] : $@noescape @callee_guaranteed (Int) -> () - // CHECK-NEXT: destroy_value [[SELF]] : $TestWithStored + // CHECK-NEXT: assign_or_init [init] #TestWithStored.count, self [[SELF_REF]] : $*TestWithStored, value %0 : $Int, init {{.*}} : $@noescape @callee_guaranteed (Int) -> @out Int, set [[SETTER_CLOSURE]] : $@noescape @callee_guaranteed (Int) -> () init(count: Int) { self.count = count } @@ -461,16 +467,12 @@ func test_handling_of_nonmutating_set() { // // CHECK: [[SETTER_REF:%.*]] = function_ref @$s23assign_or_init_lowering32test_handling_of_nonmutating_setyyF14TestWithStoredL_V5countSivs : $@convention(method) (Int, @guaranteed TestWithStored) -> () // CHECK-NEXT: [[SETTER_CLOSURE:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[SETTER_REF]]([[SELF]]) : $@convention(method) (Int, @guaranteed TestWithStored) -> () - // CHECK-NEXT: assign_or_init [init] #TestWithStored.count, self [[SELF_REF]] : $*TestWithStored, value {{.*}} : $Int, init {{.*}} : $@convention(thin) (Int) -> @out Int, set [[SETTER_CLOSURE]] : $@noescape @callee_guaranteed (Int) -> () - // CHECK-NEXT: destroy_value [[SETTER_CLOSURE]] : $@noescape @callee_guaranteed (Int) -> () - // CHECK-NEXT: destroy_value [[SELF]] : $TestWithStored + // CHECK-NEXT: assign_or_init [init] #TestWithStored.count, self [[SELF_REF]] : $*TestWithStored, value {{.*}} : $Int, init {{.*}} : $@noescape @callee_guaranteed (Int) -> @out Int, set [[SETTER_CLOSURE]] : $@noescape @callee_guaranteed (Int) -> () // // CHECK: [[SELF:%.*]] = load [copy] {{.*}} : $*TestWithStored // CHECK: [[SETTER_REF:%.*]] = function_ref @$s23assign_or_init_lowering32test_handling_of_nonmutating_setyyF14TestWithStoredL_V5countSivs : $@convention(method) (Int, @guaranteed TestWithStored) -> () // CHECK-NEXT: [[SETTER_CLOSURE:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[SETTER_REF]]([[SELF]]) : $@convention(method) (Int, @guaranteed TestWithStored) -> () - // CHECK-NEXT: assign_or_init [set] #TestWithStored.count, self [[SELF_REF]] : $*TestWithStored, value %0 : $Int, init {{.*}} : $@convention(thin) (Int) -> @out Int, set [[SETTER_CLOSURE]] : $@noescape @callee_guaranteed (Int) -> () - // CHECK-NEXT: destroy_value [[SETTER_CLOSURE]] : $@noescape @callee_guaranteed (Int) -> () - // CHECK-NEXT: destroy_value [[SELF]] : $TestWithStored + // CHECK-NEXT: assign_or_init [set] #TestWithStored.count, self [[SELF_REF]] : $*TestWithStored, value %0 : $Int, init {{.*}} : $@noescape @callee_guaranteed (Int) -> @out Int, set [[SETTER_CLOSURE]] : $@noescape @callee_guaranteed (Int) -> () init(value: Int) { self.count = 0 self.count = value diff --git a/test/SILOptimizer/init_accessors.swift b/test/SILOptimizer/init_accessors.swift index 47a1959bbc7e9..a1a6bb01b27c0 100644 --- a/test/SILOptimizer/init_accessors.swift +++ b/test/SILOptimizer/init_accessors.swift @@ -10,8 +10,8 @@ struct TestInit { var full: (Int, Int) var point: (Int, Int) { - // CHECK-LABEL: sil private [ossa] @$s14init_accessors8TestInitV5pointSi_Sitvi : $@convention(thin) (Int, Int, @inout Int) -> (@out Int, @out (Int, Int)) - // CHECK: bb0([[Y_REF:%.*]] : $*Int, [[FULL_REF:%.*]] : $*(Int, Int), [[X_VAL:%.*]] : $Int, [[Y_VAL:%.*]] : $Int, [[X_REF:%.*]] : $*Int): + // CHECK-LABEL: sil private [ossa] @$s14init_accessors8TestInitV5pointSi_Sitvi : $@convention(thin) (Int, Int, @inout Int, @thin TestInit.Type) -> (@out Int, @out (Int, Int)) + // CHECK: bb0([[Y_REF:%.*]] : $*Int, [[FULL_REF:%.*]] : $*(Int, Int), [[X_VAL:%.*]] : $Int, [[Y_VAL:%.*]] : $Int, [[X_REF:%.*]] : $*Int, [[METATYPE:%.*]] : $@thin TestInit.Type): // // CHECK: [[INITIAL_VALUE:%.*]] = tuple ([[X_VAL]] : $Int, [[Y_VAL]] : $Int) // CHECK: ([[X_VAL:%.*]], [[Y_VAL:%.*]]) = destructure_tuple [[INITIAL_VALUE]] : $(Int, Int) @@ -42,13 +42,14 @@ struct TestInit { // CHECK-LABEL: sil hidden [ossa] @$s14init_accessors8TestInitV1x1yACSi_SitcfC : $@convention(method) (Int, Int, @thin TestInit.Type) -> TestInit // CHECK: // function_ref TestInit.point.init - // CHECK-NEXT: [[INIT_ACCESSOR:%.*]] = function_ref @$s14init_accessors8TestInitV5pointSi_Sitvi : $@convention(thin) (Int, Int, @inout Int) -> (@out Int, @out (Int, Int)) + // CHECK-NEXT: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s14init_accessors8TestInitV5pointSi_Sitvi : $@convention(thin) (Int, Int, @inout Int, @thin TestInit.Type) -> (@out Int, @out (Int, Int)) + // CHECK-NEXT: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]](%2) : $@convention(thin) (Int, Int, @inout Int, @thin TestInit.Type) -> (@out Int, @out (Int, Int)) // CHECK: [[SELF_VALUE:%.*]] = begin_access [modify] [dynamic] {{.*}} : $*TestInit // CHECK: [[Y_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*TestInit, #TestInit.y // CHECK-NEXT: [[FULL_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*TestInit, #TestInit.full // CHECK-NEXT: ([[X_VAL:%.*]], [[Y_VAL:%.*]]) = destructure_tuple {{.*}} : $(Int, Int) // CHECK-NEXT: [[X_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*TestInit, #TestInit.x - // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[Y_REF]], [[FULL_REF]], [[X_VAL]], [[Y_VAL]], [[X_REF]]) : $@convention(thin) (Int, Int, @inout Int) -> (@out Int, @out (Int, Int)) + // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[Y_REF]], [[FULL_REF]], [[X_VAL]], [[Y_VAL]], [[X_REF]]) : $@noescape @callee_guaranteed (Int, Int, @inout Int) -> (@out Int, @out (Int, Int)) // CHECK-NEXT: end_access [[SELF_VALUE]] : $*TestInit init(x: Int, y: Int) { self.x = x @@ -70,12 +71,13 @@ struct TestSetter { } // CHECK-LABEL: sil hidden [ossa] @$s14init_accessors10TestSetterV1x1yACSi_SitcfC : $@convention(method) (Int, Int, @thin TestSetter.Type) -> TestSetter - // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s14init_accessors10TestSetterV5pointSi_Sitvi : $@convention(thin) (Int, Int, @inout Int, @inout Int) -> () + // CHECK: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s14init_accessors10TestSetterV5pointSi_Sitvi : $@convention(thin) (Int, Int, @inout Int, @inout Int, @thin TestSetter.Type) -> () + // CHECK: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]](%2) : $@convention(thin) (Int, Int, @inout Int, @inout Int, @thin TestSetter.Type) -> () // CHECK: [[SELF:%.*]] = begin_access [modify] [dynamic] %14 : $*TestSetter // CHECK-NEXT: ([[X:%.*]], [[Y:%.*]]) = destructure_tuple {{.*}} : $(Int, Int) // CHECK-NEXT: [[X_REF:%.*]] = struct_element_addr [[SELF]] : $*TestSetter, #TestSetter.x // CHECK-NEXT: [[Y_REF:%.*]] = struct_element_addr [[SELF]] : $*TestSetter, #TestSetter.y - // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[X]], [[Y]], [[X_REF]], [[Y_REF]]) : $@convention(thin) (Int, Int, @inout Int, @inout Int) -> () + // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[X]], [[Y]], [[X_REF]], [[Y_REF]]) : $@noescape @callee_guaranteed (Int, Int, @inout Int, @inout Int) -> () init(x: Int, y: Int) { self.x = x self.y = y @@ -99,10 +101,11 @@ struct TestInitThenSetter { } // CHECK-LABEL: sil hidden [ossa] @$s14init_accessors18TestInitThenSetterV1x1yACSi_SitcfC : $@convention(method) (Int, Int, @thin TestInitThenSetter.Type) -> TestInitThenSetter - // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s14init_accessors18TestInitThenSetterV5pointSi_Sitvi : $@convention(thin) (Int, Int) -> (@out Int, @out Int) + // CHECK: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s14init_accessors18TestInitThenSetterV5pointSi_Sitvi : $@convention(thin) (Int, Int, @thin TestInitThenSetter.Type) -> (@out Int, @out Int) + // CHECK: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]](%2) : $@convention(thin) (Int, Int, @thin TestInitThenSetter.Type) -> (@out Int, @out Int) // CHECK: [[X_REF:%.*]] = struct_element_addr {{.*}} : $*TestInitThenSetter, #TestInitThenSetter.x // CHECK-NEXT: [[Y_REF:%.*]] = struct_element_addr {{.*}} : $*TestInitThenSetter, #TestInitThenSetter.y - // CHECK: {{.*}} = apply [[INIT_ACCESSOR]]([[X_REF]], [[Y_REF]], {{.*}}) : $@convention(thin) (Int, Int) -> (@out Int, @out Int) + // CHECK: {{.*}} = apply [[INIT_ACCESSOR]]([[X_REF]], [[Y_REF]], {{.*}}) : $@noescape @callee_guaranteed (Int, Int) -> (@out Int, @out Int) // // CHECK: [[SETTER_REF:%.*]] = function_ref @$s14init_accessors18TestInitThenSetterV5pointSi_Sitvs : $@convention(method) (Int, Int, @inout TestInitThenSetter) -> () // CHECK-NEXT: [[SETTER_CLOSURE:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[SETTER_REF]]([[SELF_VALUE:%.*]]) : $@convention(method) (Int, Int, @inout TestInitThenSetter) -> () @@ -143,13 +146,15 @@ struct TestPartialInt { // CHECK-LABEL: sil hidden [ossa] @$s14init_accessors14TestPartialIntV1x1yACSi_SitcfC : $@convention(method) (Int, Int, @thin TestPartialInt.Type) -> TestPartialInt // - // CHECK: [[INIT_REF:%.*]] = function_ref @$s14init_accessors14TestPartialIntV6pointXSivi : $@convention(thin) (Int) -> @out Int + // CHECK: [[INIT_REF_FN:%.*]] = function_ref @$s14init_accessors14TestPartialIntV6pointXSivi : $@convention(thin) (Int, @thin TestPartialInt.Type) -> @out Int + // CHECK: [[INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF_FN]](%2) : $@convention(thin) (Int, @thin TestPartialInt.Type) -> @out Int // CHECK: [[X_REF:%.*]] = struct_element_addr {{.*}} : $*TestPartialInt, #TestPartialInt.x - // CHECK-NEXT: {{.*}} = apply [[INIT_REF]]([[X_REF]], %0) : $@convention(thin) (Int) -> @out Int + // CHECK-NEXT: {{.*}} = apply [[INIT_REF]]([[X_REF]], %0) : $@noescape @callee_guaranteed (Int) -> @out Int // - // CHECK: [[INIT_REF:%.*]] = function_ref @$s14init_accessors14TestPartialIntV6pointYSivi : $@convention(thin) (Int) -> @out Int + // CHECK: [[INIT_REF_FN:%.*]] = function_ref @$s14init_accessors14TestPartialIntV6pointYSivi : $@convention(thin) (Int, @thin TestPartialInt.Type) -> @out Int + // CHECK: [[INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF_FN]](%2) : $@convention(thin) (Int, @thin TestPartialInt.Type) -> @out Int // CHECK: [[Y_REF:%.*]] = struct_element_addr {{.*}} : $*TestPartialInt, #TestPartialInt.y - // CHECK-NEXT: {{.*}} = apply [[INIT_REF]]([[Y_REF]], %1) : $@convention(thin) (Int) -> @out Int + // CHECK-NEXT: {{.*}} = apply [[INIT_REF]]([[Y_REF]], %1) : $@noescape @callee_guaranteed (Int) -> @out Int // // CHECK: [[BUILTIN_ONE:%.*]] = integer_literal $Builtin.IntLiteral, 1 // CHECK: [[SETTER_REF:%.*]] = function_ref @$s14init_accessors14TestPartialIntV6pointXSivs : $@convention(method) (Int, @inout TestPartialInt) -> () @@ -199,16 +204,18 @@ struct TestNoInitAndInit { // CHECK-LABEL: sil hidden [ossa] @$s14init_accessors013TestNoInitAndE0V1x1yACSi_SitcfC : $@convention(method) (Int, Int, @thin TestNoInitAndInit.Type) -> TestNoInitAndInit // - // CHECK: [[INIT_REF:%.*]] = function_ref @$s14init_accessors013TestNoInitAndE0V6pointXSivi : $@convention(thin) (Int, @inout Int) -> () + // CHECK: [[INIT_REF_FN:%.*]] = function_ref @$s14init_accessors013TestNoInitAndE0V6pointXSivi : $@convention(thin) (Int, @inout Int, @thin TestNoInitAndInit.Type) -> () + // CHECK: [[INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF_FN]](%2) : $@convention(thin) (Int, @inout Int, @thin TestNoInitAndInit.Type) -> () // CHECK: [[SELF_REF:%.*]] = begin_access [modify] [dynamic] {{.*}} : $*TestNoInitAndInit // CHECK-NEXT: [[X_REF:%.*]] = struct_element_addr [[SELF_REF]] : $*TestNoInitAndInit, #TestNoInitAndInit.x - // CHECK-NEXT: {{.*}} = apply [[INIT_REF]](%0, [[X_REF]]) : $@convention(thin) (Int, @inout Int) -> () + // CHECK-NEXT: {{.*}} = apply [[INIT_REF]](%0, [[X_REF]]) : $@noescape @callee_guaranteed (Int, @inout Int) -> () // CHECK-NEXT: end_access [[SELF_REF]] : $*TestNoInitAndInit // - // CHECK: [[INIT_REF:%.*]] = function_ref @$s14init_accessors013TestNoInitAndE0V6pointYSivi : $@convention(thin) (Int) -> @out Int + // CHECK: [[INIT_REF_FN:%.*]] = function_ref @$s14init_accessors013TestNoInitAndE0V6pointYSivi : $@convention(thin) (Int, @thin TestNoInitAndInit.Type) -> @out Int + // CHECK: [[INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF_FN]](%2) : $@convention(thin) (Int, @thin TestNoInitAndInit.Type) -> @out Int // CHECK: [[SELF_REF:%.*]] = begin_access [modify] [dynamic] {{.*}} : $*TestNoInitAndInit // CHECK-NEXT: [[Y_REF:%.*]] = struct_element_addr [[SELF_REF]] : $*TestNoInitAndInit, #TestNoInitAndInit.y - // CHECK-NEXT: {{.*}} = apply [[INIT_REF]]([[Y_REF]], %1) : $@convention(thin) (Int) -> @out Int + // CHECK-NEXT: {{.*}} = apply [[INIT_REF]]([[Y_REF]], %1) : $@noescape @callee_guaranteed (Int) -> @out Int // CHECK-NEXT: end_access [[SELF_REF]] : $*TestNoInitAndInit init(x: Int, y: Int) { self.x = x @@ -223,8 +230,8 @@ class TestClass { var y: (Int, [String]) var data: (Int, (Int, [String])) { - // CHECK-LABEL: sil private [ossa] @$s14init_accessors9TestClassC4dataSi_Si_SaySSGttvi : $@convention(thin) (Int, Int, @owned Array) -> (@out Int, @out (Int, Array)) - // CHECK: bb0([[X_REF:%.*]] : $*Int, [[Y_REF:%.*]] : $*(Int, Array), [[X_VAL:%.*]] : $Int, [[Y_VAL_0:%.*]] : $Int, [[Y_VAL_1:%.*]] : @owned $Array): + // CHECK-LABEL: sil private [ossa] @$s14init_accessors9TestClassC4dataSi_Si_SaySSGttvi : $@convention(thin) (Int, Int, @owned Array, @thick TestClass.Type) -> (@out Int, @out (Int, Array)) + // CHECK: bb0([[X_REF:%.*]] : $*Int, [[Y_REF:%.*]] : $*(Int, Array), [[X_VAL:%.*]] : $Int, [[Y_VAL_0:%.*]] : $Int, [[Y_VAL_1:%.*]] : @owned $Array, [[METATYPE:%.*]] : $@thick TestClass.Type): // // CHECK: ([[X_VAL:%.*]], [[Y_VAL:%.*]]) = destructure_tuple {{.*}} : $(Int, (Int, Array)) // CHECK: [[X_ACCESS:%.*]] = begin_access [modify] [static] [[X_REF]] : $*Int @@ -250,14 +257,16 @@ class TestClass { } // CHECK-LABEL: sil hidden [ossa] @$s14init_accessors9TestClassC1x1yACSi_Si_SaySSGttcfc : $@convention(method) (Int, Int, @owned Array, @owned TestClass) -> @owned TestClass - // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s14init_accessors9TestClassC4dataSi_Si_SaySSGttvi : $@convention(thin) (Int, Int, @owned Array) -> (@out Int, @out (Int, Array)) + // CHECK: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s14init_accessors9TestClassC4dataSi_Si_SaySSGttvi : $@convention(thin) (Int, Int, @owned Array, @thick TestClass.Type) -> (@out Int, @out (Int, Array)) + // CHECK: [[METATYPE:%.*]] = value_metatype $@thick TestClass.Type, {{%.*}} + // CHECK: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]]([[METATYPE]]) : $@convention(thin) (Int, Int, @owned Array, @thick TestClass.Type) -> (@out Int, @out (Int, Array)) // CHECK: [[SELF_REF:%.*]] = begin_borrow [[SELF_VALUE:%.*]] : $TestClass // CHECK: [[X_REF:%.*]] = ref_element_addr [[SELF_REF]] : $TestClass, #TestClass.x // CHECK-NEXT: [[Y_REF:%.*]] = ref_element_addr [[SELF_REF]] : $TestClass, #TestClass.y // // CHECK-NEXT: ([[X_VAL:%.*]], [[Y_VAL:%.*]]) = destructure_tuple {{.*}} : $(Int, (Int, Array)) // CHECK-NEXT: ([[Y_VAL_0:%.*]], [[Y_VAL_1:%.*]]) = destructure_tuple [[Y_VAL]] : $(Int, Array) - // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[X_REF]], [[Y_REF]], [[X_VAL]], [[Y_VAL_0]], [[Y_VAL_1]]) : $@convention(thin) (Int, Int, @owned Array) -> (@out Int, @out (Int, Array)) + // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[X_REF]], [[Y_REF]], [[X_VAL]], [[Y_VAL_0]], [[Y_VAL_1]]) : $@noescape @callee_guaranteed (Int, Int, @owned Array) -> (@out Int, @out (Int, Array)) init(x: Int, y: (Int, [String])) { self.data = (x, y) } @@ -268,9 +277,9 @@ struct TestGeneric { var b: T var c: U - // CHECK-LABEL: sil private [ossa] @$s14init_accessors11TestGenericV4datax_xtvi : $@convention(thin) (@in T, @in T, @inout U) -> (@out T, @out T) + // CHECK-LABEL: sil private [ossa] @$s14init_accessors11TestGenericV4datax_xtvi : $@convention(thin) (@in T, @in T, @inout U, @thin TestGeneric.Type) -> (@out T, @out T) // - // CHECK: bb0([[A_REF:%.*]] : $*T, [[B_REF:%.*]] : $*T, [[A_VALUE:%.*]] : $*T, [[B_VALUE:%.*]] : $*T, [[C_REF:%.*]] : $*U): + // CHECK: bb0([[A_REF:%.*]] : $*T, [[B_REF:%.*]] : $*T, [[A_VALUE:%.*]] : $*T, [[B_VALUE:%.*]] : $*T, [[C_REF:%.*]] : $*U, [[METATYPE:%.*]] : $@thin TestGeneric.Type): // // CHECK: [[A_ACCESS:%.*]] = begin_access [modify] [static] [[A_REF]] : $*T // CHECK-NEXT: copy_addr [take] {{.*}} to [init] [[A_ACCESS]] : $*T @@ -298,9 +307,9 @@ struct TestGeneric { // CHECK-LABEL: sil hidden [ossa] @$s14init_accessors11TestGenericV1a1b1cACyxq_Gx_xq_tcfC : $@convention(method) (@in T, @in T, @in U, @thin TestGeneric.Type) -> @out TestGeneric // - // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s14init_accessors11TestGenericV4datax_xtvi : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_0, @inout τ_0_1) -> (@out τ_0_0, @out τ_0_0) - // CHECK-NEXT: [[SUBST_INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [[INIT_ACCESSOR]]() : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_0, @inout τ_0_1) -> (@out τ_0_0, @out τ_0_0) - // CHECK: {{.*}} = apply [[SUBST_INIT_ACCESSOR]]({{.*}}) : $@callee_guaranteed (@in T, @in T, @inout U) -> (@out T, @out T) + // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s14init_accessors11TestGenericV4datax_xtvi : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_0, @inout τ_0_1, @thin TestGeneric<τ_0_0, τ_0_1>.Type) -> (@out τ_0_0, @out τ_0_0) + // CHECK-NEXT: [[SUBST_INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR]](%4) : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_0, @inout τ_0_1, @thin TestGeneric<τ_0_0, τ_0_1>.Type) -> (@out τ_0_0, @out τ_0_0) + // CHECK: {{.*}} = apply [[SUBST_INIT_ACCESSOR]]({{.*}}) : $@noescape @callee_guaranteed (@in T, @in T, @inout U) -> (@out T, @out T) // // CHECK: [[SETTER:%.*]] = function_ref @$s14init_accessors11TestGenericV4datax_xtvs : $@convention(method) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_0, @inout TestGeneric<τ_0_0, τ_0_1>) -> () // CHECK-NEXT: [[SETTER_CLOSURE:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[SETTER]]([[SELF_VALUE:%.*]]) : $@convention(method) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_0, @inout TestGeneric<τ_0_0, τ_0_1>) -> () @@ -317,9 +326,9 @@ struct TestGenericTuple { var a: T var b: (T, U) - // CHECK-LABEL: sil private [ossa] @$s14init_accessors16TestGenericTupleV4datax_x_q_ttvi : $@convention(thin) (@in T, @in T, @in U) -> (@out T, @out (T, U)) { + // CHECK-LABEL: sil private [ossa] @$s14init_accessors16TestGenericTupleV4datax_x_q_ttvi : $@convention(thin) (@in T, @in T, @in U, @thin TestGenericTuple.Type) -> (@out T, @out (T, U)) { // - // CHECK: bb0([[A_REF:%.*]] : $*T, [[B_REF:%.*]] : $*(T, U), [[A_VALUE:%.*]] : $*T, [[B_VALUE:%.*]] : $*T, [[C_VALUE:%.*]] : $*U): + // CHECK: bb0([[A_REF:%.*]] : $*T, [[B_REF:%.*]] : $*(T, U), [[A_VALUE:%.*]] : $*T, [[B_VALUE:%.*]] : $*T, [[C_VALUE:%.*]] : $*U, [[METATYPE:%.*]] : $@thin TestGenericTuple.Type): // // CHECK: [[INIT_VALUE_1:%.*]] = alloc_stack $(T, U), let, name "initialValue" // CHECK-NEXT: [[INIT_VALUE_1_0:%.*]] = tuple_element_addr [[INIT_VALUE_1]] : $*(T, U), 0 @@ -374,8 +383,8 @@ func test_local_with_memberwise() { // CHECK: [[SELF_VALUE:%.*]] = alloc_stack $TestMemberwiseConcrete // CHECK-NEXT: [[A_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*TestMemberwiseConcrete, #TestMemberwiseConcrete.a // CHECK-NEXT: [[B_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*TestMemberwiseConcrete, #TestMemberwiseConcrete.b - // CHECK: [[INIT_ACCESSOR_REF:%.*]] = function_ref @$s14init_accessors26test_local_with_memberwiseyyF22TestMemberwiseConcreteL_V4pairSi_SStvi : $@convention(thin) (Int, @owned String) -> (@out Int, @out String) - // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR_REF]]([[A_REF]], [[B_REF]], %0, %1) : $@convention(thin) (Int, @owned String) -> (@out Int, @out String) + // CHECK: [[INIT_ACCESSOR_REF:%.*]] = function_ref @$s14init_accessors26test_local_with_memberwiseyyF22TestMemberwiseConcreteL_V4pairSi_SStvi : $@convention(thin) (Int, @owned String, @thin TestMemberwiseConcrete.Type) -> (@out Int, @out String) + // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR_REF]]([[A_REF]], [[B_REF]], %0, %1, %3) : $@convention(thin) (Int, @owned String, @thin TestMemberwiseConcrete.Type) -> (@out Int, @out String) // CHECK-NEXT: [[C_REF:%.*]] = struct_element_addr %4 : $*TestMemberwiseConcrete, #TestMemberwiseConcrete.c // CHECK-NEXT: store %2 to [init] [[C_REF]] : $*Array // CHECK-NEXT: [[RESULT:%.*]] = load [take] [[SELF_VALUE]] : $*TestMemberwiseConcrete @@ -415,13 +424,13 @@ func test_local_with_memberwise() { // CHECK-LABEL: sil private [ossa] @$s14init_accessors26test_local_with_memberwiseyyF21TestMemberwiseGenericL_V1a4pairADyxq_Gx_SS_q_ttcfC : $@convention(method) (@in T, @owned String, @in C, @thin TestMemberwiseGeneric.Type) -> @out TestMemberwiseGeneric // CHECK: bb0([[SELF_VALUE:%.*]] : $*TestMemberwiseGeneric, [[A_VALUE:%*.]] : $*T, [[B_VALUE:%.*]] : @owned $String, [[C_VALUE:%.*]] : $*C, [[METATYPE:%.*]] : $@thin TestMemberwiseGeneric.Type): // CHECK-NEXT: [[A_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*TestMemberwiseGeneric, #TestMemberwiseGeneric._a - // CHECK: [[INIT_ACCESSOR_REF:%.*]] = function_ref @$s14init_accessors26test_local_with_memberwiseyyF21TestMemberwiseGenericL_V1axvi : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1.Element, τ_0_1 : RangeReplaceableCollection> (@in τ_0_0) -> @out τ_0_0 // user: %7 - // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR_REF]]([[A_REF]], [[A_VALUE]]) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1.Element, τ_0_1 : RangeReplaceableCollection> (@in τ_0_0) -> @out τ_0_0 + // CHECK: [[INIT_ACCESSOR_REF:%.*]] = function_ref @$s14init_accessors26test_local_with_memberwiseyyF21TestMemberwiseGenericL_V1axvi : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1.Element, τ_0_1 : RangeReplaceableCollection> (@in τ_0_0, @thin TestMemberwiseGeneric<τ_0_0, τ_0_1>.Type) -> @out τ_0_0 // user: %7 + // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR_REF]]([[A_REF]], [[A_VALUE]], [[METATYPE]]) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1.Element, τ_0_1 : RangeReplaceableCollection> (@in τ_0_0, @thin TestMemberwiseGeneric<τ_0_0, τ_0_1>.Type) -> @out τ_0_0 // CHECK-NEXT: [[B_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*TestMemberwiseGeneric, #TestMemberwiseGeneric._b // CHECK-NEXT: [[C_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*TestMemberwiseGeneric, #TestMemberwiseGeneric._c // CHECK-NEXT: [[A_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*TestMemberwiseGeneric, #TestMemberwiseGeneric._a - // CHECK: [[INIT_ACCESSOR_REF:%.*]] = function_ref @$s14init_accessors26test_local_with_memberwiseyyF21TestMemberwiseGenericL_V4pairSS_q_tvi : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1.Element, τ_0_1 : RangeReplaceableCollection> (@owned String, @in τ_0_1, @inout τ_0_0) -> (@out String, @out τ_0_1) - // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR_REF]]([[B_REF]], [[C_REF]], [[B_VALUE]], [[C_VALUE]], [[A_REF]]) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1.Element, τ_0_1 : RangeReplaceableCollection> (@owned String, @in τ_0_1, @inout τ_0_0) -> (@out String, @out τ_0_1) + // CHECK: [[INIT_ACCESSOR_REF:%.*]] = function_ref @$s14init_accessors26test_local_with_memberwiseyyF21TestMemberwiseGenericL_V4pairSS_q_tvi : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1.Element, τ_0_1 : RangeReplaceableCollection> (@owned String, @in τ_0_1, @inout τ_0_0, @thin TestMemberwiseGeneric<τ_0_0, τ_0_1>.Type) -> (@out String, @out τ_0_1) + // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR_REF]]([[B_REF]], [[C_REF]], [[B_VALUE]], [[C_VALUE]], [[A_REF]], [[METATYPE]]) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1.Element, τ_0_1 : RangeReplaceableCollection> (@owned String, @in τ_0_1, @inout τ_0_0, @thin TestMemberwiseGeneric<τ_0_0, τ_0_1>.Type) -> (@out String, @out τ_0_1) // CHECK-NEXT: [[VOID:%.*]] = tuple () // CHECK-NEXT: return [[VOID]] : $() } @@ -430,12 +439,12 @@ func test_local_with_memberwise() { } // CHECK-LABEL: sil private [ossa] @$s14init_accessors023test_type_lowering_for_A9_accessoryyF4TestL_V2fnADyxq_Gq_xc_tcfC : $@convention(method) (@owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @thin Test.Type) -> @owned Test -// CHECK: {{.*}} = function_ref @$s14init_accessors023test_type_lowering_for_A9_accessoryyF4TestL_V2fnyq_xcvi : $@convention(thin) <τ_0_0, τ_0_1> (@owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <τ_0_0, τ_0_1>) -> @out Optional<@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <τ_0_0, τ_0_1>> +// CHECK: {{.*}} = function_ref @$s14init_accessors023test_type_lowering_for_A9_accessoryyF4TestL_V2fnyq_xcvi : $@convention(thin) <τ_0_0, τ_0_1> (@owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <τ_0_0, τ_0_1>, @thin Test<τ_0_0, τ_0_1>.Type) -> @out Optional<@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <τ_0_0, τ_0_1>> func test_type_lowering_for_init_accessor() { struct Test { var _fn: ((T) -> U)? = nil - // CHECK-LABEL: sil private [ossa] @$s14init_accessors023test_type_lowering_for_A9_accessoryyF4TestL_V2fnyq_xcvi : $@convention(thin) (@owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out Optional<@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for > + // CHECK-LABEL: sil private [ossa] @$s14init_accessors023test_type_lowering_for_A9_accessoryyF4TestL_V2fnyq_xcvi : $@convention(thin) (@owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @thin Test.Type) -> @out Optional<@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for > var fn: (T) -> U { @storageRestrictions(initializes: _fn) init { _fn = newValue } @@ -479,13 +488,15 @@ func test_assignments() { } // CHECK-LABEL: sil private [ossa] @$s14init_accessors16test_assignmentsyyF4TestL_V1aADSi_tcfC : $@convention(method) (Int, @thin Test.Type) -> Test - // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s14init_accessors16test_assignmentsyyF4TestL_V1aSivi : $@convention(thin) (Int) -> @out Int + // CHECK: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s14init_accessors16test_assignmentsyyF4TestL_V1aSivi : $@convention(thin) (Int, @thin Test.Type) -> @out Int + // CHECK: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]](%1) : $@convention(thin) (Int, @thin Test.Type) -> @out Int // CHECK: [[A_REF:%.*]] = struct_element_addr {{.*}} : $*Test, #Test._a - // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[A_REF]], %0) : $@convention(thin) (Int) -> @out Int - // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s14init_accessors16test_assignmentsyyF4TestL_V1aSivi : $@convention(thin) (Int) -> @out Int + // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[A_REF]], %0) : $@noescape @callee_guaranteed (Int) -> @out Int + // CHECK: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s14init_accessors16test_assignmentsyyF4TestL_V1aSivi : $@convention(thin) (Int, @thin Test.Type) -> @out Int + // CHECK: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]](%1) : $@convention(thin) (Int, @thin Test.Type) -> @out Int // CHECK: [[A_REF:%.*]] = struct_element_addr {{.*}} : $*Test, #Test._a // CHECK-NEXT: destroy_addr [[A_REF]] : $*Int - // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[A_REF]], %0) : $@convention(thin) (Int) -> @out Int + // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[A_REF]], %0) : $@noescape @callee_guaranteed (Int) -> @out Int // CHECK: [[B_REF:%.*]] = struct_element_addr {{.*}} : $*Test, #Test._b // CHECK-NEXT: store {{.*}} to [trivial] [[B_REF]] : $*Int // CHECK: [[SETTER_REF:%.*]] = function_ref @$s14init_accessors16test_assignmentsyyF4TestL_V1aSivs : $@convention(method) (Int, @inout Test) -> () @@ -499,14 +510,16 @@ func test_assignments() { } // CHECK-LABEL: sil private [ossa] @$s14init_accessors16test_assignmentsyyF4TestL_V1a1bADSi_SitcfC : $@convention(method) (Int, Int, @thin Test.Type) -> Test - // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s14init_accessors16test_assignmentsyyF4TestL_V1aSivi : $@convention(thin) (Int) -> @out Int + // CHECK: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s14init_accessors16test_assignmentsyyF4TestL_V1aSivi : $@convention(thin) (Int, @thin Test.Type) -> @out Int + // CHECK: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]](%2) : $@convention(thin) (Int, @thin Test.Type) -> @out Int // CHECK: [[A_REF:%.*]] = struct_element_addr {{.*}} : $*Test, #Test._a - // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[A_REF]], %0) : $@convention(thin) (Int) -> @out Int - // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s14init_accessors16test_assignmentsyyF4TestL_V4pairSi_Sitvi : $@convention(thin) (Int, Int) -> (@out Int, @out Int) + // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[A_REF]], %0) : $@noescape @callee_guaranteed (Int) -> @out Int + // CHECK: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s14init_accessors16test_assignmentsyyF4TestL_V4pairSi_Sitvi : $@convention(thin) (Int, Int, @thin Test.Type) -> (@out Int, @out Int) + // CHECK: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]](%2) : $@convention(thin) (Int, Int, @thin Test.Type) -> (@out Int, @out Int) // CHECK: [[A_REF:%.*]] = struct_element_addr [[SELF_VALUE:%.*]] : $*Test, #Test._a // CHECK-NEXT: destroy_addr [[A_REF]] : $*Int // CHECK-NEXT: [[B_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*Test, #Test._b - // CHECK: {{.*}} = apply [[INIT_ACCESSOR]]([[A_REF]], [[B_REF]], {{.*}}) : $@convention(thin) (Int, Int) -> (@out Int, @out Int) + // CHECK: {{.*}} = apply [[INIT_ACCESSOR]]([[A_REF]], [[B_REF]], {{.*}}) : $@noescape @callee_guaranteed (Int, Int) -> (@out Int, @out Int) init(a: Int, b: Int) { self.a = a self.pair = (0, b) diff --git a/test/SILOptimizer/init_accessors_with_indirect_newValue.swift b/test/SILOptimizer/init_accessors_with_indirect_newValue.swift index 122a2a65a34a8..6d66a69e1877d 100644 --- a/test/SILOptimizer/init_accessors_with_indirect_newValue.swift +++ b/test/SILOptimizer/init_accessors_with_indirect_newValue.swift @@ -35,12 +35,12 @@ public class Test { // CHECK-NEXT: [[DEFAULT_VALUE:%.*]] = load [take] [[DEFAULT_VALUE_SLOT]] : $*Test.State // CHECK: [[NEW_VALUE:%.*]] = alloc_stack $Test.State // CHECK-NEXT: store [[DEFAULT_VALUE]] to [init] [[NEW_VALUE]] : $*Test.State - // CHECK: assign_or_init [init] #Test.state, self [[MU]] : $Test, value [[NEW_VALUE]] : $*Test.State, init {{.*}} : $@convention(thin) (@in Test.State) -> @out Test.State, set {{.*}} : $@noescape @callee_guaranteed (@in Test.State) -> () + // CHECK: assign_or_init [init] #Test.state, self [[MU]] : $Test, value [[NEW_VALUE]] : $*Test.State, init {{.*}} : $@noescape @callee_guaranteed (@in Test.State) -> @out Test.State, set {{.*}} : $@noescape @callee_guaranteed (@in Test.State) -> () // // CHECK: [[START_STATE:%.*]] = enum $Test.State, #Test.State.start!enumelt // CHECK-NEXT: [[NEW_VALUE:%.*]] = alloc_stack $Test.State // CHECK-NEXT: store [[START_STATE]] to [trivial] [[NEW_VALUE]] : $*Test.State - // CHECK: assign_or_init [set] #Test.state, self [[MU]] : $Test, value [[NEW_VALUE]] : $*Test.State, init {{.*}} : $@convention(thin) (@in Test.State) -> @out Test.State, set {{.*}} : $@noescape @callee_guaranteed (@in Test.State) -> () + // CHECK: assign_or_init [set] #Test.state, self [[MU]] : $Test, value [[NEW_VALUE]] : $*Test.State, init {{.*}} : $@noescape @callee_guaranteed (@in Test.State) -> @out Test.State, set {{.*}} : $@noescape @callee_guaranteed (@in Test.State) -> () public init() { state = .start }