Skip to content

Commit 631555a

Browse files
authored
Merge pull request #29738 from zoecarver/ossa/let-prop-opt
[ownership] update let properties opts to support ossa
2 parents 62e0da9 + a079a21 commit 631555a

File tree

3 files changed

+128
-41
lines changed

3 files changed

+128
-41
lines changed

lib/SILOptimizer/IPO/LetPropertiesOpts.cpp

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,8 @@ void LetPropertiesOpt::optimizeLetPropertyAccess(VarDecl *Property,
203203
};
204204

205205
// Look for any instructions accessing let properties.
206-
if (isa<RefElementAddrInst>(Load) || isa<StructElementAddrInst>(Load)
207-
|| isa<BeginAccessInst>(Load)) {
206+
if (isa<RefElementAddrInst>(Load) || isa<StructElementAddrInst>(Load) ||
207+
isa<BeginAccessInst>(Load) || isa<BeginBorrowInst>(Load)) {
208208
auto proj = cast<SingleValueInstruction>(Load);
209209

210210
// Copy the initializer into the function
@@ -216,7 +216,7 @@ void LetPropertiesOpt::optimizeLetPropertyAccess(VarDecl *Property,
216216
++UI;
217217

218218
// A nested begin_access will be mapped as a separate "Load".
219-
if (isa<BeginAccessInst>(User))
219+
if (isa<BeginAccessInst>(User) || isa<BeginBorrowInst>(User))
220220
continue;
221221

222222
if (!canReplaceLoadSequence(User))
@@ -372,18 +372,6 @@ bool LetPropertiesOpt::isConstantLetProperty(VarDecl *Property) {
372372
LLVM_DEBUG(llvm::dbgs() << "Property '" << *Property
373373
<< "' has no unknown uses\n");
374374

375-
// Only properties of simple types can be optimized.
376-
377-
// FIXME: Expansion
378-
auto &TL = Module->Types.getTypeLowering(Property->getType(),
379-
TypeExpansionContext::minimal());
380-
if (!TL.isTrivial()) {
381-
LLVM_DEBUG(llvm::dbgs() << "Property '" << *Property
382-
<< "' is not of trivial type\n");
383-
SkipProcessing.insert(Property);
384-
return false;
385-
}
386-
387375
PotentialConstantLetProperty.insert(Property);
388376

389377
return true;
@@ -412,6 +400,8 @@ LetPropertiesOpt::analyzeInitValue(SILInstruction *I, VarDecl *Property) {
412400
&& "Store instruction should store into a proper let property");
413401
(void) Dest;
414402
value = SI->getSrc();
403+
} else if (auto *copyAddr = dyn_cast<CopyAddrInst>(I)) {
404+
value = copyAddr->getSrc();
415405
}
416406

417407
// Check if it's just a copy from another instance of the struct.
@@ -530,8 +520,9 @@ void LetPropertiesOpt::collectPropertyAccess(SILInstruction *I,
530520
<< *Property << "':\n";
531521
llvm::dbgs() << "The instructions are:\n"; I->dumpInContext());
532522

533-
if (isa<RefElementAddrInst>(I) || isa<StructElementAddrInst>(I)
534-
|| isa<BeginAccessInst>(I)) {
523+
if (isa<RefElementAddrInst>(I) || isa<StructElementAddrInst>(I) ||
524+
isa<BeginAccessInst>(I) || isa<CopyAddrInst>(I) ||
525+
isa<BeginBorrowInst>(I)) {
535526
// Check if there is a store to this property.
536527
auto projection = cast<SingleValueInstruction>(I);
537528
for (auto Use : getNonDebugUses(projection)) {
@@ -541,8 +532,17 @@ void LetPropertiesOpt::collectPropertyAccess(SILInstruction *I,
541532

542533
// Each begin_access is analyzed as a separate property access. Do not
543534
// consider a begin_access a use of the current projection.
544-
if (isa<BeginAccessInst>(User))
535+
if (isa<BeginAccessInst>(User) || isa<BeginBorrowInst>(I))
536+
continue;
537+
538+
if (auto *copyAddr = dyn_cast<CopyAddrInst>(User)) {
539+
if (copyAddr->getSrc() != projection ||
540+
!analyzeInitValue(copyAddr, Property)) {
541+
SkipProcessing.insert(Property);
542+
return;
543+
}
545544
continue;
545+
}
546546

547547
if (auto *SI = dyn_cast<StoreInst>(User)) {
548548
// There is a store into this property.
@@ -582,9 +582,6 @@ void LetPropertiesOpt::run(SILModuleTransform *T) {
582582
// properties.
583583
bool NonRemovable = !F.shouldOptimize();
584584

585-
// FIXME: We should be able to handle ownership.
586-
NonRemovable &= !F.hasOwnership();
587-
588585
for (auto &BB : F) {
589586
for (auto &I : BB)
590587
// Look for any instructions accessing let properties.

test/SILOptimizer/let_properties_opts.sil

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,20 @@ struct Point {
1212
var x: Int64
1313
var y: Int64
1414
}
15-
class HasCenter {
1615

16+
class HasCenter {
1717
let centerPoint: Point = Point(x: 0, y: 0)
18-
1918
public func getCenter() -> Int64
2019
}
2120

22-
sil hidden @$s19let_properties_opts5PointV1x1yACSi_SitcfC : $@convention(method) (Int64, Int64, @thin Point.Type) -> Point {
21+
sil hidden [ossa] @$s19let_properties_opts5PointV1x1yACSi_SitcfC : $@convention(method) (Int64, Int64, @thin Point.Type) -> Point {
2322
bb0(%0 : $Int64, %1 : $Int64, %2 : $@thin Point.Type):
2423
%3 = struct $Point (%0 : $Int64, %1 : $Int64)
2524
return %3 : $Point
2625
}
2726

2827
// variable initialization expression of HasCenter.centerPoint
29-
sil hidden [transparent] @$s19let_properties_opts9HasCenterC11centerPointAA0E0Vvpfi : $@convention(thin) () -> Point {
28+
sil hidden [transparent] [ossa] @$s19let_properties_opts9HasCenterC11centerPointAA0E0Vvpfi : $@convention(thin) () -> Point {
3029
bb0:
3130
%0 = integer_literal $Builtin.Int64, 0
3231
%1 = struct $Int64 (%0 : $Builtin.Int64)
@@ -35,43 +34,47 @@ bb0:
3534
}
3635

3736
// HasCenter.centerPoint.getter
38-
// CHECK-LABEL: sil hidden [transparent] @$s19let_properties_opts9HasCenterC11centerPointAA0E0Vvg : $@convention(method) (@guaranteed HasCenter) -> Point {
39-
// CHECK: bb0(%0 : $HasCenter):
37+
// CHECK-LABEL: sil hidden [transparent] [ossa] @$s19let_properties_opts9HasCenterC11centerPointAA0E0Vvg : $@convention(method) (@guaranteed HasCenter) -> Point {
38+
// CHECK: bb0(%0 : @guaranteed $HasCenter):
4039
// CHECK: [[LIT:%.*]] = integer_literal $Builtin.Int64, 0
4140
// CHECK: [[INT:%.*]] = struct $Int64 ([[LIT]] : $Builtin.Int64)
4241
// CHECK: [[PNT:%.*]] = struct $Point ([[INT]] : $Int64, [[INT]] : $Int64)
4342
// CHECK: return [[PNT]] : $Point
4443
// CHECK-LABEL: } // end sil function '$s19let_properties_opts9HasCenterC11centerPointAA0E0Vvg'
45-
sil hidden [transparent] @$s19let_properties_opts9HasCenterC11centerPointAA0E0Vvg : $@convention(method) (@guaranteed HasCenter) -> Point {
46-
bb0(%0 : $HasCenter):
44+
sil hidden [transparent] [ossa] @$s19let_properties_opts9HasCenterC11centerPointAA0E0Vvg : $@convention(method) (@guaranteed HasCenter) -> Point {
45+
bb0(%0 : @guaranteed $HasCenter):
4746
%1 = ref_element_addr %0 : $HasCenter, #HasCenter.centerPoint
48-
%2 = load %1 : $*Point
47+
%2 = load [trivial] %1 : $*Point
4948
return %2 : $Point
5049
}
5150

5251
// HasCenter.getCenter()
53-
// CHECK-LABEL: sil hidden @$s19let_properties_opts9HasCenterC9getCenterSiyF : $@convention(method) (@guaranteed HasCenter) -> Int64 {
52+
// CHECK-LABEL: sil hidden [ossa] @$s19let_properties_opts9HasCenterC9getCenterSiyF : $@convention(method) (@guaranteed HasCenter) -> Int64 {
5453
// CHECK: [[LIT:%.*]] = integer_literal $Builtin.Int64, 0
5554
// CHECK: [[INT:%.*]] = struct $Int64 ([[LIT]] : $Builtin.Int64)
5655
// CHECK: [[PNT:%.*]] = struct $Point ([[INT]] : $Int64, [[INT]] : $Int64)
5756
// CHECK: [[X:%.*]] = struct_extract [[PNT]] : $Point, #Point.x
5857
// CHECK: return [[X]] : $Int64
5958
// CHECK-LABEL: } // end sil function '$s19let_properties_opts9HasCenterC9getCenterSiyF'
60-
sil hidden @$s19let_properties_opts9HasCenterC9getCenterSiyF : $@convention(method) (@guaranteed HasCenter) -> Int64 {
61-
bb0(%0 : $HasCenter):
59+
sil hidden [ossa] @$s19let_properties_opts9HasCenterC9getCenterSiyF : $@convention(method) (@guaranteed HasCenter) -> Int64 {
60+
bb0(%0 : @guaranteed $HasCenter):
6261
%1 = ref_element_addr %0 : $HasCenter, #HasCenter.centerPoint
6362
%2 = struct_element_addr %1 : $*Point, #Point.x
64-
%3 = load %2 : $*Int64
63+
%3 = load [trivial] %2 : $*Int64
6564
return %3 : $Int64
6665
}
6766

6867
// HasCenter.init()
69-
sil hidden @$s19let_properties_opts9HasCenterCACycfc : $@convention(method) (@owned HasCenter) -> @owned HasCenter {
70-
bb0(%0 : $HasCenter):
68+
sil hidden [ossa] @$s19let_properties_opts9HasCenterCACycfc : $@convention(method) (@owned HasCenter) -> @owned HasCenter {
69+
bb0(%0 : @owned $HasCenter):
7170
%1 = integer_literal $Builtin.Int64, 0
72-
%2 = struct $Int64 (%1 : $Builtin.Int64)
73-
%3 = struct $Point (%2 : $Int64, %2 : $Int64)
74-
%4 = ref_element_addr %0 : $HasCenter, #HasCenter.centerPoint
75-
store %3 to %4 : $*Point
76-
return %0 : $HasCenter
71+
%3 = struct $Int64 (%1 : $Builtin.Int64)
72+
%4 = struct $Point (%3 : $Int64, %3 : $Int64)
73+
%5 = begin_borrow %0 : $HasCenter
74+
%6 = ref_element_addr %5 : $HasCenter, #HasCenter.centerPoint
75+
store %4 to [trivial] %6 : $*Point
76+
end_borrow %5 : $HasCenter
77+
%9 = copy_value %0 : $HasCenter
78+
destroy_value %0 : $HasCenter
79+
return %9 : $HasCenter
7780
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// RUN: %target-sil-opt -let-properties-opt -enable-sil-verify-all %s | %FileCheck %s
2+
3+
sil_stage canonical
4+
5+
import Builtin
6+
import Swift
7+
8+
class Point {
9+
let x: Int64 = 0
10+
let y: Int64 = 0
11+
}
12+
13+
class HasCenter {
14+
let centerPoint: Point = Point()
15+
public func getCenter() -> Int64
16+
}
17+
18+
// Point.init()
19+
sil hidden [ossa] @$s19let_properties_opts5PointCACycfc : $@convention(method) (@owned Point) -> @owned Point {
20+
bb0(%0 : @owned $Point):
21+
%1 = integer_literal $Builtin.Int64, 0
22+
%2 = struct $Int64 (%1 : $Builtin.Int64)
23+
24+
%3 = begin_borrow %0 : $Point
25+
%6 = ref_element_addr %3 : $Point, #Point.x
26+
store %2 to [trivial] %6 : $*Int64
27+
end_borrow %3 : $Point
28+
29+
%9 = begin_borrow %0 : $Point
30+
%12 = ref_element_addr %9 : $Point, #Point.y
31+
store %2 to [trivial] %12 : $*Int64
32+
end_borrow %9 : $Point
33+
34+
%15 = copy_value %0 : $Point
35+
destroy_value %0 : $Point
36+
return %15 : $Point
37+
}
38+
39+
// HasCenter.init()
40+
sil hidden [ossa] @$s19let_properties_opts9HasCenterCACycfc : $@convention(method) (@owned HasCenter) -> @owned HasCenter {
41+
// %0 // users: %2, %1
42+
bb0(%0 : @owned $HasCenter):
43+
%1 = alloc_ref $Point
44+
// function_ref Point.init()
45+
%2 = function_ref @$s19let_properties_opts5PointCACycfc : $@convention(method) (@owned Point) -> @owned Point
46+
%3 = apply %2(%1) : $@convention(method) (@owned Point) -> @owned Point
47+
48+
%5 = begin_borrow %0 : $HasCenter // users: %8, %6
49+
%6 = ref_element_addr %5 : $HasCenter, #HasCenter.centerPoint // user: %7
50+
51+
store %3 to [init] %6 : $*Point // id: %7
52+
end_borrow %5 : $HasCenter // id: %8
53+
54+
%9 = copy_value %0 : $HasCenter // user: %11
55+
destroy_value %0 : $HasCenter // id: %10
56+
return %9 : $HasCenter // id: %11
57+
} // end sil function '$s19let_properties_opts9HasCenterCACycfc'
58+
59+
// HasCenter.centerPoint.getter
60+
sil hidden [transparent] [ossa] @$s19let_properties_opts9HasCenterC11centerPointAA0G0Cvg : $@convention(method) (@guaranteed HasCenter) -> @owned Point {
61+
// %0 // users: %2, %1
62+
bb0(%0 : @guaranteed $HasCenter):
63+
debug_value %0 : $HasCenter, let, name "self", argno 1 // id: %1
64+
%2 = ref_element_addr %0 : $HasCenter, #HasCenter.centerPoint // user: %3
65+
%3 = load [copy] %2 : $*Point // user: %4
66+
return %3 : $Point // id: %4
67+
} // end sil function '$s19let_properties_opts9HasCenterC11centerPointAA0G0Cvg'
68+
69+
// HasCenter.getCenter()
70+
// CHECK-LABEL: sil hidden [ossa] @$s19let_properties_opts9HasCenterC03getE0s5Int64VyF : $@convention(method) (@guaranteed HasCenter) -> Int64 {
71+
// CHECK: [[LIT:%.*]] = integer_literal $Builtin.Int64, 0
72+
// CHECK: [[INT:%.*]] = struct $Int64 ([[LIT]] : $Builtin.Int64)
73+
// CHECK: return [[INT]] : $Int64
74+
// CHECK-LABEL: } // end sil function '$s19let_properties_opts9HasCenterC03getE0s5Int64VyF'
75+
sil hidden [ossa] @$s19let_properties_opts9HasCenterC03getE0s5Int64VyF : $@convention(method) (@guaranteed HasCenter) -> Int64 {
76+
// %0 // users: %2, %1
77+
bb0(%0 : @guaranteed $HasCenter):
78+
debug_value %0 : $HasCenter, let, name "self", argno 1 // id: %1
79+
%2 = ref_element_addr %0 : $HasCenter, #HasCenter.centerPoint // user: %3
80+
%3 = load [copy] %2 : $*Point // users: %8, %4
81+
%4 = begin_borrow %3 : $Point // users: %7, %5
82+
%5 = ref_element_addr %4 : $Point, #Point.x // user: %6
83+
%6 = load [trivial] %5 : $*Int64 // user: %9
84+
end_borrow %4 : $Point // id: %7
85+
destroy_value %3 : $Point // id: %8
86+
return %6 : $Int64 // id: %9
87+
} // end sil function '$s19let_properties_opts9HasCenterC03getE0s5Int64VyF'

0 commit comments

Comments
 (0)