File: specialize_recursive_generics.sil

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (149 lines) | stat: -rw-r--r-- 7,725 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// RUN: %target-sil-opt -enable-sil-verify-all %s -generic-specializer -cse | %FileCheck %s

// Check that SIL cloner can correctly handle specialization of recursive
// functions with generic arguments.

sil_stage canonical

import Builtin
import Swift

// Check that this recursive function is specialized only for Int32.
// CHECK-LABEL: sil shared [noinline] @$s62_TF29specialize_recursive_generics18recursive_genericsU__FQ_T_s5Int32V_Tg5
// CHECK: function_ref @$s62_TF29specialize_recursive_generics18recursive_genericsU__FQ_T_s5Int32V_Tg5
// CHECK: return
sil [noinline] @_TF29specialize_recursive_generics18recursive_genericsU__FQ_T_ : $@convention(thin) <T> (@in T) -> () {
bb0(%0 : $*T):
  debug_value %0 : $*T, let, name "t", expr op_deref // id: %1
  // function_ref specialize_recursive_generics.recursive_generics <A>(A) -> ()
  %2 = function_ref @_TF29specialize_recursive_generics18recursive_genericsU__FQ_T_ : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () // user: %5
  %3 = alloc_stack $T                             // users: %4, %5, %6
  copy_addr %0 to [init] %3 : $*T     // id: %4
  %5 = apply %2<T>(%3) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> ()
  dealloc_stack %3 : $*T         // id: %6
  destroy_addr %0 : $*T                           // id: %7
  %8 = tuple ()                                   // user: %9
  return %8 : $()                                 // id: %9
}

// Check that this recursive function is specialized twice: for (Int, Double) and for (Double, Int).

// CHECK-LABEL: sil shared [noinline] @$s97_TF29specialize_recursive_generics47recursive_generics_with_different_substitutionsU___FTQ_Q0__T_Sd_s5Int32VTg5
// CHECK: function_ref @$s97_TF29specialize_recursive_generics47recursive_generics_with_different_substitutionsU___FTQ_Q0__T_s5Int32V_SdTg5
// CHECK: return

// CHECK-LABEL: sil shared [noinline] @$s97_TF29specialize_recursive_generics47recursive_generics_with_different_substitutionsU___FTQ_Q0__T_s5Int32V_SdTg5
// CHECK: function_ref @$s97_TF29specialize_recursive_generics47recursive_generics_with_different_substitutionsU___FTQ_Q0__T_Sd_s5Int32VTg5
// CHECK: return


sil [noinline] @_TF29specialize_recursive_generics47recursive_generics_with_different_substitutionsU___FTQ_Q0__T_ : $@convention(thin) <T, U> (@in T, @in U) -> () {
bb0(%0 : $*T, %1 : $*U):
  debug_value %0 : $*T, let, name "t", expr op_deref // id: %2
  debug_value %1 : $*U, let, name "u", expr op_deref // id: %3
  // function_ref specialize_recursive_generics.recursive_generics_with_different_substitutions <A, B>(A, B) -> ()
  %4 = function_ref @_TF29specialize_recursive_generics47recursive_generics_with_different_substitutionsU___FTQ_Q0__T_ : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_1) -> () // user: %9
  %5 = alloc_stack $U                             // users: %6, %9, %11
  copy_addr %1 to [init] %5 : $*U     // id: %6
  %7 = alloc_stack $T                             // users: %8, %9, %10
  copy_addr %0 to [init] %7 : $*T     // id: %8
  %9 = apply %4<U, T>(%5, %7) : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_1) -> ()
  dealloc_stack %7 : $*T         // id: %10
  dealloc_stack %5 : $*U         // id: %11
  destroy_addr %1 : $*U                           // id: %12
  destroy_addr %0 : $*T                           // id: %13
  %14 = tuple ()                                  // user: %15
  return %14 : $()                                // id: %15
}

sil @$s29specialize_recursive_generics05test_b1_C0yyF : $@convention(thin) () -> () {
bb0:
  // function_ref specialize_recursive_generics.recursive_generics <A>(A) -> ()
  %0 = function_ref @_TF29specialize_recursive_generics18recursive_genericsU__FQ_T_ : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () // user: %5
  %1 = integer_literal $Builtin.Int32, 3          // user: %2
  %2 = struct $Int32 (%1 : $Builtin.Int32)        // user: %4
  %3 = alloc_stack $Int32                         // users: %4, %5, %6
  store %2 to %3 : $*Int32                      // id: %4
  %5 = apply %0<Int32>(%3) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> ()
  dealloc_stack %3 : $*Int32     // id: %6
  %7 = tuple ()                                   // user: %8
  return %7 : $()                                 // id: %8
}

