Files
swift-mirror/test/SIL/Parser/boxes.sil
Erik Eckstein 18063707b5 Optimizer: enable complete OSSA lifetimes throughout the pass pipeline
This new OSSA invariant simplifies many optimizations because they don't have to take care of the corner case of incomplete lifetimes in dead-end blocks.

The implementation basically consists of these changes:
* add the lifetime completion utility
* add a flag in SILFunction which tells optimization that they need to run the lifetime completion utility
* let all optimizations complete lifetimes if necessary
* enable the ownership verifier to check complete lifetimes
2026-01-22 17:41:48 +01:00

111 lines
4.2 KiB
Plaintext

// RUN: %target-swift-frontend -emit-silgen %s | %FileCheck %s
sil_stage raw
import Swift
protocol P {}
struct F {}
struct G: P {}
struct Q: P {}
// TODO: Transform boxes by transforming their arguments, not as single-field,
// so that they work as parameters in generic SIL functions.
// CHECK-LABEL: sil [ossa] @box_type_parsing : $@convention(thin) (
sil [ossa] @box_type_parsing : $@convention(thin) (
// CHECK: <τ_0_0> { var τ_0_0 } <F>,
<B>{ var B }<F>,
// CHECK: <τ_0_0 where τ_0_0 : P> { let τ_0_0 } <G>,
<C: P>{ let C }<G>,
// CHECK: <τ_0_0 where τ_0_0 : P> { var τ_0_0 } <Q>,
<D: P>{ var D }<Q>,
// CHECK: { let Int },
{ let Int },
// CHECK: { var Int, let String },
{ var Int, let String },
// CHECK: { },
{},
// CHECK: <τ_0_0, τ_0_1, τ_0_2> { var τ_0_0, let τ_0_2 } <Int, String, Optional<Double>>
<X, Y, Z>{ var X, let Z }<Int, String, Optional<Double>>
// CHECK: ) -> ()
) -> () {
entry(%0 : @unowned $<E>{ var E }<F>, %1 : @unowned $<F: P>{ let F }<G>, %2 : @unowned $<G: P>{ var G }<Q>, %3 : @unowned ${ let Int }, %4 : @unowned ${ var Int, let String }, %5 : @unowned ${}, %6 : @unowned $<XX, YY, ZZ>{ var XX, let ZZ }<Int, String, Optional<Double>>):
unreachable
}
// CHECK-LABEL: sil [ossa] @box_type_parsing_in_generic_function : $@convention(thin) <F, G where G : P> (
sil [ossa] @box_type_parsing_in_generic_function : $@convention(thin) <F, G: P> (
// CHECK: <τ_0_0> { var τ_0_0 } <F>,
<B>{ var B }<F>,
// CHECK: <τ_0_0 where τ_0_0 : P> { let τ_0_0 } <G>,
<C: P>{ let C }<G>,
// CHECK: <τ_0_0 where τ_0_0 : P> { var τ_0_0 } <Q>,
<D: P>{ var D }<Q>,
// CHECK: { let Int },
{ let Int },
// CHECK: { var Int, let String },
{ var Int, let String },
// CHECK: { },
{},
// CHECK: <τ_0_0, τ_0_1, τ_0_2> { var τ_0_0, let τ_0_2 } <Int, String, Optional<Double>>
<X, Y, Z>{ var X, let Z }<Int, String, Optional<Double>>
// CHECK: ) -> ()
) -> () {
entry(%0 : @unowned $<E>{ var E }<F>, %1 : @unowned $<F: P>{ let F }<G>, %2 : @unowned $<G: P>{ var G }<Q>, %3 : @unowned ${ let Int }, %4 : @unowned ${ var Int, let String }, %5 : @unowned ${}, %6 : @unowned $<XX, YY, ZZ>{ var XX, let ZZ }<Int, String, Optional<Double>>):
unreachable
}
// CHECK-LABEL: sil [ossa] @same_generic_param_name_in_multiple_box_signatures : $@convention(thin) (
sil [ossa] @same_generic_param_name_in_multiple_box_signatures : $@convention(thin) (
// CHECK: <τ_0_0> { var τ_0_0 } <Int>,
<A> { var A } <Int>,
// CHECK: <τ_0_0> { var τ_0_0 } <String>
<A> { var A } <String>
// CHECK: ) -> ()
) -> () {
entry(%0 : @unowned $<A> { var A } <Int>, %1 : @unowned $<A> { var A } <String>):
unreachable
}
// CHECK-LABEL: sil [ossa] @same_generic_param_name_in_outer_scope : $@convention(thin) <A> (
sil [ossa] @same_generic_param_name_in_outer_scope : $@convention(thin) <A> (
// CHECK: <τ_0_0> { var τ_0_0 } <A>
<A> { var A } <A>
// CHECK: ) -> ()
) -> () {
entry(%0 : @unowned $<B> { var B } <A>):
unreachable
}
// CHECK-LABEL: sil [ossa] @box_ownership : $@convention(thin) (@owned { var Int }, @guaranteed <τ_0_0> { let τ_0_0 } <Int>) -> ()
sil [ossa] @box_ownership : $@convention(thin) (@owned { var Int }, @guaranteed <T> { let T } <Int>) -> () {
entry(%0 : @owned ${ var Int }, %1 : @guaranteed $<T> { let T } <Int>):
destroy_value [dead_end] %0
unreachable
}
// CHECK-LABEL: sil [ossa] @address_of_box
sil [ossa] @address_of_box : $@convention(thin) (@in { var Int }, @in <T> { let T } <Int>) -> () {
// CHECK: %0 : $*{ var Int }, %1 : $*<τ_0_0> { let τ_0_0 } <Int>
entry(%0 : $*{ var Int }, %1 : $*<T> { let T } <Int>):
unreachable
}
// CHECK-LABEL: sil [ossa] @alloc_box_attrs
sil [ossa] @alloc_box_attrs : $@convention(thin) () -> () {
entry:
// CHECK: %0 = alloc_box $
%0 = alloc_box ${ let Int }
// CHECK: %1 = alloc_box [dynamic_lifetime] $
%1 = alloc_box [dynamic_lifetime] ${ let Int }
// CHECK: %2 = alloc_box [reflection] $
%2 = alloc_box [reflection] ${ let Int }
// CHECK: %3 = alloc_box [dynamic_lifetime] [reflection] $
%3 = alloc_box [dynamic_lifetime] [reflection] ${ let Int }
dealloc_box %3: ${ let Int }
dealloc_box %2: ${ let Int }
dealloc_box %1: ${ let Int }
dealloc_box %0: ${ let Int }
return undef : $()
}