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