mirror of
https://github.com/apple/swift.git
synced 2026-10-04 11:58:22 +02:00
- Remove redundant isCrossingCheck ternary in MismatchedIsolatedConformances: printStringForDiagnostics now correctly returns "@concurrent" for NonisolatedConcurrent and "nonisolated" for Nonisolated, so the manual override is unnecessary. Remove the isCrossingCheck field entirely. - Change isolated_conformance_wrong_domain and isolated_conformance_may_cross_isolation diagnostics to accept ActorIsolation directly instead of StringRef, letting the diagnostic engine call printForDiagnostics. - Rename ASTDumper flag from "isolated_to_caller_isolation" to "nonisolated_nonsending". - Restore SIL test CHECK lines that lost @caller_isolated annotations during rebase conflict resolution (optimize_hop_to_executor.sil, attr_execution tests, SILGen tests, Serialization tests). - Apply caller_isolation_inheriting -> nonisolated(nonsending) rename to restored test files.
484 lines
22 KiB
Plaintext
484 lines
22 KiB
Plaintext
// RUN: %target-sil-opt -sil-print-function-isolation-info -enable-sil-verify-all %s -optimize-hop-to-executor | %FileCheck %s
|
|
|
|
// REQUIRES: concurrency
|
|
// REQUIRES: asserts
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
actor MyActor {
|
|
@_hasStorage private var p: Int { get set }
|
|
}
|
|
|
|
sil [ossa] @requiredToRunOnActor : $@convention(method) (@guaranteed MyActor) -> ()
|
|
sil [ossa] @anotherAsyncFunction : $@convention(thin) @async () -> ()
|
|
sil [ossa] @nonisolatedNonsendingAsyncFunction : $@convention(thin) @caller_isolated @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()
|
|
sil [ossa] @asyncThrowingFunction : $@convention(thin) @async () -> @error any Error
|
|
sil [ossa] @syncFunction : $@convention(thin) () -> ()
|
|
|
|
// CHECK-LABEL: sil [ossa] @simpleRedundantActor : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
// CHECK: bb0(%0 : @guaranteed $MyActor):
|
|
// CHECK-NEXT: hop_to_executor %0
|
|
// CHECK-NOT: hop_to_executor
|
|
// CHECK: } // end sil function 'simpleRedundantActor'
|
|
sil [ossa] @simpleRedundantActor : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor):
|
|
hop_to_executor %0 : $MyActor
|
|
%f = function_ref @requiredToRunOnActor : $@convention(method) (@guaranteed MyActor) -> ()
|
|
apply %f(%0) : $@convention(method) (@guaranteed MyActor) -> ()
|
|
hop_to_executor %0 : $MyActor
|
|
apply %f(%0) : $@convention(method) (@guaranteed MyActor) -> ()
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @redundantActorAndControlFlow : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
// CHECK: bb0(%0 : @guaranteed $MyActor):
|
|
// CHECK-NEXT: hop_to_executor %0
|
|
// CHECK-NOT: hop_to_executor
|
|
// CHECK: } // end sil function 'redundantActorAndControlFlow'
|
|
sil [ossa] @redundantActorAndControlFlow : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor):
|
|
hop_to_executor %0 : $MyActor
|
|
%f = function_ref @requiredToRunOnActor : $@convention(method) (@guaranteed MyActor) -> ()
|
|
apply %f(%0) : $@convention(method) (@guaranteed MyActor) -> ()
|
|
cond_br undef, bb1, bb2
|
|
bb1:
|
|
hop_to_executor %0 : $MyActor
|
|
br bb3
|
|
bb2:
|
|
br bb3
|
|
bb3:
|
|
hop_to_executor %0 : $MyActor
|
|
apply %f(%0) : $@convention(method) (@guaranteed MyActor) -> ()
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @notRedundantActor : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
// CHECK: bb1:
|
|
// CHECK-NEXT: hop_to_executor %0
|
|
// CHECK: bb3:
|
|
// CHECK-NEXT: hop_to_executor %0
|
|
// CHECK: } // end sil function 'notRedundantActor'
|
|
sil [ossa] @notRedundantActor : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor):
|
|
%f = function_ref @requiredToRunOnActor : $@convention(method) (@guaranteed MyActor) -> ()
|
|
cond_br undef, bb1, bb2
|
|
bb1:
|
|
hop_to_executor %0 : $MyActor
|
|
apply %f(%0) : $@convention(method) (@guaranteed MyActor) -> ()
|
|
br bb3
|
|
bb2:
|
|
br bb3
|
|
bb3:
|
|
hop_to_executor %0 : $MyActor
|
|
apply %f(%0) : $@convention(method) (@guaranteed MyActor) -> ()
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @mismatchingActor : $@convention(method) @async (@guaranteed MyActor, @guaranteed MyActor) -> () {
|
|
// CHECK: hop_to_executor %0
|
|
// CHECK: apply
|
|
// CHECK: hop_to_executor %1
|
|
// CHECK: apply
|
|
// CHECK: } // end sil function 'mismatchingActor'
|
|
sil [ossa] @mismatchingActor : $@convention(method) @async (@guaranteed MyActor, @guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor, %1 : @guaranteed $MyActor):
|
|
%f = function_ref @requiredToRunOnActor : $@convention(method) (@guaranteed MyActor) -> ()
|
|
hop_to_executor %0 : $MyActor
|
|
apply %f(%0) : $@convention(method) (@guaranteed MyActor) -> ()
|
|
hop_to_executor %1 : $MyActor
|
|
apply %f(%1) : $@convention(method) (@guaranteed MyActor) -> ()
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @simpleDeadHopElimination : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
// CHECK-NOT: hop_to_executor
|
|
// CHECK: } // end sil function 'simpleDeadHopElimination'
|
|
sil [ossa] @simpleDeadHopElimination : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor):
|
|
hop_to_executor %0 : $MyActor
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @doubleDeadHopElimination : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
// CHECK: bb0(%0 : @guaranteed $MyActor):
|
|
// CHECK-NEXT: hop_to_executor %0
|
|
// CHECK-NOT: hop_to_executor
|
|
// CHECK: } // end sil function 'doubleDeadHopElimination'
|
|
sil [ossa] @doubleDeadHopElimination : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor):
|
|
hop_to_executor %0 : $MyActor
|
|
hop_to_executor %0 : $MyActor
|
|
%f = function_ref @requiredToRunOnActor : $@convention(method) (@guaranteed MyActor) -> ()
|
|
apply %f(%0) : $@convention(method) (@guaranteed MyActor) -> ()
|
|
hop_to_executor %0 : $MyActor
|
|
apply %f(%0) : $@convention(method) (@guaranteed MyActor) -> ()
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @deadHopAndControlFlow : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
// CHECK-NOT: hop_to_executor
|
|
// CHECK: } // end sil function 'deadHopAndControlFlow'
|
|
sil [ossa] @deadHopAndControlFlow : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor):
|
|
hop_to_executor %0 : $MyActor
|
|
cond_br undef, bb1, bb2
|
|
bb1:
|
|
br bb3
|
|
bb2:
|
|
br bb3
|
|
bb3:
|
|
%f = function_ref @anotherAsyncFunction : $@convention(thin) @async () -> ()
|
|
apply %f() : $@convention(thin) @async () -> ()
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @partialAliveHop : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
// CHECK: bb0(%0 : @guaranteed $MyActor):
|
|
// CHECK-NEXT: hop_to_executor %0
|
|
// CHECK-NOT: hop_to_executor
|
|
// CHECK: } // end sil function 'partialAliveHop'
|
|
sil [ossa] @partialAliveHop : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor):
|
|
hop_to_executor %0 : $MyActor
|
|
cond_br undef, bb1, bb2
|
|
bb1:
|
|
%f = function_ref @requiredToRunOnActor : $@convention(method) (@guaranteed MyActor) -> ()
|
|
apply %f(%0) : $@convention(method) (@guaranteed MyActor) -> ()
|
|
br bb3
|
|
bb2:
|
|
br bb3
|
|
bb3:
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @handleUnreachable1 : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
// CHECK: bb0(%0 : @guaranteed $MyActor):
|
|
// CHECK-NOT: hop_to_executor
|
|
// CHECK: } // end sil function 'handleUnreachable1'
|
|
sil [ossa] @handleUnreachable1 : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor):
|
|
hop_to_executor %0 : $MyActor
|
|
cond_br undef, bb1, bb2
|
|
bb1:
|
|
unreachable
|
|
bb2:
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @handleUnreachable2 : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
// CHECK: bb0(%0 : @guaranteed $MyActor):
|
|
// CHECK-NOT: hop_to_executor
|
|
// CHECK: } // end sil function 'handleUnreachable2'
|
|
sil [ossa] @handleUnreachable2 : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor):
|
|
cond_br undef, bb1, bb2
|
|
bb1:
|
|
hop_to_executor %0 : $MyActor
|
|
unreachable
|
|
bb2:
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @handleUnreachableBlock : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
// CHECK: bb0(%0 : $MyActor):
|
|
// CHECK-NEXT: hop_to_executor
|
|
// CHECK: bb2:
|
|
// CHECK-NOT: hop_to_executor
|
|
// CHECK: } // end sil function 'handleUnreachableBlock'
|
|
sil @handleUnreachableBlock : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
bb0(%0 : $MyActor):
|
|
hop_to_executor %0 : $MyActor
|
|
%f = function_ref @requiredToRunOnActor : $@convention(method) (@guaranteed MyActor) -> ()
|
|
apply %f(%0) : $@convention(method) (@guaranteed MyActor) -> ()
|
|
br bb2
|
|
bb1:
|
|
br bb2
|
|
bb2:
|
|
hop_to_executor %0 : $MyActor
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// This pattern is definitely optimizable, but it's *not* supposed to
|
|
// be optimized by simply removing the hop before the builtin.
|
|
// CHECK-LABEL: sil [ossa] @handleGetCurrentExecutor : $@convention(method) @async (@guaranteed MyActor, @guaranteed MyActor) -> () {
|
|
// CHECK: bb0(%0 : @guaranteed $MyActor, %1 : @guaranteed $MyActor):
|
|
// CHECK-NEXT: // function_ref
|
|
// CHECK-NEXT: function_ref
|
|
// CHECK-NEXT: apply
|
|
// CHECK-NEXT: hop_to_executor
|
|
// CHECK-NEXT: builtin
|
|
// CHECK-NEXT: hop_to_executor
|
|
// CHECK-NEXT: // function_ref
|
|
// CHECK-NEXT: function_ref
|
|
// CHECK-NEXT: apply
|
|
// CHECK-NEXT: tuple
|
|
// CHECK-NEXT: return
|
|
// CHECK: } // end sil function 'handleGetCurrentExecutor'
|
|
sil [ossa] @handleGetCurrentExecutor : $@convention(method) @async (@guaranteed MyActor, @guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor, %1 : @guaranteed $MyActor):
|
|
hop_to_executor %0 : $MyActor
|
|
%async_f = function_ref @anotherAsyncFunction : $@convention(thin) @async () -> ()
|
|
apply %async_f() : $@convention(thin) @async () -> ()
|
|
hop_to_executor %0 : $MyActor
|
|
%curExec = builtin "getCurrentExecutor"() : $Optional<Builtin.Executor>
|
|
hop_to_executor %1 : $MyActor
|
|
%f = function_ref @requiredToRunOnActor : $@convention(method) (@guaranteed MyActor) -> ()
|
|
apply %f(%1) : $@convention(method) (@guaranteed MyActor) -> ()
|
|
hop_to_executor %0 : $MyActor
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @redundantMandatoryHop : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
// CHECK: bb0(%0 : @guaranteed $MyActor):
|
|
// CHECK-NEXT: hop_to_executor %0
|
|
// CHECK: apply
|
|
// CHECK: hop_to_executor [mandatory] %0
|
|
// CHECK: } // end sil function 'redundantMandatoryHop'
|
|
sil [ossa] @redundantMandatoryHop : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor):
|
|
hop_to_executor %0 : $MyActor
|
|
%f = function_ref @requiredToRunOnActor : $@convention(method) (@guaranteed MyActor) -> ()
|
|
apply %f(%0) : $@convention(method) (@guaranteed MyActor) -> ()
|
|
hop_to_executor [mandatory] %0 : $MyActor
|
|
apply %f(%0) : $@convention(method) (@guaranteed MyActor) -> ()
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @simpleMandatoryHop : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
// CHECK: hop_to_executor [mandatory]
|
|
// CHECK: } // end sil function 'simpleMandatoryHop'
|
|
sil [ossa] @simpleMandatoryHop : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor):
|
|
hop_to_executor [mandatory] %0 : $MyActor
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @simpleMandatoryHopAndSuspend : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
// CHECK: hop_to_executor [mandatory]
|
|
// CHECK: apply
|
|
// CHECK: } // end sil function 'simpleMandatoryHopAndSuspend'
|
|
sil [ossa] @simpleMandatoryHopAndSuspend : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor):
|
|
hop_to_executor [mandatory] %0 : $MyActor
|
|
%async_f = function_ref @anotherAsyncFunction : $@convention(thin) @async () -> ()
|
|
apply %async_f() : $@convention(thin) @async () -> ()
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @handleBeginBorrow : {{.*}} {
|
|
// CHECK-NOT: hop_to_executor
|
|
// CHECK-LABEL: } // end sil function 'handleBeginBorrow'
|
|
sil [ossa] @handleBeginBorrow : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor):
|
|
hop_to_executor %0 : $MyActor
|
|
%b = begin_borrow %0 : $MyActor
|
|
end_borrow %b : $MyActor
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @handleEndBorrow : {{.*}} {
|
|
// CHECK-NOT: hop_to_executor
|
|
// CHECK-LABEL: } // end sil function 'handleEndBorrow'
|
|
sil [ossa] @handleEndBorrow : $@convention(method) @async (@guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor):
|
|
%b = begin_borrow %0 : $MyActor
|
|
hop_to_executor %0 : $MyActor
|
|
end_borrow %b : $MyActor
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @simpleDCEAsync : $@convention(thin) @async (@guaranteed MyActor) -> () {
|
|
// CHECK-NOT: hop_to_executor
|
|
// CHECK: } // end sil function 'simpleDCEAsync'
|
|
sil [ossa] @simpleDCEAsync : $@convention(thin) @async (@guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor):
|
|
hop_to_executor %0
|
|
%f = function_ref @anotherAsyncFunction : $@convention(thin) @async () -> ()
|
|
apply %f() : $@convention(thin) @async () -> ()
|
|
%9999 = tuple ()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @simpleNonisolatedNonsendingStopsDCE : $@convention(thin) @async (@guaranteed MyActor) -> () {
|
|
// CHECK: hop_to_executor
|
|
// CHECK: } // end sil function 'simpleNonisolatedNonsendingStopsDCE'
|
|
sil [ossa] @simpleNonisolatedNonsendingStopsDCE : $@convention(thin) @async (@guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor):
|
|
hop_to_executor %0
|
|
%1 = unchecked_value_cast %0 to $Builtin.ImplicitActor
|
|
%f = function_ref @nonisolatedNonsendingAsyncFunction : $@convention(thin) @caller_isolated @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()
|
|
apply %f(%1) : $@convention(thin) @caller_isolated @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()
|
|
%9999 = tuple ()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @nonisolatedNonsendingParameterStopsDCE : $@convention(thin) @async (@guaranteed MyActor, @guaranteed @caller_isolated @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()) -> () {
|
|
// CHECK: hop_to_executor
|
|
// CHECK: } // end sil function 'nonisolatedNonsendingParameterStopsDCE'
|
|
sil [ossa] @nonisolatedNonsendingParameterStopsDCE : $@convention(thin) @async (@guaranteed MyActor, @guaranteed @caller_isolated @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()) -> () {
|
|
bb0(%0 : @guaranteed $MyActor, %1 : @guaranteed $@caller_isolated @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()):
|
|
hop_to_executor %0
|
|
%2 = unchecked_value_cast %0 to $Builtin.ImplicitActor
|
|
apply %1(%2) : $@caller_isolated @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()
|
|
%9999 = tuple ()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// We should eliminate none of the hop_to_executor here since
|
|
// nonisolated(nonsending) @async apply sites do not cross isolation
|
|
// boundaries.
|
|
//
|
|
// CHECK-LABEL: sil [ossa] @simpleNonisolatedNonsendingStopsDCE2 : $@convention(thin) @async (@guaranteed MyActor, @guaranteed MyActor, @guaranteed MyActor) -> () {
|
|
// CHECK: hop_to_executor
|
|
// CHECK: hop_to_executor
|
|
// CHECK: hop_to_executor
|
|
// CHECK: } // end sil function 'simpleNonisolatedNonsendingStopsDCE2'
|
|
sil [ossa] @simpleNonisolatedNonsendingStopsDCE2 : $@convention(thin) @async (@guaranteed MyActor, @guaranteed MyActor, @guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor, %1 : @guaranteed $MyActor, %2 : @guaranteed $MyActor):
|
|
hop_to_executor %0
|
|
%actor0 = unchecked_value_cast %0 to $Builtin.ImplicitActor
|
|
%f = function_ref @nonisolatedNonsendingAsyncFunction : $@convention(thin) @caller_isolated @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()
|
|
apply %f(%actor0) : $@convention(thin) @caller_isolated @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()
|
|
hop_to_executor %1
|
|
%actor1 = unchecked_value_cast %1 to $Builtin.ImplicitActor
|
|
%f2 = function_ref @syncFunction : $@convention(thin) () -> ()
|
|
apply %f2() : $@convention(thin) () -> ()
|
|
apply %f(%actor1) : $@convention(thin) @caller_isolated @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()
|
|
hop_to_executor %2
|
|
%actor2 = unchecked_value_cast %2 to $Builtin.ImplicitActor
|
|
apply %f2() : $@convention(thin) () -> ()
|
|
apply %f(%actor2) : $@convention(thin) @caller_isolated @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()
|
|
%9999 = tuple ()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @simpleWithoutCallerIsolationInheritingHaveDCE : $@convention(thin) @async (@guaranteed MyActor, @guaranteed MyActor, @guaranteed MyActor) -> () {
|
|
// CHECK: bb0([[ARG1:%.*]] : @guaranteed $MyActor, [[ARG2:%.*]] : @guaranteed $MyActor, [[ARG3:%.*]] : @guaranteed $MyActor):
|
|
// CHECK-NEXT: // function_ref anotherAsyncFunction
|
|
// CHECK-NEXT: [[FUNC:%.*]] = function_ref @anotherAsyncFunction : $@convention(thin) @async () -> ()
|
|
// CHECK-NEXT: apply [[FUNC]]() : $@convention(thin) @async () -> ()
|
|
// CHECK-NEXT: hop_to_executor [[ARG2]]
|
|
// CHECK-NEXT: // function_ref syncFunction
|
|
// CHECK-NEXT: [[FUNC2:%.*]] = function_ref @syncFunction : $@convention(thin) () -> ()
|
|
// CHECK-NEXT: apply [[FUNC2]]() : $@convention(thin) () -> ()
|
|
// CHECK-NEXT: apply [[FUNC]]() : $@convention(thin) @async () -> ()
|
|
// CHECK-NEXT: hop_to_executor [[ARG3]]
|
|
// CHECK-NEXT: apply [[FUNC2]]() : $@convention(thin) () -> ()
|
|
// CHECK-NEXT: apply [[FUNC]]() : $@convention(thin) @async () -> ()
|
|
// CHECK-NEXT: apply [[FUNC]]() : $@convention(thin) @async () -> ()
|
|
// CHECK: } // end sil function 'simpleWithoutCallerIsolationInheritingHaveDCE'
|
|
sil [ossa] @simpleWithoutCallerIsolationInheritingHaveDCE : $@convention(thin) @async (@guaranteed MyActor, @guaranteed MyActor, @guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor, %1 : @guaranteed $MyActor, %2 : @guaranteed $MyActor):
|
|
hop_to_executor %0
|
|
%f = function_ref @anotherAsyncFunction : $@convention(thin) @async () -> ()
|
|
apply %f() : $@convention(thin) @async () -> ()
|
|
hop_to_executor %1
|
|
%f2 = function_ref @syncFunction : $@convention(thin) () -> ()
|
|
apply %f2() : $@convention(thin) () -> ()
|
|
apply %f() : $@convention(thin) @async () -> ()
|
|
hop_to_executor %2
|
|
apply %f2() : $@convention(thin) () -> ()
|
|
apply %f() : $@convention(thin) @async () -> ()
|
|
hop_to_executor %2
|
|
apply %f() : $@convention(thin) @async () -> ()
|
|
%9999 = tuple ()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// We do not allow for these to be propagated yet through caller isolation
|
|
// inheriting, so we should have all of the hop_to_executor.
|
|
//
|
|
// CHECK-LABEL: sil [ossa] @nonisolatedNonsendingStopsAllowsPropagating : $@convention(thin) @async (@guaranteed MyActor, @guaranteed MyActor, @guaranteed MyActor) -> () {
|
|
// CHECK: bb0(
|
|
// CHECK: hop_to_executor
|
|
// CHECK-NOT: hop_to_executor
|
|
// CHECK: } // end sil function 'nonisolatedNonsendingStopsAllowsPropagating'
|
|
sil [ossa] @nonisolatedNonsendingStopsAllowsPropagating : $@convention(thin) @async (@guaranteed MyActor, @guaranteed MyActor, @guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor, %1 : @guaranteed $MyActor, %2 : @guaranteed $MyActor):
|
|
hop_to_executor %0
|
|
%actor0 = unchecked_value_cast %0 to $Builtin.ImplicitActor
|
|
%f = function_ref @nonisolatedNonsendingAsyncFunction : $@convention(thin) @caller_isolated @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()
|
|
apply %f(%actor0) : $@convention(thin) @caller_isolated @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()
|
|
hop_to_executor %0
|
|
%f2 = function_ref @syncFunction : $@convention(thin) () -> ()
|
|
apply %f2() : $@convention(thin) () -> ()
|
|
apply %f(%actor0) : $@convention(thin) @caller_isolated @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()
|
|
hop_to_executor %0
|
|
apply %f2() : $@convention(thin) () -> ()
|
|
apply %f(%actor0) : $@convention(thin) @caller_isolated @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()
|
|
%9999 = tuple ()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// Since we are caller isolation inheriting, make sure that we leave around the
|
|
// hop_to_executor due to ehre elase. We do eliminate one of the hop_to_executor
|
|
// though.
|
|
//
|
|
// CHECK: sil [isolation "nonisolated(nonsending)"] [ossa] @nonisolatedNonsendingStopsReturnDeadEnd : $@convention(thin) @async (@sil_isolated @guaranteed MyActor) -> () {
|
|
// CHECK: bb0(
|
|
// CHECK-NEXT: tuple
|
|
// CHECK-NEXT: return
|
|
// CHECK: } // end sil function 'nonisolatedNonsendingStopsReturnDeadEnd'
|
|
sil [isolation "nonisolated(nonsending)"] [ossa] @nonisolatedNonsendingStopsReturnDeadEnd : $@convention(thin) @async (@sil_isolated @guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor):
|
|
hop_to_executor %0
|
|
hop_to_executor %0
|
|
%9999 = tuple ()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @noIsolationStillRemoves : $@convention(thin) @async (@guaranteed MyActor, @guaranteed MyActor, @guaranteed MyActor) -> () {
|
|
// CHECK-NOT: hop_to_executor
|
|
// CHECK: } // end sil function 'noIsolationStillRemoves'
|
|
sil [ossa] @noIsolationStillRemoves : $@convention(thin) @async (@guaranteed MyActor, @guaranteed MyActor, @guaranteed MyActor) -> () {
|
|
bb0(%0 : @guaranteed $MyActor, %1 : @guaranteed $MyActor, %2 : @guaranteed $MyActor):
|
|
hop_to_executor %0
|
|
%9999 = tuple ()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// https://github.com/swiftlang/swift/issues/88259
|
|
|
|
// CHECK-LABEL: sil [isolation "nonisolated(nonsending)"] [ossa] @nonisolatedNonsendingPreservesHopBeforeThrow : $@convention(thin) @caller_isolated @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> @error any Error {
|
|
// CHECK: bb1
|
|
// CHECK: hop_to_executor
|
|
// CHECK: return
|
|
// CHECK: bb2
|
|
// CHECK: hop_to_executor
|
|
// CHECK: throw
|
|
// CHECK: } // end sil function 'nonisolatedNonsendingPreservesHopBeforeThrow'
|
|
sil [isolation "nonisolated(nonsending)"] [ossa] @nonisolatedNonsendingPreservesHopBeforeThrow : $@convention(thin) @caller_isolated @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> @error any Error {
|
|
bb0(%0 : @guaranteed $Builtin.ImplicitActor):
|
|
%f = function_ref @asyncThrowingFunction : $@convention(thin) @async () -> @error any Error
|
|
try_apply %f() : $@convention(thin) @async () -> @error any Error, normal bb1, error bb2
|
|
|
|
bb1(%result : $()):
|
|
hop_to_executor %0 : $Builtin.ImplicitActor
|
|
%ret = tuple ()
|
|
return %ret: $()
|
|
|
|
bb2(%error : @owned $any Error):
|
|
hop_to_executor %0 : $Builtin.ImplicitActor
|
|
throw %error : $any Error
|
|
}
|