Skip to content

Commit 85b94a4

Browse files
committed
SILGen: Refactor emitMemberInitializers() to use Initialization
Instead of constructing an LValue and storing the result of the stored property initializer to the lvalue, let's emit the call of the stored property initializer directly into an initialization pointing at the stored properties named by the pattern.
1 parent 47e32d1 commit 85b94a4

10 files changed

+148
-118
lines changed

lib/SILGen/SILGenConstructor.cpp

Lines changed: 80 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -901,68 +901,66 @@ static ManagedValue emitSelfForMemberInit(SILGenFunction &SGF, SILLocation loc,
901901
SGFAccessKind::Write);
902902
}
903903

904-
static LValue emitLValueForMemberInit(SILGenFunction &SGF, SILLocation loc,
905-
VarDecl *selfDecl,
906-
VarDecl *property) {
907-
CanType selfFormalType = selfDecl->getType()->getCanonicalType();
908-
auto self = emitSelfForMemberInit(SGF, loc, selfDecl);
909-
return SGF.emitPropertyLValue(loc, self, selfFormalType, property,
910-
LValueOptions(), SGFAccessKind::Write,
911-
AccessSemantics::DirectToStorage);
912-
}
913-
914-
/// Emit a member initialization for the members described in the
915-
/// given pattern from the given source value.
916-
static void emitMemberInit(SILGenFunction &SGF, VarDecl *selfDecl,
917-
Pattern *pattern, RValue &&src) {
904+
// FIXME: Can emitMemberInit() share code with InitializationForPattern in
905+
// SILGenDecl.cpp? Note that this version operates on stored properties of
906+
// types, whereas the former only knows how to handle local bindings, but
907+
// we could generalize it.
908+
static InitializationPtr
909+
emitMemberInit(SILGenFunction &SGF, VarDecl *selfDecl, Pattern *pattern) {
918910
switch (pattern->getKind()) {
919911
case PatternKind::Paren:
920912
return emitMemberInit(SGF, selfDecl,
921-
cast<ParenPattern>(pattern)->getSubPattern(),
922-
std::move(src));
913+
cast<ParenPattern>(pattern)->getSubPattern());
923914

924915
case PatternKind::Tuple: {
916+
TupleInitialization *init = new TupleInitialization();
925917
auto tuple = cast<TuplePattern>(pattern);
926-
auto fields = tuple->getElements();
927-
928-
SmallVector<RValue, 4> elements;
929-
std::move(src).extractElements(elements);
930-
for (unsigned i = 0, n = fields.size(); i != n; ++i) {
931-
emitMemberInit(SGF, selfDecl, fields[i].getPattern(),
932-
std::move(elements[i]));
918+
for (auto &elt : tuple->getElements()) {
919+
init->SubInitializations.push_back(
920+
emitMemberInit(SGF, selfDecl, elt.getPattern()));
933921
}
934-
break;
922+
return InitializationPtr(init);
935923
}
936924

937925
case PatternKind::Named: {
938926
auto named = cast<NamedPattern>(pattern);
939-
// Form the lvalue referencing this member.
940-
FormalEvaluationScope scope(SGF);
941-
LValue memberRef = emitLValueForMemberInit(SGF, pattern, selfDecl,
942-
named->getDecl());
943927

944-
// Assign to it.
945-
SGF.emitAssignToLValue(pattern, std::move(src), std::move(memberRef));
946-
return;
928+
auto self = emitSelfForMemberInit(SGF, pattern, selfDecl);
929+
930+
auto *field = named->getDecl();
931+
932+
auto selfTy = self.getType();
933+
auto fieldTy =
934+
selfTy.getFieldType(field, SGF.SGM.M, SGF.getTypeExpansionContext());
935+
SILValue slot;
936+
937+
if (auto *structDecl = dyn_cast<StructDecl>(field->getDeclContext())) {
938+
slot = SGF.B.createStructElementAddr(pattern, self.forward(SGF), field,
939+
fieldTy.getAddressType());
940+
} else {
941+
assert(isa<ClassDecl>(field->getDeclContext()));
942+
slot = SGF.B.createRefElementAddr(pattern, self.forward(SGF), field,
943+
fieldTy.getAddressType());
944+
}
945+
946+
return InitializationPtr(new KnownAddressInitialization(slot));
947947
}
948948

949949
case PatternKind::Any:
950-
return;
950+
return InitializationPtr(new BlackHoleInitialization());;
951951

952952
case PatternKind::Typed:
953953
return emitMemberInit(SGF, selfDecl,
954-
cast<TypedPattern>(pattern)->getSubPattern(),
955-
std::move(src));
954+
cast<TypedPattern>(pattern)->getSubPattern());
956955

957956
case PatternKind::Binding:
958957
return emitMemberInit(SGF, selfDecl,
959-
cast<BindingPattern>(pattern)->getSubPattern(),
960-
std::move(src));
958+
cast<BindingPattern>(pattern)->getSubPattern());
961959

962960
#define PATTERN(Name, Parent)
963961
#define REFUTABLE_PATTERN(Name, Parent) case PatternKind::Name:
964962
#include "swift/AST/PatternNodes.def"
965-
llvm_unreachable("Refutable pattern in pattern binding");
963+
llvm_unreachable("Refutable pattern in stored property pattern binding");
966964
}
967965
}
968966

