xref: /llvm-project/llvm/test/ThinLTO/X86/memprof-recursive.ll (revision 3055e86c719c6cc72e50bb74a0e3b9cffebb41b5)
1;; Test recursion handling during cloning.
2;;
3;; See llvm/test/Transforms/MemProfContextDisambiguation/recursive.ll for
4;; information on how the test was created.
5
6; RUN: opt -thinlto-bc %s >%t.o
7
8;; Check behavior when we enable cloning of contexts involved with recursive
9;; cycles, but not through the cycle itself. I.e. until full support for
10;; recursion is added, the cloned recursive call from C back to B (line 12) will
11;; not be updated to call a clone.
12; RUN: llvm-lto2 run %t.o -enable-memprof-context-disambiguation \
13; RUN:  -supports-hot-cold-new \
14; RUN:  -r=%t.o,_Z1Dv,plx \
15; RUN:  -r=%t.o,_Z1Ci,plx \
16; RUN:  -r=%t.o,_Z1Bi,plx \
17; RUN:  -r=%t.o,main,plx \
18; RUN:  -r=%t.o,_Znam, \
19; RUN:  -memprof-verify-ccg -memprof-verify-nodes \
20; RUN:  -pass-remarks=memprof-context-disambiguation \
21; RUN:	-memprof-allow-recursive-callsites=true \
22; RUN:  -o %t.out 2>&1 | FileCheck %s \
23; RUN:  --implicit-check-not "memprof_recursive3.cc:12:10: call in clone _Z1Ci.memprof.1 assigned" \
24; RUN:  --check-prefix=ALLOW-RECUR-CALLSITES --check-prefix=ALLOW-RECUR-CONTEXTS
25
26;; Skipping recursive callsites should result in no cloning.
27; RUN: llvm-lto2 run %t.o -enable-memprof-context-disambiguation \
28; RUN:  -supports-hot-cold-new \
29; RUN:  -r=%t.o,_Z1Dv,plx \
30; RUN:  -r=%t.o,_Z1Ci,plx \
31; RUN:  -r=%t.o,_Z1Bi,plx \
32; RUN:  -r=%t.o,main,plx \
33; RUN:  -r=%t.o,_Znam, \
34; RUN:  -memprof-verify-ccg -memprof-verify-nodes \
35; RUN:  -pass-remarks=memprof-context-disambiguation \
36; RUN:	-memprof-allow-recursive-callsites=false \
37; RUN:  -o %t.out 2>&1 | FileCheck %s --allow-empty \
38; RUN:  --implicit-check-not "memprof_recursive3.cc:12:10: call in clone _Z1Ci.memprof.1 assigned" \
39; RUN:  --implicit-check-not="created clone" \
40; RUN:	--implicit-check-not="marked with memprof allocation attribute cold"
41
42;; Check the default behavior (disabled recursive callsites).
43; RUN: llvm-lto2 run %t.o -enable-memprof-context-disambiguation \
44; RUN:  -supports-hot-cold-new \
45; RUN:  -r=%t.o,_Z1Dv,plx \
46; RUN:  -r=%t.o,_Z1Ci,plx \
47; RUN:  -r=%t.o,_Z1Bi,plx \
48; RUN:  -r=%t.o,main,plx \
49; RUN:  -r=%t.o,_Znam, \
50; RUN:  -memprof-verify-ccg -memprof-verify-nodes \
51; RUN:  -pass-remarks=memprof-context-disambiguation \
52; RUN:  -o %t.out 2>&1 | FileCheck %s --allow-empty \
53; RUN:  --implicit-check-not "memprof_recursive3.cc:12:10: call in clone _Z1Ci.memprof.1 assigned" \
54; RUN:  --implicit-check-not="created clone" \
55; RUN:	--implicit-check-not="marked with memprof allocation attribute cold"
56
57;; Skipping recursive contexts should prevent spurious call to cloned version of
58;; B from the context starting at memprof_recursive.cc:19:13, which is actually
59;; recursive (until that support is added).
60; RUN: llvm-lto2 run %t.o -enable-memprof-context-disambiguation \
61; RUN:  -supports-hot-cold-new \
62; RUN:  -r=%t.o,_Z1Dv,plx \
63; RUN:  -r=%t.o,_Z1Ci,plx \
64; RUN:  -r=%t.o,_Z1Bi,plx \
65; RUN:  -r=%t.o,main,plx \
66; RUN:  -r=%t.o,_Znam, \
67; RUN:  -memprof-verify-ccg -memprof-verify-nodes \
68; RUN:  -pass-remarks=memprof-context-disambiguation \
69; RUN:	-memprof-allow-recursive-callsites=true \
70; RUN:	-memprof-allow-recursive-contexts=false \
71; RUN:  -o %t.out 2>&1 | FileCheck %s \
72; RUN:  --implicit-check-not "memprof_recursive3.cc:12:10: call in clone _Z1Ci.memprof.1 assigned" \
73; RUN:  --check-prefix=ALLOW-RECUR-CALLSITES --check-prefix=SKIP-RECUR-CONTEXTS
74
75; ALLOW-RECUR-CALLSITES: memprof_recursive.cc:4:0: created clone _Z1Dv.memprof.1
76; ALLOW-RECUR-CALLSITES: memprof_recursive.cc:5:10: call in clone _Z1Dv marked with memprof allocation attribute notcold
77; ALLOW-RECUR-CALLSITES: memprof_recursive.cc:5:10: call in clone _Z1Dv.memprof.1 marked with memprof allocation attribute cold
78; ALLOW-RECUR-CALLSITES: memprof_recursive.cc:8:0: created clone _Z1Ci.memprof.1
79; ALLOW-RECUR-CALLSITES: memprof_recursive.cc:10:12: call in clone _Z1Ci.memprof.1 assigned to call function clone _Z1Dv.memprof.1
80; ALLOW-RECUR-CALLSITES: memprof_recursive.cc:14:0: created clone _Z1Bi.memprof.1
81; ALLOW-RECUR-CALLSITES: memprof_recursive.cc:15:10: call in clone _Z1Bi.memprof.1 assigned to call function clone _Z1Ci.memprof.1
82;; We should only call the cold clone for the recursive context if we enabled
83;; recursive contexts via -memprof-allow-recursive-contexts=true (default).
84; ALLOW-RECUR-CONTEXTS: memprof_recursive.cc:19:13: call in clone main assigned to call function clone _Z1Bi.memprof.1
85; SKIP-RECUR-CONTEXTS-NOT: memprof_recursive.cc:19:13: call in clone main assigned to call function clone _Z1Bi.memprof.1
86; ALLOW-RECUR-CALLSITES: memprof_recursive.cc:20:13: call in clone main assigned to call function clone _Z1Bi.memprof.1
87
88target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
89target triple = "x86_64-unknown-linux-gnu"
90
91define ptr @_Z1Dv() !dbg !3 {
92entry:
93  %call = tail call ptr @_Znam(i64 10), !dbg !6, !memprof !7, !callsite !14
94  ret ptr null
95}
96
97define ptr @_Z1Ci(i32 %n) !dbg !15 {
98entry:
99  %call = tail call ptr @_Z1Dv(), !dbg !16, !callsite !17
100  br label %return
101
102if.end:                                           ; No predecessors!
103  %call1 = tail call ptr @_Z1Bi(i32 0), !dbg !18, !callsite !19
104  br label %return
105
106return:                                           ; preds = %if.end, %entry
107  ret ptr null
108}
109
110define ptr @_Z1Bi(i32 %n) !dbg !20 {
111entry:
112  %call = tail call ptr @_Z1Ci(i32 0), !dbg !21, !callsite !22
113  ret ptr null
114}
115
116define i32 @main() {
117entry:
118  %call = tail call ptr @_Z1Bi(i32 0), !dbg !23, !callsite !25
119  %call1 = tail call ptr @_Z1Bi(i32 0), !dbg !26, !callsite !27
120  %call2 = tail call ptr @_Z1Bi(i32 0), !dbg !28, !callsite !29
121  ret i32 0
122}
123
124declare ptr @_Znam(i64)
125
126!llvm.dbg.cu = !{!0}
127!llvm.module.flags = !{!2}
128
129!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 20.0.0git (https://github.com/llvm/llvm-project.git 7aec6dc477f8148ed066d10dfc7a012a51b6599c)", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, splitDebugInlining: false, debugInfoForProfiling: true, nameTableKind: None)
130!1 = !DIFile(filename: "memprof_recursive.cc", directory: ".", checksumkind: CSK_MD5, checksum: "2f15f63b187a0e0d40e7fdd18b10576a")
131!2 = !{i32 2, !"Debug Info Version", i32 3}
132!3 = distinct !DISubprogram(name: "D", linkageName: "_Z1Dv", scope: !1, file: !1, line: 4, type: !4, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
133!4 = !DISubroutineType(types: !5)
134!5 = !{}
135!6 = !DILocation(line: 5, column: 10, scope: !3)
136!7 = !{!8, !10, !12}
137!8 = !{!9, !"cold"}
138!9 = !{i64 6541423618768552252, i64 -200552803509692312, i64 -2954124005641725917, i64 6307901912192269588}
139!10 = !{!11, !"notcold"}
140!11 = !{i64 6541423618768552252, i64 -200552803509692312, i64 -2954124005641725917, i64 -7155190423157709404, i64 -2954124005641725917, i64 8632435727821051414}
141!12 = !{!13, !"cold"}
142!13 = !{i64 6541423618768552252, i64 -200552803509692312, i64 -2954124005641725917, i64 -7155190423157709404, i64 -2954124005641725917, i64 -3421689549917153178}
143!14 = !{i64 6541423618768552252}
144!15 = distinct !DISubprogram(name: "C", linkageName: "_Z1Ci", scope: !1, file: !1, line: 8, type: !4, scopeLine: 8, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
145!16 = !DILocation(line: 10, column: 12, scope: !15)
146!17 = !{i64 -200552803509692312}
147!18 = !DILocation(line: 12, column: 10, scope: !15)
148!19 = !{i64 -7155190423157709404}
149!20 = distinct !DISubprogram(name: "B", linkageName: "_Z1Bi", scope: !1, file: !1, line: 14, type: !4, scopeLine: 14, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
150!21 = !DILocation(line: 15, column: 10, scope: !20)
151!22 = !{i64 -2954124005641725917}
152!23 = !DILocation(line: 18, column: 13, scope: !24)
153!24 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 17, type: !4, scopeLine: 17, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
154!25 = !{i64 8632435727821051414}
155!26 = !DILocation(line: 19, column: 13, scope: !24)
156!27 = !{i64 -3421689549917153178}
157!28 = !DILocation(line: 20, column: 13, scope: !24)
158!29 = !{i64 6307901912192269588}
159