Skip to content

Commit 63808be

Browse files
committed
DefinitInitialization: convert begin_access instructions of initializations to a static accesses
In case of `var` initializations, SILGen creates a dynamic begin/end_access pair around the initialization store. If it's an initialization (and not a re-assign) it's guanranteed that it's an exlusive access and we can convert the access to an `[init] [static]` access. #66496
1 parent 6a2f3c9 commit 63808be

10 files changed

+87
-20
lines changed

lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2312,6 +2312,19 @@ void LifetimeChecker::handleSelfInitUse(unsigned UseID) {
23122312
}
23132313
}
23142314

2315+
// In case of `var` initializations, SILGen creates a dynamic begin/end_access
2316+
// pair around the initialization store. If it's an initialization (and not
2317+
// a re-assign) it's guaranteed that it's an exclusive access and we can
2318+
// convert the access to an `[init] [static]` access.
2319+
static void setStaticInitAccess(SILValue memoryAddress) {
2320+
if (auto *ba = dyn_cast<BeginAccessInst>(memoryAddress)) {
2321+
if (ba->getEnforcement() == SILAccessEnforcement::Dynamic) {
2322+
ba->setEnforcement(SILAccessEnforcement::Static);
2323+
if (ba->getAccessKind() == SILAccessKind::Modify)
2324+
ba->setAccessKind(SILAccessKind::Init);
2325+
}
2326+
}
2327+
}
23152328

23162329
/// updateInstructionForInitState - When an instruction being analyzed moves
23172330
/// from being InitOrAssign to some concrete state, update it for that state.
@@ -2336,6 +2349,8 @@ void LifetimeChecker::updateInstructionForInitState(unsigned UseID) {
23362349
assert(!CA->isInitializationOfDest() &&
23372350
"should not modify copy_addr that already knows it is initialized");
23382351
CA->setIsInitializationOfDest(InitKind);
2352+
if (InitKind == IsInitialization)
2353+
setStaticInitAccess(CA->getDest());
23392354
return;
23402355
}
23412356

@@ -2382,6 +2397,7 @@ void LifetimeChecker::updateInstructionForInitState(unsigned UseID) {
23822397
MarkMustCheckInst::CheckKind::InitableButNotConsumable);
23832398
}
23842399
}
2400+
setStaticInitAccess(AI->getDest());
23852401
}
23862402

23872403
return;