@@ -991,6 +989,46 @@ getInitializationTypeInContext(
991989
return std::make_pair(origType, substType);
992990
}
993991

992+
static void
993+
emitAndStoreInitialValueInto(SILGenFunction &SGF,
994+
SILLocation loc,
995+
PatternBindingDecl *pbd, unsigned i,
996+
SubstitutionMap subs,
997+
AbstractionPattern origType,
998+
CanType substType,
999+
Initialization *init) {
1000+
bool injectIntoWrapper = false;
1001+
if (auto singleVar = pbd->getSingleVar()) {
1002+
auto originalVar = singleVar->getOriginalWrappedProperty();
1003+
if (originalVar &&
1004+
originalVar->isPropertyMemberwiseInitializedWithWrappedType()) {
1005+
injectIntoWrapper = true;
1006+
}
1007+
}
1008+
1009+
SGFContext C = (injectIntoWrapper ? SGFContext() : SGFContext(init));
1010+
1011+
RValue result = SGF.emitApplyOfStoredPropertyInitializer(
1012+
pbd->getExecutableInit(i),
1013+
pbd->getAnchoringVarDecl(i),
1014+
subs, substType, origType, C);
1015+
1016+
// need to store result into the init if its in context
1017+
1018+
// If we have the backing storage for a property with an attached
1019+
// property wrapper initialized with `=`, inject the value into an
1020+
// instance of the wrapper.
1021+
if (injectIntoWrapper) {
1022+
auto *singleVar = pbd->getSingleVar();
1023+
result = maybeEmitPropertyWrapperInitFromValue(
1024+
SGF, pbd->getExecutableInit(i),
1025+
singleVar, subs, std::move(result));
1026+
}
1027+
1028+
if (!result.isInContext())
1029+
std::move(result).forwardInto(SGF, loc, init);
1030+
}
1031+
9941032
void SILGenFunction::emitMemberInitializers(DeclContext *dc,
9951033
VarDecl *selfDecl,
9961034
NominalTypeDecl *nominal) {
@@ -1006,6 +1044,7 @@ void SILGenFunction::emitMemberInitializers(DeclContext *dc,
10061044
if (!init) continue;
10071045

10081046
auto *varPattern = pbd->getPattern(i);
1047+
10091048
// Cleanup after this initialization.
10101049
FullExpr scope(Cleanups, varPattern);
10111050

@@ -1016,26 +1055,11 @@ void SILGenFunction::emitMemberInitializers(DeclContext *dc,
10161055
AbstractionPattern origType = resultType.first;
10171056
CanType substType = resultType.second;
10181057

1019-
// FIXME: Can emitMemberInit() share code with
1020-
// InitializationForPattern in SILGenDecl.cpp?
1021-
RValue result = emitApplyOfStoredPropertyInitializer(
1022-
init, pbd->getAnchoringVarDecl(i), subs,
1023-
substType, origType,
1024-
SGFContext());
1025-
1026-
// If we have the backing storage for a property with an attached
1027-
// property wrapper initialized with `=`, inject the value into an
1028-
// instance of the wrapper.
1029-
if (auto singleVar = pbd->getSingleVar()) {
1030-
auto originalVar = singleVar->getOriginalWrappedProperty();
1031-
if (originalVar &&
1032-
originalVar->isPropertyMemberwiseInitializedWithWrappedType()) {
1033-
result = maybeEmitPropertyWrapperInitFromValue(
1034-
*this, init, singleVar, subs, std::move(result));
1035-
}
1036-
}
1058+
// Figure out what we're initializing.
1059+
auto memberInit = emitMemberInit(*this, selfDecl, varPattern);
10371060

1038-
emitMemberInit(*this, selfDecl, varPattern, std::move(result));
1061+
emitAndStoreInitialValueInto(*this, varPattern, pbd, i, subs,
1062+
origType, substType, memberInit.get());
10391063
}
10401064
}
10411065
}

