Skip to content

Commit 376651d

Browse files
authored
Merge pull request #81139 from eeckstein/keypath-optimization
Optimize keypaths in language 6 mode
2 parents 22c34dd + 6ccd1ac commit 376651d

File tree

3 files changed

+37
-9
lines changed

3 files changed

+37
-9
lines changed

lib/SILOptimizer/Utils/KeyPathProjector.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -674,8 +674,8 @@ class CompleteKeyPathProjector : public KeyPathProjector {
674674

675675
KeyPathInst *
676676
KeyPathProjector::getLiteralKeyPath(SILValue keyPath) {
677-
while (auto *upCast = dyn_cast<UpcastInst>(keyPath)) {
678-
keyPath = lookThroughOwnershipInsts(upCast->getOperand());
677+
while (isa<UpcastInst>(keyPath) || isa<OpenExistentialRefInst>(keyPath)) {
678+
keyPath = lookThroughOwnershipInsts(cast<SingleValueInstruction>(keyPath)->getOperand(0));
679679
}
680680

681681
return dyn_cast<KeyPathInst>(keyPath);

test/SILOptimizer/capture_propagate_keypath.swift

+6
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ func testGenStr(_ mymap: ((GenStr<Int>)->Int) -> ()) {
6060

6161
// CHECK-LABEL: sil {{.*}} @$s4test0A22GenericEscapingClosureAA5GetIDVySayAA3StrVGSiGyF :
6262
// CHECK-NOT: keypath
63+
// CHECK: = function_ref @[[SPECIALIZED_CLOSURE:.*]] : $@convention(thin) (@in_guaranteed Str) -> @out Int
64+
// CHECK-NOT: keypath
6365
// CHECK-LABEL: } // end sil function '$s4test0A22GenericEscapingClosureAA5GetIDVySayAA3StrVGSiGyF'
6466
@inline(never)
6567
func testGenericEscapingClosure() -> GetID<[Str], Int> {
@@ -85,6 +87,10 @@ public func _opaqueIdentity<T>(_ x: T) -> T {
8587
return x
8688
}
8789

90+
// CHECK: sil shared {{.*}}@[[SPECIALIZED_CLOSURE]] :
91+
// CHECK-NOT: keypath
92+
// CHECK: } // end sil function '[[SPECIALIZED_CLOSURE]]'
93+
8894
func calltests() {
8995
// CHECK-OUTPUT-LABEL: testSimple:
9096
print("testSimple:")

test/SILOptimizer/optimize_keypath.swift

+29-7
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,16 @@
33
// RUN: %FileCheck %s < %t/output.sil
44
// RUN: %FileCheck -check-prefix=CHECK-ALL %s < %t/output.sil
55

6+
// RUN: %target-swift-frontend -primary-file %s -O -sil-verify-all -swift-version 6 -Xllvm -sil-print-types -emit-sil >%t/output6.sil
7+
// RUN: %FileCheck %s < %t/output6.sil
8+
// RUN: %FileCheck -check-prefix=CHECK-ALL %s < %t/output6.sil
9+
610
// RUN: %target-build-swift -O %s -o %t/a.out
7-
// RUN: %target-run %t/a.out | %FileCheck %s -check-prefix=CHECK-OUTPUT
11+
// RUN: %target-run %t/a.out | %FileCheck %s -check-prefix=CHECK-OUTPUT -check-prefix=CHECK5-OUTPUT
12+
13+
// RUN: %target-build-swift -swift-version 6 -O %s -o %t/a6.out
14+
// RUN: %target-run %t/a6.out | %FileCheck %s -check-prefix=CHECK-OUTPUT
15+
816
// REQUIRES: executable_test,optimized_stdlib
917
// REQUIRES: CPU=arm64 || CPU=x86_64
1018

@@ -28,7 +36,9 @@ struct GenStruct<T : P> : P {
2836
}
2937
}
3038

39+
#if !swift(>=6)
3140
var numGenClassObjs = 0
41+
#endif
3242

3343
final class GenClass<T : P> : P {
3444
var ct: T
@@ -39,11 +49,15 @@ final class GenClass<T : P> : P {
3949
init(_ ct: T) {
4050
self.ct = ct
4151
self.gs = .init(ct)
52+
#if !swift(>=6)
4253
numGenClassObjs += 1
54+
#endif
4355
}
4456

4557
deinit {
58+
#if !swift(>=6)
4659
numGenClassObjs -= 1
60+
#endif
4761
}
4862

4963
func modifyIt() {
@@ -63,7 +77,9 @@ final class DerivedClass2 : DerivedClass<Int> {
6377

6478
final class SimpleClass : P {
6579
var i: Int
80+
#if !swift(>=6)
6681
static var numObjs = 0
82+
#endif
6783

6884
var tuple = (0, 1)
6985

@@ -78,11 +94,15 @@ final class SimpleClass : P {
7894
init(_ i: Int, nested: Int? = nil) {
7995
self.i = i
8096
self.opt = nested.map { Nested(i: $0) }
97+
#if !swift(>=6)
8198
Self.numObjs += 1
99+
#endif
82100
}
83101

84102
deinit {
103+
#if !swift(>=6)
85104
Self.numObjs -= 1
105+
#endif
86106
}
87107

88108
func modifyIt() {
@@ -422,7 +442,7 @@ func testModifyOptionalForceClass(_ s: inout SimpleClass) {
422442
//
423443
// Check if value is null
424444
// CHECK: switch_enum [[O:%[0-9]+]]
425-
// CHECK: {{bb.}}:
445+
// CHECK: bb{{.*}}:
426446
// Unwrap value
427447
// CHECK: [[A1:%[0-9]+]] = alloc_stack
428448
// CHECK: store [[O]] to [[A1]]
@@ -453,7 +473,7 @@ func testOptionalChain(_ s: SimpleStruct) -> Int? {
453473
// CHECK: [[E2:%[0-9]+]] = begin_access [read] [dynamic] [no_nested_conflict] [[E1]]
454474
// Check if value is null
455475
// CHECK: switch_enum [[O:%[0-9]+]]
456-
// CHECK: {{bb.}}:
476+
// CHECK: bb{{.*}}:
457477
// Unwrap value
458478
// CHECK: [[A1:%[0-9]+]] = alloc_stack
459479
// CHECK: store [[O]] to [[A1]]
@@ -483,15 +503,15 @@ func testOptionalChainClass(_ s: SimpleClass) -> Int? {
483503
//
484504
// Check if value is null
485505
// CHECK: switch_enum [[O:%[0-9]+]]
486-
// CHECK: {{bb.}}:
506+
// CHECK: bb{{.*}}:
487507
// Unwrap value
488508
// CHECK: [[A1:%[0-9]+]] = alloc_stack
489509
// CHECK: store [[O]] to [[A1]]
490510
// CHECK: [[U:%[0-9]+]] = unchecked_take_enum_data_addr [[A1]]
491511
//
492512
// Unwrap nested optional
493513
// CHECK: switch_enum [[O2:%[0-9]+]]
494-
// CHECK: {{bb.}}:
514+
// CHECK: bb{{.*}}:
495515
// CHECK: [[A2:%[0-9]+]] = alloc_stack
496516
// CHECK: store [[O2]] to [[A2]]
497517
// CHECK: [[U2:%[0-9]+]] = unchecked_take_enum_data_addr [[A2]]
@@ -705,9 +725,11 @@ func testit() {
705725

706726
testit()
707727

708-
// CHECK-OUTPUT: SimpleClass obj count: 0
728+
#if !swift(>=6)
729+
// CHECK5-OUTPUT: SimpleClass obj count: 0
709730
print("SimpleClass obj count: \(SimpleClass.numObjs)")
710-
// CHECK-OUTPUT: GenClass obj count: 0
731+
// CHECK5-OUTPUT: GenClass obj count: 0
711732
print("GenClass obj count: \(numGenClassObjs)")
733+
#endif
712734

713735

0 commit comments

Comments
 (0)