Skip to content

Commit 2df6e80

Browse files
Merge pull request #68389 from nate-chandler/rdar115033825
[AccessBase] FindAccessBaseVisitor visits nested accesses.
2 parents 28fb321 + de2be03 commit 2df6e80

File tree

2 files changed

+112
-1
lines changed

2 files changed

+112
-1
lines changed

lib/SIL/Utils/MemAccessUtils.cpp

+45-1
Original file line numberDiff line numberDiff line change
@@ -193,13 +193,21 @@ class FindAccessVisitorImpl : public AccessUseDefChainVisitor<Impl, SILValue> {
193193

194194
// Override AccessUseDefChainVisitor to ignore access markers and find the
195195
// outer access base.
196-
SILValue visitNestedAccess(BeginAccessInst *access) {
196+
SILValue visitNestedAccessImpl(BeginAccessInst *access) {
197197
if (nestedAccessTy == NestedAccessType::IgnoreAccessBegin)
198198
return access->getSource();
199199

200200
return SuperTy::visitNestedAccess(access);
201201
}
202202

203+
SILValue visitNestedAccess(BeginAccessInst *access) {
204+
auto value = visitNestedAccessImpl(access);
205+
if (value) {
206+
reenterUseDef(value);
207+
}
208+
return SILValue();
209+
}
210+
203211
SILValue visitPhi(SILPhiArgument *phiArg) {
204212
// Cycles involving phis are only handled within AccessPhiVisitor.
205213
// Path components are not allowed in phi cycles.
@@ -362,6 +370,18 @@ SILValue swift::getTypedAccessAddress(SILValue address) {
362370
return accessAddress;
363371
}
364372

373+
namespace swift::test {
374+
static FunctionTest
375+
GetTypedAccessAddress("get_typed_access_address",
376+
[](auto &function, auto &arguments, auto &test) {
377+
auto address = arguments.takeValue();
378+
function.dump();
379+
llvm::dbgs() << "Address: " << address;
380+
auto access = getTypedAccessAddress(address);
381+
llvm::dbgs() << "Access: " << access;
382+
});
383+
} // end namespace swift::test
384+
365385
// TODO: When the optimizer stops stripping begin_access markers and SILGen
366386
// protects all memory operations with at least an "unsafe" access scope, then
367387
// we should be able to assert that this returns a BeginAccessInst.
@@ -379,6 +399,18 @@ SILValue swift::getAccessBase(SILValue address) {
379399
.findPossibleBaseAddress(address);
380400
}
381401

402+
namespace swift::test {
403+
static FunctionTest GetAccessBaseTest("get_access_base",
404+
[](auto &function, auto &arguments,
405+
auto &test) {
406+
auto address = arguments.takeValue();
407+
function.dump();
408+
llvm::dbgs() << "Address: " << address;
409+
auto base = getAccessBase(address);
410+
llvm::dbgs() << "Base: " << base;
411+
});
412+
} // end namespace swift::test
413+
382414
static bool isLetForBase(SILValue base) {
383415
// Is this an address of a "let" class member?
384416
if (auto *rea = dyn_cast<RefElementAddrInst>(base))
@@ -1156,6 +1188,18 @@ AccessStorage AccessStorage::compute(SILValue sourceAddress) {
11561188
return AccessStorageWithBase::compute(sourceAddress).storage;
11571189
}
11581190

1191+
namespace swift::test {
1192+
static FunctionTest ComputeAccessStorage("compute_access_storage",
1193+
[](auto &function, auto &arguments,
1194+
auto &test) {
1195+
auto address = arguments.takeValue();
1196+
function.dump();
1197+
llvm::dbgs() << "Address: " << address;
1198+
auto accessStorage = AccessStorage::compute(address);
1199+
accessStorage.dump();
1200+
});
1201+
} // end namespace swift::test
1202+
11591203
AccessStorage AccessStorage::computeInScope(SILValue sourceAddress) {
11601204
return AccessStorageWithBase::computeInScope(sourceAddress).storage;
11611205
}

test/SILOptimizer/accessbase_unit.sil

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// RUN: %target-sil-opt -test-runner %s -o /dev/null 2>&1 | %FileCheck %s
2+
3+
import Builtin
4+
5+
class Box<T> {
6+
var value: T
7+
}
8+
9+
class C {}
10+
11+
12+
// CHECK-LABEL: begin running test {{.*}} on test_phi_nested_access: get_access_base with
13+
// CHECK: sil @test_phi_nested_access : {{.*}} {
14+
// CHECK: bb0([[BOX:%[^,]+]] :
15+
// CHECK: [[VALUE_ADDR:%[^,]+]] = ref_element_addr [[BOX]]
16+
// CHECK: [[VALUE_ACCESS:%[^,]+]] = begin_access [read] [unsafe] [[VALUE_ADDR]]
17+
// CHECK: [[VALUE_PTR:%[^,]+]] = address_to_pointer [stack_protection] [[VALUE_ACCESS]]
18+
// CHECK: end_access [[VALUE_ACCESS]]
19+
// CHECK: br bb1([[VALUE_PTR]]
20+
// CHECK: bb1([[VALUE_PHI:%[^,]+]] :
21+
// CHECK: } // end sil function 'test_phi_nested_access'
22+
// CHECK: Address: [[VALUE_PHI]] = argument of bb1
23+
// CHECK: Base: [[VALUE_ADDR]] = ref_element_addr
24+
// CHECK-LABEL: end running test {{.*}} on test_phi_nested_access: get_access_base with
25+
// CHECK-LABEL: begin running test {{.*}} on test_phi_nested_access: compute_access_storage with
26+
// CHECK: Address: [[VALUE_PHI]] = argument of bb1
27+
// CHECK: Class [[BOX]] = argument of bb0
28+
// CHECK: Field: var value: T Index: 0
29+
// CHECK-LABEL: end running test {{.*}} on test_phi_nested_access: compute_access_storage with
30+
// CHECK-LABEL: begin running test 3 of 3 on test_phi_nested_access: accesspath-base
31+
// CHECK: Access path base: %6 = argument of bb1
32+
// CHECK: Exact Use: end_access %2
33+
// CHECK-LABEL: end running test 3 of 3 on test_phi_nested_access: accesspath-base
34+
sil @test_phi_nested_access : $@convention(method) (@guaranteed Box<C>) -> () {
35+
bb1(%box : $Box<C>):
36+
%value_addr = ref_element_addr %box : $Box<C>, #Box.value
37+
%value_access = begin_access [read] [unsafe] %value_addr : $*C
38+
%value_ptr = address_to_pointer [stack_protection] %value_access : $*C to $Builtin.RawPointer
39+
end_access %value_access : $*C
40+
br exit(%value_ptr : $Builtin.RawPointer)
41+
42+
exit(%phi : $Builtin.RawPointer):
43+
test_specification "get_access_base @argument"
44+
test_specification "compute_access_storage @argument"
45+
test_specification "accesspath-base @argument"
46+
%retval = tuple ()
47+
return %retval : $()
48+
}
49+
50+
sil_global @global_c : $C
51+
52+
// CHECK-LABEL: begin running test {{.*}} on test_access_global
53+
// CHECK: sil @test_access_global : {{.*}} {
54+
// CHECK: [[GLOBAL:%[^,]+]] = global_addr @global_c
55+
// CHECK: [[ACCESS:%[^,]+]] = begin_access [read] [dynamic] [[GLOBAL]]
56+
// CHECK: } // end sil function 'test_access_global'
57+
// CHECK: Address: [[ACCESS]] = begin_access [read] [dynamic] [[GLOBAL]]
58+
// CHECK: Access: [[ACCESS]] = begin_access [read] [dynamic] [[GLOBAL]]
59+
// CHECK-LABEL: end running test {{.*}} on test_access_global
60+
sil @test_access_global : $@convention(thin) () -> () {
61+
%15 = global_addr @global_c : $*C
62+
test_specification "get_typed_access_address @instruction"
63+
%16 = begin_access [read] [dynamic] %15 : $*C
64+
end_access %16 : $*C
65+
%retval = tuple ()
66+
return %retval : $()
67+
}

0 commit comments

Comments
 (0)