Files
swift-mirror/test/ModuleInterface/Conformances.swiftinterface
Erik Eckstein 21b4004d69 Devirtualizer: don't de-virtualize witness calls to non-generic thunks which call a generic function.
If the callee is a non-generic thunk which calls a (not inlinable) generic function in the defining module,
it's more efficient to not devirtualize, but call the non-generic thunk - even though it's done through the witness table.
Example:
```
  protocol P {
    func f(x: [Int])   // not generic
  }
  struct S: P {
    func f(x: some RandomAccessCollection<Int>) { ... } // generic
  }
```

In the defining module, the generic conformance can be fully specialized (which is not possible in the client module, because it's not inlinable).

rdar://102623022
2022-12-21 08:52:53 +01:00

69 lines
2.8 KiB
Plaintext

// swift-compiler-version: Swift 4.0
// swift-module-flags:
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -emit-module-path %t/Conformances.swiftmodule -enable-library-evolution -emit-sil -o %t/Conformances.sil -enable-objc-interop -disable-objc-attr-requires-foundation-module %s
// RUN: %target-swift-frontend -enable-objc-interop -emit-sil -I %t %S/Inputs/ConformancesUser.swift -O | %FileCheck %s
public protocol MyProto {
init()
func method()
var prop: Int { get set }
subscript(index: Int) -> Int { get set }
}
extension MyProto {
public func method() {}
}
// Make sure there's no default witness table. (But also make sure we printed at
// least some regular witness tables, or we'll have to change the test.)
// CHECK-MODULE: sil_witness_table{{.+}}: MyProto module Conformances
// NEGATIVE-MODULE-NOT: sil_default_witness_table{{.+}}MyProto
@frozen // allow conformance devirtualization
public struct FullStructImpl: MyProto {
public init()
public func method()
public var prop: Int { get set }
public subscript(index: Int) -> Int { get set }
}
// CHECK-LABEL: sil @$s16ConformancesUser8testFullSiyF
// CHECK: function_ref @$s12Conformances14FullStructImplVACycfC
// CHECK: function_ref @$s12Conformances14FullStructImplV6methodyyF
// CHECK: function_ref @$s12Conformances14FullStructImplV4propSivs
// CHECK: function_ref @$s12Conformances14FullStructImplVyS2icig
// CHECK: end sil function '$s16ConformancesUser8testFullSiyF'
@frozen // allow conformance devirtualization
public struct OpaqueStructImpl: MyProto {}
// CHECK-LABEL: sil @$s16ConformancesUser10testOpaqueSiyF
// CHECK: witness_method $OpaqueStructImpl, #MyProto.init!allocator
// Note the default implementation is filled in here.
// CHECK: witness_method $OpaqueStructImpl, #MyProto.method
// CHECK: witness_method $OpaqueStructImpl, #MyProto.prop!setter
// CHECK: witness_method $OpaqueStructImpl, #MyProto.subscript!getter
// CHECK: end sil function '$s16ConformancesUser10testOpaqueSiyF'
@objc public protocol OptionalReqs {
@objc optional func method()
}
@_fixed_layout
public final class OptionalReqsPresent: OptionalReqs {
public func method () {}
}
@_fixed_layout
public final class OptionalReqsAbsent: OptionalReqs {}
// It would be okay if this one got optimized...
// CHECK-LABEL: sil @$s16ConformancesUser19testOptionalPresentySb0A00d4ReqsE0CF
// CHECK: dynamic_method_br %0 : $OptionalReqsPresent, #OptionalReqs.method!foreign
// CHECK: end sil function '$s16ConformancesUser19testOptionalPresentySb0A00d4ReqsE0CF'
// ...but not this one, because the method that's currently absent might get added.
// CHECK-LABEL: sil @$s16ConformancesUser18testOptionalAbsentySb0A00d4ReqsE0CF
// CHECK: dynamic_method_br %0 : $OptionalReqsAbsent, #OptionalReqs.method!foreign
// CHECK: end sil function '$s16ConformancesUser18testOptionalAbsentySb0A00d4ReqsE0CF'