Skip to content

Commit 98d6480

Browse files
authored
Merge pull request #80275 from jckarter/classify-address-projections
SILGen: Properly classify LValue component projections in more cases.
2 parents 9d6305c + f990413 commit 98d6480

File tree

3 files changed

+96
-15
lines changed

3 files changed

+96
-15
lines changed

Diff for: lib/SILGen/ManagedValue.h

+1-6
Original file line numberDiff line numberDiff line change
@@ -189,11 +189,6 @@ class ManagedValue {
189189
assert(value->getType().isAddress() && "Expected value to be an address");
190190
// We check for value->getFunction() here since we /could/ be passed
191191
// SILUndef here.
192-
if (auto *f = value->getFunction()) {
193-
if (value->getType().isTrivial(f)) {
194-
return forTrivialAddressRValue(value);
195-
}
196-
}
197192
assert(value->getOwnershipKind() == OwnershipKind::None &&
198193
"Addresses always have trivial ownership");
199194
return ManagedValue(value, false, CleanupHandle::invalid());
@@ -256,7 +251,7 @@ class ManagedValue {
256251

257252
/// Creates a managed value for an address that is undergoing a formal
258253
/// access. This will be `forLValue` if the `accessKind` is a mutating
259-
/// (exclusive) access or `forBorrowedRValueAddress` if the
254+
/// (exclusive) access or `forBorrowedAddressRValue` if the
260255
/// `accessKind` is borrowing (shared).
261256
static ManagedValue forFormalAccessedAddress(SILValue address,
262257
SGFAccessKind accessKind);

Diff for: lib/SILGen/SILGenLValue.cpp

+13-9
Original file line numberDiff line numberDiff line change
@@ -855,7 +855,7 @@ namespace {
855855
checkKind);
856856
}
857857

858-
return ManagedValue::forLValue(result);
858+
return ManagedValue::forFormalAccessedAddress(result, getAccessKind());
859859
}
860860

