Skip to content

Commit 19c6894

Browse files
authored
Merge pull request #61437 from atrick/ossa-fold-noescape
Fix lexical destroy folding to handle PointerEscape
2 parents 6105077 + c89d0d0 commit 19c6894

File tree

5 files changed

+54
-24
lines changed

5 files changed

+54
-24
lines changed

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ OPERAND_OWNERSHIP(PointerEscape, UncheckedOwnershipConversion)
239239
OPERAND_OWNERSHIP(PointerEscape, ConvertEscapeToNoEscape)
240240

241241
// UncheckedBitwiseCast ownership behaves like RefToUnowned. It produces an
242-
// Unowned values from a non-trivial value, without consuming or borrowing the
242+
// Unowned value from a non-trivial value, without consuming or borrowing the
243243
// non-trivial value. Unlike RefToUnowned, a bitwise cast works on a compound
244244
// value and may truncate the value. The resulting value is still Unowned and
245245
// should be immediately copied to produce an owned value. These happen for two

lib/SILOptimizer/Utils/LexicalDestroyFolding.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -626,16 +626,22 @@ bool findBorroweeUsage(Context const &context, BorroweeUsage &usage) {
626626
auto *user = use->getUser();
627627
if (user == context.introducer)
628628
continue;
629-
if (use->getOperandOwnership() == OperandOwnership::Borrow) {
629+
switch (use->getOperandOwnership()) {
630+
case OperandOwnership::PointerEscape:
631+
return false;
632+
case OperandOwnership::Borrow:
630633
if (!BorrowingOperand(use).visitScopeEndingUses([&](Operand *end) {
631-
if (end->getOperandOwnership() == OperandOwnership::Reborrow) {
632-
return false;
633-
}
634-
recordUse(end);
635-
return true;
636-
})) {
634+
if (end->getOperandOwnership() == OperandOwnership::Reborrow) {
635+
return false;
636+
}
637+
recordUse(end);
638+
return true;
639+
})) {
637640
return false;
638641
}
642+
break;
643+
default:
644+
break;
639645
}
640646
recordUse(use);
641647
}

test/SILOptimizer/copy_propagation.sil

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -928,19 +928,3 @@ bb0:
928928
%99 = tuple ()
929929
return %99 : $()
930930
}
931-
932-
// Lexical destroy hoisting cannot handle a PointerEscape.
933-
//
934-
// CHECK-LABEL: sil [ossa] @testNoLexicalHoistEscape : $@convention(thin) (@owned Optional<@Sendable @callee_guaranteed () -> ()>) -> @owned Optional<@callee_guaranteed () -> ()> {
935-
// CHECK: bb0(%0 : @owned $Optional<@Sendable @callee_guaranteed () -> ()>):
936-
// CHECK: [[CAST:%.*]] = unchecked_bitwise_cast %0 : $Optional<@Sendable @callee_guaranteed () -> ()> to $Optional<@callee_guaranteed () -> ()>
937-
// CHECK: [[COPY:%.*]] = copy_value [[CAST]] : $Optional<@callee_guaranteed () -> ()>
938-
// CHECK: destroy_value %0 : $Optional<@Sendable @callee_guaranteed () -> ()>
939-
// CHECK-LABEL: } // end sil function 'testNoLexicalHoistEscape'
940-
sil [ossa] @testNoLexicalHoistEscape : $@convention(thin) (@owned Optional<@Sendable @callee_guaranteed () -> ()>) -> @owned Optional<@callee_guaranteed () -> ()> {
941-
bb0(%0 : @owned $Optional<@Sendable @callee_guaranteed () -> ()>):
942-
%cast = unchecked_bitwise_cast %0 : $Optional<@Sendable @callee_guaranteed () -> ()> to $Optional<@callee_guaranteed () -> ()>
943-
%copy = copy_value %cast : $Optional<@callee_guaranteed () -> ()>
944-
destroy_value %0 : $Optional<@Sendable @callee_guaranteed () -> ()>
945-
return %copy : $Optional<@callee_guaranteed () -> ()>
946-
}

test/SILOptimizer/lexical_destroy_folding.sil

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// =============================================================================
66

