| // 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] |
| } |