861861
void dump(raw_ostream &OS, unsigned indent) const override {
@@ -884,7 +884,7 @@ namespace {
884884
auto Res = SGF.B.createTupleElementAddr(loc, base.getValue(),
885885
ElementIndex,
886886
getTypeOfRValue().getAddressType());
887-
return ManagedValue::forLValue(Res);
887+
return ManagedValue::forFormalAccessedAddress(Res, getAccessKind());
888888
}
889889

890890
void dump(raw_ostream &OS, unsigned indent) const override {
@@ -913,22 +913,26 @@ namespace {
913913

914914
// If we have a moveonlywrapped type, unwrap it. The reason why is that
915915
// any fields that we access we want to be treated as copyable.
916-
if (base.getType().isMoveOnlyWrapped())
917-
base = ManagedValue::forLValue(
918-
SGF.B.createMoveOnlyWrapperToCopyableAddr(loc, base.getValue()));
916+
if (base.getType().isMoveOnlyWrapped()) {
917+
base = ManagedValue::forFormalAccessedAddress(
918+
SGF.B.createMoveOnlyWrapperToCopyableAddr(loc, base.getValue()),
919+
getAccessKind());
920+
}
919921

920922
// TODO: if the base is +1, break apart its cleanup.
921923
auto Res = SGF.B.createStructElementAddr(loc, base.getValue(),
922924
Field, SubstFieldType);
923925

924926
if (!Field->getPointerAuthQualifier().isPresent() ||
925927
!SGF.getOptions().EnableImportPtrauthFieldFunctionPointers) {
926-
return ManagedValue::forLValue(Res);
928+
return ManagedValue::forFormalAccessedAddress(Res,
929+
getAccessKind());
927930
}
928931
auto beginAccess =
929932
enterAccessScope(SGF, loc, base, Res, getTypeData(), getAccessKind(),
930933
SILAccessEnforcement::Signed, takeActorIsolation());
931-
return ManagedValue::forLValue(beginAccess);
934+
return ManagedValue::forFormalAccessedAddress(beginAccess,
935+
getAccessKind());
932936
}
933937

934938
void dump(raw_ostream &OS, unsigned indent) const override {
@@ -1028,7 +1032,7 @@ namespace {
10281032
llvm_unreachable("Bad existential representation for address-only type");
10291033
}
10301034

1031-
return ManagedValue::forLValue(addr);
1035+
return ManagedValue::forFormalAccessedAddress(addr, getAccessKind());
10321036
}
10331037

10341038
void dump(raw_ostream &OS, unsigned indent) const override {
@@ -1180,7 +1184,7 @@ namespace {
11801184
NoConsumeOrAssign
11811185
: MarkUnresolvedNonCopyableValueInst::CheckKind::
11821186
AssignableButNotConsumable);
1183-
return ManagedValue::forLValue(addr);
1187+
return ManagedValue::forFormalAccessedAddress(addr, getAccessKind());
11841188
}
11851189
}
11861190

Diff for: test/SILGen/inline_array_stored_properties.swift

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// RUN: %target-swift-emit-silgen -module-name main %s -define-availability 'InlineArray 0.1:macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, visionOS 9999' | %FileCheck %s
2+
3+
@available(InlineArray 0.1, *)
4+
struct S {
5+
var a: InlineArray<40, Int> = .init(repeating: 0)
6+
7+
// CHECK-LABEL: sil {{.*}} @$s{{.*}}1SV1f
8+
mutating func f(x: inout Int, y: Int) {
9+
// CHECK: bb0({{.*}}, [[SELF:%.*]] : $*S):
10+
// CHECK: [[ACCESS:%.*]] = begin_access [read] [unknown] [[SELF]]
11+
// CHECK: [[ADDRESSOR:%.*]] = function_ref @$s{{.*}}11InlineArrayV
12+
// CHECK: [[PTR:%.*]] = apply [[ADDRESSOR]]
13+
// CHECK: [[RAWPTR:%.*]] = struct_extract [[PTR]]
14+
// CHECK: [[ADDR:%.*]] = pointer_to_address [[RAWPTR]]
15+
// CHECK: [[DEP:%.*]] = mark_dependence [unresolved] [[ADDR]]
16+
// CHECK: [[ADDR_ACCESS:%.*]] = begin_access [read] [unsafe] [[DEP]]
17+
// CHECK: load [trivial] [[ADDR_ACCESS]]
18+
// CHECK: end_access [[ADDR_ACCESS]]
19+
// CHECK: end_access [[ACCESS]]
20+
x += a[y]
21+
}
22+
}
23+
24+
@available(InlineArray 0.1, *)
25+
final class C {
26+
final var a: InlineArray<40, Int> = .init(repeating: 0)
27+
28+
// CHECK-LABEL: sil {{.*}} @$s{{.*}}1CC1f
29+
func f(x: inout Int, y: Int) {
30+
// CHECK: bb0({{.*}}, [[SELF:%.*]] : @guaranteed $C):
31+
// CHECK: [[FIELD:%.*]] = ref_element_addr [[SELF]]
32+
// CHECK: [[ACCESS:%.*]] = begin_access [read] [dynamic] [[FIELD]]
33+
// CHECK: [[ADDRESSOR:%.*]] = function_ref @$s{{.*}}11InlineArrayV
34+
// CHECK: [[PTR:%.*]] = apply [[ADDRESSOR]]
35+
// CHECK: [[RAWPTR:%.*]] = struct_extract [[PTR]]
36+
// CHECK: [[ADDR:%.*]] = pointer_to_address [[RAWPTR]]
37+
// CHECK: [[DEP:%.*]] = mark_dependence [unresolved] [[ADDR]]
38+
// CHECK: [[ADDR_ACCESS:%.*]] = begin_access [read] [unsafe] [[DEP]]
39+
// CHECK: load [trivial] [[ADDR_ACCESS]]
40+
// CHECK: end_access [[ADDR_ACCESS]]
41+
// CHECK: end_access [[ACCESS]]
42+
x += a[y]
43+
}
44+
}
45+
46+
// CHECK-LABEL: sil {{.*}} @$s{{.*}}6tupleF
47+
@available(InlineArray 0.1, *)
48+
func tupleF(tuple: inout (Int, InlineArray<40, Int>), x: inout Int, y: Int) {
49+
// CHECK: bb0([[TUPLE:%.*]] : $*(Int, InlineArray<40, Int>)
50+
// CHECK: [[ACCESS:%.*]] = begin_access [read] [unknown] [[TUPLE]]
51+
// CHECK: [[ADDRESSOR:%.*]] = function_ref @$s{{.*}}11InlineArrayV
52+
// CHECK: [[PTR:%.*]] = apply [[ADDRESSOR]]
53+
// CHECK: [[RAWPTR:%.*]] = struct_extract [[PTR]]
54+
// CHECK: [[ADDR:%.*]] = pointer_to_address [[RAWPTR]]
55+
// CHECK: [[DEP:%.*]] = mark_dependence [unresolved] [[ADDR]]
56+
// CHECK: [[ADDR_ACCESS:%.*]] = begin_access [read] [unsafe] [[DEP]]
57+
// CHECK: load [trivial] [[ADDR_ACCESS]]
58+
// CHECK: end_access [[ADDR_ACCESS]]
59+
// CHECK: end_access [[ACCESS]]
60+
x += tuple.1[y]
61+
}
62+
63+
@available(InlineArray 0.1, *)
64+
protocol P {
65+
var a: InlineArray<40, Int> { get set }
66+
}
67+
68+
// CHECK-LABEL: sil {{.*}} @$s{{.*}}12existentialF
69+
@available(InlineArray 0.1, *)
70+
func existentialF(e: inout P, x: inout Int, y: Int) {
71+
// CHECK: [[TEMP:%.*]] = alloc_stack $InlineArray
72+
// CHECK: [[ADDRESSOR:%.*]] = function_ref @$s{{.*}}11InlineArrayV
73+
// CHECK: [[PTR:%.*]] = apply [[ADDRESSOR]]
74+
// CHECK: [[RAWPTR:%.*]] = struct_extract [[PTR]]
75+
// CHECK: [[ADDR:%.*]] = pointer_to_address [[RAWPTR]]
76+
// CHECK: [[DEP:%.*]] = mark_dependence [unresolved] [[ADDR]]
77+
// CHECK: [[ADDR_ACCESS:%.*]] = begin_access [read] [unsafe] [[DEP]]
78+
// CHECK: load [trivial] [[ADDR_ACCESS]]
79+
// CHECK: end_access [[ADDR_ACCESS]]
80+
// CHECK: dealloc_stack [[TEMP]]
81+
x += e.a[y]
82+
}

0 commit comments

Comments
 (0)