mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Type annotations for instruction operands are omitted, e.g. ``` %3 = struct $S(%1, %2) ``` Operand types are redundant anyway and were only used for sanity checking in the SIL parser. But: operand types _are_ printed if the definition of the operand value was not printed yet. This happens: * if the block with the definition appears after the block where the operand's instruction is located * if a block or instruction is printed in isolation, e.g. in a debugger The old behavior can be restored with `-Xllvm -sil-print-types`. This option is added to many existing test files which check for operand types in their check-lines.
125 lines
6.3 KiB
Swift
125 lines
6.3 KiB
Swift
// RUN: %target-swift-frontend -module-name A -verify -Xllvm -sil-print-types -emit-sil -import-objc-header %S/Inputs/Closure.h -enable-copy-propagation=false -disable-objc-attr-requires-foundation-module %s | %FileCheck %s
|
|
// RUN: %target-swift-frontend -module-name A -verify -Xllvm -sil-print-types -emit-sil -import-objc-header %S/Inputs/Closure.h -enable-copy-propagation=false -disable-objc-attr-requires-foundation-module -Xllvm -sil-disable-convert-escape-to-noescape-switch-peephole %s | %FileCheck %s --check-prefix=NOPEEPHOLE
|
|
//
|
|
// Using -enable-copy-propagation=false to pattern match against older SIL
|
|
// output. At least until -enable-copy-propagation has been around
|
|
// long enough in the same form to be worth rewriting CHECK lines.
|
|
|
|
// REQUIRES: objc_interop
|
|
|
|
import Foundation
|
|
|
|
// Make sure that we keep the escaping closures alive across the ultimate call.
|
|
// CHECK-LABEL: sil @$s1A19bridgeNoescapeBlock5optFn0D3Fn2yySSSgcSg_AFtF
|
|
// CHECK: bb0
|
|
// CHECK: retain_value %0
|
|
// CHECK: retain_value %0
|
|
// CHECK: bb1
|
|
// CHECK: convert_escape_to_noescape %
|
|
// CHECK: strong_release
|
|
// CHECK: bb5
|
|
// CHECK: retain_value %1
|
|
// CHECK: retain_value %1
|
|
// CHECK: bb6
|
|
// CHECK: convert_escape_to_noescape %
|
|
// CHECK: strong_release
|
|
// CHECK: bb10
|
|
// CHECK: [[F:%.*]] = function_ref @noescapeBlock3
|
|
// CHECK: apply [[F]]
|
|
// CHECK: release_value {{.*}} : $Optional<NSString>
|
|
// CHECK: release_value %1 : $Optional<@callee_guaranteed (@guaranteed Optional<String>) -> ()>
|
|
// CHECK: release_value {{.*}} : $Optional<@convention(block) @noescape (Optional<NSString>) -> ()>
|
|
// CHECK: release_value %0 : $Optional<@callee_guaranteed (@guaranteed Optional<String>) -> ()>
|
|
// CHECK: release_value {{.*}} : $Optional<@convention(block) @noescape (Optional<NSString>)
|
|
public func bridgeNoescapeBlock( optFn: ((String?) -> ())?, optFn2: ((String?) -> ())?) {
|
|
noescapeBlock3(optFn, optFn2, "Foobar")
|
|
}
|
|
|
|
|
|
@_silgen_name("_returnOptionalEscape")
|
|
public func returnOptionalEscape() -> (() ->())?
|
|
|
|
// Make sure that we keep the escaping closure alive across the ultimate call.
|
|
|
|
// CHECK-LABEL: sil @$s1A19bridgeNoescapeBlockyyF : $@convention(thin) () -> () {
|
|
// CHECK: bb0:
|
|
// CHECK: [[NONE:%.*]] = enum $Optional<{{.*}}>, #Optional.none!enumelt
|
|
// CHECK: [[V0:%.*]] = function_ref @_returnOptionalEscape
|
|
// CHECK: [[V1:%.*]] = apply [[V0]]
|
|
// CHECK: retain_value [[V1]]
|
|
// CHECK: switch_enum [[V1]] : $Optional<{{.*}}>, case #Optional.some!enumelt: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
|
|
//
|
|
// CHECK: [[SOME_BB]]([[V2:%.*]] : $@callee_guaranteed () -> ()):
|
|
// CHECK: [[V1_UNWRAPPED:%.*]] = unchecked_enum_data [[V1]]
|
|
// CHECK: [[CVT:%.*]] = convert_escape_to_noescape [[V1_UNWRAPPED]]
|
|
// CHECK: [[SOME:%.*]] = enum $Optional<{{.*}}>, #Optional.some!enumelt, [[CVT]]
|
|
// CHECK: strong_release [[V2]]
|
|
// CHECK: br [[NEXT_BB:bb[0-9]+]]([[SOME]] :
|
|
//
|
|
// CHECK: [[NEXT_BB]]([[SOME_PHI:%.*]] :
|
|
// CHECK: switch_enum [[SOME_PHI]] : $Optional<{{.*}}>, case #Optional.some!enumelt: [[SOME_BB_2:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB_2:bb[0-9]+]]
|
|
//
|
|
// CHECK: [[SOME_BB_2]]([[SOME_PHI_PAYLOAD:%.*]] :
|
|
// CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] {{%.*}}([[SOME_PHI_PAYLOAD]])
|
|
// CHECK: [[MDI:%.*]] = mark_dependence [[PAI]]
|
|
// CHECK: strong_retain [[MDI]]
|
|
// CHECK: [[BLOCK_SLOT:%.*]] = alloc_stack
|
|
// CHECK: [[BLOCK_PROJ:%.*]] = project_block_storage [[BLOCK_SLOT]]
|
|
// CHECK: store [[MDI]] to [[BLOCK_PROJ]]
|
|
// CHECK: [[BLOCK:%.*]] = init_block_storage_header [[BLOCK_SLOT]]
|
|
// CHECK: [[SOME_2:%.*]] = enum $Optional<{{.*}}>, #Optional.some!enumelt, [[MDI]]
|
|
// CHECK: [[BLOCK_COPY:%.*]] = copy_block [[BLOCK]]
|
|
// CHECK: [[BLOCK_SOME:%.*]] = enum $Optional<{{.*}}>, #Optional.some!enumelt, [[BLOCK_COPY]]
|
|
// CHECK: br bb5([[BLOCK_SOME]] : ${{.*}}, [[SOME_2]] :
|
|
//
|
|
// CHECK: bb4:
|
|
// CHECK: [[NONE_BLOCK:%.*]] = enum $Optional<{{.*}}>, #Optional.none!enumelt
|
|
// CHECK: br bb5([[NONE_BLOCK]] : {{.*}}, [[NONE]] :
|
|
//
|
|
// CHECK: bb5([[BLOCK_PHI:%.*]] : $Optional<{{.*}}>, [[SWIFT_CLOSURE_PHI:%.*]] :
|
|
// CHECK: [[F:%.*]] = function_ref @noescapeBlock
|
|
// CHECK: apply [[F]]([[BLOCK_PHI]])
|
|
// CHECK: release_value [[BLOCK_PHI]]
|
|
// CHECK: release_value [[SWIFT_CLOSURE_PHI]]
|
|
// CHECK-NEXT: return
|
|
|
|
// NOPEEPHOLE-LABEL: sil @$s1A19bridgeNoescapeBlockyyF : $@convention(thin) () -> () {
|
|
// NOPEEPHOLE: bb0:
|
|
// NOPEEPHOLE: [[NONE_1:%.*]] = enum $Optional<{{.*}}>, #Optional.none!enumelt
|
|
// NOPEEPHOLE: [[NONE_2:%.*]] = enum $Optional<{{.*}}>, #Optional.none!enumelt
|
|
// NOPEEPHOLE: [[V0:%.*]] = function_ref @_returnOptionalEscape
|
|
// NOPEEPHOLE: [[V1:%.*]] = apply [[V0]]
|
|
// NOPEEPHOLE: switch_enum [[V1]] : $Optional<{{.*}}>, case #Optional.some!enumelt: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
|
|
//
|
|
// NOPEEPHOLE: [[SOME_BB]]([[V2:%.*]]: $@callee_guaranteed () -> ()):
|
|
// NOPEEPHOLE-NEXT: [[CVT:%.*]] = convert_escape_to_noescape [[V2]]
|
|
// NOPEEPHOLE-NEXT: [[SOME:%.*]] = enum $Optional<{{.*}}>, #Optional.some!enumelt, [[V2]]
|
|
// NOPEEPHOLE-NEXT: [[MDI:%.*]] = mark_dependence [[CVT]] : $@noescape @callee_guaranteed () -> () on [[SOME]] : $Optional<@callee_guaranteed () -> ()>
|
|
// NOPEEPHOLE-NEXT: [[NOESCAPE_SOME:%.*]] = enum $Optional<{{.*}}>, #Optional.some!enumelt, [[MDI]]
|
|
// NOPEEPHOLE-NEXT: br bb2([[NOESCAPE_SOME]] : $Optional<{{.*}}>, [[SOME]] : $Optional<{{.*}}>, [[SOME]] : $Optional<{{.*}}>)
|
|
//
|
|
// NOPEEPHOLE: bb2([[NOESCAPE_SOME:%.*]] : $Optional<{{.*}}>, [[SOME1:%.*]] : $Optional<{{.*}}>, [[SOME:%.*]] : $Optional<{{.*}}>):
|
|
// NOPEEPHOLE: switch_enum [[NOESCAPE_SOME]] : $Optional<{{.*}}>, case #Optional.some!enumelt: [[SOME_BB_2:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB_2:bb[0-9]+]]
|
|
//
|
|
// NOPEEPHOLE: [[SOME_BB_2]](
|
|
// NOPEEPHOLE: br bb5
|
|
//
|
|
// NOPEEPHOLE: [[NONE_BB_2]]:
|
|
// NOPEEPHOLE: br bb5
|
|
//
|
|
// NOPEEPHOLE: bb5([[BLOCK_PHI:%.*]] : $Optional<{{.*}}>, [[SWIFT_CLOSURE_PHI:%.*]] :
|
|
// NOPEEPHOLE-NEXT: function_ref noescapeBlock
|
|
// NOPEEPHOLE-NEXT: [[F:%.*]] = function_ref @noescapeBlock :
|
|
// NOPEEPHOLE-NEXT: apply [[F]]([[BLOCK_PHI]])
|
|
// NOPEEPHOLE-NEXT: release_value [[BLOCK_PHI]]
|
|
// NOPEEPHOLE-NEXT: tuple
|
|
// NOPEEPHOLE-NEXT: release_value [[SOME]]
|
|
// NOPEEPHOLE-NEXT: release_value [[SWIFT_CLOSURE_PHI]]
|
|
// NOPEEPHOLE-NEXT: return
|
|
// NOPEEPHOLE: } // end sil function '$s1A19bridgeNoescapeBlockyyF'
|
|
public func bridgeNoescapeBlock() {
|
|
noescapeBlock(returnOptionalEscape())
|
|
}
|
|
|
|
|