Skip to content

Commit 2405db0

Browse files
authored
Merge pull request swiftlang#78160 from eeckstein/keypath-in-cpature-propagation
CapturePropagation: handle keypaths which are upcast.
2 parents 90176b3 + 750d6ec commit 2405db0

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

lib/SILOptimizer/IPO/CapturePropagation.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ static SILInstruction *getConstant(SILValue V) {
6868
if (auto *lit = dyn_cast<LiteralInst>(V))
6969
return lit;
7070

71+
if (auto *uc = dyn_cast<UpcastInst>(V))
72+
V = uc->getOperand();
73+
7174
if (auto *kp = dyn_cast<KeyPathInst>(V)) {
7275
// We could support operands, if they are constants, to enable propagation
7376
// of subscript keypaths. This would require to add the operands in the
@@ -567,7 +570,11 @@ bool CapturePropagation::optimizePartialApply(PartialApplyInst *PAI) {
567570
// keypath instruction in this pass, but let dead-object-elimination clean
568571
// it up later.
569572
if (!PAI->isOnStack()) {
570-
if (getSingleNonDebugUser(kp) != PAI)
573+
SILInstruction *user = getSingleNonDebugUser(kp);
574+
if (auto *uc = dyn_cast_or_null<UpcastInst>(user))
575+
user = getSingleNonDebugUser(uc);
576+
577+
if (user != PAI)
571578
return false;
572579
toDelete.push_back(kp);
573580
}

test/SILOptimizer/capture_propagate_keypath.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,14 @@ struct GenStr<T> {
2828
}
2929
}
3030

31+
struct GetID<C: RandomAccessCollection, ID> {
32+
var getID: (C.Element) -> ID
3133

34+
@inline(__always)
35+
init(id: KeyPath<C.Element, ID>) {
36+
getID = { $0[keyPath: id] }
37+
}
38+
}
3239

3340
// CHECK-LABEL: sil {{.*}} @$s4test0A6SimpleyyySiAA3StrVXEXEF :
3441
// CHECK-NOT: keypath
@@ -50,6 +57,14 @@ func testGenStr(_ mymap: ((GenStr<Int>)->Int) -> ()) {
5057
mymap(\.c)
5158
}
5259

60+
// CHECK-LABEL: sil {{.*}} @$s4test0A22GenericEscapingClosureAA5GetIDVySayAA3StrVGSiGyF :
61+
// CHECK-NOT: keypath
62+
// CHECK-LABEL: } // end sil function '$s4test0A22GenericEscapingClosureAA5GetIDVySayAA3StrVGSiGyF'
63+
@inline(never)
64+
func testGenericEscapingClosure() -> GetID<[Str], Int> {
65+
GetID(id: \.i)
66+
}
67+
5368
// CHECK-LABEL: sil {{.*}} @$s4test0A7GenericyyyxAA6GenStrVyxGXEXElF :
5469
// CHECK: keypath
5570
// CHECK: keypath
@@ -103,6 +118,11 @@ func calltests() {
103118
print(c(s))
104119
}
105120

121+
// CHECK-OUTPUT-LABEL: testGenericEscapingClosure:
122+
print("testGenericEscapingClosure:")
123+
124+
// CHECK-OUTPUT-NEXT: 27
125+
print(testGenericEscapingClosure().getID(Str()))
106126
}
107127

108128
calltests()

test/SILOptimizer/capture_propagation.sil

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,23 @@ bb0:
530530
return %7 : $()
531531
}
532532

533+
// CHECK-LABEL: sil @testCastKeypath :
534+
// CHECK-NOT: keypath
535+
// CHECK: } // end sil function 'testCastKeypath'
536+
sil @testCastKeypath : $@convention(thin) () -> () {
537+
bb0:
538+
%0 = keypath $WritableKeyPath<Str, Int>, (root $Str; stored_property #Str.a : $Int)
539+
%c = upcast %0 to $KeyPath<Str, Int>
540+
%1 = function_ref @closureWithKeypath : $@convention(thin) (Str, @guaranteed KeyPath<Str, Int>) -> Int
541+
%2 = partial_apply [callee_guaranteed] %1(%c) : $@convention(thin) (Str, @guaranteed KeyPath<Str, Int>) -> Int
542+
%3 = convert_escape_to_noescape %2 : $@callee_guaranteed (Str) -> Int to $@noescape @callee_guaranteed (Str) -> Int
543+
%4 = function_ref @calleeWithKeypath : $@convention(thin) (@noescape @callee_guaranteed (Str) -> Int) -> ()
544+
%5 = apply %4(%3) : $@convention(thin) (@noescape @callee_guaranteed (Str) -> Int) -> ()
545+
strong_release %2 : $@callee_guaranteed (Str) -> Int
546+
%7 = tuple ()
547+
return %7 : $()
548+
}
549+
533550
// CHECK-LABEL: sil shared @$s18closureWithKeypath{{.*}}main3StrVSiTf3npk_n : $@convention(thin) (Str) -> Int {
534551
// CHECK: [[K:%[0-9]+]] = keypath
535552
// CHECK: [[F:%[0-9]+]] = function_ref @swift_getAtKeyPath
@@ -566,6 +583,24 @@ bb0:
566583
return %7 : $()
567584
}
568585

586+
// CHECK-LABEL: sil [ossa] @testCastKeypathOSSA :
587+
// CHECK-NOT: keypath
588+
// CHECK: } // end sil function 'testCastKeypathOSSA'
589+
sil [ossa] @testCastKeypathOSSA : $@convention(thin) () -> () {
590+
bb0:
591+
%0 = keypath $WritableKeyPath<Str, Int>, (root $Str; stored_property #Str.a : $Int)
592+
%c = upcast %0 to $KeyPath<Str, Int>
593+
%1 = function_ref @closureWithKeypathOSSA : $@convention(thin) (Str, @guaranteed KeyPath<Str, Int>) -> Int
594+
%2 = partial_apply [callee_guaranteed] %1(%c) : $@convention(thin) (Str, @guaranteed KeyPath<Str, Int>) -> Int
595+
%3 = convert_escape_to_noescape %2 : $@callee_guaranteed (Str) -> Int to $@noescape @callee_guaranteed (Str) -> Int
596+
%4 = function_ref @calleeWithKeypath : $@convention(thin) (@noescape @callee_guaranteed (Str) -> Int) -> ()
597+
%5 = apply %4(%3) : $@convention(thin) (@noescape @callee_guaranteed (Str) -> Int) -> ()
598+
destroy_value %3 : $@noescape @callee_guaranteed (Str) -> Int
599+
destroy_value %2 : $@callee_guaranteed (Str) -> Int
600+
%7 = tuple ()
601+
return %7 : $()
602+
}
603+
569604
// CHECK-LABEL: sil [ossa] @testKeypathNoescapeOSSA
570605
// CHECK: [[K:%[0-9]+]] = keypath
571606
// CHECK: [[C:%[0-9]+]] = function_ref @$s22closureWithKeypathOSSA{{.*}}main3StrVSiTf3npk_n

0 commit comments

Comments
 (0)