Skip to content

Commit 86076e2

Browse files
committed
RawSILInstLowering: Don't insert an access scope for assign_or_init if there is already one.
This avoids inserting a dynamic access check when the parent is static (and therefore can be statically enforced).
1 parent 667de83 commit 86076e2

File tree

3 files changed

+22
-10
lines changed

3 files changed

+22
-10
lines changed

lib/SILOptimizer/Mandatory/RawSILInstLowering.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,13 +290,20 @@ lowerAssignOrInitInstruction(SILBuilderWithScope &b,
290290
auto isRefSelf = selfValue->getType().getASTType()->mayHaveSuperclass();
291291

292292
SILValue selfRef;
293+
bool needInsertEndAccess = false;
293294
if (isRefSelf) {
294295
selfRef = b.emitBeginBorrowOperation(loc, selfValue);
296+
} else if (isa<BeginAccessInst>(selfValue)) {
297+
// Don't insert an access scope if there is already one. This avoids
298+
// inserting a dynamic access check when the parent is static (and therefore
299+
// can be statically enforced).
300+
selfRef = selfValue;
295301
} else {
296302
selfRef = b.createBeginAccess(loc, selfValue, SILAccessKind::Modify,
297303
SILAccessEnforcement::Dynamic,
298304
/*noNestedConflict=*/false,
299305
/*fromBuiltin=*/false);
306+
needInsertEndAccess = true;
300307
}
301308

302309
auto emitFieldReference = [&](VarDecl *field,
@@ -341,7 +348,7 @@ lowerAssignOrInitInstruction(SILBuilderWithScope &b,
341348
if (isRefSelf) {
342349
if (selfRef != selfValue)
343350
b.emitEndBorrowOperation(loc, selfRef);
344-
} else {
351+
} else if (needInsertEndAccess) {
345352
b.createEndAccess(loc, selfRef, /*aborted=*/false);
346353
}
347354

test/SILOptimizer/init_accessors.sil

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ bb0(%0 : $Int, %1 : $*Test):
3939
}
4040

4141
// CHECK-LABEL: sil hidden [ossa] @$s14init_accessors4TestV1vACSi_tcfC : $@convention(method) (Int, @thin Test.Type) -> Test
42+
// CHECK: [[SELF_REF:%.*]] = begin_access [modify] [unknown] [[SELF:%.*]] : $*Test
4243
// CHECK: [[INIT_REF:%.*]] = function_ref @$s14init_accessors4TestV1xSivi : $@convention(thin) (Int) -> @out Int
43-
// CHECK: [[SELF_REF:%.*]] = begin_access [modify] [dynamic] [[SELF:%.*]] : $*Test
44-
// CHECK-NEXT: [[FIELD_REF:%.*]] = struct_element_addr [[SELF_REF]] : $*Test, #Test._x
44+
// CHECK: [[FIELD_REF:%.*]] = struct_element_addr [[SELF_REF]] : $*Test, #Test._x
4545
// CHECK-NEXT: {{.*}} = apply [[INIT_REF]]([[FIELD_REF]], %0) : $@convention(thin) (Int) -> @out Int
4646
sil hidden [ossa] @$s14init_accessors4TestV1vACSi_tcfC : $@convention(method) (Int, @thin Test.Type) -> Test {
4747
bb0(%0 : $Int, %1 : $@thin Test.Type):

test/SILOptimizer/init_accessors.swift

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,11 @@ struct TestInit {
4141
}
4242

4343
// CHECK-LABEL: sil hidden [ossa] @$s14init_accessors8TestInitV1x1yACSi_SitcfC : $@convention(method) (Int, Int, @thin TestInit.Type) -> TestInit
44+
// CHECK: end_access
45+
// CHECK: [[SELF_VALUE:%.*]] = begin_access [modify] [static] {{.*}} : $*TestInit
4446
// CHECK: // function_ref TestInit.point.init
4547
// CHECK-NEXT: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s14init_accessors8TestInitV5pointSi_Sitvi : $@convention(thin) (Int, Int, @inout Int, @thin TestInit.Type) -> (@out Int, @out (Int, Int))
4648
// 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))
47-
// CHECK: [[SELF_VALUE:%.*]] = begin_access [modify] [dynamic] {{.*}} : $*TestInit
4849
// CHECK: [[Y_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*TestInit, #TestInit.y
4950
// CHECK-NEXT: [[FULL_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*TestInit, #TestInit.full
5051
// CHECK-NEXT: ([[X_VAL:%.*]], [[Y_VAL:%.*]]) = destructure_tuple {{.*}} : $(Int, Int)
@@ -71,10 +72,13 @@ struct TestSetter {
7172
}
7273

7374
// CHECK-LABEL: sil hidden [ossa] @$s14init_accessors10TestSetterV1x1yACSi_SitcfC : $@convention(method) (Int, Int, @thin TestSetter.Type) -> TestSetter
75+
// CHECK: [[AS:%.*]] = alloc_stack
76+
// CHECK: end_access
77+
// CHECK: end_access
78+
// CHECK: [[SELF:%.*]] = begin_access [modify] [static] [[AS]] : $*TestSetter
7479
// CHECK: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s14init_accessors10TestSetterV5pointSi_Sitvi : $@convention(thin) (Int, Int, @inout Int, @inout Int, @thin TestSetter.Type) -> ()
7580
// CHECK: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]](%2) : $@convention(thin) (Int, Int, @inout Int, @inout Int, @thin TestSetter.Type) -> ()
76-
// CHECK: [[SELF:%.*]] = begin_access [modify] [dynamic] %14 : $*TestSetter
77-
// CHECK-NEXT: ([[X:%.*]], [[Y:%.*]]) = destructure_tuple {{.*}} : $(Int, Int)
81+
// CHECK: ([[X:%.*]], [[Y:%.*]]) = destructure_tuple {{.*}} : $(Int, Int)
7882
// CHECK-NEXT: [[X_REF:%.*]] = struct_element_addr [[SELF]] : $*TestSetter, #TestSetter.x
7983
// CHECK-NEXT: [[Y_REF:%.*]] = struct_element_addr [[SELF]] : $*TestSetter, #TestSetter.y
8084
// CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[X]], [[Y]], [[X_REF]], [[Y_REF]]) : $@noescape @callee_guaranteed (Int, Int, @inout Int, @inout Int) -> ()
@@ -204,17 +208,18 @@ struct TestNoInitAndInit {
204208

205209
// CHECK-LABEL: sil hidden [ossa] @$s14init_accessors013TestNoInitAndE0V1x1yACSi_SitcfC : $@convention(method) (Int, Int, @thin TestNoInitAndInit.Type) -> TestNoInitAndInit
206210
//
211+
// CHECK: end_access
212+
// CHECK: [[SELF_REF:%.*]] = begin_access [modify] [static] {{.*}} : $*TestNoInitAndInit
207213
// CHECK: [[INIT_REF_FN:%.*]] = function_ref @$s14init_accessors013TestNoInitAndE0V6pointXSivi : $@convention(thin) (Int, @inout Int, @thin TestNoInitAndInit.Type) -> ()
208214
// CHECK: [[INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF_FN]](%2) : $@convention(thin) (Int, @inout Int, @thin TestNoInitAndInit.Type) -> ()
209-
// CHECK: [[SELF_REF:%.*]] = begin_access [modify] [dynamic] {{.*}} : $*TestNoInitAndInit
210-
// CHECK-NEXT: [[X_REF:%.*]] = struct_element_addr [[SELF_REF]] : $*TestNoInitAndInit, #TestNoInitAndInit.x
215+
// CHECK: [[X_REF:%.*]] = struct_element_addr [[SELF_REF]] : $*TestNoInitAndInit, #TestNoInitAndInit.x
211216
// CHECK-NEXT: {{.*}} = apply [[INIT_REF]](%0, [[X_REF]]) : $@noescape @callee_guaranteed (Int, @inout Int) -> ()
212217
// CHECK-NEXT: end_access [[SELF_REF]] : $*TestNoInitAndInit
213218
//
219+
// CHECK: [[SELF_REF:%.*]] = begin_access [modify] [static] {{.*}} : $*TestNoInitAndInit
214220
// CHECK: [[INIT_REF_FN:%.*]] = function_ref @$s14init_accessors013TestNoInitAndE0V6pointYSivi : $@convention(thin) (Int, @thin TestNoInitAndInit.Type) -> @out Int
215221
// CHECK: [[INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF_FN]](%2) : $@convention(thin) (Int, @thin TestNoInitAndInit.Type) -> @out Int
216-
// CHECK: [[SELF_REF:%.*]] = begin_access [modify] [dynamic] {{.*}} : $*TestNoInitAndInit
217-
// CHECK-NEXT: [[Y_REF:%.*]] = struct_element_addr [[SELF_REF]] : $*TestNoInitAndInit, #TestNoInitAndInit.y
222+
// CHECK: [[Y_REF:%.*]] = struct_element_addr [[SELF_REF]] : $*TestNoInitAndInit, #TestNoInitAndInit.y
218223
// CHECK-NEXT: {{.*}} = apply [[INIT_REF]]([[Y_REF]], %1) : $@noescape @callee_guaranteed (Int) -> @out Int
219224
// CHECK-NEXT: end_access [[SELF_REF]] : $*TestNoInitAndInit
220225
init(x: Int, y: Int) {

0 commit comments

Comments
 (0)