77
class C {}
8+
class D {}
89

910
sil [ossa] @barrier : $@convention(thin) () -> ()
1011
sil [ossa] @callee_guaranteed : $@convention(thin) (@guaranteed C) -> ()
@@ -856,6 +857,30 @@ entry(%instance : @owned $@convention(thick) () -> ()):
856857
return %retval : $()
857858
}
858859

860+
// Lexical destroy folding cannot handle a PointerEscape.
861+
//
862+
// CHECK-LABEL: sil [ossa] @dont_fold_over_escape : $@convention(thin) (@owned C) -> @owned D {
863+
// CHECK: bb0(%0 : @owned $C):
864+
// CHECK: [[CAST:%.*]] = unchecked_bitwise_cast %0 : $C to $D
865+
// CHECK: [[BORROW:%.*]] = begin_borrow [lexical] %0 : $C
866+
// CHECK: [[COPY0:%.*]] = copy_value [[BORROW]] : $C
867+
// CHECK: apply %{{.*}}([[COPY0]]) : $@convention(thin) (@owned C) -> ()
868+
// CHECK: [[COPY1:%.*]] = copy_value [[CAST]] : $D
869+
// CHECK: destroy_value %0 : $C
870+
// CHECK-LABEL: } // end sil function 'dont_fold_over_escape'
871+
sil [ossa] @dont_fold_over_escape : $@convention(thin) (@owned C) -> @owned D {
872+
bb0(%0 : @owned $C):
873+
%callee_owned = function_ref @callee_owned : $@convention(thin) (@owned C) -> ()
874+
%cast = unchecked_bitwise_cast %0 : $C to $D
875+
%lifetime = begin_borrow [lexical] %0 : $C
876+
%copy0 = copy_value %lifetime : $C
877+
apply %callee_owned(%copy0) : $@convention(thin) (@owned C) -> ()
878+
end_borrow %lifetime : $C
879+
%copy = copy_value %cast : $D
880+
destroy_value %0 : $C
881+
return %copy : $D
882+
}
883+
859884
// =============================================================================
860885
// TESTS }}
861886
// =============================================================================

test/SILOptimizer/lexical_destroy_hoisting.sil

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,21 @@ entry(%instance : @owned $C, %input : $S):
455455
return %retval : $()
456456
}
457457

458+
// Lexical destroy hoisting cannot handle a PointerEscape.
459+
//
460+
// CHECK-LABEL: sil [ossa] @dont_hoist_over_escape : $@convention(thin) (@owned Optional<@Sendable @callee_guaranteed () -> ()>) -> @owned Optional<@callee_guaranteed () -> ()> {
461+
// CHECK: bb0(%0 : @owned $Optional<@Sendable @callee_guaranteed () -> ()>):
462+
// CHECK: [[CAST:%.*]] = unchecked_bitwise_cast %0 : $Optional<@Sendable @callee_guaranteed () -> ()> to $Optional<@callee_guaranteed () -> ()>
463+
// CHECK: [[COPY:%.*]] = copy_value [[CAST]] : $Optional<@callee_guaranteed () -> ()>
464+
// CHECK: destroy_value %0 : $Optional<@Sendable @callee_guaranteed () -> ()>
465+
// CHECK-LABEL: } // end sil function 'dont_hoist_over_escape'
466+
sil [ossa] @dont_hoist_over_escape : $@convention(thin) (@owned Optional<@Sendable @callee_guaranteed () -> ()>) -> @owned Optional<@callee_guaranteed () -> ()> {
467+
bb0(%0 : @owned $Optional<@Sendable @callee_guaranteed () -> ()>):
468+
%cast = unchecked_bitwise_cast %0 : $Optional<@Sendable @callee_guaranteed () -> ()> to $Optional<@callee_guaranteed () -> ()>
469+
%copy = copy_value %cast : $Optional<@callee_guaranteed () -> ()>
470+
destroy_value %0 : $Optional<@Sendable @callee_guaranteed () -> ()>
471+
return %copy : $Optional<@callee_guaranteed () -> ()>
472+
}
458473

459474
// =============================================================================
460475
// instruction tests }}

0 commit comments

Comments
 (0)