mirror of
https://github.com/apple/swift.git
synced 2026-06-27 12:25:55 +02:00
70938b1aee
Add back a stand-alone devirtualizer pass, running prior to generic specialization. As with the stand-alone generic specializer pass, this may add functions to the pass manager's work list. This is another step in unbundling these passes from the performance inliner.
91 lines
2.6 KiB
Plaintext
91 lines
2.6 KiB
Plaintext
// RUN: %target-sil-opt -enable-sil-verify-all %s -devirtualizer -dce | FileCheck %s
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
class Bar {
|
|
init()
|
|
func ping()
|
|
}
|
|
|
|
class Foo : Bar {
|
|
override init()
|
|
override func ping()
|
|
}
|
|
|
|
sil_global @x : $Bar
|
|
|
|
// CHECK-LABEL: sil @function_with_cm_with_cast
|
|
// CHECK-NOT: class_method
|
|
// CHECK: [[REF:%.*]] = function_ref @_TFC4main3Bar4pingfS0_FT_T_
|
|
// CHECK: [[SELF:%.*]] = upcast
|
|
// CHECK: apply [[REF]]([[SELF]])
|
|
// CHECK: return
|
|
sil @function_with_cm_with_cast : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = global_addr @x : $*Bar // users: %7, %8
|
|
%1 = alloc_ref $Foo // users: %5, %3, %2
|
|
strong_retain %1 : $Foo // id: %2
|
|
%3 = upcast %1 : $Foo to $Bar // user: %4
|
|
%4 = unconditional_checked_cast %3 : $Bar to $Foo // user: %6
|
|
strong_release %1 : $Foo // id: %5
|
|
%6 = upcast %4 : $Foo to $Bar // user: %7
|
|
store %6 to %0 : $*Bar // id: %7
|
|
%8 = load %0 : $*Bar // users: %11, %10, %9
|
|
strong_retain %6 : $Bar // id: %9
|
|
%10 = class_method %6 : $Bar, #Bar.ping!1 : Bar -> () -> () , $@convention(method) (@guaranteed Bar) -> () // user: %11
|
|
%11 = apply %10(%8) : $@convention(method) (@guaranteed Bar) -> ()
|
|
%12 = tuple () // user: %13
|
|
return %12 : $() // id: %13
|
|
}
|
|
|
|
// CHECK-LABEL: sil @function_with_cm_with_dynamic_type_known_from_checked_cast_br
|
|
// CHECK-NOT: class_method
|
|
// CHECK: bb1([[SELF:%.*]] : $Bar):
|
|
// CHECK: [[REF:%.*]] = function_ref @_TFC4main3Bar4pingfS0_FT_T_
|
|
// CHECK: apply [[REF]]([[SELF]])
|
|
// CHECK: return
|
|
sil @function_with_cm_with_dynamic_type_known_from_checked_cast_br : $@convention(thin) (Bar) -> () {
|
|
bb0(%0 : $Bar):
|
|
checked_cast_br [exact] %0 : $Bar to $Bar, bb1, bb5
|
|
|
|
bb1(%1 : $Bar):
|
|
br bb2(%1 : $Bar)
|
|
|
|
bb2(%2 : $Bar):
|
|
br bb3(%2 : $Bar)
|
|
|
|
bb3(%3 : $Bar):
|
|
br bb4(%3 : $Bar)
|
|
|
|
bb4(%4 : $Bar):
|
|
// Devirtualizer should be able to figure out that the exact dynamic type of %1 is Bar.
|
|
%5 = class_method %4 : $Bar, #Bar.ping!1 : Bar -> () -> () , $@convention(method) (@guaranteed Bar) -> ()
|
|
%6 = apply %5(%4) : $@convention(method) (@guaranteed Bar) -> ()
|
|
br bb6
|
|
|
|
bb5:
|
|
br bb6
|
|
|
|
bb6:
|
|
%7 = tuple ()
|
|
return %7 : $()
|
|
}
|
|
|
|
|
|
sil @_TFC4main3Bar4pingfS0_FT_T_ : $@convention(method) (@guaranteed Bar) -> ()
|
|
sil @_TFC4main3Foo4pingfS0_FT_T_ : $@convention(method) (@guaranteed Foo) -> ()
|
|
|
|
sil_vtable Bar {
|
|
#Bar.ping!1: _TFC4main3Bar4pingfS0_FT_T_
|
|
}
|
|
|
|
sil_vtable Foo {
|
|
#Foo.ping!1: _TFC4main3Foo4pingfS0_FT_T_
|
|
}
|
|
|
|
|
|
|