Skip to content

Commit bbb6ca1

Browse files
author
Joe Shajrawi
authored
Merge pull request #19023 from shajrawi/licm_apply_begin
[LICM/Exclusivity] Hoist (some) conflicting begin_accesses out of loops
2 parents 15e4094 + 95344f6 commit bbb6ca1

File tree

2 files changed

+94
-3
lines changed

2 files changed

+94
-3
lines changed

lib/SILOptimizer/LoopTransforms/LICM.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,8 @@ static bool handledEndAccesses(BeginAccessInst *BI, SILLoop *Loop) {
537537
static bool analyzeBeginAccess(BeginAccessInst *BI,
538538
SmallVector<BeginAccessInst *, 8> &BeginAccesses,
539539
SmallVector<FullApplySite, 8> &fullApplies,
540-
AccessedStorageAnalysis *ASA) {
540+
AccessedStorageAnalysis *ASA,
541+
DominanceInfo *DT) {
541542
if (BI->getEnforcement() != SILAccessEnforcement::Dynamic) {
542543
return false;
543544
}
@@ -564,8 +565,18 @@ static bool analyzeBeginAccess(BeginAccessInst *BI,
564565
FunctionAccessedStorage callSiteAccesses;
565566
ASA->getCallSiteEffects(callSiteAccesses, fullApply);
566567
SILAccessKind accessKind = BI->getAccessKind();
567-
if (callSiteAccesses.mayConflictWith(accessKind, storage))
568+
if (!callSiteAccesses.mayConflictWith(accessKind, storage))
569+
continue;
570+
// Check if we can ignore this conflict:
571+
// If the apply is “sandwiched” between the begin and end access,
572+
// there’s no reason we can’t hoist out of the loop.
573+
auto *applyInstr = fullApply.getInstruction();
574+
if (!DT->dominates(BI, applyInstr))
568575
return false;
576+
for (auto *EI : BI->getEndAccesses()) {
577+
if (!DT->dominates(applyInstr, EI))
578+
return false;
579+
}
569580
}
570581

571582
return true;
@@ -687,7 +698,7 @@ void LoopTreeOptimization::analyzeCurrentLoop(
687698
LLVM_DEBUG(llvm::dbgs() << "Some end accesses can't be handled\n");
688699
continue;
689700
}
690-
if (analyzeBeginAccess(BI, BeginAccesses, fullApplies, ASA)) {
701+
if (analyzeBeginAccess(BI, BeginAccesses, fullApplies, ASA, DomTree)) {
691702
SpecialHoist.insert(BI);
692703
}
693704
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enforce-exclusivity=checked -enable-sil-verify-all %s -licm | %FileCheck %s
2+
3+
sil_stage canonical
4+
5+
6+
import Builtin
7+
import Swift
8+
9+
struct X {
10+
@sil_stored var i: Int64 { get set }
11+
init(i: Int64)
12+
init()
13+
}
14+
15+
var globalX: X
16+
17+
sil_global hidden @globalX : $X
18+
19+
20+
sil hidden_external [global_init] @globalAddressor : $@convention(thin) () -> Builtin.RawPointer
21+
22+
// public func hoist_access_with_conflict() {
23+
// Tests Hoisting of begin/end access when there's a "sandwiched" unidentified access
24+
//
25+
// CHECK-LABEL: sil @hoist_access_with_conflict : $@convention(thin) () -> () {
26+
// CHECK: [[GLOBAL:%.*]] = global_addr @globalX : $*X
27+
// CHECK: [[BEGIN:%.*]] = begin_access [read] [dynamic] %0 : $*X
28+
// CHECK-NEXT: br bb1
29+
// CHECK: apply
30+
// CHECK: load
31+
// CHECK: cond_br
32+
// CHECK: bb2
33+
// CHECK: end_access [[BEGIN]]
34+
// CHECK-LABEL: } // end sil function 'hoist_access_with_conflict'
35+
sil @hoist_access_with_conflict : $@convention(thin) () -> () {
36+
bb0:
37+
%0 = global_addr @globalX: $*X
38+
%u0 = function_ref @globalAddressor : $@convention(thin) () -> Builtin.RawPointer
39+
br bb1
40+
41+
bb1:
42+
%u3 = begin_access [read] [dynamic] %0 : $*X
43+
%u1 = apply %u0() : $@convention(thin) () -> Builtin.RawPointer
44+
%u4 = load %u3 : $*X
45+
end_access %u3 : $*X
46+
cond_br undef, bb1, bb2
47+
48+
bb2:
49+
%10 = tuple ()
50+
return %10 : $()
51+
}
52+
53+
// public func dont_hoist_access_with_conflict() {
54+
// Tests *not* hoisting begin/end access when there's an unidentified access not protected by them
55+
//
56+
// CHECK-LABEL: sil @dont_hoist_access_with_conflict : $@convention(thin) () -> () {
57+
// CHECK: [[GLOBAL:%.*]] = global_addr @globalX : $*X
58+
// CHECK: br bb1
59+
// CHECK: apply
60+
// CHECK-NEXT: [[BEGIN:%.*]] = begin_access [read] [dynamic] %0 : $*X
61+
// CHECK-NEXT: load
62+
// CHECK-NEXT: end_access [[BEGIN]]
63+
// CHECK-LABEL: } // end sil function 'dont_hoist_access_with_conflict'
64+
sil @dont_hoist_access_with_conflict : $@convention(thin) () -> () {
65+
bb0:
66+
%0 = global_addr @globalX: $*X
67+
%u0 = function_ref @globalAddressor : $@convention(thin) () -> Builtin.RawPointer
68+
br bb1
69+
70+
bb1:
71+
%u1 = apply %u0() : $@convention(thin) () -> Builtin.RawPointer
72+
%u3 = begin_access [read] [dynamic] %0 : $*X
73+
%u4 = load %u3 : $*X
74+
end_access %u3 : $*X
75+
cond_br undef, bb1, bb2
76+
77+
bb2:
78+
%10 = tuple ()
79+
return %10 : $()
80+
}

0 commit comments

Comments
 (0)