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