mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This is necessary because we need to model its stack-allocation behavior, although I'm not yet doing that in this patch because StackNesting first needs to be taught to not try to move the deallocation. I'm not convinced that `async let` *should* be doing a stack allocation, but it undoubtedly *is* doing a stack allocation, and until we have an alternative to that, we will need to model it properly.
556 lines
26 KiB
Plaintext
556 lines
26 KiB
Plaintext
// RUN: %target-sil-opt %s -access-summary-dump -o /dev/null | %FileCheck %s
|
|
|
|
sil_stage raw
|
|
|
|
import Builtin
|
|
import Swift
|
|
import SwiftShims
|
|
|
|
struct StructWithStoredProperties {
|
|
@_hasStorage var f: Int
|
|
@_hasStorage var g: Int
|
|
}
|
|
|
|
struct StructWithStructWithStoredProperties {
|
|
@_hasStorage var a: StructWithStoredProperties
|
|
@_hasStorage var b: StructWithStoredProperties
|
|
}
|
|
|
|
// CHECK-LABEL: @assignsToCapture
|
|
// CHECK-NEXT: ([modify], [])
|
|
sil private [ossa] @assignsToCapture : $@convention(thin) (@inout_aliasable Int, Int) -> () {
|
|
bb0(%0 : $*Int, %1: $Int):
|
|
%2 = begin_access [modify] [unknown] %0 : $*Int
|
|
assign %1 to %2 : $*Int
|
|
end_access %2 : $*Int
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @readsAndModifiesSameCapture
|
|
// CHECK-NEXT: ([modify])
|
|
sil private [ossa] @readsAndModifiesSameCapture : $@convention(thin) (@inout_aliasable Int) -> () {
|
|
bb0(%0 : $*Int):
|
|
%1 = begin_access [read] [unknown] %0 : $*Int
|
|
end_access %1 : $*Int
|
|
%2 = begin_access [modify] [unknown] %0 : $*Int
|
|
end_access %2 : $*Int
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @readsAndModifiesSeparateCaptures
|
|
// CHECK-NEXT: ([read], [modify])
|
|
sil private [ossa] @readsAndModifiesSeparateCaptures : $@convention(thin) (@inout_aliasable Int, @inout_aliasable Int) -> () {
|
|
bb0(%0 : $*Int, %1 : $*Int):
|
|
%2 = begin_access [read] [unknown] %0 : $*Int
|
|
end_access %2 : $*Int
|
|
%3 = begin_access [modify] [unknown] %1 : $*Int
|
|
end_access %3 : $*Int
|
|
%4 = tuple ()
|
|
return %4 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @modifyInModifySubAccess
|
|
// CHECK-NEXT: ([modify])
|
|
sil private [ossa] @modifyInModifySubAccess : $@convention(thin) (@inout_aliasable Int) -> () {
|
|
bb0(%0 : $*Int):
|
|
%1 = begin_access [modify] [unknown] %0 : $*Int
|
|
%2 = begin_access [modify] [unknown] %1 : $*Int
|
|
end_access %2 : $*Int
|
|
end_access %1 : $*Int
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @readInModifySubAccess
|
|
// CHECK-NEXT: ([modify])
|
|
sil private [ossa] @readInModifySubAccess : $@convention(thin) (@inout_aliasable Int) -> () {
|
|
bb0(%0 : $*Int):
|
|
%1 = begin_access [modify] [unknown] %0 : $*Int
|
|
%2 = begin_access [read] [unknown] %1 : $*Int
|
|
end_access %2 : $*Int
|
|
end_access %1 : $*Int
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @accessSeparateStoredPropertiesOfSameCapture
|
|
// CHECK-NEXT: ([.f modify, .g read])
|
|
sil private [ossa] @accessSeparateStoredPropertiesOfSameCapture : $@convention(thin) (@inout_aliasable StructWithStoredProperties) -> () {
|
|
bb0(%0 : $*StructWithStoredProperties):
|
|
%1 = begin_access [modify] [unknown] %0: $*StructWithStoredProperties
|
|
%2 = struct_element_addr %1 : $*StructWithStoredProperties, #StructWithStoredProperties.f
|
|
end_access %1 : $*StructWithStoredProperties
|
|
%4 = begin_access [read] [unknown] %0: $*StructWithStoredProperties
|
|
%5 = struct_element_addr %4 : $*StructWithStoredProperties, #StructWithStoredProperties.g
|
|
end_access %4 : $*StructWithStoredProperties
|
|
%7 = tuple ()
|
|
return %7 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @accessSeparateElementsOfSameCapture
|
|
// CHECK-NEXT: ([.0 modify, .1 read])
|
|
sil private [ossa] @accessSeparateElementsOfSameCapture : $@convention(thin) (@inout_aliasable (Int, Int)) -> () {
|
|
bb0(%0 : $*(Int, Int)):
|
|
%1 = begin_access [modify] [unknown] %0: $*(Int, Int)
|
|
%2 = tuple_element_addr %1 : $*(Int, Int), 0
|
|
end_access %1 : $*(Int, Int)
|
|
%4 = begin_access [read] [unknown] %0: $*(Int, Int)
|
|
%5 = tuple_element_addr %4 : $*(Int, Int), 1
|
|
end_access %4 : $*(Int, Int)
|
|
%7 = tuple ()
|
|
return %7 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @accessSeparateNestedStoredPropertiesOfSameCapture
|
|
// CHECK-NEXT: ([.a.f modify, .b.g modify])
|
|
sil private [ossa] @accessSeparateNestedStoredPropertiesOfSameCapture : $@convention(thin) (@inout_aliasable StructWithStructWithStoredProperties) -> () {
|
|
bb0(%0 : $*StructWithStructWithStoredProperties):
|
|
%1 = begin_access [modify] [unknown] %0: $*StructWithStructWithStoredProperties
|
|
%2 = struct_element_addr %1 : $*StructWithStructWithStoredProperties, #StructWithStructWithStoredProperties.a
|
|
%3 = struct_element_addr %2 : $*StructWithStoredProperties, #StructWithStoredProperties.f
|
|
end_access %1 : $*StructWithStructWithStoredProperties
|
|
%5 = begin_access [modify] [unknown] %0: $*StructWithStructWithStoredProperties
|
|
%6 = struct_element_addr %5 : $*StructWithStructWithStoredProperties, #StructWithStructWithStoredProperties.b
|
|
%7 = struct_element_addr %6 : $*StructWithStoredProperties, #StructWithStoredProperties.g
|
|
end_access %5 : $*StructWithStructWithStoredProperties
|
|
%9 = tuple ()
|
|
return %9 : $()
|
|
}
|
|
|
|
|
|
// CHECK-LABEL: @accessSeparateStoredPropertiesOfSameCaptureOppositeOfDeclarationOrder
|
|
// CHECK-NEXT: ([.f read, .g modify])
|
|
sil private [ossa] @accessSeparateStoredPropertiesOfSameCaptureOppositeOfDeclarationOrder : $@convention(thin) (@inout_aliasable StructWithStoredProperties) -> () {
|
|
bb0(%0 : $*StructWithStoredProperties):
|
|
%1 = begin_access [modify] [unknown] %0: $*StructWithStoredProperties
|
|
%2 = struct_element_addr %1 : $*StructWithStoredProperties, #StructWithStoredProperties.g
|
|
end_access %1 : $*StructWithStoredProperties
|
|
%4 = begin_access [read] [unknown] %0: $*StructWithStoredProperties
|
|
%5 = struct_element_addr %4 : $*StructWithStoredProperties, #StructWithStoredProperties.f
|
|
end_access %4 : $*StructWithStoredProperties
|
|
%7 = tuple ()
|
|
return %7 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @accessAggregateDoesNotSubsumeAccessStoredProp
|
|
// CHECK-NEXT: ([modify, .g modify])
|
|
sil private [ossa] @accessAggregateDoesNotSubsumeAccessStoredProp : $@convention(thin) (@inout_aliasable StructWithStoredProperties) -> () {
|
|
bb0(%0 : $*StructWithStoredProperties):
|
|
%1 = begin_access [modify] [unknown] %0: $*StructWithStoredProperties
|
|
end_access %1 : $*StructWithStoredProperties
|
|
%4 = begin_access [modify] [unknown] %0: $*StructWithStoredProperties
|
|
%5 = struct_element_addr %4 : $*StructWithStoredProperties, #StructWithStoredProperties.g
|
|
end_access %4 : $*StructWithStoredProperties
|
|
%7 = tuple ()
|
|
return %7 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @accessAggregateDoesNotSubsumeAccessStoredPropWithAggregateSecond
|
|
// CHECK-NEXT: ([modify, .f modify])
|
|
sil private [ossa] @accessAggregateDoesNotSubsumeAccessStoredPropWithAggregateSecond : $@convention(thin) (@inout_aliasable StructWithStoredProperties) -> () {
|
|
bb0(%0 : $*StructWithStoredProperties):
|
|
%1 = begin_access [modify] [unknown] %0: $*StructWithStoredProperties
|
|
%2 = struct_element_addr %1 : $*StructWithStoredProperties, #StructWithStoredProperties.f
|
|
end_access %1 : $*StructWithStoredProperties
|
|
%4 = begin_access [modify] [unknown] %0: $*StructWithStoredProperties
|
|
end_access %4 : $*StructWithStoredProperties
|
|
%7 = tuple ()
|
|
return %7 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @accessSameStoredPropertyOfSameCapture
|
|
// CHECK-NEXT: ([.f modify])
|
|
sil private [ossa] @accessSameStoredPropertyOfSameCapture : $@convention(thin) (@inout_aliasable StructWithStoredProperties) -> () {
|
|
bb0(%0 : $*StructWithStoredProperties):
|
|
%1 = begin_access [read] [unknown] %0: $*StructWithStoredProperties
|
|
%2 = struct_element_addr %1 : $*StructWithStoredProperties, #StructWithStoredProperties.f
|
|
end_access %1 : $*StructWithStoredProperties
|
|
%4 = begin_access [modify] [unknown] %0: $*StructWithStoredProperties
|
|
%5 = struct_element_addr %4 : $*StructWithStoredProperties, #StructWithStoredProperties.f
|
|
end_access %4 : $*StructWithStoredProperties
|
|
%7 = tuple ()
|
|
return %7 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @accessSeparateStoredPropertiesOfSameCaptureWithTSanInstrumentation
|
|
// CHECK-NEXT: ([.f modify, .g read])
|
|
sil private [ossa] @accessSeparateStoredPropertiesOfSameCaptureWithTSanInstrumentation : $@convention(thin) (@inout_aliasable StructWithStoredProperties) -> () {
|
|
bb0(%0 : $*StructWithStoredProperties):
|
|
%1 = begin_access [modify] [unknown] %0: $*StructWithStoredProperties
|
|
%2 = builtin "tsanInoutAccess"(%1 : $*StructWithStoredProperties) : $()
|
|
%3 = struct_element_addr %1 : $*StructWithStoredProperties, #StructWithStoredProperties.f
|
|
%4 = builtin "tsanInoutAccess"(%3 : $*Int) : $()
|
|
end_access %1 : $*StructWithStoredProperties
|
|
%6 = begin_access [read] [unknown] %0: $*StructWithStoredProperties
|
|
%7 = builtin "tsanInoutAccess"(%6 : $*StructWithStoredProperties) : $()
|
|
%8 = struct_element_addr %6 : $*StructWithStoredProperties, #StructWithStoredProperties.g
|
|
%9 = builtin "tsanInoutAccess"(%8 : $*Int) : $()
|
|
end_access %6 : $*StructWithStoredProperties
|
|
%11 = tuple ()
|
|
return %11 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @addressToPointerOfStructElementAddr
|
|
// CHECK-NEXT: ([])
|
|
// This mirrors the code pattern for materializeForSet on a struct stored
|
|
// property
|
|
sil private [ossa] @addressToPointerOfStructElementAddr : $@convention(method) (@inout StructWithStoredProperties) -> (Builtin.RawPointer) {
|
|
bb0(%1 : $*StructWithStoredProperties):
|
|
%2 = struct_element_addr %1 : $*StructWithStoredProperties, #StructWithStoredProperties.f
|
|
%3 = address_to_pointer %2 : $*Int to $Builtin.RawPointer
|
|
return %3 : $(Builtin.RawPointer)
|
|
}
|
|
|
|
// CHECK-LABEL: @endUnpairedAccess
|
|
// CHECK-NEXT: ([])
|
|
sil private [ossa] @endUnpairedAccess : $@convention(method) (@inout Builtin.UnsafeValueBuffer) -> () {
|
|
bb0(%0 : $*Builtin.UnsafeValueBuffer):
|
|
end_unpaired_access [dynamic] %0 : $*Builtin.UnsafeValueBuffer
|
|
%1 = tuple ()
|
|
return %1 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @tupleElementAddr
|
|
// CHECK-NEXT: ([modify])
|
|
sil private [ossa] @tupleElementAddr : $@convention(thin) (@inout_aliasable (Int, Int)) -> () {
|
|
bb0(%0 : $*(Int, Int)):
|
|
%1 = tuple_element_addr %0 : $*(Int, Int), 1
|
|
%2 = begin_access [modify] [unknown] %1 : $*Int
|
|
end_access %2 : $*Int
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
}
|
|
|
|
sil @closureWithMissingBody : $@convention(thin) (@inout_aliasable Int, Int) -> ()
|
|
|
|
// CHECK-LABEL: @callClosureWithMissingBody
|
|
// CHECK-NEXT: ([modify], [])
|
|
sil private [ossa] @callClosureWithMissingBody : $@convention(thin) (@inout_aliasable Int, Int) -> () {
|
|
bb0(%0 : $*Int, %1 : $Int):
|
|
%2 = function_ref @closureWithMissingBody : $@convention(thin) (@inout_aliasable Int, Int) -> ()
|
|
%3 = apply %2(%0, %1) : $@convention(thin) (@inout_aliasable Int, Int) -> () // no-crash
|
|
%4 = tuple ()
|
|
return %4 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @callClosureThatModifiesCapture
|
|
// CHECK-NEXT: ([modify], [])
|
|
sil private [ossa] @callClosureThatModifiesCapture : $@convention(thin) (@inout_aliasable Int, Int) -> () {
|
|
bb0(%0 : $*Int, %1 : $Int):
|
|
%2 = function_ref @assignsToCapture : $@convention(thin) (@inout_aliasable Int, Int) -> ()
|
|
%3 = apply %2(%0, %1) : $@convention(thin) (@inout_aliasable Int, Int) -> ()
|
|
%4 = tuple ()
|
|
return %4 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @throwingClosureThatModifiesCapture
|
|
// CHECK-NEXT: ([modify])
|
|
sil private [ossa] @throwingClosureThatModifiesCapture : $@convention(thin) (@inout_aliasable Int) -> @error Error {
|
|
bb0(%0 : $*Int):
|
|
%1 = begin_access [modify] [unknown] %0 : $*Int
|
|
end_access %1 : $*Int
|
|
%2 = tuple ()
|
|
return %2 : $()
|
|
}
|
|
// CHECK-LABEL: @callThrowingClosureThatModifiesCapture
|
|
// CHECK-NEXT: ([modify])
|
|
sil private [ossa] @callThrowingClosureThatModifiesCapture : $@convention(thin) (@inout_aliasable Int) -> () {
|
|
bb0(%0 : $*Int):
|
|
%1 = function_ref @throwingClosureThatModifiesCapture : $@convention(thin) (@inout_aliasable Int) -> @error Error
|
|
try_apply %1(%0) : $@convention(thin) (@inout_aliasable Int) -> @error Error, normal bb1, error bb2
|
|
bb1(%3 : $()):
|
|
%4 = tuple ()
|
|
return %4 : $()
|
|
bb2(%5: @owned $Error):
|
|
%6 = builtin "unexpectedError"(%5 : $Error) : $()
|
|
unreachable
|
|
}
|
|
|
|
sil @takesNoEscapeClosure : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
|
|
|
|
// CHECK-LABEL: @partialApplyPassedOffToFunction
|
|
// CHECK-NEXT: ([modify], [])
|
|
sil private [ossa] @partialApplyPassedOffToFunction : $@convention(thin) (@inout_aliasable Int, Int) -> () {
|
|
bb0(%0 : $*Int, %1: $Int):
|
|
%2 = function_ref @assignsToCapture : $@convention(thin) (@inout_aliasable Int, Int) -> ()
|
|
%3 = partial_apply %2(%0, %1) : $@convention(thin) (@inout_aliasable Int, Int) -> ()
|
|
%4 = function_ref @takesNoEscapeClosure : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
|
|
%5 = apply %4(%3) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
|
|
%6 = tuple ()
|
|
return %6 : $()
|
|
}
|
|
|
|
sil @takesNoEscapeClosureTakingArgument : $@convention(thin) (@owned @callee_owned (Int) -> ()) -> ()
|
|
sil @takesNoEscapeClosureTakingArgumentThrowing : $@convention(thin) (@owned @callee_owned (Int) -> (@error Error)) -> ()
|
|
sil @takesGuaranteedNoEscapeClosureTakingArgumentThrowing : $@convention(thin) (@guaranteed @callee_owned (Int) -> @error Error) -> ()
|
|
// CHECK-LABEL: @hasThreeCapturesAndTakesArgument
|
|
// CHECK-NEXT: ([], [modify], [], [read])
|
|
sil private [ossa] @hasThreeCapturesAndTakesArgument : $@convention(thin) (Int, @inout_aliasable Int, @inout_aliasable Int, @inout_aliasable Int) -> () {
|
|
bb0(%0 : $Int, %1: $*Int, %2: $*Int, %3: $*Int):
|
|
%4 = begin_access [modify] [unknown] %1 : $*Int
|
|
end_access %4 : $*Int
|
|
%5 = begin_access [read] [unknown] %3 : $*Int
|
|
end_access %5 : $*Int
|
|
%6 = tuple ()
|
|
return %6 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @partialApplyOfClosureTakingArgumentPassedOffToFunction
|
|
// CHECK-NEXT: ([modify], [], [read])
|
|
sil private [ossa] @partialApplyOfClosureTakingArgumentPassedOffToFunction : $@convention(thin) (@inout_aliasable Int, @inout_aliasable Int, @inout_aliasable Int) -> () {
|
|
bb0(%0 : $*Int, %1 : $*Int, %2 : $*Int):
|
|
%3 = function_ref @hasThreeCapturesAndTakesArgument : $@convention(thin) (Int, @inout_aliasable Int, @inout_aliasable Int, @inout_aliasable Int) -> ()
|
|
%4 = partial_apply %3(%0, %1, %2) : $@convention(thin) (Int, @inout_aliasable Int, @inout_aliasable Int, @inout_aliasable Int) -> ()
|
|
%5 = function_ref @takesNoEscapeClosureTakingArgument : $@convention(thin) (@owned @callee_owned (Int) -> ()) -> ()
|
|
%6 = apply %5(%4) : $@convention(thin) (@owned @callee_owned (Int) -> ()) -> ()
|
|
%7 = tuple ()
|
|
return %7 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @partialApplyFollowedByConvertFunction
|
|
// CHECK-NEXT: ([modify], [], [read])
|
|
sil private [ossa] @partialApplyFollowedByConvertFunction : $@convention(thin) (@inout_aliasable Int, @inout_aliasable Int, @inout_aliasable Int) -> () {
|
|
bb0(%0 : $*Int, %1 : $*Int, %2 : $*Int):
|
|
%3 = function_ref @hasThreeCapturesAndTakesArgument : $@convention(thin) (Int, @inout_aliasable Int, @inout_aliasable Int, @inout_aliasable Int) -> ()
|
|
%4 = partial_apply %3(%0, %1, %2) : $@convention(thin) (Int, @inout_aliasable Int, @inout_aliasable Int, @inout_aliasable Int) -> ()
|
|
%5 = convert_function %4 : $@callee_owned (Int) -> () to $@callee_owned (Int) -> @error Error
|
|
%6 = function_ref @takesNoEscapeClosureTakingArgumentThrowing : $@convention(thin) (@owned @callee_owned (Int) -> @error Error) -> ()
|
|
%7 = apply %6(%5) : $@convention(thin) (@owned @callee_owned (Int) -> @error Error) -> ()
|
|
%8 = tuple ()
|
|
return %8 : $()
|
|
}
|
|
|
|
|
|
sil @takesAutoClosureReturningGeneric : $@convention(thin) <T where T : Equatable> (@owned @callee_owned () -> (@out T, @error Error)) -> ()
|
|
sil @thunkForAutoClosure : $@convention(thin) (@owned @callee_owned () -> (Int, @error Error)) -> (@out Int, @error Error)
|
|
|
|
// CHECK-LABEL: @readsAndThrows
|
|
// CHECK-NEXT: ([read])
|
|
sil private [ossa] @readsAndThrows : $@convention(thin) (@inout_aliasable Int) -> (Int, @error Error) {
|
|
bb0(%0 : $*Int):
|
|
%3 = begin_access [read] [unknown] %0 : $*Int
|
|
%4 = load [trivial] %3 : $*Int
|
|
end_access %3 : $*Int
|
|
return %4 : $Int
|
|
}
|
|
|
|
// CHECK-LABEL: @passPartialApplyAsArgumentToPartialApply
|
|
// CHECK-NEXT: ([read])
|
|
sil hidden [ossa] @passPartialApplyAsArgumentToPartialApply : $@convention(thin) (@inout_aliasable Int) -> () {
|
|
bb0(%0 : $*Int):
|
|
%2 = function_ref @takesAutoClosureReturningGeneric : $@convention(thin) <τ_0_0 where τ_0_0 : Equatable> (@owned @callee_owned () -> (@out τ_0_0, @error Error)) -> ()
|
|
%3 = function_ref @readsAndThrows : $@convention(thin) (@inout_aliasable Int) -> (Int, @error Error)
|
|
%4 = partial_apply %3(%0) : $@convention(thin) (@inout_aliasable Int) -> (Int, @error Error)
|
|
%5 = function_ref @thunkForAutoClosure : $@convention(thin) (@owned @callee_owned () -> (Int, @error Error)) -> (@out Int, @error Error)
|
|
%6 = partial_apply %5(%4) : $@convention(thin) (@owned @callee_owned () -> (Int, @error Error)) -> (@out Int, @error Error)
|
|
%7 = apply %2<Int>(%6) : $@convention(thin) <τ_0_0 where τ_0_0 : Equatable> (@owned @callee_owned () -> (@out τ_0_0, @error Error)) -> ()
|
|
%8 = tuple ()
|
|
return %8 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @reads
|
|
// CHECK-NEXT: ([read])
|
|
sil private [ossa] @reads : $@convention(thin) (@inout_aliasable Int) -> Int {
|
|
bb0(%0 : $*Int):
|
|
%3 = begin_access [read] [unknown] %0 : $*Int
|
|
%4 = load [trivial] %3 : $*Int
|
|
end_access %3 : $*Int
|
|
return %4 : $Int
|
|
}
|
|
|
|
// CHECK-LABEL: @convertPartialApplyAndPassToPartialApply
|
|
// CHECK-NEXT: ([read])
|
|
sil hidden [ossa] @convertPartialApplyAndPassToPartialApply : $@convention(thin) (@inout_aliasable Int) -> () {
|
|
bb0(%0 : $*Int):
|
|
%2 = function_ref @takesAutoClosureReturningGeneric : $@convention(thin) <τ_0_0 where τ_0_0 : Equatable> (@owned @callee_owned () -> (@out τ_0_0, @error Error)) -> ()
|
|
%3 = function_ref @reads : $@convention(thin) (@inout_aliasable Int) -> Int
|
|
%4 = partial_apply %3(%0) : $@convention(thin) (@inout_aliasable Int) -> Int
|
|
%5 = convert_function %4 : $@callee_owned () -> Int to $@callee_owned () -> (Int, @error Error)
|
|
%6 = function_ref @thunkForAutoClosure : $@convention(thin) (@owned @callee_owned () -> (Int, @error Error)) -> (@out Int, @error Error)
|
|
%7 = partial_apply %6(%5) : $@convention(thin) (@owned @callee_owned () -> (Int, @error Error)) -> (@out Int, @error Error)
|
|
%8 = apply %2<Int>(%7) : $@convention(thin) <τ_0_0 where τ_0_0 : Equatable> (@owned @callee_owned () -> (@out τ_0_0, @error Error)) -> ()
|
|
%9 = tuple ()
|
|
return %9 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @selfRecursion
|
|
// CHECK-NEXT: ([modify], [])
|
|
sil private [ossa] @selfRecursion : $@convention(thin) (@inout_aliasable Int, Int) -> () {
|
|
bb0(%0 : $*Int, %1 : $Int):
|
|
%2 = function_ref @selfRecursion : $@convention(thin) (@inout_aliasable Int, Int) -> ()
|
|
%3 = apply %2(%0, %1) : $@convention(thin) (@inout_aliasable Int, Int) -> ()
|
|
%4 = begin_access [modify] [unknown] %0 : $*Int
|
|
end_access %4 : $*Int
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @callsMutuallyRecursive
|
|
// CHECK-NEXT: ([modify], [])
|
|
sil private [ossa] @callsMutuallyRecursive : $@convention(thin) (@inout_aliasable Int, Int) -> () {
|
|
bb0(%0 : $*Int, %1 : $Int):
|
|
%2 = function_ref @mutualRecursion1 : $@convention(thin) (@inout_aliasable Int, Int) -> ()
|
|
%3 = apply %2(%0, %1) : $@convention(thin) (@inout_aliasable Int, Int) -> ()
|
|
%4 = tuple ()
|
|
return %4 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @mutualRecursion1
|
|
// CHECK-NEXT: ([modify], [])
|
|
sil private [ossa] @mutualRecursion1 : $@convention(thin) (@inout_aliasable Int, Int) -> () {
|
|
bb0(%0 : $*Int, %1 : $Int):
|
|
%2 = function_ref @mutualRecursion2 : $@convention(thin) (@inout_aliasable Int, Int) -> ()
|
|
%3 = apply %2(%0, %1) : $@convention(thin) (@inout_aliasable Int, Int) -> ()
|
|
%4 = begin_access [modify] [unknown] %0 : $*Int
|
|
end_access %4 : $*Int
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @mutualRecursion2
|
|
// CHECK-NEXT: ([modify], [])
|
|
sil private [ossa] @mutualRecursion2 : $@convention(thin) (@inout_aliasable Int, Int) -> () {
|
|
bb0(%0 : $*Int, %1 : $Int):
|
|
%2 = function_ref @mutualRecursion1 : $@convention(thin) (@inout_aliasable Int, Int) -> ()
|
|
%3 = apply %2(%0, %1) : $@convention(thin) (@inout_aliasable Int, Int) -> ()
|
|
%4 = begin_access [read] [unknown] %0 : $*Int
|
|
end_access %4 : $*Int
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
// Multiple cycles. This requires two iterations of the edge propagation.
|
|
// Once to propagate the modify from A to B and one to propagate from
|
|
// B to C
|
|
//
|
|
// A [Call B then later modify param]
|
|
// / |
|
|
// \ |
|
|
// B
|
|
// / |
|
|
// \ |
|
|
// C
|
|
//
|
|
// CHECK-LABEL: @multipleCycleA
|
|
// CHECK-NEXT: ([modify])
|
|
sil private [ossa] @multipleCycleA : $@convention(thin) (@inout_aliasable Int) -> () {
|
|
bb0(%0 : $*Int):
|
|
%1 = function_ref @multipleCycleB : $@convention(thin) (@inout_aliasable Int) -> ()
|
|
%2 = apply %1(%0) : $@convention(thin) (@inout_aliasable Int) -> ()
|
|
%3 = begin_access [modify] [unknown] %0 : $*Int
|
|
end_access %3 : $*Int
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @multipleCycleB
|
|
// CHECK-NEXT: ([modify])
|
|
sil private [ossa] @multipleCycleB : $@convention(thin) (@inout_aliasable Int) -> () {
|
|
bb0(%0 : $*Int):
|
|
%1 = function_ref @multipleCycleA : $@convention(thin) (@inout_aliasable Int) -> ()
|
|
%2 = apply %1(%0) : $@convention(thin) (@inout_aliasable Int) -> ()
|
|
%3 = function_ref @multipleCycleC : $@convention(thin) (@inout_aliasable Int) -> ()
|
|
%4 = apply %3(%0) : $@convention(thin) (@inout_aliasable Int) -> ()
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @multipleCycleC
|
|
// CHECK-NEXT: ([modify])
|
|
sil private [ossa] @multipleCycleC : $@convention(thin) (@inout_aliasable Int) -> () {
|
|
bb0(%0 : $*Int):
|
|
%1 = function_ref @multipleCycleB : $@convention(thin) (@inout_aliasable Int) -> ()
|
|
%2 = apply %1(%0) : $@convention(thin) (@inout_aliasable Int) -> ()
|
|
%4 = tuple ()
|
|
return %4 : $()
|
|
}
|
|
|
|
// Make sure that we can accept borrows of partial apply by looking through the
|
|
// borrow.
|
|
// CHECK-LABEL: @partialApplyFollowedByConvertFunctionWithBorrow
|
|
// CHECK-NEXT: ([modify], [], [read])
|
|
sil private [ossa] @partialApplyFollowedByConvertFunctionWithBorrow : $@convention(thin) (@inout_aliasable Int, @inout_aliasable Int, @inout_aliasable Int) -> () {
|
|
bb0(%0 : $*Int, %1 : $*Int, %2 : $*Int):
|
|
%3 = function_ref @hasThreeCapturesAndTakesArgument : $@convention(thin) (Int, @inout_aliasable Int, @inout_aliasable Int, @inout_aliasable Int) -> ()
|
|
%4 = partial_apply %3(%0, %1, %2) : $@convention(thin) (Int, @inout_aliasable Int, @inout_aliasable Int, @inout_aliasable Int) -> ()
|
|
%5 = convert_function %4 : $@callee_owned (Int) -> () to $@callee_owned (Int) -> @error Error
|
|
%6 = begin_borrow %5 : $@callee_owned (Int) -> @error Error
|
|
%7 = function_ref @takesGuaranteedNoEscapeClosureTakingArgumentThrowing : $@convention(thin) (@guaranteed @callee_owned (Int) -> @error Error) -> ()
|
|
%8 = apply %7(%6) : $@convention(thin) (@guaranteed @callee_owned (Int) -> @error Error) -> ()
|
|
end_borrow %6 : $@callee_owned (Int) -> @error Error
|
|
destroy_value %5 : $@callee_owned (Int) -> @error Error
|
|
%9999 = tuple ()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// Look through moves.
|
|
// CHECK-LABEL: @partialApplyFollowedByConvertFunctionWithMove
|
|
// CHECK-NEXT: ([modify], [], [read])
|
|
sil private [ossa] @partialApplyFollowedByConvertFunctionWithMove : $@convention(thin) (@inout_aliasable Int, @inout_aliasable Int, @inout_aliasable Int) -> () {
|
|
bb0(%0 : $*Int, %1 : $*Int, %2 : $*Int):
|
|
%3 = function_ref @hasThreeCapturesAndTakesArgument : $@convention(thin) (Int, @inout_aliasable Int, @inout_aliasable Int, @inout_aliasable Int) -> ()
|
|
%4 = partial_apply %3(%0, %1, %2) : $@convention(thin) (Int, @inout_aliasable Int, @inout_aliasable Int, @inout_aliasable Int) -> ()
|
|
%5 = convert_function %4 : $@callee_owned (Int) -> () to $@callee_owned (Int) -> @error Error
|
|
%6 = move_value %5 : $@callee_owned (Int) -> @error Error
|
|
%7 = function_ref @takesGuaranteedNoEscapeClosureTakingArgumentThrowing : $@convention(thin) (@guaranteed @callee_owned (Int) -> @error Error) -> ()
|
|
%8 = apply %7(%6) : $@convention(thin) (@guaranteed @callee_owned (Int) -> @error Error) -> ()
|
|
destroy_value %6 : $@callee_owned (Int) -> @error Error
|
|
%9999 = tuple ()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil @use : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
|
|
sil @subject : $@convention(thin) (Builtin.Int64) -> ()
|
|
|
|
// CHECK-LABEL: @partial_apply_convert
|
|
sil [ossa] @partial_apply_convert : $@convention(thin) () -> () {
|
|
entry:
|
|
%f = function_ref @subject : $@convention(thin) (Builtin.Int64) -> ()
|
|
%z = integer_literal $Builtin.Int64, 0
|
|
%e = partial_apply [callee_guaranteed] %f(%z) : $@convention(thin) (Builtin.Int64) -> ()
|
|
%b = begin_borrow %e : $@callee_guaranteed () -> ()
|
|
%n = convert_escape_to_noescape %b : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
|
|
%n2 = mark_dependence %n : $@noescape @callee_guaranteed () -> () on %e : $@callee_guaranteed () -> ()
|
|
%f2 = function_ref @use : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
|
|
apply %f2(%n2) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
|
|
destroy_value %n2 : $@noescape @callee_guaranteed () -> ()
|
|
end_borrow %b : $@callee_guaranteed () -> ()
|
|
destroy_value %e : $@callee_guaranteed () -> ()
|
|
%t = tuple ()
|
|
return %t : $()
|
|
}
|
|
|
|
sil [ossa] @asyncIntClosure : $@convention(thin) @async (@inout_aliasable Builtin.Int64) -> (@out Builtin.Int64, @error any Error) {
|
|
bb0(%0 : $*Builtin.Int64, %1: $*Builtin.Int64):
|
|
%2 = begin_access [modify] [unknown] %0 : $*Builtin.Int64
|
|
%3 = load [trivial] %1 : $*Builtin.Int64
|
|
assign %3 to %2 : $*Builtin.Int64
|
|
end_access %2 : $*Builtin.Int64
|
|
%4 = tuple ()
|
|
return %4 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @partial_apply_asynclet
|
|
sil [ossa] @partial_apply_asynclet : $@convention(thin) @async (@inout_aliasable Builtin.Int64) -> () {
|
|
bb0(%0 : $*Builtin.Int64):
|
|
%i = alloc_stack $Builtin.Int64
|
|
%p = address_to_pointer %i : $*Builtin.Int64 to $Builtin.RawPointer
|
|
%o = enum $Optional<Builtin.RawPointer>, #Optional.none!enumelt
|
|
%x = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
|
|
%f = function_ref @asyncIntClosure : $@convention(thin) @async (@inout_aliasable Builtin.Int64) -> (@out Builtin.Int64, @error any Error)
|
|
%e = partial_apply [callee_guaranteed] %f(%0) : $@convention(thin) @async (@inout_aliasable Builtin.Int64) -> (@out Builtin.Int64, @error any Error)
|
|
%a = convert_function %e : $@async @callee_guaranteed () -> (@out Builtin.Int64, @error any Error) to $@async @callee_guaranteed @substituted <τ_0_0> () -> (@sil_sending @out τ_0_0, @error any Error) for <Builtin.Int64>
|
|
%n = convert_escape_to_noescape [not_guaranteed] %a : $@async @callee_guaranteed @substituted <τ_0_0> () -> (@sil_sending @out τ_0_0, @error any Error) for <Builtin.Int64> to $@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> (@sil_sending @out τ_0_0, @error any Error) for <Builtin.Int64>
|
|
%sl = builtin "startAsyncLetWithLocalBuffer"<Builtin.Int64>(%o : $Optional<Builtin.RawPointer>, %n : $@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> (@sil_sending @out τ_0_0, @error any Error) for <Builtin.Int64>, %p : $Builtin.RawPointer) : $Builtin.RawPointer
|
|
%ap = builtin "finishAsyncLet"(%sl, %p) : $()
|
|
hop_to_executor %x : $Optional<Builtin.Executor>
|
|
%el = builtin "endAsyncLetLifetime"(%sl : $Builtin.RawPointer) : $()
|
|
destroy_value %n : $@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> (@sil_sending @out τ_0_0, @error any Error) for <Builtin.Int64>
|
|
destroy_value %a : $@async @callee_guaranteed @substituted <τ_0_0> () -> (@sil_sending @out τ_0_0, @error any Error) for <Builtin.Int64>
|
|
dealloc_stack %i : $*Builtin.Int64
|
|
%t = tuple ()
|
|
return %t : $()
|
|
}
|