mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This pass has been disabled since a very long time (because it's terrible for code size). It does not work for OSSA. Therefore it cannot be enabled anymore (as is) once we have OSSA throughout the pipeline. So it's time to completely remove it.
489 lines
18 KiB
Plaintext
489 lines
18 KiB
Plaintext
// RUN: %target-sil-opt -sil-print-types -enable-sil-verify-all -inline -generic-specializer -inline %s > %t.sil
|
|
// RUN: %target-sil-opt -sil-print-types -sil-full-demangle -enable-sil-verify-all %t.sil | %FileCheck %s
|
|
|
|
// Check that the @_optimize(none) annotation prevents
|
|
// any optimizations of the annotated function:
|
|
// - No functions are inlined into the annotated function.
|
|
// - No calls are devirtualized in the body of the annotated function.
|
|
// - No generic specializations of the annotated function are generated.
|
|
// - The annotated function is not inlined into any other function.
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
import SwiftShims
|
|
|
|
public class C {
|
|
@inline(never) func foo() -> Int32
|
|
deinit
|
|
init()
|
|
}
|
|
|
|
public class D : C {
|
|
@inline(never) override func foo() -> Int32
|
|
deinit
|
|
override init()
|
|
}
|
|
|
|
public class Base {
|
|
@_optimize(none) func foo() -> Int32
|
|
func boo() -> Int32
|
|
deinit
|
|
init()
|
|
}
|
|
|
|
public class Derived1 : Base {
|
|
override func foo() -> Int32
|
|
@_optimize(none) override func boo() -> Int32
|
|
deinit
|
|
override init()
|
|
}
|
|
|
|
public class Derived2 : Base {
|
|
override func foo() -> Int32
|
|
override func boo() -> Int32
|
|
deinit
|
|
override init()
|
|
}
|
|
|
|
public func transform1<T>(x: T) -> Int32
|
|
|
|
@_optimize(none) public func foo1<T>(x: T, _ c: C) -> Int32
|
|
|
|
public func boo1(c: C) -> Int32
|
|
|
|
public func transform2(x: Int32) -> Int32
|
|
|
|
@_optimize(none) public func foo2(x: Int32, _ c: C) -> Int32
|
|
|
|
public func boo2(c: C) -> Int32
|
|
|
|
public func transform3<T>(x: T) -> Int32
|
|
|
|
public func foo3<T>(x: T, _ c: C) -> Int32
|
|
|
|
public func boo3(c: C) -> Int32
|
|
|
|
public func transform4(x: Int32) -> Int32
|
|
|
|
public func foo4(x: Int32, _ c: C) -> Int32
|
|
|
|
public func boo4(c: C) -> Int32
|
|
|
|
|
|
sil_global [serialized] @$ss7ProcessO5_argcs5Int32VvZ : $Int32
|
|
|
|
|
|
sil_global [serialized] @globalinit_33_1BDF70FFC18749BAB495A73B459ED2F0_token5 : $Builtin.Word
|
|
|
|
|
|
sil_global [serialized] @$ss7ProcessO11_unsafeArgvSpySpys4Int8VGGvZ : $UnsafeMutablePointer<UnsafeMutablePointer<Int8>>
|
|
|
|
|
|
|
|
sil hidden [noinline] @$s14optimize_never1CC3foos5Int32VyF : $@convention(method) (@guaranteed C) -> Int32 {
|
|
bb0(%0 : $C):
|
|
%2 = integer_literal $Builtin.Int32, 1
|
|
%3 = struct $Int32 (%2 : $Builtin.Int32)
|
|
return %3 : $Int32
|
|
}
|
|
|
|
|
|
sil [transparent] [serialized] @$ss5Int32V22_builtinIntegerLiteralABBI__tcfC : $@convention(thin) (Builtin.IntLiteral, @thin Int32.Type) -> Int32
|
|
|
|
|
|
sil @$s14optimize_never1CCfD : $@convention(method) (@owned C) -> () {
|
|
bb0(%0 : $C):
|
|
%2 = function_ref @$s14optimize_never1CCfd : $@convention(method) (@guaranteed C) -> @owned Builtin.NativeObject
|
|
%3 = apply %2(%0) : $@convention(method) (@guaranteed C) -> @owned Builtin.NativeObject
|
|
%4 = unchecked_ref_cast %3 : $Builtin.NativeObject to $C
|
|
dealloc_ref %4 : $C
|
|
%6 = tuple ()
|
|
return %6 : $()
|
|
}
|
|
|
|
|
|
sil @$s14optimize_never1CCfd : $@convention(method) (@guaranteed C) -> @owned Builtin.NativeObject {
|
|
bb0(%0 : $C):
|
|
%2 = unchecked_ref_cast %0 : $C to $Builtin.NativeObject
|
|
return %2 : $Builtin.NativeObject
|
|
}
|
|
|
|
|
|
sil hidden @$s14optimize_never1CCACycfc : $@convention(method) (@owned C) -> @owned C {
|
|
bb0(%0 : $C):
|
|
return %0 : $C
|
|
}
|
|
|
|
|
|
sil hidden [noinline] @$s14optimize_never1DC3foos5Int32VyF : $@convention(method) (@guaranteed D) -> Int32 {
|
|
bb0(%0 : $D):
|
|
%2 = integer_literal $Builtin.Int32, 11
|
|
%3 = struct $Int32 (%2 : $Builtin.Int32)
|
|
return %3 : $Int32
|
|
}
|
|
|
|
|
|
sil @$s14optimize_never1DCfD : $@convention(method) (@owned D) -> () {
|
|
bb0(%0 : $D):
|
|
%2 = function_ref @$s14optimize_never1DCfd : $@convention(method) (@guaranteed D) -> @owned Builtin.NativeObject
|
|
%3 = apply %2(%0) : $@convention(method) (@guaranteed D) -> @owned Builtin.NativeObject
|
|
%4 = unchecked_ref_cast %3 : $Builtin.NativeObject to $D
|
|
dealloc_ref %4 : $D
|
|
%6 = tuple ()
|
|
return %6 : $()
|
|
}
|
|
|
|
|
|
sil @$s14optimize_never1DCfd : $@convention(method) (@guaranteed D) -> @owned Builtin.NativeObject {
|
|
bb0(%0 : $D):
|
|
%2 = upcast %0 : $D to $C
|
|
%3 = function_ref @$s14optimize_never1CCfd : $@convention(method) (@guaranteed C) -> @owned Builtin.NativeObject
|
|
%4 = apply %3(%2) : $@convention(method) (@guaranteed C) -> @owned Builtin.NativeObject
|
|
return %4 : $Builtin.NativeObject
|
|
}
|
|
|
|
|
|
sil hidden @$s14optimize_never1DCACycfc : $@convention(method) (@owned D) -> @owned D {
|
|
bb0(%0 : $D):
|
|
%1 = alloc_stack $D
|
|
store %0 to %1 : $*D
|
|
%3 = upcast %0 : $D to $C
|
|
|
|
%4 = function_ref @$s14optimize_never1CCACycfc : $@convention(method) (@owned C) -> @owned C
|
|
%5 = apply %4(%3) : $@convention(method) (@owned C) -> @owned C
|
|
%6 = unchecked_ref_cast %5 : $C to $D
|
|
store %6 to %1 : $*D
|
|
dealloc_stack %1 : $*D
|
|
return %6 : $D
|
|
}
|
|
|
|
|
|
sil @$s14optimize_never10transform1ys5Int32VxlF : $@convention(thin) <T> (@in T) -> Int32 {
|
|
bb0(%0 : $*T):
|
|
%2 = integer_literal $Builtin.Int32, 2
|
|
%3 = struct $Int32 (%2 : $Builtin.Int32)
|
|
destroy_addr %0 : $*T
|
|
return %3 : $Int32
|
|
}
|
|
|
|
|
|
|
|
// Check that both calls are not inlined or devirtualized.
|
|
// CHECK-LABEL: sil [Onone] @$s14optimize_never4foo1ys5Int32Vx_AA1CCtlF
|
|
// CHECK-NOT: checked_cast_br
|
|
// CHECK: function_ref @$s14optimize_never10transform1ys5Int32VxlF
|
|
// CHECK: apply
|
|
// CHECK-NOT: checked_cast_br
|
|
// CHECK: class_method {{%.*}} : $C, #C.foo : (C) -> () -> Int32, $@convention(method) (@guaranteed C) -> Int32
|
|
// CHECK: apply
|
|
// CHECK: return
|
|
sil [Onone] @$s14optimize_never4foo1ys5Int32Vx_AA1CCtlF : $@convention(thin) <T> (@in T, @owned C) -> Int32 {
|
|
bb0(%0 : $*T, %1 : $C):
|
|
%4 = function_ref @$s14optimize_never10transform1ys5Int32VxlF : $@convention(thin) <τ_0_0> (@in τ_0_0) -> Int32
|
|
%5 = alloc_stack $T
|
|
copy_addr %0 to [init] %5 : $*T
|
|
%7 = apply %4<T>(%5) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> Int32
|
|
%8 = class_method %1 : $C, #C.foo : (C) -> () -> Int32, $@convention(method) (@guaranteed C) -> Int32
|
|
%9 = apply %8(%1) : $@convention(method) (@guaranteed C) -> Int32
|
|
%10 = struct_extract %7 : $Int32, #Int32._value
|
|
%11 = struct_extract %9 : $Int32, #Int32._value
|
|
%12 = integer_literal $Builtin.Int1, -1
|
|
%13 = builtin "sadd_with_overflow_Int32"(%10 : $Builtin.Int32, %11 : $Builtin.Int32, %12 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
|
|
%14 = tuple_extract %13 : $(Builtin.Int32, Builtin.Int1), 0
|
|
%15 = tuple_extract %13 : $(Builtin.Int32, Builtin.Int1), 1
|
|
cond_fail %15 : $Builtin.Int1
|
|
%17 = struct $Int32 (%14 : $Builtin.Int32)
|
|
dealloc_stack %5 : $*T
|
|
strong_release %1 : $C
|
|
destroy_addr %0 : $*T
|
|
return %17 : $Int32
|
|
}
|
|
|
|
|
|
sil [transparent] [serialized] @$ss1poiys5Int32VAC_ACtFZ : $@convention(thin) (Int32, Int32) -> Int32
|
|
|
|
|
|
// CHECK-LABEL: sil @$s14optimize_never4boo1ys5Int32VAA1CCF
|
|
// CHECK-NOT: return
|
|
// This call should not be inlined, because the callee is annotated with @_optimize(none)
|
|
// CHECK: function_ref @$s14optimize_never4foo1ys5Int32Vx_AA1CCtlF
|
|
// CHECK: apply
|
|
// CHECK: return
|
|
sil @$s14optimize_never4boo1ys5Int32VAA1CCF : $@convention(thin) (@owned C) -> Int32 {
|
|
bb0(%0 : $C):
|
|
%2 = function_ref @$s14optimize_never4foo1ys5Int32Vx_AA1CCtlF : $@convention(thin) <τ_0_0> (@in τ_0_0, @owned C) -> Int32
|
|
%3 = integer_literal $Builtin.Int32, 1
|
|
%4 = struct $Int32 (%3 : $Builtin.Int32)
|
|
%5 = alloc_stack $Int32
|
|
store %4 to %5 : $*Int32
|
|
strong_retain %0 : $C
|
|
%8 = apply %2<Int32>(%5, %0) : $@convention(thin) <τ_0_0> (@in τ_0_0, @owned C) -> Int32
|
|
dealloc_stack %5 : $*Int32
|
|
strong_release %0 : $C
|
|
return %8 : $Int32
|
|
}
|
|
|
|
|
|
sil [transparent] [serialized] @$sSi22_builtinIntegerLiteralSiBI__tcfC : $@convention(thin) (Builtin.IntLiteral, @thin Int.Type) -> Int
|
|
|
|
|
|
sil @$s14optimize_never10transform2ys5Int32VADF : $@convention(thin) (Int32) -> Int32 {
|
|
bb0(%0 : $Int32):
|
|
return %0 : $Int32
|
|
}
|
|
|
|
|
|
// Check that both calls are not inlined or devirtualized.
|
|
// CHECK-LABEL: sil [Onone] @$s14optimize_never4foo2ys5Int32VAD_AA1CCtF
|
|
// CHECK-NOT: checked_cast_br
|
|
// CHECK: function_ref @$s14optimize_never10transform2ys5Int32VADF
|
|
// CHECK: apply
|
|
// CHECK-NOT: checked_cast_br
|
|
// CHECK: class_method {{%.*}} : $C, #C.foo : (C) -> () -> Int32, $@convention(method) (@guaranteed C) -> Int32
|
|
// CHECK: apply
|
|
// CHECK: return
|
|
sil [Onone] @$s14optimize_never4foo2ys5Int32VAD_AA1CCtF : $@convention(thin) (Int32, @owned C) -> Int32 {
|
|
bb0(%0 : $Int32, %1 : $C):
|
|
%4 = function_ref @$s14optimize_never10transform2ys5Int32VADF : $@convention(thin) (Int32) -> Int32
|
|
%5 = apply %4(%0) : $@convention(thin) (Int32) -> Int32
|
|
%6 = class_method %1 : $C, #C.foo : (C) -> () -> Int32, $@convention(method) (@guaranteed C) -> Int32
|
|
%7 = apply %6(%1) : $@convention(method) (@guaranteed C) -> Int32
|
|
%8 = struct_extract %5 : $Int32, #Int32._value
|
|
%9 = struct_extract %7 : $Int32, #Int32._value
|
|
%10 = integer_literal $Builtin.Int1, -1
|
|
%11 = builtin "sadd_with_overflow_Int32"(%8 : $Builtin.Int32, %9 : $Builtin.Int32, %10 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
|
|
%12 = tuple_extract %11 : $(Builtin.Int32, Builtin.Int1), 0
|
|
%13 = tuple_extract %11 : $(Builtin.Int32, Builtin.Int1), 1
|
|
cond_fail %13 : $Builtin.Int1
|
|
%15 = struct $Int32 (%12 : $Builtin.Int32)
|
|
strong_release %1 : $C
|
|
return %15 : $Int32
|
|
}
|
|
|
|
|
|
// CHECK-LABEL: sil @$s14optimize_never4boo2ys5Int32VAA1CCF
|
|
// CHECK-NOT: return
|
|
// This call should not be inlined, because the callee is annotated with @_optimize(none)
|
|
// CHECK: function_ref @$s14optimize_never4foo2ys5Int32VAD_AA1CCtF
|
|
// CHECK: apply
|
|
// CHECK: return
|
|
sil @$s14optimize_never4boo2ys5Int32VAA1CCF : $@convention(thin) (@owned C) -> Int32 {
|
|
bb0(%0 : $C):
|
|
%2 = function_ref @$s14optimize_never4foo2ys5Int32VAD_AA1CCtF : $@convention(thin) (Int32, @owned C) -> Int32
|
|
%3 = integer_literal $Builtin.Int32, 1
|
|
%4 = struct $Int32 (%3 : $Builtin.Int32)
|
|
strong_retain %0 : $C
|
|
%6 = apply %2(%4, %0) : $@convention(thin) (Int32, @owned C) -> Int32
|
|
strong_release %0 : $C
|
|
return %6 : $Int32
|
|
}
|
|
|
|
// Check that no generic specialization was produced for foo1 because it is excluded from optimizations.
|
|
// CHECK-NOT: generic specialization <Swift.Int> of {{.*}}.foo1
|
|
// But foo3 was specialized, because it is not annotated with @_optimize(none)
|
|
// CHECK: generic specialization <Swift.Int32> of {{.*}}.foo3
|
|
|
|
|
|
sil @$s14optimize_never10transform3ys5Int32VxlF : $@convention(thin) <T> (@in T) -> Int32 {
|
|
bb0(%0 : $*T):
|
|
%2 = integer_literal $Builtin.Int32, 2
|
|
%3 = struct $Int32 (%2 : $Builtin.Int32)
|
|
destroy_addr %0 : $*T
|
|
return %3 : $Int32
|
|
}
|
|
|
|
|
|
sil @$s14optimize_never4foo3ys5Int32Vx_AA1CCtlF : $@convention(thin) <T> (@in T, @owned C) -> Int32 {
|
|
bb0(%0 : $*T, %1 : $C):
|
|
%4 = function_ref @$s14optimize_never10transform3ys5Int32VxlF : $@convention(thin) <τ_0_0> (@in τ_0_0) -> Int32
|
|
%5 = alloc_stack $T
|
|
copy_addr %0 to [init] %5 : $*T
|
|
%7 = apply %4<T>(%5) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> Int32
|
|
%8 = class_method %1 : $C, #C.foo : (C) -> () -> Int32, $@convention(method) (@guaranteed C) -> Int32
|
|
%9 = apply %8(%1) : $@convention(method) (@guaranteed C) -> Int32
|
|
%10 = struct_extract %7 : $Int32, #Int32._value
|
|
%11 = struct_extract %9 : $Int32, #Int32._value
|
|
%12 = integer_literal $Builtin.Int1, -1
|
|
%13 = builtin "sadd_with_overflow_Int32"(%10 : $Builtin.Int32, %11 : $Builtin.Int32, %12 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
|
|
%14 = tuple_extract %13 : $(Builtin.Int32, Builtin.Int1), 0
|
|
%15 = tuple_extract %13 : $(Builtin.Int32, Builtin.Int1), 1
|
|
cond_fail %15 : $Builtin.Int1
|
|
%17 = struct $Int32 (%14 : $Builtin.Int32)
|
|
dealloc_stack %5 : $*T
|
|
strong_release %1 : $C
|
|
destroy_addr %0 : $*T
|
|
return %17 : $Int32
|
|
}
|
|
|
|
|
|
// Everything in this function should get devirtualized, inlined and folded together,
|
|
// because neither this function nor any of its callees are annotated to be
|
|
// excluded from the optimization.
|
|
// CHECK-LABEL: sil @$s14optimize_never4boo3ys5Int32VAA1CCF
|
|
// CHECK: bb0
|
|
// CHECK-NOT: function_ref @$s14optimize_never4foo3ys5Int32Vx_AA1CCtlF
|
|
// CHECK: return
|
|
sil @$s14optimize_never4boo3ys5Int32VAA1CCF : $@convention(thin) (@owned C) -> Int32 {
|
|
bb0(%0 : $C):
|
|
%2 = function_ref @$s14optimize_never4foo3ys5Int32Vx_AA1CCtlF : $@convention(thin) <τ_0_0> (@in τ_0_0, @owned C) -> Int32
|
|
%3 = integer_literal $Builtin.Int32, 1
|
|
%4 = struct $Int32 (%3 : $Builtin.Int32)
|
|
%5 = alloc_stack $Int32
|
|
store %4 to %5 : $*Int32
|
|
strong_retain %0 : $C
|
|
%8 = apply %2<Int32>(%5, %0) : $@convention(thin) <τ_0_0> (@in τ_0_0, @owned C) -> Int32
|
|
dealloc_stack %5 : $*Int32
|
|
strong_release %0 : $C
|
|
return %8 : $Int32
|
|
}
|
|
|
|
|
|
sil @$s14optimize_never10transform4ys5Int32VADF : $@convention(thin) (Int32) -> Int32 {
|
|
bb0(%0 : $Int32):
|
|
return %0 : $Int32
|
|
}
|
|
|
|
|
|
sil @$s14optimize_never4foo4ys5Int32VAD_AA1CCtF : $@convention(thin) (Int32, @owned C) -> Int32 {
|
|
bb0(%0 : $Int32, %1 : $C):
|
|
%4 = function_ref @$s14optimize_never10transform4ys5Int32VADF : $@convention(thin) (Int32) -> Int32
|
|
%5 = apply %4(%0) : $@convention(thin) (Int32) -> Int32
|
|
%6 = class_method %1 : $C, #C.foo : (C) -> () -> Int32, $@convention(method) (@guaranteed C) -> Int32
|
|
%7 = apply %6(%1) : $@convention(method) (@guaranteed C) -> Int32
|
|
%8 = struct_extract %5 : $Int32, #Int32._value
|
|
%9 = struct_extract %7 : $Int32, #Int32._value
|
|
%10 = integer_literal $Builtin.Int1, -1
|
|
%11 = builtin "sadd_with_overflow_Int32"(%8 : $Builtin.Int32, %9 : $Builtin.Int32, %10 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
|
|
%12 = tuple_extract %11 : $(Builtin.Int32, Builtin.Int1), 0
|
|
%13 = tuple_extract %11 : $(Builtin.Int32, Builtin.Int1), 1
|
|
cond_fail %13 : $Builtin.Int1
|
|
%15 = struct $Int32 (%12 : $Builtin.Int32)
|
|
strong_release %1 : $C
|
|
return %15 : $Int32
|
|
}
|
|
|
|
|
|
// Everything in this function should get devirtualized and inlined,
|
|
// because neither this function nor any of its callees are annotated to be
|
|
// excluded from the optimization.
|
|
// CHECK-LABEL: sil @$s14optimize_never4boo4ys5Int32VAA1CCF
|
|
// CHECK: bb0
|
|
// CHECK-NOT: function_ref @$s14optimize_never4foo4ys5Int32VAD_AA1CCtF
|
|
// CHECK: return
|
|
sil @$s14optimize_never4boo4ys5Int32VAA1CCF : $@convention(thin) (@owned C) -> Int32 {
|
|
bb0(%0 : $C):
|
|
%2 = function_ref @$s14optimize_never4foo4ys5Int32VAD_AA1CCtF : $@convention(thin) (Int32, @owned C) -> Int32
|
|
%3 = integer_literal $Builtin.Int32, 1
|
|
%4 = struct $Int32 (%3 : $Builtin.Int32)
|
|
strong_retain %0 : $C
|
|
%6 = apply %2(%4, %0) : $@convention(thin) (Int32, @owned C) -> Int32
|
|
strong_release %0 : $C
|
|
return %6 : $Int32
|
|
}
|
|
|
|
sil hidden [Onone] @$s14optimize_never4BaseC3foos5Int32VyF : $@convention(method) (@guaranteed Base) -> Int32 {
|
|
bb0(%0 : $Base):
|
|
%2 = integer_literal $Builtin.Int32, 1
|
|
%3 = struct $Int32 (%2 : $Builtin.Int32)
|
|
return %3 : $Int32
|
|
}
|
|
|
|
sil hidden @$s14optimize_never4BaseC3boos5Int32VyF : $@convention(method) (@guaranteed Base) -> Int32 {
|
|
bb0(%0 : $Base):
|
|
%2 = integer_literal $Builtin.Int32, 2
|
|
%3 = struct $Int32 (%2 : $Builtin.Int32)
|
|
return %3 : $Int32
|
|
}
|
|
sil hidden @$s14optimize_never8Derived1C3foos5Int32VyF : $@convention(method) (@guaranteed Derived1) -> Int32 {
|
|
bb0(%0 : $Derived1):
|
|
%2 = integer_literal $Builtin.Int32, 3
|
|
%3 = struct $Int32 (%2 : $Builtin.Int32)
|
|
return %3 : $Int32
|
|
}
|
|
|
|
sil hidden [Onone] @$s14optimize_never8Derived1C3boos5Int32VyF : $@convention(method) (@guaranteed Derived1) -> Int32 {
|
|
bb0(%0 : $Derived1):
|
|
%2 = integer_literal $Builtin.Int32, 4
|
|
%3 = struct $Int32 (%2 : $Builtin.Int32)
|
|
return %3 : $Int32
|
|
}
|
|
|
|
sil hidden @$s14optimize_never8Derived2C3foos5Int32VyF : $@convention(method) (@guaranteed Derived2) -> Int32 {
|
|
bb0(%0 : $Derived2):
|
|
%2 = integer_literal $Builtin.Int32, 5
|
|
%3 = struct $Int32 (%2 : $Builtin.Int32)
|
|
return %3 : $Int32
|
|
}
|
|
|
|
sil hidden @$s14optimize_never8Derived2C3boos5Int32VyF : $@convention(method) (@guaranteed Derived2) -> Int32 {
|
|
bb0(%0 : $Derived2):
|
|
%2 = integer_literal $Builtin.Int32, 6
|
|
%3 = struct $Int32 (%2 : $Builtin.Int32)
|
|
return %3 : $Int32
|
|
}
|
|
|
|
// Check that class_method is not speculatively devirtualized, because the
|
|
// method foo in the class Base, which mentioned in the class_method
|
|
// instruction is marked with @_optimize(none).
|
|
//
|
|
// CHECK-LABEL: sil @$s14optimize_never19testDoNotDevirtBase1os5Int32VAA0G0C_tF
|
|
// CHECK: bb0
|
|
// CHECK-NOT: checked_cast_br
|
|
// CHECK: class_method {{%[0-9]+}} : $Base, #Base.foo : (Base) -> () -> Int32
|
|
// CHECK-NOT: checked_cast_br
|
|
// CHECK: return
|
|
sil @$s14optimize_never19testDoNotDevirtBase1os5Int32VAA0G0C_tF : $@convention(thin) (@owned Base) -> Int32 {
|
|
bb0(%0 : $Base):
|
|
%2 = class_method %0 : $Base, #Base.foo : (Base) -> () -> Int32, $@convention(method) (@guaranteed Base) -> Int32
|
|
%3 = apply %2(%0) : $@convention(method) (@guaranteed Base) -> Int32
|
|
strong_release %0 : $Base
|
|
return %3 : $Int32
|
|
}
|
|
|
|
// Check that Derived1.boo is not devirtualized, because this method
|
|
// is marked with @_optimize(none) and thus should not
|
|
// participate in speculative devirtualization.
|
|
//
|
|
// CHECK-LABEL: sil @$s14optimize_never23testDoNotDevirtDerived11os5Int32VAA4BaseC_tF
|
|
// CHECK: bb0
|
|
// This used to check speculative-devirtualization, which we don't have anymore.
|
|
// CHECK: class_method {{%[0-9]+}} : $Base, #Base.boo : (Base) -> () -> Int32
|
|
// CHECK: }
|
|
sil @$s14optimize_never23testDoNotDevirtDerived11os5Int32VAA4BaseC_tF : $@convention(thin) (@owned Base) -> Int32 {
|
|
bb0(%0 : $Base):
|
|
%2 = class_method %0 : $Base, #Base.boo : (Base) -> () -> Int32, $@convention(method) (@guaranteed Base) -> Int32
|
|
%3 = apply %2(%0) : $@convention(method) (@guaranteed Base) -> Int32
|
|
strong_release %0 : $Base
|
|
return %3 : $Int32
|
|
}
|
|
|
|
sil_vtable C {
|
|
#C.foo: @$s14optimize_never1CC3foos5Int32VyF
|
|
#C.init!initializer: @$s14optimize_never1CCACycfc
|
|
#C.deinit!deallocator: @$s14optimize_never1CCfD
|
|
}
|
|
|
|
sil_vtable D {
|
|
#C.foo: @$s14optimize_never1DC3foos5Int32VyF [override]
|
|
#C.init!initializer: @$s14optimize_never1DCACycfc [override]
|
|
#D.deinit!deallocator: @$s14optimize_never1DCfD
|
|
}
|
|
|
|
sil_vtable Base {
|
|
#Base.foo: @$s14optimize_never4BaseC3foos5Int32VyF
|
|
#Base.boo: @$s14optimize_never4BaseC3boos5Int32VyF
|
|
}
|
|
|
|
sil_vtable Derived1 {
|
|
#Base.foo: @$s14optimize_never8Derived1C3foos5Int32VyF [override]
|
|
#Base.boo: @$s14optimize_never8Derived1C3boos5Int32VyF [override]
|
|
}
|
|
|
|
sil_vtable Derived2 {
|
|
#Base.foo: @$s14optimize_never8Derived2C3foos5Int32VyF [override]
|
|
#Base.boo: @$s14optimize_never8Derived2C3boos5Int32VyF [override]
|
|
}
|
|
|