File: arcsequenceopts_uniquecheck.sil

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 (133 lines) | stat: -rw-r--r-- 4,397 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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// RUN: %target-sil-opt -enable-sil-verify-all -enable-loop-arc=0 -arc-sequence-opts %s | %FileCheck %s
// RUN: %target-sil-opt -enable-sil-verify-all -enable-loop-arc=1 -arc-sequence-opts %s | %FileCheck %s

import Builtin
import Swift
import SwiftShims

class MD5 {
  init()
  final var w: [UInt32]
}

// CHECK-LABEL:sil @test_unique_check_arc : $@convention(method) (@owned MD5) -> ()
sil @test_unique_check_arc : $@convention(method) (@owned MD5) -> () {
// CHECK: bb0
bb0(%0 : $MD5):
  %1 = integer_literal $Builtin.Int32, 0
  %2 = integer_literal $Builtin.Int32, 16
  %3 = struct $Int32 (%1 : $Builtin.Int32)
  br bb1(%1 : $Builtin.Int32)

// CHECK: bb1
bb1(%5 : $Builtin.Int32):
  %7 = builtin "cmp_eq_Int32"(%5 : $Builtin.Int32, %2 : $Builtin.Int32) : $Builtin.Int1
  cond_br %7, bb3, bb2

// CHECK: bb2
bb2:
  %9 = integer_literal $Builtin.Int32, 1
  %11 = integer_literal $Builtin.Int1, -1
  %12 = builtin "sadd_with_overflow_Int32"(%5 : $Builtin.Int32, %9 : $Builtin.Int32, %11 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
  %13 = tuple_extract %12 : $(Builtin.Int32, Builtin.Int1), 0
  // CHECK-NOT: strong_retain
  // CHECK-NOT: strong_release
  strong_retain %0 : $MD5
  %314 = ref_element_addr %0 : $MD5, #MD5.w
  %318 = load %314 : $*Array<UInt32>
  %319 = alloc_stack $Array<UInt32>
  store %318 to %319 : $*Array<UInt32>
  dealloc_stack %319 : $*Array<UInt32>
  %179 = is_unique %314 : $*Array<UInt32>
  cond_br %179, bb4, bb5

// CHECK: bb3
// CHECK-NEXT: strong_release
// CHECK-NEXT: tuple
// CHECK-NEXT: return
bb3:
  strong_release %0 : $MD5
  %273 = tuple ()
  return %273 : $()

bb4:
  br bb6

bb5:
  br bb6

// CHECK-NOT: strong_release
bb6:
  strong_release %0 : $MD5
  br bb1(%13 : $Builtin.Int32)

}

class C {}

// Check that retains are not moved across an is_unique that may alias.
sil @test_uniq_alias : $@convention(method) (@owned C) -> Builtin.Int1 {
// CHECK: bb0
bb0(%0 : $C):
  %1 = alloc_stack $C, var, name "x"
  store %0 to %1 : $*C
// CHECK: strong_retain %0 : $C
  strong_retain %0 : $C
// CHECK: is_unique %1 : $*C
  %4 = is_unique %1 : $*C
// CHECK-NOT: strong_retain
  fix_lifetime %0 : $C
// CHECK: strong_release %0 : $C
  strong_release %0 : $C
// CHECK: [[LOADED:%[0-9]+]] = load %1 : $*C
  %8 = load %1 : $*C
// CHECK: strong_release [[LOADED]] : $C
  strong_release %8 : $C
  dealloc_stack %1 : $*C
  return %4 : $Builtin.Int1
}

// The following test could optimize to:
//  %2 = load %1 : $*C                              // user: %4
//  %3 = is_unique %0 : $*C                         // user: %5
//  fix_lifetime %2 : $C                            // id: %4
//
// But ARC is currently conservative. When this is fixed,
// change _CHECK: strong... into _CHECK_NOT: strong...
sil @test_uniq_noalias : $@convention(thin) (@inout C, @inout C) -> Builtin.Int1 {
// CHECK: bb0
bb0(%0 : $*C, %1 : $*C):
  %2 = load %1 : $*C
// CHECK: strong_retain %2 : $C
  strong_retain %2 : $C
// CHECK: is_unique %0 : $*C
  %4 = is_unique %0 : $*C
  fix_lifetime %2 : $C
// CHECK: strong_release %2 : $C
  strong_release %2 : $C
  return %4 : $Builtin.Int1
}

// Similarly, do not remove a retain/release pair that spans an
// is_escaping_closure instruction. This would fail to catch closures
// that are returned from the function.
// <rdar://problem/52803634>

// thunk for @callee_guaranteed () -> ()
sil shared [transparent] [serialized] [reabstraction_thunk] [without_actually_escaping] @$sIg_Ieg_TR : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () {
bb0(%0 : $@noescape @callee_guaranteed () -> ()):
  %1 = apply %0() : $@noescape @callee_guaranteed () -> ()
  return %1 : $()
}

sil hidden [noinline] @testEscapingClosure : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> @owned @callee_guaranteed () -> () {
bb0(%0 : $@noescape @callee_guaranteed () -> ()):
  %1 = function_ref @$sIg_Ieg_TR : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
  %2 = partial_apply [callee_guaranteed] %1(%0) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
  %3 = mark_dependence %2 : $@callee_guaranteed () -> () on %0 : $@noescape @callee_guaranteed () -> ()
  strong_retain %3 : $@callee_guaranteed () -> ()
  %5 = is_escaping_closure %3 : $@callee_guaranteed () -> ()
  strong_release %3 : $@callee_guaranteed () -> ()
  cond_fail %5 : $Builtin.Int1
  return %3 : $@callee_guaranteed () -> ()
}