brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.6 KiB · ce800b6 Raw
273 lines · plain
1; RUN: opt < %s -passes='cgscc(inline)' -inline-threshold=0 -S | FileCheck %s2 3; The 'test1_' prefixed functions test the basic 'last callsite' inline4; threshold adjustment where we specifically inline the last call site of an5; internal function regardless of cost.6 7define internal void @test1_f() {8entry:9  %p = alloca i3210  store volatile i32 0, ptr %p11  store volatile i32 0, ptr %p12  store volatile i32 0, ptr %p13  store volatile i32 0, ptr %p14  store volatile i32 0, ptr %p15  store volatile i32 0, ptr %p16  store volatile i32 0, ptr %p17  store volatile i32 0, ptr %p18  ret void19}20 21; Identical to @test1_f but doesn't get inlined because there is more than one22; call. If this *does* get inlined, the body used both here and in @test1_f23; isn't a good test for different threshold based on the last call.24define internal void @test1_g() {25entry:26  %p = alloca i3227  store volatile i32 0, ptr %p28  store volatile i32 0, ptr %p29  store volatile i32 0, ptr %p30  store volatile i32 0, ptr %p31  store volatile i32 0, ptr %p32  store volatile i32 0, ptr %p33  store volatile i32 0, ptr %p34  store volatile i32 0, ptr %p35  ret void36}37 38define void @test1() {39; CHECK-LABEL: define void @test1()40entry:41  call void @test1_f()42; CHECK-NOT: @test1_f43 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 void50}51 52 53; The 'test2_' prefixed functions test that we can discover the last callsite54; bonus after having inlined the prior call site. For this to work, we need55; a callsite dependent cost so we have a trivial predicate guarding all the56; cost, and set that in a particular direction.57 58define internal void @test2_f(i1 %b) {59entry:60  %p = alloca i3261  br i1 %b, label %then, label %exit62 63then:64  store volatile i32 0, ptr %p65  store volatile i32 0, ptr %p66  store volatile i32 0, ptr %p67  store volatile i32 0, ptr %p68  store volatile i32 0, ptr %p69  store volatile i32 0, ptr %p70  store volatile i32 0, ptr %p71  store volatile i32 0, ptr %p72  br label %exit73 74exit:75  ret void76}77 78; Identical to @test2_f but doesn't get inlined because there is more than one79; call. If this *does* get inlined, the body used both here and in @test2_f80; isn't a good test for different threshold based on the last call.81define internal void @test2_g(i1 %b) {82entry:83  %p = alloca i3284  br i1 %b, label %then, label %exit85 86then:87  store volatile i32 0, ptr %p88  store volatile i32 0, ptr %p89  store volatile i32 0, ptr %p90  store volatile i32 0, ptr %p91  store volatile i32 0, ptr %p92  store volatile i32 0, ptr %p93  store volatile i32 0, ptr %p94  store volatile i32 0, ptr %p95  br label %exit96 97exit:98  ret void99}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_f107 108  ; The second call is too expensive to inline unless we update the number of109  ; calls after inlining the second.110  call void @test2_f(i1 true)111; CHECK-NOT: @test2_f112 113  ; 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 void120}121 122 123; The 'test3_' prefixed functions are similar to the 'test2_' functions but the124; relative order of the trivial and hard to inline callsites is reversed. This125; checks that the order of calls isn't significant to whether we observe the126; "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 i32132  br i1 %b, label %then, label %exit133 134then:135  store volatile i32 0, ptr %p136  store volatile i32 0, ptr %p137  store volatile i32 0, ptr %p138  store volatile i32 0, ptr %p139  store volatile i32 0, ptr %p140  store volatile i32 0, ptr %p141  store volatile i32 0, ptr %p142  store volatile i32 0, ptr %p143  br label %exit144 145exit:146  ret void147}148 149; Identical to @test3_f but doesn't get inlined because there is more than one150; call. If this *does* get inlined, the body used both here and in @test3_f151; isn't a good test for different threshold based on the last call.152define internal void @test3_g(i1 %b) {153entry:154  %p = alloca i32155  br i1 %b, label %then, label %exit156 157then:158  store volatile i32 0, ptr %p159  store volatile i32 0, ptr %p160  store volatile i32 0, ptr %p161  store volatile i32 0, ptr %p162  store volatile i32 0, ptr %p163  store volatile i32 0, ptr %p164  store volatile i32 0, ptr %p165  store volatile i32 0, ptr %p166  br label %exit167 168exit:169  ret void170}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 of176  ; 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_f184 185  ; 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 void192}193 194 195; The 'test4_' prefixed functions are similar to the 'test2_' prefixed196; functions but include unusual constant expressions that make discovering that197; a function is dead harder.198 199define internal void @test4_f(i64 %a, i64 %b) {200entry:201  %p = alloca i32202  %cmp = icmp ne i64 %a, %b203  br i1 %cmp, label %then, label %exit204 205then:206  store volatile i32 0, ptr %p207  store volatile i32 0, ptr %p208  store volatile i32 0, ptr %p209  store volatile i32 0, ptr %p210  store volatile i32 0, ptr %p211  store volatile i32 0, ptr %p212  store volatile i32 0, ptr %p213  store volatile i32 0, ptr %p214  br label %exit215 216exit:217  ret void218}219 220; Identical to @test4_f but doesn't get inlined because there is more than one221; call. If this *does* get inlined, the body used both here and in @test4_f222; isn't a good test for different threshold based on the last call.223define internal void @test4_g(i1 %b) {224entry:225  %p = alloca i32226  br i1 %b, label %then, label %exit227 228then:229  store volatile i32 0, ptr %p230  store volatile i32 0, ptr %p231  store volatile i32 0, ptr %p232  store volatile i32 0, ptr %p233  store volatile i32 0, ptr %p234  store volatile i32 0, ptr %p235  store volatile i32 0, ptr %p236  store volatile i32 0, ptr %p237  br label %exit238 239exit:240  ret void241}242 243define void @test4() {244; CHECK-LABEL: define void @test4()245entry:246  ; The first call is trivial to inline due to the argument. However this247  ; argument also uses the function being called as part of a complex248  ; constant expression. Merely inlining and deleting the call isn't enough to249  ; drop the use count here, we need to GC the dead constant expression as250  ; well.251  call void @test4_f(i64 ptrtoint (ptr @test4_f to i64), i64 ptrtoint(ptr @test4_f to i64))252; CHECK-NOT: @test4_f253 254  ; The second call is too expensive to inline unless we update the number of255  ; calls after inlining the second.256  call void @test4_f(i64 0, i64 1)257; CHECK-NOT: @test4_f258 259  ; And check that a single call to a function which is used by a complex260  ; constant expression cannot be inlined because the constant expression forms261  ; a second use. If this part starts failing we need to use more complex262  ; constant expressions to reference a particular function with them.263  %sink = alloca i64264  %mul = mul i64 ptrtoint (ptr @test4_g to i64), ptrtoint(ptr @test4_g to i64)265  store volatile i64 %mul, ptr %sink266  call void @test4_g(i1 true)267; CHECK: %mul = mul i64 ptrtoint (ptr @test4_g to i64), ptrtoint (ptr @test4_g to i64)268; CHECK: store volatile i64 %mul, ptr %sink269; CHECK: call void @test4_g(i1 true)270 271  ret void272}273