test/IRGen/generic_structs.swift

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -disable-type-layout -primary-file %s -emit-ir | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize -DINT=i%target-ptrsize -DINT_32=i32
1+
// RUN: %target-swift-frontend -disable-type-layout -primary-file %s -emit-ir
22

33
struct A<T1, T2>
44
{
@@ -37,13 +37,3 @@ public struct GenericStruct<T : Proto> {
3737

3838
public init() {}
3939
}
40-
41-
// CHECK-LABEL: define{{.*}} swiftcc void @"$s15generic_structs13GenericStructVACyxGycfC"
42-
// CHECK: [[T0:%.*]] = call swiftcc %swift.metadata_response @"$s15generic_structs13GenericStructVMa"([[INT]] 0, %swift.type* %T, i8** %T.Proto)
43-
// CHECK: [[TYPE:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
44-
// CHECK: [[PTR:%.*]] = bitcast %swift.type* [[TYPE]] to [[INT_32]]*
45-
// CHECK: [[FIELDOFFSET:%.*]] = getelementptr inbounds [[INT_32]], [[INT_32]]* [[PTR]], [[INT]] [[IDX:6|10]]
46-
// CHECK: [[OFFSET:%.*]] = load [[INT_32]], [[INT_32]]* [[FIELDOFFSET]]
47-
// CHECK: [[ADDROFOPT:%.*]] = getelementptr inbounds i8, i8* {{.*}}, [[INT_32]] [[OFFSET]]
48-
// CHECK: [[OPTPTR:%.*]] = bitcast i8* [[ADDROFOPT]] to %TSq*
49-
// CHECK: call %TSq* @"$sxSg15generic_structs5ProtoRzlWOb"(%TSq* {{.*}}, %TSq* [[OPTPTR]]

test/SILGen/constrained_extensions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,8 @@ struct AnythingGoes<T> {
177177
extension AnythingGoes where T : VeryConstrained {
178178
// CHECK-LABEL: sil hidden [ossa] @$s22constrained_extensions12AnythingGoesVA2A15VeryConstrainedRzlE13fromExtensionACyxGyt_tcfC : $@convention(method) <T where T : VeryConstrained> (@thin AnythingGoes<T>.Type) -> @out AnythingGoes<T> {
179179

180+
// CHECK: [[RESULT:%.*]] = struct_element_addr {{%.*}} : $*AnythingGoes<T>, #AnythingGoes.meaningOfLife
180181
// CHECK: [[INIT:%.*]] = function_ref @$s22constrained_extensions12AnythingGoesV13meaningOfLifexSgvpfi : $@convention(thin) <τ_0_0> () -> @out Optional<τ_0_0>
181-
// CHECK: [[RESULT:%.*]] = alloc_stack $Optional<T>
182182
// CHECK: apply [[INIT]]<T>([[RESULT]]) : $@convention(thin) <τ_0_0> () -> @out Optional<τ_0_0>
183183
// CHECK: return
184184
init(fromExtension: ()) {}

test/SILGen/default_constructor.swift

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ struct D {
3131
// CHECK: [[THISBOX:%[0-9]+]] = alloc_box ${ var D }
3232
// CHECK: [[THIS:%[0-9]+]] = mark_uninit
3333
// CHECK: [[PB_THIS:%.*]] = project_box [[THIS]]
34+
// CHECK: [[IADDR:%[0-9]+]] = struct_element_addr [[PB_THIS]] : $*D, #D.i
35+
// CHECK: [[JADDR:%[0-9]+]] = struct_element_addr [[PB_THIS]] : $*D, #D.j
3436
// CHECK: [[INIT:%[0-9]+]] = function_ref @$s19default_constructor1DV1iSivpfi
3537
// CHECK: [[RESULT:%[0-9]+]] = apply [[INIT]]()
3638
// CHECK: ([[INTVAL:%[0-9]+]], [[FLOATVAL:%[0-9]+]]) = destructure_tuple [[RESULT]]
37-
// CHECK: [[IADDR:%[0-9]+]] = struct_element_addr [[PB_THIS]] : $*D, #D.i
38-
// CHECK: assign [[INTVAL]] to [[IADDR]]
39-
// CHECK: [[JADDR:%[0-9]+]] = struct_element_addr [[PB_THIS]] : $*D, #D.j
40-
// CHECK: assign [[FLOATVAL]] to [[JADDR]]
39+
// CHECK: store [[INTVAL]] to [trivial] [[IADDR]]
40+
// CHECK: store [[FLOATVAL]] to [trivial] [[JADDR]]
4141

4242
class E {
4343
var i = Int64()
@@ -55,13 +55,11 @@ class E {
5555
// CHECK-LABEL: sil hidden [ossa] @$s19default_constructor1EC{{[_0-9a-zA-Z]*}}fc : $@convention(method) (@owned E) -> @owned E
5656
// CHECK: bb0([[SELFIN:%[0-9]+]] : @owned $E)
5757
// CHECK: [[SELF:%[0-9]+]] = mark_uninitialized
58-
// CHECK: [[INIT:%[0-9]+]] = function_ref @$s19default_constructor1EC1is5Int64Vvpfi : $@convention(thin) () -> Int64
59-
// CHECK-NEXT: [[VALUE:%[0-9]+]] = apply [[INIT]]() : $@convention(thin) () -> Int64
6058
// CHECK-NEXT: [[BORROWED_SELF:%.*]] = begin_borrow [[SELF]]
6159
// CHECK-NEXT: [[IREF:%[0-9]+]] = ref_element_addr [[BORROWED_SELF]] : $E, #E.i
62-
// CHECK-NEXT: [[WRITE:%.*]] = begin_access [modify] [dynamic] [[IREF]] : $*Int64
63-
// CHECK-NEXT: assign [[VALUE]] to [[WRITE]] : $*Int64
64-
// CHECK-NEXT: end_access [[WRITE]] : $*Int64
60+
// CHECK: [[INIT:%[0-9]+]] = function_ref @$s19default_constructor1EC1is5Int64Vvpfi : $@convention(thin) () -> Int64
61+
// CHECK-NEXT: [[VALUE:%[0-9]+]] = apply [[INIT]]() : $@convention(thin) () -> Int64
62+
// CHECK-NEXT: store [[VALUE]] to [trivial] [[IREF]] : $*Int64
6563
// CHECK-NEXT: end_borrow [[BORROWED_SELF]]
6664
// CHECK-NEXT: [[SELF_COPY:%.*]] = copy_value [[SELF]]
6765
// CHECK-NEXT: destroy_value [[SELF]]
@@ -103,8 +101,8 @@ struct H<T> {
103101
var opt: T?
104102

105103
// CHECK-LABEL: sil hidden [ossa] @$s19default_constructor1HVyACyxGqd__clufC : $@convention(method) <T><U> (@in U, @thin H<T>.Type) -> @out H<T> {
104+
// CHECK: [[OPT_T:%[0-9]+]] = struct_element_addr {{%.*}} : $*H<T>, #H.opt
106105
// CHECK: [[INIT_FN:%[0-9]+]] = function_ref @$s19default_constructor1HV3optxSgvpfi : $@convention(thin) <τ_0_0> () -> @out Optional<τ_0_0>
107-
// CHECK-NEXT: [[OPT_T:%[0-9]+]] = alloc_stack $Optional<T>
108106
// CHECK-NEXT: apply [[INIT_FN]]<T>([[OPT_T]]) : $@convention(thin) <τ_0_0> () -> @out Optional<τ_0_0>
109107
init<U>(_: U) { }
110108
}
@@ -115,10 +113,10 @@ struct I {
115113
var x: Int = 0
116114

117115
// CHECK-LABEL: sil hidden [ossa] @$s19default_constructor1IVyACxclufC : $@convention(method) <T> (@in T, @thin I.Type) -> I {
116+
// CHECK: [[X_ADDR:%[0-9]+]] = struct_element_addr {{.*}} : $*I, #I.x
118117
// CHECK: [[INIT_FN:%[0-9]+]] = function_ref @$s19default_constructor1IV1xSivpfi : $@convention(thin) () -> Int
119118
// CHECK: [[RESULT:%[0-9]+]] = apply [[INIT_FN]]() : $@convention(thin) () -> Int
120-
// CHECK: [[X_ADDR:%[0-9]+]] = struct_element_addr {{.*}} : $*I, #I.x
121-
// CHECK: assign [[RESULT]] to [[X_ADDR]] : $*Int
119+
// CHECK: store [[RESULT]] to [trivial] [[X_ADDR]] : $*Int
122120
init<T>(_: T) {}
123121
}
124122

test/SILGen/extensions.swift

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,12 @@ struct Box<T> {
5353
// CHECK: [[SELF_BOX:%.*]] = alloc_box $<τ_0_0> { var Box<τ_0_0> } <T>
5454
// CHECK-NEXT: [[UNINIT_SELF_BOX:%.*]] = mark_uninitialized [rootself] [[SELF_BOX]]
5555
// CHECK-NEXT: [[SELF_ADDR:%.*]] = project_box [[UNINIT_SELF_BOX]] : $<τ_0_0> { var Box<τ_0_0> } <T>
56+
// CHECK: [[RESULT:%.*]] = struct_element_addr [[SELF_ADDR]] : $*Box<T>, #Box.t
5657
// CHECK: [[INIT:%.*]] = function_ref @$s10extensions3BoxV1txSgvpfi : $@convention(thin) <τ_0_0> () -> @out Optional<τ_0_0>
57-
// CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $Optional<T>
5858
// CHECK-NEXT: apply [[INIT]]<T>([[RESULT]]) : $@convention(thin) <τ_0_0> () -> @out Optional<τ_0_0>
59-
// CHECK-NEXT: [[T_ADDR:%.*]] = struct_element_addr [[SELF_ADDR]] : $*Box<T>, #Box.t
60-
// CHECK-NEXT: copy_addr [take] [[RESULT]] to [[T_ADDR]] : $*Optional<T>
61-
// CHECK-NEXT: dealloc_stack [[RESULT]] : $*Optional<T>
6259
// CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $Optional<T>
6360
// CHECK-NEXT: [[RESULT_ADDR:%.*]] = init_enum_data_addr [[RESULT]] : $*Optional<T>, #Optional.some!enumelt
64-
// CHECK-NEXT: copy_addr %1 to [initialization] %14 : $*T
61+
// CHECK-NEXT: copy_addr %1 to [initialization] [[RESULT_ADDR]] : $*T
6562
// CHECK-NEXT: inject_enum_addr [[RESULT]] : $*Optional<T>, #Optional.some!enumelt
6663
// CHECK-NEXT: [[WRITE:%.*]] = begin_access [modify] [unknown] [[SELF_ADDR]] : $*Box<T>
6764
// CHECK-NEXT: [[T_ADDR:%.*]] = struct_element_addr [[WRITE]] : $*Box<T>, #Box.t

test/SILGen/initializers.swift

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -580,13 +580,11 @@ class ThrowDerivedClass : ThrowBaseClass {
580580
// CHECK: store {{%.*}} to [init] [[PROJ]]
581581
//
582582
// Then initialize the canary with nil. We are able to borrow the initialized self to avoid retain/release overhead.
583-
// CHECK: [[CANARY_FUNC:%.*]] = function_ref @$s21failable_initializers17ThrowDerivedClassC6canaryAA6CanaryCSgvpfi :
584-
// CHECK: [[OPT_CANARY:%.*]] = apply [[CANARY_FUNC]]()
585583
// CHECK: [[SELF:%.*]] = load_borrow [[PROJ]]
586584
// CHECK: [[CANARY_ADDR:%.*]] = ref_element_addr [[SELF]]
587-
// CHECK: [[CANARY_ACCESS:%.*]] = begin_access [modify] [dynamic] [[CANARY_ADDR]]
588-
// CHECK: assign [[OPT_CANARY]] to [[CANARY_ACCESS]]
589-
// CHECK: end_access [[CANARY_ACCESS]]
585+
// CHECK: [[CANARY_FUNC:%.*]] = function_ref @$s21failable_initializers17ThrowDerivedClassC6canaryAA6CanaryCSgvpfi :
586+
// CHECK: [[OPT_CANARY:%.*]] = apply [[CANARY_FUNC]]()
587+
// CHECK: store [[OPT_CANARY]] to [init] [[CANARY_ADDR]]
590588
// CHECK: end_borrow [[SELF]]
591589
//
592590
// Now we perform the unwrap.
@@ -624,13 +622,11 @@ class ThrowDerivedClass : ThrowBaseClass {
624622
// CHECK: store {{%.*}} to [init] [[PROJ]]
625623
//
626624
// Then initialize the canary with nil. We are able to borrow the initialized self to avoid retain/release overhead.
627-
// CHECK: [[CANARY_FUNC:%.*]] = function_ref @$s21failable_initializers17ThrowDerivedClassC6canaryAA6CanaryCSgvpfi :
628-
// CHECK: [[OPT_CANARY:%.*]] = apply [[CANARY_FUNC]]()
629625
// CHECK: [[SELF:%.*]] = load_borrow [[PROJ]]
630626
// CHECK: [[CANARY_ADDR:%.*]] = ref_element_addr [[SELF]]
631-
// CHECK: [[CANARY_ACCESS:%.*]] = begin_access [modify] [dynamic] [[CANARY_ADDR]]
632-
// CHECK: assign [[OPT_CANARY]] to [[CANARY_ACCESS]]
633-
// CHECK: end_access [[CANARY_ACCESS]]
627+
// CHECK: [[CANARY_FUNC:%.*]] = function_ref @$s21failable_initializers17ThrowDerivedClassC6canaryAA6CanaryCSgvpfi :
628+
// CHECK: [[OPT_CANARY:%.*]] = apply [[CANARY_FUNC]]()
629+
// CHECK: store [[OPT_CANARY]] to [init] [[CANARY_ADDR]]
634630
// CHECK: end_borrow [[SELF]]
635631
//
636632
// Now we begin argument emission where we perform the unwrap.

test/SILGen/lifetime.swift

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -398,26 +398,23 @@ class Foo<T> {
398398
// CHECK: [[THIS:%[0-9]+]] = mark_uninitialized
399399

400400
// -- initialization for y
401+
// CHECK: [[BORROWED_THIS:%.*]] = begin_borrow [[THIS]]
402+
// CHECK: [[THIS_Y:%.*]] = ref_element_addr [[BORROWED_THIS]] : {{.*}}, #Foo.y
401403
// CHECK: [[Y_INIT:%[0-9]+]] = function_ref @$s8lifetime3FooC1ySi_AA3RefCtvpfi : $@convention(thin) <τ_0_0> () -> (Int, @owned Ref)
404+
// CHECK: [[THIS_Y_0:%.*]] = tuple_element_addr [[THIS_Y]] : $*(Int, Ref), 0
405+
// CHECK: [[THIS_Y_1:%.*]] = tuple_element_addr [[THIS_Y]] : $*(Int, Ref), 1
402406
// CHECK: [[Y_VALUE:%[0-9]+]] = apply [[Y_INIT]]<T>()
403407
// CHECK: ([[Y_EXTRACTED_0:%.*]], [[Y_EXTRACTED_1:%.*]]) = destructure_tuple
404-
// CHECK: [[BORROWED_THIS:%.*]] = begin_borrow [[THIS]]
405-
// CHECK: [[THIS_Y:%.*]] = ref_element_addr [[BORROWED_THIS]] : {{.*}}, #Foo.y
406-
// CHECK: [[WRITE:%.*]] = begin_access [modify] [dynamic] [[THIS_Y]] : $*(Int, Ref)
407-
// CHECK: [[THIS_Y_0:%.*]] = tuple_element_addr [[WRITE]] : $*(Int, Ref), 0
408-
// CHECK: assign [[Y_EXTRACTED_0]] to [[THIS_Y_0]]
409-
// CHECK: [[THIS_Y_1:%.*]] = tuple_element_addr [[WRITE]] : $*(Int, Ref), 1
410-
// CHECK: assign [[Y_EXTRACTED_1]] to [[THIS_Y_1]]
411-
// CHECK: end_access [[WRITE]] : $*(Int, Ref)
408+
// CHECK: store [[Y_EXTRACTED_0]] to [trivial] [[THIS_Y_0]]
409+
// CHECK: store [[Y_EXTRACTED_1]] to [init] [[THIS_Y_1]]
412410
// CHECK: end_borrow [[BORROWED_THIS]]
413411

414412
// -- Initialization for w
415-
// CHECK: [[Z_FUNC:%.*]] = function_ref @$s{{.*}}8lifetime3FooC1wAA3RefCvpfi : $@convention(thin) <τ_0_0> () -> @owned Ref
416-
// CHECK: [[Z_RESULT:%.*]] = apply [[Z_FUNC]]<T>()
417413
// CHECK: [[BORROWED_THIS:%.*]] = begin_borrow [[THIS]]
418414
// CHECK: [[THIS_Z:%.*]] = ref_element_addr [[BORROWED_THIS]]
419-
// CHECK: [[WRITE:%.*]] = begin_access [modify] [dynamic] [[THIS_Z]] : $*Ref
420-
// CHECK: assign [[Z_RESULT]] to [[WRITE]]
415+
// CHECK: [[Z_FUNC:%.*]] = function_ref @$s{{.*}}8lifetime3FooC1wAA3RefCvpfi : $@convention(thin) <τ_0_0> () -> @owned Ref
416+
// CHECK: [[Z_RESULT:%.*]] = apply [[Z_FUNC]]<T>()
417+
// CHECK: store [[Z_RESULT]] to [init] [[THIS_Z]]
421418
// CHECK: end_borrow [[BORROWED_THIS]]
422419

423420
// -- Initialization for x
@@ -462,11 +459,10 @@ class Foo<T> {
462459
// -- First we initialize #Foo.y.
463460
// CHECK: [[BORROWED_THIS:%.*]] = begin_borrow [[THIS]]
464461
// CHECK: [[THIS_Y:%.*]] = ref_element_addr [[BORROWED_THIS]] : $Foo<T>, #Foo.y
465-
// CHECK: [[WRITE:%.*]] = begin_access [modify] [dynamic] [[THIS_Y]] : $*(Int, Ref)
466-
// CHECK: [[THIS_Y_1:%.*]] = tuple_element_addr [[WRITE]] : $*(Int, Ref), 0
467-
// CHECK: assign {{.*}} to [[THIS_Y_1]] : $*Int
468-
// CHECK: [[THIS_Y_2:%.*]] = tuple_element_addr [[WRITE]] : $*(Int, Ref), 1
469-
// CHECK: assign {{.*}} to [[THIS_Y_2]] : $*Ref
462+
// CHECK: [[THIS_Y_1:%.*]] = tuple_element_addr [[THIS_Y]] : $*(Int, Ref), 0
463+
// CHECK: [[THIS_Y_2:%.*]] = tuple_element_addr [[THIS_Y]] : $*(Int, Ref), 1
464+
// CHECK: store {{.*}} to [trivial] [[THIS_Y_1]] : $*Int
465+
// CHECK: store {{.*}} to [init] [[THIS_Y_2]] : $*Ref
470466
// CHECK: end_borrow [[BORROWED_THIS]]
471467

472468
// -- Then we create a box that we will use to perform a copy_addr into #Foo.x a bit later.

0 commit comments

Comments
 (0)