[Frontend] Remove unused includes (NFC) (#116927)
[llvm-project.git] / llvm / test / Analysis / CtxProfAnalysis / inline.ll
blob9381418c4e3f125d75da8c74023c324cd4887bad
1 ; RUN: rm -rf %t
2 ; RUN: split-file %s %t
3 ; RUN: llvm-ctxprof-util fromJSON --input=%t/profile.json --output=%t/profile.ctxprofdata
5 ; RUN: opt -passes='module-inline,print<ctx-prof-analysis>' -ctx-profile-printer-level=everything %t/module.ll -S \
6 ; RUN:   -use-ctx-profile=%t/profile.ctxprofdata -ctx-profile-printer-level=json \
7 ; RUN:   -o - 2> %t/profile-final.txt | FileCheck %s
8 ; RUN: %python %S/json_equals.py %t/profile-final.txt %t/expected.json
10 ; There are 2 calls to @a from @entrypoint. We only inline the one callsite
11 ; marked as alwaysinline, the rest are blocked (marked noinline). After the inline,
12 ; the updated contextual profile should still have the same tree for the non-inlined case.
13 ; For the inlined case, we should observe, for the @entrypoint context:
14 ;  - an empty callsite where the inlined one was (first one, i.e. 0)
15 ;  - more counters appended to the old counter list (because we ingested the
16 ;    ones from @a). The values are copied.
17 ;  - a new callsite to @b
18 ; CHECK-LABEL: @entrypoint
19 ; CHECK-LABEL: yes:
20 ; CHECK:         call void @llvm.instrprof.increment(ptr @entrypoint, i64 0, i32 3, i32 1)
21 ; CHECK-NEXT:    br label %loop.i
22 ; CHECK-LABEL:  loop.i:
23 ; CHECK-NEXT:    %indvar.i = phi i32 [ %indvar.next.i, %loop.i ], [ 0, %yes ]
24 ; CHECK-NEXT:    call void @llvm.instrprof.increment(ptr @entrypoint, i64 0, i32 2, i32 3)
25 ; CHECK-NEXT:    %b.i = add i32 %x, %indvar.i
26 ; CHECK-NEXT:    call void @llvm.instrprof.callsite(ptr @entrypoint, i64 0, i32 1, i32 2, ptr @b)
27 ; CHECK-NEXT:    %call3.i = call i32 @b() #1
28 ; CHECK-LABEL: no:
29 ; CHECK-NEXT:    call void @llvm.instrprof.increment(ptr @entrypoint, i64 0, i32 3, i32 2)
30 ; CHECK-NEXT:    call void @llvm.instrprof.callsite(ptr @entrypoint, i64 0, i32 2, i32 1, ptr @a)
31 ; CHECK-NEXT:    %call2 = call i32 @a(i32 %x) #1
32 ; CHECK-NEXT:    br label %exit
34 ; Make sure the postlink thinlto pipeline is aware of ctxprof
35 ; RUN: opt -passes='thinlto<O2>' -use-ctx-profile=%t/profile.ctxprofdata \
36 ; RUN:   %t/module.ll -S -o - | FileCheck %s --check-prefix=PIPELINE
38 ; PIPELINE-LABEL: define i32 @entrypoint
39 ; PIPELINE-SAME: !prof ![[ENTRYPOINT_COUNT:[0-9]+]]
40 ; PIPELINE-LABEL: loop.i:
41 ; PIPELINE:         br i1 %cond.i, label %loop.i, label %exit, !prof ![[LOOP_BW_INL:[0-9]+]]
42 ; PIPELINE-LABEL: define i32 @a
43 ; PIPELINE-LABEL: loop:
44 ; PIPELINE:         br i1 %cond, label %loop, label %exit, !prof ![[LOOP_BW_ORIG:[0-9]+]]
46 ; PIPELINE: ![[ENTRYPOINT_COUNT]] = !{!"function_entry_count", i64 10}
47 ; These are the weights of the inlined @a, where the counters were 2, 100 (2 for entry, 100 for loop)
48 ; PIPELINE: ![[LOOP_BW_INL]] = !{!"branch_weights", i32 98, i32 2}
49 ; These are the weights of the un-inlined @a, where the counters were 8, 500 (8 for entry, 500 for loop)
50 ; PIPELINE: ![[LOOP_BW_ORIG]] = !{!"branch_weights", i32 492, i32 8}
52 ;--- module.ll
53 define i32 @entrypoint(i32 %x) !guid !0 {
54   call void @llvm.instrprof.increment(ptr @entrypoint, i64 0, i32 3, i32 0)
55   %t = icmp eq i32 %x, 0
56   br i1 %t, label %yes, label %no
57 yes:
58   call void @llvm.instrprof.increment(ptr @entrypoint, i64 0, i32 3, i32 1)
59   call void @llvm.instrprof.callsite(ptr @entrypoint, i64 0, i32 2, i32 0, ptr @a)
60   %call1 = call i32 @a(i32 %x) alwaysinline
61   br label %exit
62 no:
63   call void @llvm.instrprof.increment(ptr @entrypoint, i64 0, i32 3, i32 2)
64   call void @llvm.instrprof.callsite(ptr @entrypoint, i64 0, i32 2, i32 1, ptr @a)
65   %call2 = call i32 @a(i32 %x) noinline
66   br label %exit
67 exit:
68   %ret = phi i32 [%call1, %yes], [%call2, %no]
69   ret i32 %ret
72 define i32 @a(i32 %x) !guid !1 {
73 entry:
74   call void @llvm.instrprof.increment(ptr @a, i64 0, i32 2, i32 0)
75   br label %loop
76 loop:
77   %indvar = phi i32 [%indvar.next, %loop], [0, %entry]
78   call void @llvm.instrprof.increment(ptr @a, i64 0, i32 2, i32 1)
79   %b = add i32 %x, %indvar
80   call void @llvm.instrprof.callsite(ptr @a, i64 0, i32 1, i32 0, ptr @b)
81   %call3 = call i32 @b() noinline
82   %indvar.next = add i32 %indvar, %call3
83   %cond = icmp slt i32 %indvar.next, %x
84   br i1 %cond, label %loop, label %exit
85 exit:
86   ret i32 8
89 define i32 @b() !guid !2 {
90   call void @llvm.instrprof.increment(ptr @b, i64 0, i32 1, i32 0)
91   ret i32 1
94 !0 = !{i64 1000}
95 !1 = !{i64 1001}
96 !2 = !{i64 1002}
97 ;--- profile.json
99   { "Guid": 1000,
100     "Counters": [10, 2, 8],
101     "Callsites": [
102       [ { "Guid": 1001,
103           "Counters": [2, 100],
104           "Callsites": [[{"Guid": 1002, "Counters": [100]}]]}
105       ],
106       [ { "Guid": 1001,
107           "Counters": [8, 500],
108           "Callsites": [[{"Guid": 1002, "Counters": [500]}]]}
109       ]
110     ]
111   }
113 ;--- expected.json
115   { "Guid": 1000,
116     "Counters": [10, 2, 8, 100],
117     "Callsites": [
118       [],
119       [ { "Guid": 1001,
120           "Counters": [8, 500],
121           "Callsites": [[{"Guid": 1002, "Counters": [500]}]]}
122       ],
123       [{ "Guid": 1002, "Counters": [100]}]
124     ]
125   }