1 ;; Test callsite context graph generation for call graph with with MIBs
2 ;; that have pruned contexts that partially match multiple inlined
3 ;; callsite contexts, requiring duplication of context ids and nodes
4 ;; while matching callsite nodes onto the graph. This test requires more
5 ;; complex duplication due to multiple contexts for different allocations
6 ;; that share some of the same callsite nodes.
8 ;; Original code looks like:
10 ;; char *D(bool Call1) {
12 ;; return new char[10];
14 ;; return new char[10];
17 ;; char *C(bool Call1) {
21 ;; char *B(bool Call1) {
28 ;; char *A(bool Call1) {
56 ;; int main(int argc, char **argv) {
57 ;; char *a1 = A1(); // cold
58 ;; char *a2 = A2(); // cold
59 ;; char *e = E(); // default
60 ;; char *a3 = A3(); // default
61 ;; char *a4 = A4(); // default
62 ;; char *f = F(); // cold
79 ;; Code compiled with -mllvm -memprof-ave-lifetime-cold-threshold=5 so that the
80 ;; memory freed after sleep(10) results in cold lifetimes.
82 ;; The code below was created by forcing inlining of A into its callers,
83 ;; without any other inlining or optimizations. Since both allocation contexts
84 ;; via A for each allocation in D have the same allocation type (cold via
85 ;; A1 and A2 for the first new in D, and non-cold via A3 and A4 for the second
86 ;; new in D, the contexts for those respective allocations are pruned above A.
87 ;; The allocations via E and F are to ensure we don't prune above B.
89 ;; The matching onto the inlined A[1234]->A sequences will require duplication
90 ;; of the context id assigned to the context from A for each allocation in D.
91 ;; This test ensures that we do this correctly in the presence of callsites
92 ;; shared by the different duplicated context ids (i.e. callsite in C).
94 ;; The IR was then reduced using llvm-reduce with the expected FileCheck input.
96 ; RUN: opt -thinlto-bc %s >%t.o
97 ; RUN: llvm-lto2 run %t.o -enable-memprof-context-disambiguation \
98 ; RUN: -supports-hot-cold-new \
99 ; RUN: -r=%t.o,main,plx \
100 ; RUN: -r=%t.o,_Z1Db,plx \
101 ; RUN: -r=%t.o,_Z1Cb,plx \
102 ; RUN: -r=%t.o,_Z1Bb,plx \
103 ; RUN: -r=%t.o,_Z1Ab,plx \
104 ; RUN: -r=%t.o,_Z2A1v,plx \
105 ; RUN: -r=%t.o,_Z2A2v,plx \
106 ; RUN: -r=%t.o,_Z2A3v,plx \
107 ; RUN: -r=%t.o,_Z2A4v,plx \
108 ; RUN: -r=%t.o,_Z1Ev,plx \
109 ; RUN: -r=%t.o,_Z1Fv,plx \
110 ; RUN: -r=%t.o,_ZdaPv, \
111 ; RUN: -r=%t.o,sleep, \
112 ; RUN: -r=%t.o,_Znam, \
113 ; RUN: -memprof-verify-ccg -memprof-verify-nodes -memprof-dump-ccg \
114 ; RUN: -memprof-export-to-dot -memprof-dot-file-path-prefix=%t. \
115 ; RUN: -o %t.out 2>&1 | FileCheck %s --check-prefix=DUMP
118 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
119 target triple = "x86_64-unknown-linux-gnu"
121 define ptr @_Z1Db(i1 %Call1) {
123 %call = call ptr @_Znam(i64 0), !memprof !0, !callsite !5
126 if.else: ; No predecessors!
127 %call1 = call ptr @_Znam(i64 0), !memprof !6, !callsite !11
130 return: ; preds = %if.else, %entry
134 declare ptr @_Znam(i64)
136 define ptr @_Z1Cb(i1 %Call1) {
138 %call = call ptr @_Z1Db(i1 false), !callsite !12
142 define ptr @_Z1Bb(i1 %Call1) {
144 %call = call ptr @_Z1Cb(i1 false), !callsite !13
147 if.else: ; No predecessors!
148 %call1 = call ptr @_Z1Cb(i1 false), !callsite !14
151 return: ; preds = %if.else, %entry
155 define ptr @_Z1Ab() {
157 %call = call ptr @_Z1Bb(i1 false), !callsite !15
161 define ptr @_Z2A1v() {
163 %call.i = call ptr @_Z1Bb(i1 false), !callsite !16
167 define ptr @_Z2A2v() {
169 %call.i = call ptr @_Z1Bb(i1 false), !callsite !17
173 define ptr @_Z2A3v() {
175 %call.i = call ptr @_Z1Bb(i1 false), !callsite !18
179 define ptr @_Z2A4v() {
181 %call.i = call ptr @_Z1Bb(i1 false), !callsite !19
185 define ptr @_Z1Ev() {
187 %call = call ptr @_Z1Bb(i1 false), !callsite !20
191 define ptr @_Z1Fv() {
193 %call = call ptr @_Z1Bb(i1 false), !callsite !21
199 declare void @_ZdaPv()
203 ; uselistorder directives
204 uselistorder ptr @_Znam, { 1, 0 }
207 !1 = !{!2, !"notcold"}
208 !2 = !{i64 4854880825882961848, i64 -904694911315397047, i64 6532298921261778285, i64 1905834578520680781}
210 !4 = !{i64 4854880825882961848, i64 -904694911315397047, i64 6532298921261778285, i64 -6528110295079665978}
211 !5 = !{i64 4854880825882961848}
213 !7 = !{!8, !"notcold"}
214 !8 = !{i64 -8775068539491628272, i64 -904694911315397047, i64 7859682663773658275, i64 -6528110295079665978}
216 !10 = !{i64 -8775068539491628272, i64 -904694911315397047, i64 7859682663773658275, i64 -4903163940066524832}
217 !11 = !{i64 -8775068539491628272}
218 !12 = !{i64 -904694911315397047}
219 !13 = !{i64 6532298921261778285}
220 !14 = !{i64 7859682663773658275}
221 !15 = !{i64 -6528110295079665978}
222 !16 = !{i64 -6528110295079665978, i64 5747919905719679568}
223 !17 = !{i64 -6528110295079665978, i64 -5753238080028016843}
224 !18 = !{i64 -6528110295079665978, i64 1794685869326395337}
225 !19 = !{i64 -6528110295079665978, i64 5462047985461644151}
226 !20 = !{i64 1905834578520680781}
227 !21 = !{i64 -4903163940066524832}
230 ;; After adding only the alloc node memprof metadata, we only have 4 contexts (we only
231 ;; match the interesting parts of the pre-update graph here).
233 ; DUMP: CCG before updating call stack chains:
234 ; DUMP: Callsite Context Graph:
236 ; DUMP: Node [[D1:0x[a-z0-9]+]]
237 ; DUMP: Versions: 1 MIB:
238 ; DUMP: AllocType 1 StackIds: 0, 1, 2
239 ; DUMP: AllocType 2 StackIds: 0, 1, 3
241 ; DUMP: AllocTypes: NotColdCold
242 ; DUMP: ContextIds: 1 2
244 ; DUMP: Node [[C:0x[a-z0-9]+]]
246 ; DUMP: AllocTypes: NotColdCold
247 ; DUMP: ContextIds: 1 2 3 4
249 ; DUMP: Edge from Callee [[D1]] to Caller: [[C]] AllocTypes: NotColdCold ContextIds: 1 2
250 ; DUMP: Edge from Callee [[D2:0x[a-z0-9]+]] to Caller: [[C]] AllocTypes: NotColdCold ContextIds: 3 4
253 ; DUMP: Versions: 1 MIB:
254 ; DUMP: AllocType 1 StackIds: 0, 4, 3
255 ; DUMP: AllocType 2 StackIds: 0, 4, 5
257 ; DUMP: AllocTypes: NotColdCold
258 ; DUMP: ContextIds: 3 4
261 ;; After updating for callsite metadata, we should have duplicated the context
262 ;; ids coming from node A (2 and 3) 4 times, for the 4 different callers of A,
263 ;; and used those on new nodes for those callers. Note that while in reality
264 ;; we only have cold edges coming from A1 and A2 and noncold from A3 and A4,
265 ;; due to the pruning we have lost this information and thus end up duplicating
266 ;; both of A's contexts to all of the new nodes (which could result in some
267 ;; unnecessary cloning.
269 ; DUMP: CCG before cloning:
270 ; DUMP: Callsite Context Graph:
272 ; DUMP: Versions: 1 MIB:
273 ; DUMP: AllocType 1 StackIds: 0, 1, 2
274 ; DUMP: AllocType 2 StackIds: 0, 1, 3
276 ; DUMP: AllocTypes: NotColdCold
277 ; DUMP: ContextIds: 1 2 5 7 9 11
280 ; DUMP: Edge from Callee [[D1]] to Caller: [[C]] AllocTypes: NotColdCold ContextIds: 1 2 5 7 9 11
283 ; DUMP: Callee: 11485875876353461977 (_Z1Db) Clones: 0 StackIds: 0 (clone 0)
284 ; DUMP: AllocTypes: NotColdCold
285 ; DUMP: ContextIds: 1 2 3 4 5 6 7 8 9 10 11 12
287 ; DUMP: Edge from Callee [[D1]] to Caller: [[C]] AllocTypes: NotColdCold ContextIds: 1 2 5 7 9 11
288 ; DUMP: Edge from Callee [[D2]] to Caller: [[C]] AllocTypes: NotColdCold ContextIds: 3 4 6 8 10 12
290 ; DUMP: Edge from Callee [[C]] to Caller: [[B1:0x[a-z0-9]+]] AllocTypes: NotColdCold ContextIds: 1 2 5 7 9 11
291 ; DUMP: Edge from Callee [[C]] to Caller: [[B2:0x[a-z0-9]+]] AllocTypes: NotColdCold ContextIds: 3 4 6 8 10 12
294 ; DUMP: Callee: 15062806102884567440 (_Z1Cb) Clones: 0 StackIds: 1 (clone 0)
295 ; DUMP: AllocTypes: NotColdCold
296 ; DUMP: ContextIds: 1 2 5 7 9 11
298 ; DUMP: Edge from Callee [[C]] to Caller: [[B1]] AllocTypes: NotColdCold ContextIds: 1 2 5 7 9 11
300 ; DUMP: Edge from Callee [[B1]] to Caller: [[E:0x[a-z0-9]+]] AllocTypes: NotCold ContextIds: 1
301 ; DUMP: Edge from Callee [[B1]] to Caller: [[A2:0x[a-z0-9]+]] AllocTypes: Cold ContextIds: 5
302 ; DUMP: Edge from Callee [[B1]] to Caller: [[A3:0x[a-z0-9]+]] AllocTypes: Cold ContextIds: 7
303 ; DUMP: Edge from Callee [[B1]] to Caller: [[A1:0x[a-z0-9]+]] AllocTypes: Cold ContextIds: 9
304 ; DUMP: Edge from Callee [[B1]] to Caller: [[A4:0x[a-z0-9]+]] AllocTypes: Cold ContextIds: 11
305 ; DUMP: Edge from Callee [[B1]] to Caller: [[A:0x[a-z0-9]+]] AllocTypes: Cold ContextIds: 2
308 ; DUMP: Callee: 9116113196563097487 (_Z1Bb) Clones: 0 StackIds: 2 (clone 0)
309 ; DUMP: AllocTypes: NotCold
310 ; DUMP: ContextIds: 1
312 ; DUMP: Edge from Callee [[B1]] to Caller: [[E]] AllocTypes: NotCold ContextIds: 1
316 ; DUMP: Versions: 1 MIB:
317 ; DUMP: AllocType 1 StackIds: 0, 4, 3
318 ; DUMP: AllocType 2 StackIds: 0, 4, 5
320 ; DUMP: AllocTypes: NotColdCold
321 ; DUMP: ContextIds: 3 4 6 8 10 12
324 ; DUMP: Edge from Callee [[D2]] to Caller: [[C]] AllocTypes: NotColdCold ContextIds: 3 4 6 8 10 12
327 ; DUMP: Callee: 15062806102884567440 (_Z1Cb) Clones: 0 StackIds: 4 (clone 0)
328 ; DUMP: AllocTypes: NotColdCold
329 ; DUMP: ContextIds: 3 4 6 8 10 12
331 ; DUMP: Edge from Callee [[C]] to Caller: [[B2]] AllocTypes: NotColdCold ContextIds: 3 4 6 8 10 12
333 ; DUMP: Edge from Callee [[B2]] to Caller: [[F:0x[a-z0-9]+]] AllocTypes: Cold ContextIds: 4
334 ; DUMP: Edge from Callee [[B2]] to Caller: [[A2]] AllocTypes: NotCold ContextIds: 6
335 ; DUMP: Edge from Callee [[B2]] to Caller: [[A3]] AllocTypes: NotCold ContextIds: 8
336 ; DUMP: Edge from Callee [[B2]] to Caller: [[A1]] AllocTypes: NotCold ContextIds: 10
337 ; DUMP: Edge from Callee [[B2]] to Caller: [[A4]] AllocTypes: NotCold ContextIds: 12
338 ; DUMP: Edge from Callee [[B2]] to Caller: [[A]] AllocTypes: NotCold ContextIds: 3
341 ; DUMP: Callee: 9116113196563097487 (_Z1Bb) Clones: 0 StackIds: 5 (clone 0)
342 ; DUMP: AllocTypes: Cold
343 ; DUMP: ContextIds: 4
345 ; DUMP: Edge from Callee [[B2]] to Caller: [[F]] AllocTypes: Cold ContextIds: 4
349 ; DUMP: Callee: 9116113196563097487 (_Z1Bb) Clones: 0 StackIds: 3, 7 (clone 0)
350 ; DUMP: AllocTypes: NotColdCold
351 ; DUMP: ContextIds: 5 6
353 ; DUMP: Edge from Callee [[B1]] to Caller: [[A2]] AllocTypes: Cold ContextIds: 5
354 ; DUMP: Edge from Callee [[B2]] to Caller: [[A2]] AllocTypes: NotCold ContextIds: 6
358 ; DUMP: Callee: 9116113196563097487 (_Z1Bb) Clones: 0 StackIds: 3, 8 (clone 0)
359 ; DUMP: AllocTypes: NotColdCold
360 ; DUMP: ContextIds: 7 8
362 ; DUMP: Edge from Callee [[B1]] to Caller: [[A3]] AllocTypes: Cold ContextIds: 7
363 ; DUMP: Edge from Callee [[B2]] to Caller: [[A3]] AllocTypes: NotCold ContextIds: 8
367 ; DUMP: Callee: 9116113196563097487 (_Z1Bb) Clones: 0 StackIds: 3 (clone 0)
368 ; DUMP: AllocTypes: NotColdCold
369 ; DUMP: ContextIds: 9 10
371 ; DUMP: Edge from Callee [[B1]] to Caller: [[A1]] AllocTypes: Cold ContextIds: 9
372 ; DUMP: Edge from Callee [[B2]] to Caller: [[A1]] AllocTypes: NotCold ContextIds: 10
376 ; DUMP: Callee: 9116113196563097487 (_Z1Bb) Clones: 0 StackIds: 3, 9 (clone 0)
377 ; DUMP: AllocTypes: NotColdCold
378 ; DUMP: ContextIds: 11 12
380 ; DUMP: Edge from Callee [[B1]] to Caller: [[A4]] AllocTypes: Cold ContextIds: 11
381 ; DUMP: Edge from Callee [[B2]] to Caller: [[A4]] AllocTypes: NotCold ContextIds: 12
385 ; DUMP: Callee: 9116113196563097487 (_Z1Bb) Clones: 0 StackIds: 3, 6 (clone 0)
386 ; DUMP: AllocTypes: NotColdCold
387 ; DUMP: ContextIds: 2 3
389 ; DUMP: Edge from Callee [[B1]] to Caller: [[A]] AllocTypes: Cold ContextIds: 2
390 ; DUMP: Edge from Callee [[B2]] to Caller: [[A]] AllocTypes: NotCold ContextIds: 3