sil @$s29specialize_recursive_generics05test_b1_C29_with_different_substitutionsyyF : $@convention(thin) () -> () {
bb0:
  // function_ref specialize_recursive_generics.recursive_generics_with_different_substitutions <A, B>(A, B) -> ()
  %0 = function_ref @_TF29specialize_recursive_generics47recursive_generics_with_different_substitutionsU___FTQ_Q0__T_ : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_1) -> () // user: %10
  %1 = float_literal $Builtin.FPIEEE80, 0x3FFF999999999999999A // 1.20000000000000000004 // user: %2
  %2 = builtin "fptrunc_FPIEEE80_FPIEEE64"(%1 : $Builtin.FPIEEE80) : $Builtin.FPIEEE64 // user: %3
  %3 = struct $Double (%2 : $Builtin.FPIEEE64)    // user: %5
  %4 = alloc_stack $Double                        // users: %5, %10, %12
  store %3 to %4 : $*Double                     // id: %5
  %6 = integer_literal $Builtin.Int32, 1          // user: %7
  %7 = struct $Int32 (%6 : $Builtin.Int32)        // user: %9
  %8 = alloc_stack $Int32                         // users: %9, %10, %11
  store %7 to %8 : $*Int32                      // id: %9
  %10 = apply %0<Double, Int32>(%4, %8) : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_1) -> ()
  dealloc_stack %8 : $*Int32     // id: %11
  dealloc_stack %4 : $*Double    // id: %12
  %13 = tuple ()                                  // user: %14
  return %13 : $()                                // id: %14
}


public class C : P {}

public protocol P {}

sil hidden [noinline] @helper : $@convention(thin) <T> (@in T, @in P) -> @owned Optional<C> {
bb0(%0 : $*T, %1 : $*P):
  %4 = alloc_stack $P
  copy_addr %1 to [init] %4 : $*P
  %6 = alloc_stack $C
  checked_cast_addr_br take_always P in %4 : $*P to C in %6 : $*C, bb1, bb2
bb1:
  %8 = load %6 : $*C
  %9 = enum $Optional<C>, #Optional.some!enumelt, %8 : $C
  dealloc_stack %6 : $*C
  br bb3(%9 : $Optional<C>)
bb2:
  %12 = enum $Optional<C>, #Optional.none!enumelt
  dealloc_stack %6 : $*C
  br bb3(%12 : $Optional<C>)

bb3(%15 : $Optional<C>):
  dealloc_stack %4 : $*P
  destroy_addr %1 : $*P
  destroy_addr %0 : $*T
  return %15 : $Optional<C>
}

// CHECK-LABEL: sil shared @$s6lookup4main1CC_Tg5
sil @lookup : $@convention(method) <Self where Self : P> (@owned C, @in_guaranteed Self) -> @owned Optional<C> {
bb0(%0 : $C, %1 : $*Self):
  // CHECK: [[HELPER:%.*]] = function_ref @$s6helpers5Int32V_Tg5
  %4 = function_ref @helper : $@convention(thin) <τ_0_0> (@in τ_0_0, @in P) -> @owned Optional<C>
  %5 = integer_literal $Builtin.Int32, 1
  %6 = struct $Int32 (%5 : $Builtin.Int32)
  %7 = alloc_stack $Int32
  store %6 to %7 : $*Int32
  %9 = alloc_stack $P
  %10 = init_existential_addr %9 : $*P, $Self
  copy_addr %1 to [init] %10 : $*Self
  // CHECK: apply [[HELPER]]
  // CHECK-NOT: apply [[HELPER]]
  %12 = apply %4<Int32>(%7, %9) : $@convention(thin) <τ_0_0> (@in τ_0_0, @in P) -> @owned Optional<C>
  release_value %12 : $Optional<C>
  dealloc_stack %9 : $*P
  dealloc_stack %7 : $*Int32
  // CHECK: [[LOOKUP:%.*]] = function_ref @$s6lookup4main1CC_Tg5
  %16 = function_ref @lookup : $@convention(method) <τ_0_0 where τ_0_0 : P> (@owned C, @in_guaranteed τ_0_0) -> @owned Optional<C>
  %17 = alloc_stack $C
  store %0 to %17 : $*C
  strong_retain %0 : $C
  // CHECK: apply [[LOOKUP]]
  %20 = apply %16<C>(%0, %17) : $@convention(method) <τ_0_0 where τ_0_0 : P> (@owned C, @in_guaranteed τ_0_0) -> @owned Optional<C>
  dealloc_stack %17 : $*C
  strong_release %0 : $C
  return %20 : $Optional<C>
}