File: devirt_specialized_conformance.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (76 lines) | stat: -rw-r--r-- 2,247 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// RUN: %target-swift-frontend -O -Xllvm -sil-inline-generics=false -Xllvm -sil-disable-pass=ObjectOutliner %s -emit-sil -sil-verify-all | %FileCheck %s

// Make sure that we completely inline/devirtualize/substitute all the way down
// to unknown1.

// CHECK-LABEL: sil {{.*}}@main
// CHECK: bb0({{.*}}):
// CHECK: function_ref @unknown1
// CHECK: apply
// CHECK: apply
// CHECK: return

struct Int32 {}

@_silgen_name("unknown1")
func unknown1() -> ()

protocol P {
  func doSomething(_ x : Int32)
}

struct X {}

class B<T> : P {
  func doSomething(_ x : Int32) {
     unknown1()
   }
 }

func doSomething(_ p : P, _ x : Int32) {
  p.doSomething(x)
}
func doSomething2<T : P>(_ t : T, _ x : Int32) {
  t.doSomething(x)
}

func driver() {
  var b2 = B<X>()
  var x = Int32()
  doSomething(b2, x)
  doSomething2(b2, x)
}

driver()

// <rdar://problem/46322928> Failure to devirtualize a protocol method
// applied to an opened existential blocks implementation of
// DataProtocol.
public protocol ContiguousBytes {
    func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R
}

extension Array : ContiguousBytes {}
extension ContiguousArray : ContiguousBytes {}

@inline(never)
func takesPointer(_ p: UnsafeRawBufferPointer) {}

// In specialized testWithUnsafeBytes<A>(_:), the conditional case and call to withUnsafeBytes must be eliminated.
// Normally, we expect Array.withUnsafeBytes to be inlined so we would see:
//   [[TAKES_PTR:%.*]] = function_ref @$s30devirt_specialized_conformance12takesPointeryySWF : $@convention(thin) (UnsafeRawBufferPointer) -> ()
//   apply [[TAKES_PTR]](%{{.*}}) : $@convention(thin) (UnsafeRawBufferPointer) -> ()
// But the inlining isn't consistent across builds with and without debug info.
//
// CHECK-LABEL: sil shared [noinline] @$s30devirt_specialized_conformance19testWithUnsafeBytesyyxlFSayypG_Tg5 : $@convention(thin) (@guaranteed Array<Any>) -> () {
// CHECK: bb0
// CHECK-NOT: witness_method
// CHECK-LABEL: } // end sil function '$s30devirt_specialized_conformance19testWithUnsafeBytesyyxlFSayypG_Tg5'
@inline(never)
func testWithUnsafeBytes<T>(_ t: T) {
  if let cb = t as? ContiguousBytes {
    cb.withUnsafeBytes { takesPointer($0) }
  }
}

testWithUnsafeBytes([])