Skip to content

Commit 7cab35b

Browse files
authored
Merge pull request #79816 from eeckstein/keypath-in-capture-propagation
CapturePropagation: handle existential keypaths
2 parents 9edb7f9 + 2587340 commit 7cab35b

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

lib/SILOptimizer/IPO/CapturePropagation.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ static SILInstruction *getConstant(SILValue V) {
7171
if (auto *uc = dyn_cast<UpcastInst>(V))
7272
V = uc->getOperand();
7373

74+
if (auto *oer = dyn_cast<OpenExistentialRefInst>(V))
75+
V = oer->getOperand();
76+
7477
if (auto *kp = dyn_cast<KeyPathInst>(V)) {
7578
// We could support operands, if they are constants, to enable propagation
7679
// of subscript keypaths. This would require to add the operands in the
@@ -566,11 +569,13 @@ bool CapturePropagation::optimizePartialApply(PartialApplyInst *PAI) {
566569
// instruction.
567570
//
568571
// For non-escaping closures:
569-
// The keypath is not consumed by the PAI. We don't need todelete the
572+
// The keypath is not consumed by the PAI. We don't need to delete the
570573
// keypath instruction in this pass, but let dead-object-elimination clean
571574
// it up later.
572575
if (!PAI->isOnStack()) {
573576
SILInstruction *user = getSingleNonDebugUser(kp);
577+
if (auto *oer = dyn_cast_or_null<OpenExistentialRefInst>(user))
578+
user = getSingleNonDebugUser(oer);
574579
if (auto *uc = dyn_cast_or_null<UpcastInst>(user))
575580
user = getSingleNonDebugUser(uc);
576581

test/SILOptimizer/capture_propagate_keypath.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %target-swift-frontend -primary-file %s -O -sil-verify-all -module-name=test -emit-sil | %FileCheck %s
2+
// RUN: %target-swift-frontend -primary-file %s -swift-version 6 -O -sil-verify-all -module-name=test -emit-sil | %FileCheck %s
23

34
// Also do an end-to-end test to check if the generated code is correct.
45
// RUN: %empty-directory(%t)

test/SILOptimizer/capture_propagation.sil

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,25 @@ bb0:
601601
return %7 : $()
602602
}
603603

604+
// CHECK-LABEL: sil [ossa] @testCastKeypathOSSA2 :
605+
// CHECK-NOT: keypath
606+
// CHECK: } // end sil function 'testCastKeypathOSSA2'
607+
sil [ossa] @testCastKeypathOSSA2 : $@convention(thin) () -> () {
608+
bb0:
609+
%0 = keypath $any WritableKeyPath<Str, Int> & Sendable, (root $Str; stored_property #Str.a : $Int)
610+
%o = open_existential_ref %0 to $@opened("E66BBE78-FA9E-11EF-B968-0EA13E3AABB4", any WritableKeyPath<Str, Int> & Sendable) Self
611+
%c = upcast %o to $KeyPath<Str, Int>
612+
%1 = function_ref @closureWithKeypathOSSA : $@convention(thin) (Str, @guaranteed KeyPath<Str, Int>) -> Int
613+
%2 = partial_apply [callee_guaranteed] %1(%c) : $@convention(thin) (Str, @guaranteed KeyPath<Str, Int>) -> Int
614+
%3 = convert_escape_to_noescape %2 : $@callee_guaranteed (Str) -> Int to $@noescape @callee_guaranteed (Str) -> Int
615+
%4 = function_ref @calleeWithKeypath : $@convention(thin) (@noescape @callee_guaranteed (Str) -> Int) -> ()
616+
%5 = apply %4(%3) : $@convention(thin) (@noescape @callee_guaranteed (Str) -> Int) -> ()
617+
destroy_value %3 : $@noescape @callee_guaranteed (Str) -> Int
618+
destroy_value %2 : $@callee_guaranteed (Str) -> Int
619+
%7 = tuple ()
620+
return %7 : $()
621+
}
622+
604623
// CHECK-LABEL: sil [ossa] @testKeypathNoescapeOSSA
605624
// CHECK: [[K:%[0-9]+]] = keypath
606625
// CHECK: [[C:%[0-9]+]] = function_ref @$s22closureWithKeypathOSSA{{.*}}main3StrVSiTf3npk_n

0 commit comments

Comments
 (0)