mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +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.
259 lines
6.4 KiB
Plaintext
259 lines
6.4 KiB
Plaintext
// RUN: %target-sil-opt -sil-print-types -enable-sil-verify-all %s -alloc-stack-hoisting -opt-mode=none | %FileCheck %s
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
|
|
// Make sure that we hoist the debug info and split its debug info into a
|
|
// separate debug_value.
|
|
//
|
|
// CHECK-LABEL: sil @hoist_generic_1 :
|
|
// CHECK: bb0({{.*}}):
|
|
// Make sure the debug info isn't on the alloc_stack any more.
|
|
// CHECK: [[STACK:%.*]] = alloc_stack [moveable_value_debuginfo] $T{{[ ]*}} // users:
|
|
// CHECK: bb1:
|
|
// CHECK: debug_value [moveable_value_debuginfo] [[STACK]] : $*T, let, name "x"
|
|
// CHECK-NOT: alloc_stack
|
|
// CHECK-NOT: dealloc_stack
|
|
// CHECK: bb2:
|
|
// CHECK-NOT: alloc_stack
|
|
// CHECK-NOT: dealloc_stack
|
|
// CHECK: bb3:
|
|
// CHECK: dealloc_stack
|
|
// CHECK: return
|
|
sil @hoist_generic_1 : $@convention(thin) <T> (@in T, Builtin.Int1) -> () {
|
|
bb0(%0 : $*T, %1: $Builtin.Int1):
|
|
cond_br %1, bb1, bb2
|
|
|
|
bb1:
|
|
%2 = alloc_stack [moveable_value_debuginfo] $T, let, name "x"
|
|
copy_addr [take] %0 to [init] %2 : $*T
|
|
destroy_addr %2 : $*T
|
|
dealloc_stack %2 : $*T
|
|
br bb3
|
|
bb2:
|
|
destroy_addr %0 : $*T
|
|
br bb3
|
|
bb3:
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @hoist_generic_2 :
|
|
// CHECK: bb0([[ARG:%.*]] : $*T,
|
|
// CHECK-NEXT: [[STACK:%.*]] = alloc_stack [moveable_value_debuginfo] $T{{[ ]*}} // users:
|
|
// CHECK-NEXT: cond_br {{%.*}}, bb1, bb4
|
|
//
|
|
// CHECK: bb1:
|
|
// CHECK-NEXT: debug_value [moveable_value_debuginfo] [[STACK]] : $*T, let, name "x"
|
|
// CHECK-NEXT: br bb2
|
|
//
|
|
// CHECK: bb2:
|
|
// CHECK: debug_value [moveable_value_debuginfo] [[STACK]] : $*T, let, name "y"
|
|
// CHECK-NEXT: br bb3
|
|
//
|
|
// CHECK: bb3:
|
|
// CHECK-NEXT: copy_addr [[ARG]] to [init] [[STACK]]
|
|
// CHECK-NEXT: destroy_addr [[STACK]]
|
|
// CHECK-NEXT: destroy_addr [[ARG]]
|
|
// CHECK-NEXT: br bb5
|
|
//
|
|
// CHECK: bb4:
|
|
// CHECK-NEXT: destroy_addr [[ARG]]
|
|
// CHECK-NEXT: br bb5
|
|
//
|
|
// CHECK: bb5:
|
|
// CHECK-NEXT: br bb6
|
|
//
|
|
// CHECK: bb6:
|
|
// CHECK-NEXT: tuple
|
|
// CHECK-NEXT: dealloc_stack [[STACK]]
|
|
// CHECK-NEXT: return
|
|
// CHECK: } // end sil function 'hoist_generic_2'
|
|
sil @hoist_generic_2 : $@convention(thin) <T> (@in T, Builtin.Int1) -> () {
|
|
bb0(%0 : $*T, %1: $Builtin.Int1):
|
|
cond_br %1, bb1, bb2
|
|
|
|
bb1:
|
|
%2 = alloc_stack [moveable_value_debuginfo] $T, let, name "x"
|
|
copy_addr %0 to [init] %2 : $*T
|
|
destroy_addr %2 : $*T
|
|
dealloc_stack %2 : $*T
|
|
%3 = alloc_stack [moveable_value_debuginfo] $T, let, name "y"
|
|
copy_addr %0 to [init] %3 : $*T
|
|
destroy_addr %3 : $*T
|
|
dealloc_stack %3 : $*T
|
|
destroy_addr %0 : $*T
|
|
br bb3
|
|
|
|
bb2:
|
|
destroy_addr %0 : $*T
|
|
br bb3
|
|
|
|
bb3:
|
|
br bb4
|
|
|
|
bb4:
|
|
%9999 = tuple ()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// This case we are not moving anything, so we don't add the
|
|
// [moveable_value_debuginfo] flag, but we still want debug info for the
|
|
// second alloc_stack!
|
|
//
|
|
// CHECK-LABEL: sil @hoist_generic_3 :
|
|
// CHECK: bb0([[ARG:%.*]] : $*T,
|
|
// CHECK-NEXT: [[STACK:%.*]] = alloc_stack $T{{[ ]*}}, let, name "x"
|
|
// CHECK: debug_value %{{.+}}, let, name "y"
|
|
// CHECK: } // end sil function 'hoist_generic_3'
|
|
sil @hoist_generic_3 : $@convention(thin) <T> (@in T, Builtin.Int1) -> () {
|
|
bb0(%0 : $*T, %1: $Builtin.Int1):
|
|
cond_br %1, bb1, bb2
|
|
|
|
bb1:
|
|
%2 = alloc_stack $T, let, name "x"
|
|
copy_addr %0 to [init] %2 : $*T
|
|
destroy_addr %2 : $*T
|
|
dealloc_stack %2 : $*T
|
|
%3 = alloc_stack $T, let, name "y"
|
|
copy_addr %0 to [init] %3 : $*T
|
|
destroy_addr %3 : $*T
|
|
dealloc_stack %3 : $*T
|
|
destroy_addr %0 : $*T
|
|
br bb3
|
|
|
|
bb2:
|
|
destroy_addr %0 : $*T
|
|
br bb3
|
|
|
|
bb3:
|
|
br bb4
|
|
|
|
bb4:
|
|
%9999 = tuple ()
|
|
return %9999 : $()
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Mix and Match Moved and Non Moved -> Moved //
|
|
////////////////////////////////////////////////
|
|
|
|
// CHECK-LABEL: sil @mix_and_match_1 :
|
|
// CHECK: bb0([[ARG:%.*]] : $*T,
|
|
// CHECK-NEXT: [[STACK:%.*]] = alloc_stack [moveable_value_debuginfo] $T{{[ ]*}} // users:
|
|
// CHECK-NEXT: cond_br {{%.*}}, bb1, bb4
|
|
//
|
|
// CHECK: bb1:
|
|
// CHECK-NEXT: debug_value [moveable_value_debuginfo] [[STACK]] : $*T, let, name "x"
|
|
// CHECK-NEXT: br bb2
|
|
//
|
|
// CHECK: bb2:
|
|
// CHECK: debug_value [moveable_value_debuginfo] [[STACK]] : $*T, let, name "y"
|
|
// CHECK-NEXT: br bb3
|
|
//
|
|
// CHECK: bb3:
|
|
// CHECK-NEXT: copy_addr [[ARG]] to [init] [[STACK]]
|
|
// CHECK-NEXT: destroy_addr [[STACK]]
|
|
// CHECK-NEXT: destroy_addr [[ARG]]
|
|
// CHECK-NEXT: br bb5
|
|
//
|
|
// CHECK: bb4:
|
|
// CHECK-NEXT: destroy_addr [[ARG]]
|
|
// CHECK-NEXT: br bb5
|
|
//
|
|
// CHECK: bb5:
|
|
// CHECK-NEXT: br bb6
|
|
//
|
|
// CHECK: bb6:
|
|
// CHECK-NEXT: tuple
|
|
// CHECK-NEXT: dealloc_stack [[STACK]]
|
|
// CHECK-NEXT: return
|
|
// CHECK: } // end sil function 'mix_and_match_1'
|
|
sil @mix_and_match_1 : $@convention(thin) <T> (@in T, Builtin.Int1) -> () {
|
|
bb0(%0 : $*T, %1: $Builtin.Int1):
|
|
cond_br %1, bb1, bb2
|
|
|
|
bb1:
|
|
%2 = alloc_stack $T, let, name "x"
|
|
copy_addr %0 to [init] %2 : $*T
|
|
destroy_addr %2 : $*T
|
|
dealloc_stack %2 : $*T
|
|
%3 = alloc_stack [moveable_value_debuginfo] $T, let, name "y"
|
|
copy_addr %0 to [init] %3 : $*T
|
|
destroy_addr %3 : $*T
|
|
dealloc_stack %3 : $*T
|
|
destroy_addr %0 : $*T
|
|
br bb3
|
|
|
|
bb2:
|
|
destroy_addr %0 : $*T
|
|
br bb3
|
|
|
|
bb3:
|
|
br bb4
|
|
|
|
bb4:
|
|
%9999 = tuple ()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @mix_and_match_2 :
|
|
// CHECK: bb0([[ARG:%.*]] : $*T,
|
|
// CHECK-NEXT: [[STACK:%.*]] = alloc_stack [moveable_value_debuginfo] $T{{[ ]*}} // users:
|
|
// CHECK-NEXT: cond_br {{%.*}}, bb1, bb4
|
|
//
|
|
// CHECK: bb1:
|
|
// CHECK-NEXT: debug_value [moveable_value_debuginfo] [[STACK]] : $*T, let, name "x"
|
|
// CHECK-NEXT: br bb2
|
|
//
|
|
// CHECK: bb2:
|
|
// CHECK: debug_value [moveable_value_debuginfo] [[STACK]] : $*T, let, name "y"
|
|
// CHECK-NEXT: br bb3
|
|
//
|
|
// CHECK: bb3:
|
|
// CHECK-NEXT: copy_addr [[ARG]] to [init] [[STACK]]
|
|
// CHECK-NEXT: destroy_addr [[STACK]]
|
|
// CHECK-NEXT: destroy_addr [[ARG]]
|
|
// CHECK-NEXT: br bb5
|
|
//
|
|
// CHECK: bb4:
|
|
// CHECK-NEXT: destroy_addr [[ARG]]
|
|
// CHECK-NEXT: br bb5
|
|
//
|
|
// CHECK: bb5:
|
|
// CHECK-NEXT: br bb6
|
|
//
|
|
// CHECK: bb6:
|
|
// CHECK-NEXT: tuple
|
|
// CHECK-NEXT: dealloc_stack [[STACK]]
|
|
// CHECK-NEXT: return
|
|
// CHECK: } // end sil function 'mix_and_match_2'
|
|
sil @mix_and_match_2 : $@convention(thin) <T> (@in T, Builtin.Int1) -> () {
|
|
bb0(%0 : $*T, %1: $Builtin.Int1):
|
|
cond_br %1, bb1, bb2
|
|
|
|
bb1:
|
|
%2 = alloc_stack [moveable_value_debuginfo] $T, let, name "x"
|
|
copy_addr %0 to [init] %2 : $*T
|
|
destroy_addr %2 : $*T
|
|
dealloc_stack %2 : $*T
|
|
%3 = alloc_stack $T, let, name "y"
|
|
copy_addr %0 to [init] %3 : $*T
|
|
destroy_addr %3 : $*T
|
|
dealloc_stack %3 : $*T
|
|
destroy_addr %0 : $*T
|
|
br bb3
|
|
|
|
bb2:
|
|
destroy_addr %0 : $*T
|
|
br bb3
|
|
|
|
bb3:
|
|
br bb4
|
|
|
|
bb4:
|
|
%9999 = tuple ()
|
|
return %9999 : $()
|
|
}
|