test/Concurrency/default_actor_definit.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ actor C {
4040
// CHECK-LABEL: sil hidden @$s21default_actor_definit1CC1yACSgSi_tcfc
4141
// CHECK: builtin "initializeDefaultActor"(%1 : $C)
4242
// CHECK: [[X:%.*]] = ref_element_addr %1 : $C, #C.x
43-
// CHECK-NEXT: [[ACCESS:%.*]] = begin_access [modify] [dynamic] [[X]] : $*String
43+
// CHECK-NEXT: [[ACCESS:%.*]] = begin_access [init] [static] [[X]] : $*String
4444
// CHECK-NEXT: store {{.*}} to [[ACCESS]] : $*String
4545
// CHECK-NEXT: end_access [[ACCESS]] : $*String
4646
// CHECK: cond_br {{%.*}}, bb1, bb2

test/SILOptimizer/default-cmo.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,8 @@ public func getSubmoduleKlassMember() -> Int {
8080
}
8181

8282
// CHECK-LABEL: sil @$s4Main26getSubmoduleKlassMemberTBDSiyF
83-
// CHECK: [[F:%[0-9]+]] = function_ref @$s9ModuleTBD20submoduleKlassMemberSiyF
84-
// CHECK: [[I:%[0-9]+]] = apply [[F]]
85-
// CHECK: return [[I]]
83+
// CHECK-NOT: function_ref
84+
// CHECK-NOT: apply
8685
// CHECK: } // end sil function '$s4Main26getSubmoduleKlassMemberTBDSiyF'
8786
public func getSubmoduleKlassMemberTBD() -> Int {
8887
return ModuleTBD.submoduleKlassMember()

test/SILOptimizer/definite_init_actor.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ actor BoringActor {
8383
// CHECK-LABEL: sil hidden @$s4test14SingleVarActorC10iterationsACSi_tYacfc : $@convention(method) @async (Int, @owned SingleVarActor) -> @owned SingleVarActor {
8484
// CHECK: bb0({{%[0-9]+}} : $Int, [[SELF:%[0-9]+]] : $SingleVarActor):
8585
// CHECK: [[MYVAR_REF:%[0-9]+]] = ref_element_addr [[SELF]] : $SingleVarActor, #SingleVarActor.myVar
86-
// CHECK: [[MYVAR:%[0-9]+]] = begin_access [modify] [dynamic] [[MYVAR_REF]] : $*Int
86+
// CHECK: [[MYVAR:%[0-9]+]] = begin_access [init] [static] [[MYVAR_REF]] : $*Int
8787
// CHECK: store {{%[0-9]+}} to [[MYVAR]] : $*Int
8888
// CHECK-NEXT: end_access [[MYVAR]]
8989
// CHECK-NEXT: hop_to_executor [[SELF]] : $SingleVarActor
@@ -196,7 +196,7 @@ actor MultiVarActor {
196196
// CHECK-LABEL: sil hidden @$s4test13MultiVarActorC10doNotThrowACSb_tYaKcfc : $@convention(method) @async (Bool, @owned MultiVarActor) -> (@owned MultiVarActor, @error any Error) {
197197
// CHECK: bb0({{%[0-9]+}} : $Bool, [[SELF:%[0-9]+]] : $MultiVarActor):
198198
// CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MultiVarActor, #MultiVarActor.firstVar
199-
// CHECK: [[VAR:%[0-9]+]] = begin_access [modify] [dynamic] [[REF]] : $*Int
199+
// CHECK: [[VAR:%[0-9]+]] = begin_access [init] [static] [[REF]] : $*Int
200200
// CHECK: store {{%[0-9]+}} to [[VAR]] : $*Int
201201
// CHECK-NEXT: end_access [[VAR]]
202202
// CHECK-NEXT: hop_to_executor %1 : $MultiVarActor

test/SILOptimizer/definite_init_failable_initializers.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ class FailableBaseClass {
735735
// CHECK: bb0(%0 : $FailableBaseClass):
736736
// CHECK: [[CANARY:%.*]] = apply
737737
// CHECK-NEXT: [[MEMBER_ADDR:%.*]] = ref_element_addr %0
738-
// CHECK-NEXT: [[WRITE:%.*]] = begin_access [modify] [dynamic] [[MEMBER_ADDR]] : $*Canary
738+
// CHECK-NEXT: [[WRITE:%.*]] = begin_access [init] [static] [[MEMBER_ADDR]] : $*Canary
739739
// CHECK-NEXT: store [[CANARY]] to [[WRITE]]
740740
// CHECK-NEXT: end_access [[WRITE]] : $*Canary
741741
// CHECK-NEXT: strong_release %0
@@ -849,7 +849,7 @@ class FailableDerivedClass : FailableBaseClass {
849849
// CHECK: [[CANARY_FUN:%.*]] = function_ref @$s35definite_init_failable_initializers6CanaryCACycfC :
850850
// CHECK: [[CANARY:%.*]] = apply [[CANARY_FUN]](
851851
// CHECK-NEXT: [[MEMBER_ADDR:%.*]] = ref_element_addr [[SELF]]
852-
// CHECK-NEXT: [[WRITE:%.*]] = begin_access [modify] [dynamic] [[MEMBER_ADDR]] : $*Canary
852+
// CHECK-NEXT: [[WRITE:%.*]] = begin_access [init] [static] [[MEMBER_ADDR]] : $*Canary
853853
// CHECK-NEXT: store [[CANARY]] to [[WRITE]]
854854
// CHECK-NEXT: end_access [[WRITE]] : $*Canary
855855
// CHECK-NEXT: strong_release [[SELF]]

test/SILOptimizer/definite_init_markuninitialized_rootself.sil

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@ class RootClassWithNontrivialStoredProperties {
2121
}
2222

2323
class SomeClass {}
24+
25+
final class IntClass {
26+
var i: Int
27+
init(_ i: Int)
28+
}
29+
30+
final class GenericClass<T> {
31+
var t: T
32+
init(_ t: T)
33+
}
34+
2435
sil @getSomeClass : $@convention(thin) () -> @owned SomeClass
2536
sil @getSomeOptionalClass : $@convention(thin) () -> Optional<SomeClass>
2637

@@ -131,3 +142,45 @@ bb0(%0 : @owned $RootClassWithNontrivialStoredProperties):
131142
%13 = tuple ()
132143
return %13 : $()
133144
}
145+
146+
// CHECK-LABEL: sil [ossa] @init_IntClass :
147+
// CHECK: [[ACCESS:%.*]] = begin_access [init] [static]
148+
// CHECK: store %0 to [trivial] [[ACCESS]]
149+
// CHECK: [[ACCESS2:%.*]] = begin_access [modify] [dynamic]
150+
// CHECK: store %0 to [trivial] [[ACCESS2]]
151+
// CHECK: } // end sil function 'init_IntClass'
152+
sil [ossa] @init_IntClass : $@convention(method) (Int, @owned IntClass) -> @owned IntClass {
153+
bb0(%0 : $Int, %1 : @owned $IntClass):
154+
%4 = mark_uninitialized [rootself] %1 : $IntClass
155+
%5 = begin_borrow %4 : $IntClass
156+
%6 = ref_element_addr %5 : $IntClass, #IntClass.i
157+
%7 = begin_access [modify] [dynamic] %6 : $*Int
158+
assign %0 to %7 : $*Int
159+
end_access %7 : $*Int
160+
%10 = begin_access [modify] [dynamic] %6 : $*Int
161+
assign %0 to %10 : $*Int
162+
end_access %10 : $*Int
163+
end_borrow %5 : $IntClass
164+
return %4 : $IntClass
165+
}
166+
167+
// CHECK-LABEL: sil [ossa] @init_GenericClass :
168+
// CHECK: [[ACCESS:%.*]] = begin_access [init] [static]
169+
// CHECK: copy_addr %0 to [init] [[ACCESS]]
170+
// CHECK: [[ACCESS2:%.*]] = begin_access [modify] [dynamic]
171+
// CHECK: copy_addr [take] %0 to [[ACCESS2]]
172+
// CHECK: } // end sil function 'init_GenericClass'
173+
sil [ossa] @init_GenericClass : $@convention(method) <T> (@in T, @owned GenericClass<T>) -> @owned GenericClass<T> {
174+
bb0(%0 : $*T, %1 : @owned $GenericClass<T>):
175+
%4 = mark_uninitialized [rootself] %1 : $GenericClass<T>
176+
%5 = begin_borrow %4 : $GenericClass<T>
177+
%8 = ref_element_addr %5 : $GenericClass<T>, #GenericClass.t
178+
%9 = begin_access [modify] [dynamic] %8 : $*T
179+
copy_addr %0 to %9 : $*T
180+
end_access %9 : $*T
181+
%12 = begin_access [modify] [dynamic] %8 : $*T
182+
copy_addr [take] %0 to %12 : $*T
183+
end_access %12 : $*T
184+
end_borrow %5 : $GenericClass<T>
185+
return %4 : $GenericClass<T>
186+
}

test/SILOptimizer/definite_init_root_class.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class FirstClass {
3131
// CHECK: [[INIT:%.*]] = function_ref @$s24definite_init_root_class10OtherClassCACycfC : $@convention(method) (@thick OtherClass.Type) -> @owned OtherClass
3232
// CHECK: [[OTHER:%.*]] = apply [[INIT]]([[METATYPE]]) : $@convention(method) (@thick OtherClass.Type) -> @owned OtherClass
3333
// CHECK: [[X_ADDR:%.*]] = ref_element_addr %1 : $FirstClass, #FirstClass.x
34-
// CHECK: [[X_ACCESS:%.*]] = begin_access [modify] [dynamic] %15 : $*OtherClass
34+
// CHECK: [[X_ACCESS:%.*]] = begin_access [init] [static] %15 : $*OtherClass
3535
// CHECK: [[ONE:%.*]] = integer_literal $Builtin.Int1, -1
3636
// CHECK: store [[ONE]] to [[CONTROL]] : $*Builtin.Int1
3737
// CHECK: store [[OTHER]] to [[X_ACCESS]] : $*OtherClass
@@ -115,7 +115,7 @@ class SecondClass {
115115
// CHECK: [[INIT:%.*]] = function_ref @$s24definite_init_root_class10OtherClassCACycfC : $@convention(method) (@thick OtherClass.Type) -> @owned OtherClass
116116
// CHECK: [[OTHER:%.*]] = apply [[INIT]]([[METATYPE]]) : $@convention(method) (@thick OtherClass.Type) -> @owned OtherClass
117117
// CHECK: [[X_ADDR:%.*]] = ref_element_addr %1 : $SecondClass, #SecondClass.x
118-
// CHECK: [[X_ACCESS:%.*]] = begin_access [modify] [dynamic] [[X_ADDR]] : $*OtherClass
118+
// CHECK: [[X_ACCESS:%.*]] = begin_access [init] [static] [[X_ADDR]] : $*OtherClass
119119
// CHECK: [[ONE:%.*]] = integer_literal $Builtin.Int2, 1
120120
// CHECK: store [[ONE]] to [[CONTROL]] : $*Builtin.Int2
121121
// CHECK: store [[OTHER]] to [[X_ACCESS]] : $*OtherClass
@@ -138,7 +138,7 @@ class SecondClass {
138138
// CHECK: [[INIT:%.*]] = function_ref @$s24definite_init_root_class10OtherClassCACycfC : $@convention(method) (@thick OtherClass.Type) -> @owned OtherClass
139139
// CHECK: [[OTHER:%.*]] = apply [[INIT]]([[METATYPE]]) : $@convention(method) (@thick OtherClass.Type) -> @owned OtherClass
140140
// CHECK: [[Y_ADDR:%.*]] = ref_element_addr %1 : $SecondClass, #SecondClass.y
141-
// CHECK: [[Y_ACCESS:%.*]] = begin_access [modify] [dynamic] [[Y_ADDR]] : $*OtherClass
141+
// CHECK: [[Y_ACCESS:%.*]] = begin_access [init] [static] [[Y_ADDR]] : $*OtherClass
142142
// CHECK: [[THREE:%.*]] = integer_literal $Builtin.Int2, -1
143143
// CHECK: store [[THREE]] to [[CONTROL]] : $*Builtin.Int2
144144
// CHECK: store [[OTHER]] to [[Y_ACCESS]] : $*OtherClass

test/SILOptimizer/devirt_speculative_init.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,17 @@ public class BigCat : Cat {
2020
}
2121
}
2222

23-
public func make(type: Cat.Type, cats: Int) {
24-
type.init(cats: cats)
23+
public func make(type: Cat.Type, cats: Int) -> Cat {
24+
return type.init(cats: cats)
2525
}
2626

27-
// CHECK-LABEL: sil @$s23devirt_speculative_init4make4type4catsyAA3CatCm_SitF : $@convention(thin) (@thick Cat.Type, Int) -> ()
27+
// CHECK-LABEL: sil @$s23devirt_speculative_init4make4type4catsAA3CatCAFm_SitF : $@convention(thin) (@thick Cat.Type, Int) -> @owned Cat {
2828
// CHECK: checked_cast_br [exact] %0 : $@thick Cat.Type to @thick Cat.Type, bb2, bb3
29-
// CHECK: bb1:
29+
// CHECK: bb1{{.*}}:
3030
// CHECK: return
3131
// CHECK: bb2({{%.*}} : $@thick Cat.Type):
32-
// CHECK: alloc_ref [stack] $Cat
32+
// CHECK: alloc_ref $Cat
3333
// CHECK: br bb1
3434
// CHECK: bb3:
35-
// CHECK: alloc_ref [stack] $BigCat
35+
// CHECK: alloc_ref $BigCat
3636
// CHECK: br bb1

test/SILOptimizer/merge_exclusivity.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,7 @@ private struct EscapedTransform<T>: WriteProt {
377377

378378
// TESTSIL-LABEL: sil [noinline] @$s17merge_exclusivity14run_MergeTest9yySiF : $@convention(thin)
379379
// TESTSIL: [[REFADDR:%.*]] = ref_element_addr {{.*}} : $StreamClass, #StreamClass.buffer
380-
// TESTSIL-NEXT: [[B1:%.*]] = begin_access [modify] [{{.*}}] [no_nested_conflict] [[REFADDR]]
381-
// TESTSIL: end_access [[B1]]
380+
// TESTSIL-NEXT: store {{.*}} to [[REFADDR]]
382381
// TESTSIL: [[BCONF:%.*]] = begin_access [modify] [{{.*}}] [[REFADDR]]
383382
// TESTSIL: end_access [[BCONF]]
384383
// TESTSIL: [[BCONF:%.*]] = begin_access [modify] [{{.*}}] [[REFADDR]]

test/sil-func-extractor/basic.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
// EXTRACT-INIT-LABEL: sil @$s5basic7VehicleC1nACSi_tcfc : $@convention(method) (Int, @owned Vehicle) -> @owned Vehicle {
4747
// EXTRACT-INIT: bb0
4848
// EXTRACT-INIT-NEXT: ref_element_addr
49-
// EXTRACT-INIT-NEXT: begin_access [modify] [dynamic]
49+
// EXTRACT-INIT-NEXT: begin_access [init] [static]
5050
// EXTRACT-INIT-NEXT: store
5151
// EXTRACT-INIT-NEXT: end_access
5252
// EXTRACT-INIT-NEXT: return

0 commit comments

Comments
 (0)