Skip to content

Commit 97daf4f

Browse files
Merge pull request #66263 from nate-chandler/rdar110058964
[ClosureSpecializer] Don't release trivial noescape try_apply argument twice.
2 parents 25ef5d7 + 34dbae1 commit 97daf4f

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed

lib/SILOptimizer/IPO/ClosureSpecializer.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,8 @@ static void rewriteApplyInst(const CallSiteDescriptor &CSDesc,
460460
// If we passed in the original closure as @owned, then insert a release
461461
// right after NewAI. This is to balance the +1 from being an @owned
462462
// argument to AI.
463-
if (!CSDesc.isClosureConsumed() || !CSDesc.closureHasRefSemanticContext()) {
463+
if (!CSDesc.isClosureConsumed() || CSDesc.isTrivialNoEscapeParameter() ||
464+
!CSDesc.closureHasRefSemanticContext()) {
464465
break;
465466
}
466467

test/SILOptimizer/closure_specialize.sil

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,71 @@ bb0(%0 : $Int):
702702
return %empty : $()
703703
}
704704

705+
sil @testThrowingClosureConvertHelper : $@convention(thin) (Int) -> (Int, @error any Error)
706+
sil [reabstraction_thunk] @reabstractionThunkThrowing : $@convention(thin) (@noescape @callee_guaranteed () -> (Int, @error any Error)) -> (@out Int, @error any Error)
707+
708+
sil @testClosureThunkNoEscapeThrowing : $@convention(thin) (@owned @noescape @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <Int>) -> (@out (), @error any Error) {
709+
entry(%empty : $*(), %closure : $@noescape @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <Int>):
710+
%out = alloc_stack $Int
711+
try_apply %closure(%out) : $@noescape @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <Int>, normal bb1, error bb2
712+
713+
bb1(%ret : $()):
714+
dealloc_stack %out : $*Int
715+
store %ret to %empty : $*()
716+
%retval = tuple ()
717+
return %retval : $()
718+
719+
bb2(%error : $any Error):
720+
dealloc_stack %out : $*Int
721+
throw %error : $any Error
722+
}
723+
724+
// CHECK-LABEL: sil @reabstractionThrowing : $@convention(thin) (Int) -> ((), @error any Error) {
725+
// CHECK: [[HELPER:%[^,]+]] = function_ref @testThrowingClosureConvertHelper
726+
// CHECK: [[SPECIALIZATION:%[^,]+]] = function_ref @$s32testClosureThunkNoEscapeThrowing0afB13ConvertHelperSiTf1nc_n
727+
// CHECK: [[CLOSURE:%[^,]+]] = partial_apply [callee_guaranteed] [[HELPER]]
728+
// CHECK: [[NOESCAPE_CLOSURE:%[^,]+]] = convert_escape_to_noescape [[CLOSURE]]
729+
// CHECK: try_apply [[SPECIALIZATION]]{{.*}}normal [[NORMAL_BLOCK:bb[0-9]+]], error [[ERROR_BLOCK:bb[0-9]+]]
730+
// CHECK: [[NORMAL_BLOCK]]
731+
// CHECK: release_value [[CLOSURE]]
732+
// CHECK-NOT: release_value [[CLOSURE]]
733+
// CHECK: strong_release [[NOESCAPE_CLOSURE]]
734+
// CHECK: [[ERROR_BLOCK]]
735+
// CHECK: release_value [[CLOSURE]]
736+
// CHECK-NOT: release_value [[CLOSURE]]
737+
// CHECK: strong_release [[NOESCAPE_CLOSURE]]
738+
// CHECK-LABEL: } // end sil function 'reabstractionThrowing'
739+
sil @reabstractionThrowing : $(Int) -> ((), @error any Error) {
740+
bb0(%value : $Int):
741+
%testThrowingClosureConvertHelper = function_ref @testThrowingClosureConvertHelper : $@convention(thin) (Int) -> (Int, @error any Error)
742+
%closure = partial_apply [callee_guaranteed] %testThrowingClosureConvertHelper(%value) : $@convention(thin) (Int) -> (Int, @error any Error)
743+
%noescapeClosure = convert_escape_to_noescape %closure : $@callee_guaranteed () -> (Int, @error any Error) to $@noescape @callee_guaranteed () -> (Int, @error any Error)
744+
%thunk = function_ref @reabstractionThunkThrowing : $@convention(thin) (@noescape @callee_guaranteed () -> (Int, @error any Error)) -> (@out Int, @error any Error)
745+
%appliedThunk = partial_apply [callee_guaranteed] [on_stack] %thunk(%noescapeClosure) : $@convention(thin) (@noescape @callee_guaranteed () -> (Int, @error any Error)) -> (@out Int, @error any Error)
746+
747+
%dependency = mark_dependence %appliedThunk : $@noescape @callee_guaranteed () -> (@out Int, @error any Error) on %noescapeClosure : $@noescape @callee_guaranteed () -> (Int, @error any Error)
748+
%generified = convert_function %dependency : $@noescape @callee_guaranteed () -> (@out Int, @error any Error) to $@noescape @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <Int>
749+
%test = function_ref @testClosureThunkNoEscapeThrowing : $@convention(thin) (@owned @noescape @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <Int>) -> (@out (), @error any Error)
750+
strong_retain %generified : $@noescape @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <Int>
751+
%out = alloc_stack $()
752+
try_apply %test(%out, %generified) : $@convention(thin) (@owned @noescape @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <Int>) -> (@out (), @error any Error), normal bb1, error bb2
753+
754+
bb1(%ret : $()):
755+
dealloc_stack %out : $*()
756+
release_value %closure : $@callee_guaranteed () -> (Int, @error any Error)
757+
strong_release %noescapeClosure : $@noescape @callee_guaranteed () -> (Int, @error any Error)
758+
dealloc_stack %appliedThunk : $@noescape @callee_guaranteed () -> (@out Int, @error any Error)
759+
%empty = tuple ()
760+
return %empty : $()
761+
762+
bb2(%error : $any Error):
763+
dealloc_stack %out : $*()
764+
release_value %closure : $@callee_guaranteed () -> (Int, @error any Error)
765+
strong_release %noescapeClosure : $@noescape @callee_guaranteed () -> (Int, @error any Error)
766+
dealloc_stack %appliedThunk : $@noescape @callee_guaranteed () -> (@out Int, @error any Error)
767+
throw %error : $any Error
768+
}
769+
705770
// Currently not supported cases.
706771

707772
sil @testClosureThunk4 : $@convention(thin) (@owned @callee_guaranteed () -> @out Int) -> @out Int {

0 commit comments

Comments
 (0)