173 lines · plain
1;; Test recursion handling during cloning.2;;3;; See llvm/test/Transforms/MemProfContextDisambiguation/recursive.ll for4;; information on how the test was created.5 6;; -stats requires asserts7; REQUIRES: asserts8 9; RUN: opt -thinlto-bc %s >%t.o10 11;; Check behavior when we enable cloning of contexts involved with recursive12;; cycles, but not through the cycle itself. I.e. with full support for cloning13;; recursive cycles off, the cloned recursive call from C back to B (line 12)14;; will not be updated to call a clone.15; RUN: llvm-lto2 run %t.o -enable-memprof-context-disambiguation \16; RUN: -supports-hot-cold-new \17; RUN: -r=%t.o,_Z1Dv,plx \18; RUN: -r=%t.o,_Z1Ci,plx \19; RUN: -r=%t.o,_Z1Bi,plx \20; RUN: -r=%t.o,main,plx \21; RUN: -r=%t.o,_Znam, \22; RUN: -memprof-verify-ccg -memprof-verify-nodes \23; RUN: -pass-remarks=memprof-context-disambiguation \24; RUN: -memprof-allow-recursive-callsites=true \25; RUN: -memprof-clone-recursive-contexts=false \26; RUN: -o %t.out 2>&1 | FileCheck %s \27; RUN: --implicit-check-not "memprof_recursive.cc:12:10: call in clone _Z1Ci.memprof.1 assigned" \28; RUN: --check-prefix=ALLOW-RECUR-CALLSITES --check-prefix=ALLOW-RECUR-CONTEXTS29 30;; Skipping recursive callsites should result in no cloning.31; RUN: llvm-lto2 run %t.o -enable-memprof-context-disambiguation \32; RUN: -supports-hot-cold-new \33; RUN: -r=%t.o,_Z1Dv,plx \34; RUN: -r=%t.o,_Z1Ci,plx \35; RUN: -r=%t.o,_Z1Bi,plx \36; RUN: -r=%t.o,main,plx \37; RUN: -r=%t.o,_Znam, \38; RUN: -memprof-verify-ccg -memprof-verify-nodes \39; RUN: -pass-remarks=memprof-context-disambiguation \40; RUN: -memprof-allow-recursive-callsites=false \41; RUN: -o %t.out 2>&1 | FileCheck %s --allow-empty \42; RUN: --implicit-check-not "memprof_recursive.cc:12:10: call in clone _Z1Ci.memprof.1 assigned" \43; RUN: --implicit-check-not="created clone" \44; RUN: --implicit-check-not="marked with memprof allocation attribute cold"45 46;; Check the default behavior (clone recursive callsites).47; RUN: llvm-lto2 run %t.o -enable-memprof-context-disambiguation \48; RUN: -supports-hot-cold-new \49; RUN: -r=%t.o,_Z1Dv,plx \50; RUN: -r=%t.o,_Z1Ci,plx \51; RUN: -r=%t.o,_Z1Bi,plx \52; RUN: -r=%t.o,main,plx \53; RUN: -r=%t.o,_Znam, \54; RUN: -memprof-verify-ccg -memprof-verify-nodes -stats \55; RUN: -memprof-export-to-dot -memprof-dot-file-path-prefix=%t. \56; RUN: -pass-remarks=memprof-context-disambiguation \57; RUN: -o %t.out 2>&1 | FileCheck %s \58; RUN: --check-prefix=ALLOW-RECUR-CALLSITES --check-prefix=ALLOW-RECUR-CONTEXTS \59; RUN: --check-prefix=CLONE-RECUR-CALLSITES60 61;; Check that the backedge was correctly detected and emitted to the dot file62;; as a dotted edge.63; RUN: cat %t.ccg.postbuild.dot | FileCheck %s --check-prefix=DOT64; DOT-DAG: Node[[B:0x[a-f0-9]+]] {{.*}}_Z1Bi -\> _Z1Ci65; DOT-DAG: Node[[C:0x[a-f0-9]+]] {{.*}}_Z1Ci -\> _Z1Bi66; DOT-DAG: Node[[C]] -> Node[[B]]{{.*}}style="dotted"67 68;; Skipping recursive contexts should prevent spurious call to cloned version of69;; B from the context starting at memprof_recursive.cc:19:13, which is actually70;; recursive (until that support is added).71; RUN: llvm-lto2 run %t.o -enable-memprof-context-disambiguation \72; RUN: -supports-hot-cold-new \73; RUN: -r=%t.o,_Z1Dv,plx \74; RUN: -r=%t.o,_Z1Ci,plx \75; RUN: -r=%t.o,_Z1Bi,plx \76; RUN: -r=%t.o,main,plx \77; RUN: -r=%t.o,_Znam, \78; RUN: -memprof-verify-ccg -memprof-verify-nodes \79; RUN: -pass-remarks=memprof-context-disambiguation \80; RUN: -memprof-allow-recursive-callsites=true \81; RUN: -memprof-allow-recursive-contexts=false \82; RUN: -memprof-clone-recursive-contexts=false \83; RUN: -o %t.out 2>&1 | FileCheck %s \84; RUN: --implicit-check-not "memprof_recursive.cc:12:10: call in clone _Z1Ci.memprof.1 assigned" \85; RUN: --check-prefix=ALLOW-RECUR-CALLSITES --check-prefix=SKIP-RECUR-CONTEXTS86 87; ALLOW-RECUR-CALLSITES: memprof_recursive.cc:4:0: created clone _Z1Dv.memprof.188; ALLOW-RECUR-CALLSITES: memprof_recursive.cc:5:10: call in clone _Z1Dv marked with memprof allocation attribute notcold89; ALLOW-RECUR-CALLSITES: memprof_recursive.cc:5:10: call in clone _Z1Dv.memprof.1 marked with memprof allocation attribute cold90; ALLOW-RECUR-CALLSITES: memprof_recursive.cc:8:0: created clone _Z1Ci.memprof.191; ALLOW-RECUR-CALLSITES: memprof_recursive.cc:10:12: call in clone _Z1Ci.memprof.1 assigned to call function clone _Z1Dv.memprof.192; CLONE-RECUR-CALLSITES: memprof_recursive.cc:12:10: call in clone _Z1Ci.memprof.1 assigned to call function clone _Z1Bi.memprof.193; ALLOW-RECUR-CALLSITES: memprof_recursive.cc:14:0: created clone _Z1Bi.memprof.194; ALLOW-RECUR-CALLSITES: memprof_recursive.cc:15:10: call in clone _Z1Bi.memprof.1 assigned to call function clone _Z1Ci.memprof.195;; We should only call the cold clone for the recursive context if we enabled96;; recursive contexts via -memprof-allow-recursive-contexts=true (default).97; ALLOW-RECUR-CONTEXTS: memprof_recursive.cc:19:13: call in clone main assigned to call function clone _Z1Bi.memprof.198; SKIP-RECUR-CONTEXTS-NOT: memprof_recursive.cc:19:13: call in clone main assigned to call function clone _Z1Bi.memprof.199; ALLOW-RECUR-CALLSITES: memprof_recursive.cc:20:13: call in clone main assigned to call function clone _Z1Bi.memprof.1100; CLONE-RECUR-CALLSITES: 1 memprof-context-disambiguation - Number of backedges with deferred cloning101 102target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"103target triple = "x86_64-unknown-linux-gnu"104 105define ptr @_Z1Dv() !dbg !3 {106entry:107 %call = tail call ptr @_Znam(i64 10), !dbg !6, !memprof !7, !callsite !14108 ret ptr null109}110 111define ptr @_Z1Ci(i32 %n) !dbg !15 {112entry:113 %call = tail call ptr @_Z1Dv(), !dbg !16, !callsite !17114 br label %return115 116if.end: ; No predecessors!117 %call1 = tail call ptr @_Z1Bi(i32 0), !dbg !18, !callsite !19118 br label %return119 120return: ; preds = %if.end, %entry121 ret ptr null122}123 124define ptr @_Z1Bi(i32 %n) !dbg !20 {125entry:126 %call = tail call ptr @_Z1Ci(i32 0), !dbg !21, !callsite !22127 ret ptr null128}129 130define i32 @main() {131entry:132 %call = tail call ptr @_Z1Bi(i32 0), !dbg !23, !callsite !25133 %call1 = tail call ptr @_Z1Bi(i32 0), !dbg !26, !callsite !27134 %call2 = tail call ptr @_Z1Bi(i32 0), !dbg !28, !callsite !29135 ret i32 0136}137 138declare ptr @_Znam(i64)139 140!llvm.dbg.cu = !{!0}141!llvm.module.flags = !{!2}142 143!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)144!1 = !DIFile(filename: "memprof_recursive.cc", directory: ".", checksumkind: CSK_MD5, checksum: "2f15f63b187a0e0d40e7fdd18b10576a")145!2 = !{i32 2, !"Debug Info Version", i32 3}146!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)147!4 = !DISubroutineType(types: !5)148!5 = !{}149!6 = !DILocation(line: 5, column: 10, scope: !3)150!7 = !{!8, !10, !12}151!8 = !{!9, !"cold"}152!9 = !{i64 6541423618768552252, i64 -200552803509692312, i64 -2954124005641725917, i64 6307901912192269588}153!10 = !{!11, !"notcold"}154!11 = !{i64 6541423618768552252, i64 -200552803509692312, i64 -2954124005641725917, i64 -7155190423157709404, i64 -2954124005641725917, i64 8632435727821051414}155!12 = !{!13, !"cold"}156!13 = !{i64 6541423618768552252, i64 -200552803509692312, i64 -2954124005641725917, i64 -7155190423157709404, i64 -2954124005641725917, i64 -3421689549917153178}157!14 = !{i64 6541423618768552252}158!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)159!16 = !DILocation(line: 10, column: 12, scope: !15)160!17 = !{i64 -200552803509692312}161!18 = !DILocation(line: 12, column: 10, scope: !15)162!19 = !{i64 -7155190423157709404}163!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)164!21 = !DILocation(line: 15, column: 10, scope: !20)165!22 = !{i64 -2954124005641725917}166!23 = !DILocation(line: 18, column: 13, scope: !24)167!24 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 17, type: !4, scopeLine: 17, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)168!25 = !{i64 8632435727821051414}169!26 = !DILocation(line: 19, column: 13, scope: !24)170!27 = !{i64 -3421689549917153178}171!28 = !DILocation(line: 20, column: 13, scope: !24)172!29 = !{i64 6307901912192269588}173