// RUN: %target-sil-opt -enable-sil-verify-all %/s -devirtualizer -dce -save-optimization-record-path=%t.yaml | %FileCheck %s // RUN: %FileCheck -check-prefix=YAML -input-file=%t.yaml %s sil_stage canonical import Builtin import Swift class Bar { init() func foo() } sil_global @x : $Bar //CHECK: function_with_cm //CHECK: function_ref @_TFC4main3Bar3foofS0_FT_T_ //CHECK-NEXT: apply //CHECK-NOT: class_method //CHECK: return // YAML: --- !Passed // YAML-NEXT: Pass: sil-devirtualizer // YAML-NEXT: Name: sil.ClassMethodDevirtualized // YAML-NEXT: DebugLoc: // YAML: File: {{.*}}/devirtualize.sil // YAML: Line: 47 // YAML: Column: 8 // YAML-NEXT: Function: function_with_cm // YAML-NEXT: Args: // YAML-NEXT: - String: 'Devirtualized call to class method ' // YAML-NEXT: - Method: '"main.Bar.foo(_:)"' // YAML-NEXT: DebugLoc: // YAML: File: {{.*}}/devirtualize.sil // YAML: Line: 53 // YAML: Column: 6 // YAML-NEXT: ... sil @function_with_cm : $@convention(thin) () -> () { bb0: %0 = global_addr @x : $*Bar // users: %2, %3 %1 = alloc_ref $Bar // user: %2 store %1 to %0 : $*Bar // id: %2 %3 = load %0 : $*Bar // users: %6, %5, %4 %5 = class_method %1 : $Bar, #Bar.foo : (Bar) -> () -> (), $@convention(method) (@guaranteed Bar) -> () // user: %6 %6 = apply %5(%1) : $@convention(method) (@guaranteed Bar) -> () release_value %1 : $Bar %7 = tuple () // user: %8 return %7 : $() // id: %8 } sil @_TFC4main3Bar3foofS0_FT_T_ : $@convention(method) (@guaranteed Bar) -> () sil_vtable Bar { #Bar.foo: @_TFC4main3Bar3foofS0_FT_T_ } private class Node { @_hasStorage var index: Int { get set } init(index: Int) deinit } // CHECK-LABEL: sil private @class_method_apply sil private @class_method_apply : $@convention(method) (@guaranteed Node) -> Int { bb0(%0 : $Node): // CHECK: strong_retain %0 strong_retain %0 : $Node // CHECK-NOT: class_method %0 // CHECK: [[FUNC:%.*]] = function_ref @transparent_target %3 = class_method %0 : $Node, #Node.index!getter : (Node) -> () -> Int, $@convention(method) (@guaranteed Node) -> Int // CHECK: [[RESULT:%.*]] = apply [[FUNC]](%0) %4 = apply %3(%0) : $@convention(method) (@guaranteed Node) -> Int // CHECK: strong_release %0 strong_release %0 : $Node // return [[RESULT]] return %4 : $Int } // YAML-NEXT: --- !Passed // YAML-NEXT: Pass: sil-devirtualizer // YAML-NEXT: Name: sil.ClassMethodDevirtualized // YAML-NEXT: DebugLoc: // YAML: File: {{.*}}/devirtualize.sil // YAML: Line: 74 // YAML: Column: 8 // YAML-NEXT: Function: class_method_apply // YAML-NEXT: Args: // YAML-NEXT: - String: 'Devirtualized call to class method ' // YAML-NEXT: - Method: '"transparent_target"' // YAML-NEXT: DebugLoc: // YAML: File: {{.*}}/devirtualize.sil // YAML: Line: 100 // YAML: Column: 39 // YAML-NEXT: ... // CHECK-LABEL: sil private [transparent] [noinline] @transparent_target sil private [transparent] [noinline] @transparent_target : $@convention(method) (@guaranteed Node) -> Int { bb0(%0 : $Node): %2 = ref_element_addr %0 : $Node, #Node.index %3 = load %2 : $*Int // CHECK: return return %3 : $Int } sil_vtable Node { #Node.index!getter: @transparent_target } private class B { class func foo() -> Int } private class C : B { } sil @_TZFC4metaP33_7026FC13D35FB9700BACF693F51A99011B3foofMS0_FT_Si : $@convention(method) (@thick B.Type) -> Int // CHECK-LABEL: sil private [noinline] @_TF4metaP33_7026FC13D35FB9700BACF693F51A99016callerFMCS_P33_7026FC13D35FB9700BACF693F51A99011CT_ sil private [noinline] @_TF4metaP33_7026FC13D35FB9700BACF693F51A99016callerFMCS_P33_7026FC13D35FB9700BACF693F51A99011CT_ : $@convention(method) (@thick C.Type) -> () { bb0(%0 : $@thick C.Type): %2 = upcast %0 : $@thick C.Type to $@thick B.Type // CHECK-NOT: class_method // CHECK: function_ref @_TZFC4metaP33_7026FC13D35FB9700BACF693F51A99011B3foofMS0_FT_Si %3 = class_method %2 : $@thick B.Type, #B.foo : (B.Type) -> () -> Int, $@convention(method) (@thick B.Type) -> Int %4 = apply %3(%2) : $@convention(method) (@thick B.Type) -> Int %5 = tuple () // CHECK: return return %5 : $() } // YAML-NEXT: --- !Passed // YAML-NEXT: Pass: sil-devirtualizer // YAML-NEXT: Name: sil.ClassMethodDevirtualized // YAML-NEXT: DebugLoc: // YAML: File: {{.*}}/devirtualize.sil // YAML: Line: 127 // YAML: Column: 8 // YAML-NEXT: Function: 'caller(_:)' // YAML-NEXT: Args: // YAML-NEXT: - String: 'Devirtualized call to class method ' // YAML-NEXT: - Method: '"static meta.B.foo(_:)"' // YAML-NEXT: DebugLoc: // YAML: File: {{.*}}/devirtualize.sil // YAML: Line: 118 // YAML: Column: 6 // YAML-NEXT: ... sil_vtable B { #B.foo: @_TZFC4metaP33_7026FC13D35FB9700BACF693F51A99011B3foofMS0_FT_Si } sil_vtable C { #B.foo: @_TZFC4metaP33_7026FC13D35FB9700BACF693F51A99011B3foofMS0_FT_Si [inherited] }