• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt < %s -passes='cgscc(inline)' -inline-threshold=0 -S | FileCheck %s
2
3; The 'test1_' prefixed functions test the basic 'last callsite' inline
4; threshold adjustment where we specifically inline the last call site of an
5; internal function regardless of cost.
6
7define internal void @test1_f() {
8entry:
9  %p = alloca i32
10  store volatile i32 0, i32* %p
11  store volatile i32 0, i32* %p
12  store volatile i32 0, i32* %p
13  store volatile i32 0, i32* %p
14  store volatile i32 0, i32* %p
15  store volatile i32 0, i32* %p
16  store volatile i32 0, i32* %p
17  store volatile i32 0, i32* %p
18  ret void
19}
20
21; Identical to @test1_f but doesn't get inlined because there is more than one
22; call. If this *does* get inlined, the body used both here and in @test1_f
23; isn't a good test for different threshold based on the last call.
24define internal void @test1_g() {
25entry:
26  %p = alloca i32
27  store volatile i32 0, i32* %p
28  store volatile i32 0, i32* %p
29  store volatile i32 0, i32* %p
30  store volatile i32 0, i32* %p
31  store volatile i32 0, i32* %p
32  store volatile i32 0, i32* %p
33  store volatile i32 0, i32* %p
34  store volatile i32 0, i32* %p
35  ret void
36}
37
38define void @test1() {
39; CHECK-LABEL: define void @test1()
40entry:
41  call void @test1_f()
42; CHECK-NOT: @test1_f
43
44  call void @test1_g()
45  call void @test1_g()
46; CHECK: call void @test1_g()
47; CHECK: call void @test1_g()
48
49  ret void
50}
51
52
53; The 'test2_' prefixed functions test that we can discover the last callsite
54; bonus after having inlined the prior call site. For this to work, we need
55; a callsite dependent cost so we have a trivial predicate guarding all the
56; cost, and set that in a particular direction.
57
58define internal void @test2_f(i1 %b) {
59entry:
60  %p = alloca i32
61  br i1 %b, label %then, label %exit
62
63then:
64  store volatile i32 0, i32* %p
65  store volatile i32 0, i32* %p
66  store volatile i32 0, i32* %p
67  store volatile i32 0, i32* %p
68  store volatile i32 0, i32* %p
69  store volatile i32 0, i32* %p
70  store volatile i32 0, i32* %p
71  store volatile i32 0, i32* %p
72  br label %exit
73
74exit:
75  ret void
76}
77
78; Identical to @test2_f but doesn't get inlined because there is more than one
79; call. If this *does* get inlined, the body used both here and in @test2_f
80; isn't a good test for different threshold based on the last call.
81define internal void @test2_g(i1 %b) {
82entry:
83  %p = alloca i32
84  br i1 %b, label %then, label %exit
85
86then:
87  store volatile i32 0, i32* %p
88  store volatile i32 0, i32* %p
89  store volatile i32 0, i32* %p
90  store volatile i32 0, i32* %p
91  store volatile i32 0, i32* %p
92  store volatile i32 0, i32* %p
93  store volatile i32 0, i32* %p
94  store volatile i32 0, i32* %p
95  br label %exit
96
97exit:
98  ret void
99}
100
101define void @test2() {
102; CHECK-LABEL: define void @test2()
103entry:
104  ; The first call is trivial to inline due to the argument.
105  call void @test2_f(i1 false)
106; CHECK-NOT: @test2_f
107
108  ; The second call is too expensive to inline unless we update the number of
109  ; calls after inlining the second.
110  call void @test2_f(i1 true)
111; CHECK-NOT: @test2_f
112
113  ; Sanity check that two calls with the hard predicate remain uninlined.
114  call void @test2_g(i1 true)
115  call void @test2_g(i1 true)
116; CHECK: call void @test2_g(i1 true)
117; CHECK: call void @test2_g(i1 true)
118
119  ret void
120}
121
122
123; The 'test3_' prefixed functions are similar to the 'test2_' functions but the
124; relative order of the trivial and hard to inline callsites is reversed. This
125; checks that the order of calls isn't significant to whether we observe the
126; "last callsite" threshold difference because the next-to-last gets inlined.
127; FIXME: We don't currently catch this case.
128
129define internal void @test3_f(i1 %b) {
130entry:
131  %p = alloca i32
132  br i1 %b, label %then, label %exit
133
134then:
135  store volatile i32 0, i32* %p
136  store volatile i32 0, i32* %p
137  store volatile i32 0, i32* %p
138  store volatile i32 0, i32* %p
139  store volatile i32 0, i32* %p
140  store volatile i32 0, i32* %p
141  store volatile i32 0, i32* %p
142  store volatile i32 0, i32* %p
143  br label %exit
144
145exit:
146  ret void
147}
148
149; Identical to @test3_f but doesn't get inlined because there is more than one
150; call. If this *does* get inlined, the body used both here and in @test3_f
151; isn't a good test for different threshold based on the last call.
152define internal void @test3_g(i1 %b) {
153entry:
154  %p = alloca i32
155  br i1 %b, label %then, label %exit
156
157then:
158  store volatile i32 0, i32* %p
159  store volatile i32 0, i32* %p
160  store volatile i32 0, i32* %p
161  store volatile i32 0, i32* %p
162  store volatile i32 0, i32* %p
163  store volatile i32 0, i32* %p
164  store volatile i32 0, i32* %p
165  store volatile i32 0, i32* %p
166  br label %exit
167
168exit:
169  ret void
170}
171
172define void @test3() {
173; CHECK-LABEL: define void @test3()
174entry:
175  ; The first call is too expensive to inline unless we update the number of
176  ; calls after inlining the second.
177  call void @test3_f(i1 true)
178; FIXME: We should inline this call without iteration.
179; CHECK: call void @test3_f(i1 true)
180
181  ; But the second call is trivial to inline due to the argument.
182  call void @test3_f(i1 false)
183; CHECK-NOT: @test3_f
184
185  ; Sanity check that two calls with the hard predicate remain uninlined.
186  call void @test3_g(i1 true)
187  call void @test3_g(i1 true)
188; CHECK: call void @test3_g(i1 true)
189; CHECK: call void @test3_g(i1 true)
190
191  ret void
192}
193
194
195; The 'test4_' prefixed functions are similar to the 'test2_' prefixed
196; functions but include unusual constant expressions that make discovering that
197; a function is dead harder.
198
199define internal void @test4_f(i1 %b) {
200entry:
201  %p = alloca i32
202  br i1 %b, label %then, label %exit
203
204then:
205  store volatile i32 0, i32* %p
206  store volatile i32 0, i32* %p
207  store volatile i32 0, i32* %p
208  store volatile i32 0, i32* %p
209  store volatile i32 0, i32* %p
210  store volatile i32 0, i32* %p
211  store volatile i32 0, i32* %p
212  store volatile i32 0, i32* %p
213  br label %exit
214
215exit:
216  ret void
217}
218
219; Identical to @test4_f but doesn't get inlined because there is more than one
220; call. If this *does* get inlined, the body used both here and in @test4_f
221; isn't a good test for different threshold based on the last call.
222define internal void @test4_g(i1 %b) {
223entry:
224  %p = alloca i32
225  br i1 %b, label %then, label %exit
226
227then:
228  store volatile i32 0, i32* %p
229  store volatile i32 0, i32* %p
230  store volatile i32 0, i32* %p
231  store volatile i32 0, i32* %p
232  store volatile i32 0, i32* %p
233  store volatile i32 0, i32* %p
234  store volatile i32 0, i32* %p
235  store volatile i32 0, i32* %p
236  br label %exit
237
238exit:
239  ret void
240}
241
242define void @test4() {
243; CHECK-LABEL: define void @test4()
244entry:
245  ; The first call is trivial to inline due to the argument. However this
246  ; argument also uses the function being called as part of a complex
247  ; constant expression. Merely inlining and deleting the call isn't enough to
248  ; drop the use count here, we need to GC the dead constant expression as
249  ; well.
250  call void @test4_f(i1 icmp ne (i64 ptrtoint (void (i1)* @test4_f to i64), i64 ptrtoint(void (i1)* @test4_f to i64)))
251; CHECK-NOT: @test4_f
252
253  ; The second call is too expensive to inline unless we update the number of
254  ; calls after inlining the second.
255  call void @test4_f(i1 true)
256; CHECK-NOT: @test4_f
257
258  ; And check that a single call to a function which is used by a complex
259  ; constant expression cannot be inlined because the constant expression forms
260  ; a second use. If this part starts failing we need to use more complex
261  ; constant expressions to reference a particular function with them.
262  %sink = alloca i1
263  store volatile i1 icmp ne (i64 ptrtoint (void (i1)* @test4_g to i64), i64 ptrtoint(void (i1)* @test4_g to i64)), i1* %sink
264  call void @test4_g(i1 true)
265; CHECK: store volatile i1 false
266; CHECK: call void @test4_g(i1 true)
267
268  ret void
269}
270