From 678c2ae73337bb4bee218da1d00ab4bf26622ef6 Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Tue, 19 Nov 2024 13:04:13 -0800 Subject: [PATCH 1/6] [memprof] Undrift MemProfRecord This patch undrifts source locations in MemProfRecord before readMemprof starts the matching process. The thoery of operation is as follows: 1. Collect the lists of direct calls, one from the IR and the other from the profile. 2. Compute the correspondence (called undrift map in the patch) between the two lists with longestCommonSequence. 3. Apply the undrift map just before readMemprof consumes MemProfRecord. The new function gated by a flag that is off by default. The test case is identical to recently added memprof_annotate_yaml.test except that the source location in the profile has been modified. --- .../Instrumentation/MemProfiler.cpp | 47 ++++++++++++++++++- .../PGOProfile/memprof-undrift.test | 47 +++++++++++++++++++ 2 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 llvm/test/Transforms/PGOProfile/memprof-undrift.test diff --git a/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp b/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp index c980869a1c0d8..b416ef30f406b 100644 --- a/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp @@ -171,6 +171,10 @@ static cl::opt cl::desc("The default memprof options"), cl::Hidden, cl::init("")); +static cl::opt UndriftProfile("memprof-undrift-profile", + cl::desc("Undrift MemProf profile"), + cl::init(false), cl::Hidden); + extern cl::opt MemProfReportHintedSizes; // Instrumentation statistics @@ -907,10 +911,38 @@ memprof::computeUndriftMap(Module &M, IndexedInstrProfReader *MemProfReader, return UndriftMaps; } +// Given a MemProfRecord, undrift all the source locations present in the +// record in place. +static void +undriftMemProfRecord(const DenseMap &UndriftMaps, + memprof::MemProfRecord &MemProfRec) { + // Undrift a call stack in place. + auto UndriftCallStack = [&](std::vector &CallStack) { + for (auto &F : CallStack) { + auto I = UndriftMaps.find(F.Function); + if (I == UndriftMaps.end()) + continue; + auto J = I->second.find(LineLocation(F.LineOffset, F.Column)); + if (J == I->second.end()) + continue; + auto &NewLoc = J->second; + F.LineOffset = NewLoc.LineOffset; + F.Column = NewLoc.Column; + } + }; + + for (auto &AS : MemProfRec.AllocSites) + UndriftCallStack(AS.CallStack); + + for (auto &CS : MemProfRec.CallSites) + UndriftCallStack(CS); +} + static void readMemprof(Module &M, Function &F, IndexedInstrProfReader *MemProfReader, const TargetLibraryInfo &TLI, - std::map &FullStackIdToAllocMatchInfo) { + std::map &FullStackIdToAllocMatchInfo, + DenseMap &UndriftMaps) { auto &Ctx = M.getContext(); // Previously we used getIRPGOFuncName() here. If F is local linkage, // getIRPGOFuncName() returns FuncName with prefix 'FileName;'. But @@ -958,6 +990,11 @@ readMemprof(Module &M, Function &F, IndexedInstrProfReader *MemProfReader, NumOfMemProfFunc++; + // If requested, undrfit MemProfRecord so that the source locations in it + // match those in the IR. + if (UndriftProfile) + undriftMemProfRecord(UndriftMaps, *MemProfRec); + // Detect if there are non-zero column numbers in the profile. If not, // treat all column numbers as 0 when matching (i.e. ignore any non-zero // columns in the IR). The profiled binary might have been built with @@ -1176,6 +1213,11 @@ PreservedAnalyses MemProfUsePass::run(Module &M, ModuleAnalysisManager &AM) { auto &FAM = AM.getResult(M).getManager(); + TargetLibraryInfo &TLI = FAM.getResult(*M.begin()); + DenseMap UndriftMaps; + if (UndriftProfile) + UndriftMaps = computeUndriftMap(M, MemProfReader.get(), TLI); + // Map from the stack has of each allocation context in the function profiles // to the total profiled size (bytes), allocation type, and whether we matched // it to an allocation in the IR. @@ -1186,7 +1228,8 @@ PreservedAnalyses MemProfUsePass::run(Module &M, ModuleAnalysisManager &AM) { continue; const TargetLibraryInfo &TLI = FAM.getResult(F); - readMemprof(M, F, MemProfReader.get(), TLI, FullStackIdToAllocMatchInfo); + readMemprof(M, F, MemProfReader.get(), TLI, FullStackIdToAllocMatchInfo, + UndriftMaps); } if (ClPrintMemProfMatchInfo) { diff --git a/llvm/test/Transforms/PGOProfile/memprof-undrift.test b/llvm/test/Transforms/PGOProfile/memprof-undrift.test new file mode 100644 index 0000000000000..db3c48db110b5 --- /dev/null +++ b/llvm/test/Transforms/PGOProfile/memprof-undrift.test @@ -0,0 +1,47 @@ +; REQUIRES: x86_64-linux + +; Make sure that we can undrift the MemProf profile and annotate the IR +; accordingly. + +; RUN: split-file %s %t +; RUN: llvm-profdata merge %t/memprof_annotate_yaml.yaml -o %t/memprof_annotate_yaml.memprofdata +; RUN: opt < %t/memprof_annotate_yaml.ll -passes='memprof-use' -memprof-undrift-profile -S 2>&1 | FileCheck %s + +;--- memprof_annotate_yaml.yaml +--- +HeapProfileRecords: + - GUID: _Z3foov + AllocSites: + - Callstack: + - { Function: _Z3foov, LineOffset: 3, Column: 30, IsInlineFrame: false } + - { Function: main, LineOffset: 2, Column: 5, IsInlineFrame: false } + MemInfoBlock: + # With these numbers, llvm::memprof::getAllocType will determine that + # the call to new is cold. See MemoryProfileInfo.cpp for details. + TotalSize: 400 + AllocCount: 1 + TotalLifetimeAccessDensity: 1 + TotalLifetime: 1000000 + CallSites: [] +... +;--- memprof_annotate_yaml.ll +define dso_local ptr @_Z3foov() !dbg !4 { +entry: + %call = call ptr @_Znam(i64 4) #0, !dbg !5 +; CHECK: call ptr @_Znam(i64 4) #[[ATTR:[0-9]+]], + ret ptr %call +} + +declare ptr @_Znam(i64) + +attributes #0 = { builtin allocsize(0) } +; CHECK: attributes #[[ATTR]] = {{.*}} "memprof"="cold" + +!llvm.module.flags = !{!2, !3} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1) +!1 = !DIFile(filename: "t", directory: "/") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !1, file: !1, line: 1, unit: !0) +!5 = !DILocation(line: 1, column: 22, scope: !4) From a8fa34b30e2c63d4dc49ad0c87a5ccf88296b0fd Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Mon, 16 Dec 2024 19:55:21 -0800 Subject: [PATCH 2/6] Address comments. --- .../PGOProfile/memprof-undrift.test | 48 ++++++++++++++----- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/llvm/test/Transforms/PGOProfile/memprof-undrift.test b/llvm/test/Transforms/PGOProfile/memprof-undrift.test index db3c48db110b5..071c70015e4bc 100644 --- a/llvm/test/Transforms/PGOProfile/memprof-undrift.test +++ b/llvm/test/Transforms/PGOProfile/memprof-undrift.test @@ -13,35 +13,61 @@ HeapProfileRecords: - GUID: _Z3foov AllocSites: - Callstack: - - { Function: _Z3foov, LineOffset: 3, Column: 30, IsInlineFrame: false } + - { Function: _Z3foov, LineOffset: 10, Column: 50, IsInlineFrame: true } + - { Function: _Z3barv, LineOffset: 20, Column: 30, IsInlineFrame: false } - { Function: main, LineOffset: 2, Column: 5, IsInlineFrame: false } MemInfoBlock: - # With these numbers, llvm::memprof::getAllocType will determine that - # the call to new is cold. See MemoryProfileInfo.cpp for details. - TotalSize: 400 AllocCount: 1 - TotalLifetimeAccessDensity: 1 + TotalSize: 400 TotalLifetime: 1000000 + TotalLifetimeAccessDensity: 1 CallSites: [] + - GUID: _Z3barv + AllocSites: + - Callstack: + - { Function: _Z3foov, LineOffset: 10, Column: 50, IsInlineFrame: true } + - { Function: _Z3barv, LineOffset: 20, Column: 30, IsInlineFrame: false } + - { Function: main, LineOffset: 2, Column: 5, IsInlineFrame: false } + MemInfoBlock: + AllocCount: 1 + TotalSize: 400 + TotalLifetime: 1000000 + TotalLifetimeAccessDensity: 1 + CallSites: + - - { Function: _Z3foov, LineOffset: 10, Column: 50, IsInlineFrame: true } + - { Function: _Z3barv, LineOffset: 20, Column: 30, IsInlineFrame: false } ... ;--- memprof_annotate_yaml.ll define dso_local ptr @_Z3foov() !dbg !4 { +; CHECK-LABEL: @_Z3foov entry: %call = call ptr @_Znam(i64 4) #0, !dbg !5 -; CHECK: call ptr @_Znam(i64 4) #[[ATTR:[0-9]+]], +; CHECK: = call {{.*}} #[[ATTR:[0-9]+]] ret ptr %call } -declare ptr @_Znam(i64) +declare ptr @_Znam(i64 noundef) + +define dso_local ptr @_Z3barv() !dbg !6 { +; CHECK-LABEL: @_Z3barv +entry: + %call.i = call ptr @_Znam(i64 4) #0, !dbg !7 +; CHECK: = call {{.*}} #[[ATTR]] + ret ptr %call.i +} attributes #0 = { builtin allocsize(0) } -; CHECK: attributes #[[ATTR]] = {{.*}} "memprof"="cold" +; CHECK: attributes #[[ATTR]] = { builtin allocsize(0) "memprof"="cold" } +!llvm.dbg.cu = !{!0} !llvm.module.flags = !{!2, !3} !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1) -!1 = !DIFile(filename: "t", directory: "/") +!1 = !DIFile(filename: "undrift.cc", directory: "/") !2 = !{i32 7, !"Dwarf Version", i32 5} !3 = !{i32 2, !"Debug Info Version", i32 3} -!4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !1, file: !1, line: 1, unit: !0) -!5 = !DILocation(line: 1, column: 22, scope: !4) +!4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !1, file: !1, line: 55, unit: !0) +!5 = !DILocation(line: 55, column: 53, scope: !4) +!6 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !1, file: !1, line: 56, unit: !0) +!7 = !DILocation(line: 55, column: 53, scope: !4, inlinedAt: !8) +!8 = distinct !DILocation(line: 56, column: 22, scope: !6) From 491042ed7cc82063c2e3f006e033d0caaa420f3f Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Tue, 17 Dec 2024 13:06:41 -0800 Subject: [PATCH 3/6] Rename the option to memprof-salvage-stale-profile. --- llvm/lib/Transforms/Instrumentation/MemProfiler.cpp | 11 ++++++----- llvm/test/Transforms/PGOProfile/memprof-undrift.test | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp b/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp index b416ef30f406b..729cf8f42bc44 100644 --- a/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp @@ -171,9 +171,10 @@ static cl::opt cl::desc("The default memprof options"), cl::Hidden, cl::init("")); -static cl::opt UndriftProfile("memprof-undrift-profile", - cl::desc("Undrift MemProf profile"), - cl::init(false), cl::Hidden); +static cl::opt + SalvageStaleProfile("memprof-salvage-stale-profile", + cl::desc("Salvage stale MemProf profile"), + cl::init(false), cl::Hidden); extern cl::opt MemProfReportHintedSizes; @@ -992,7 +993,7 @@ readMemprof(Module &M, Function &F, IndexedInstrProfReader *MemProfReader, // If requested, undrfit MemProfRecord so that the source locations in it // match those in the IR. - if (UndriftProfile) + if (SalvageStaleProfile) undriftMemProfRecord(UndriftMaps, *MemProfRec); // Detect if there are non-zero column numbers in the profile. If not, @@ -1215,7 +1216,7 @@ PreservedAnalyses MemProfUsePass::run(Module &M, ModuleAnalysisManager &AM) { TargetLibraryInfo &TLI = FAM.getResult(*M.begin()); DenseMap UndriftMaps; - if (UndriftProfile) + if (SalvageStaleProfile) UndriftMaps = computeUndriftMap(M, MemProfReader.get(), TLI); // Map from the stack has of each allocation context in the function profiles diff --git a/llvm/test/Transforms/PGOProfile/memprof-undrift.test b/llvm/test/Transforms/PGOProfile/memprof-undrift.test index 071c70015e4bc..bf5f115f78b60 100644 --- a/llvm/test/Transforms/PGOProfile/memprof-undrift.test +++ b/llvm/test/Transforms/PGOProfile/memprof-undrift.test @@ -5,7 +5,7 @@ ; RUN: split-file %s %t ; RUN: llvm-profdata merge %t/memprof_annotate_yaml.yaml -o %t/memprof_annotate_yaml.memprofdata -; RUN: opt < %t/memprof_annotate_yaml.ll -passes='memprof-use' -memprof-undrift-profile -S 2>&1 | FileCheck %s +; RUN: opt < %t/memprof_annotate_yaml.ll -passes='memprof-use' -memprof-salvage-stale-profile -S 2>&1 | FileCheck %s ;--- memprof_annotate_yaml.yaml --- From 875d633a2391f4f34799cdf5375606d82ab2c746 Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Wed, 18 Dec 2024 00:14:49 -0800 Subject: [PATCH 4/6] Overhaul tests. --- .../PGOProfile/memprof-undrift.test | 159 +++++++++++++----- 1 file changed, 120 insertions(+), 39 deletions(-) diff --git a/llvm/test/Transforms/PGOProfile/memprof-undrift.test b/llvm/test/Transforms/PGOProfile/memprof-undrift.test index bf5f115f78b60..6a6bdb6037cee 100644 --- a/llvm/test/Transforms/PGOProfile/memprof-undrift.test +++ b/llvm/test/Transforms/PGOProfile/memprof-undrift.test @@ -4,60 +4,109 @@ ; accordingly. ; RUN: split-file %s %t -; RUN: llvm-profdata merge %t/memprof_annotate_yaml.yaml -o %t/memprof_annotate_yaml.memprofdata -; RUN: opt < %t/memprof_annotate_yaml.ll -passes='memprof-use' -memprof-salvage-stale-profile -S 2>&1 | FileCheck %s +; RUN: llvm-profdata merge %t/memprof_undrift.yaml -o %t/memprof_undrift.memprofdata +; RUN: opt < %t/memprof_undrift.ll -passes='memprof-use' -memprof-salvage-stale-profile -memprof-ave-lifetime-cold-threshold=5 -S 2>&1 | FileCheck %s -;--- memprof_annotate_yaml.yaml +;--- memprof_undrift.yaml --- HeapProfileRecords: + - GUID: _Z3aaav + AllocSites: [] + CallSites: + - - { Function: _Z3aaav, LineOffset: 5, Column: 33, IsInlineFrame: false } + - GUID: _Z6middlev + AllocSites: [] + CallSites: + - - { Function: _Z6middlev, LineOffset: 5, Column: 33, IsInlineFrame: false } - GUID: _Z3foov AllocSites: - Callstack: - - { Function: _Z3foov, LineOffset: 10, Column: 50, IsInlineFrame: true } - - { Function: _Z3barv, LineOffset: 20, Column: 30, IsInlineFrame: false } - - { Function: main, LineOffset: 2, Column: 5, IsInlineFrame: false } + - { Function: _Z3foov, LineOffset: 5, Column: 33, IsInlineFrame: false } + - { Function: main, LineOffset: 5, Column: 33, IsInlineFrame: false } MemInfoBlock: - AllocCount: 1 - TotalSize: 400 - TotalLifetime: 1000000 - TotalLifetimeAccessDensity: 1 + AllocCount: 1 + TotalSize: 4 + TotalLifetime: 10000 + TotalLifetimeAccessDensity: 0 CallSites: [] - - GUID: _Z3barv + - GUID: _Z4leafv AllocSites: - Callstack: - - { Function: _Z3foov, LineOffset: 10, Column: 50, IsInlineFrame: true } - - { Function: _Z3barv, LineOffset: 20, Column: 30, IsInlineFrame: false } - - { Function: main, LineOffset: 2, Column: 5, IsInlineFrame: false } + - { Function: _Z4leafv, LineOffset: 5, Column: 33, IsInlineFrame: false } + - { Function: _Z6middlev, LineOffset: 5, Column: 33, IsInlineFrame: false } + - { Function: _Z3aaav, LineOffset: 5, Column: 33, IsInlineFrame: false } + - { Function: main, LineOffset: 5, Column: 33, IsInlineFrame: false } MemInfoBlock: - AllocCount: 1 - TotalSize: 400 - TotalLifetime: 1000000 - TotalLifetimeAccessDensity: 1 + AllocCount: 1 + TotalSize: 4 + TotalLifetime: 0 + TotalLifetimeAccessDensity: 25000 + - Callstack: + - { Function: _Z4leafv, LineOffset: 5, Column: 33, IsInlineFrame: false } + - { Function: _Z6middlev, LineOffset: 5, Column: 33, IsInlineFrame: false } + - { Function: _Z3bbbv, LineOffset: 5, Column: 33, IsInlineFrame: false } + - { Function: main, LineOffset: 5, Column: 33, IsInlineFrame: false } + MemInfoBlock: + AllocCount: 1 + TotalSize: 4 + TotalLifetime: 10000 + TotalLifetimeAccessDensity: 2 + CallSites: [] + - GUID: _Z3bbbv + AllocSites: [] CallSites: - - - { Function: _Z3foov, LineOffset: 10, Column: 50, IsInlineFrame: true } - - { Function: _Z3barv, LineOffset: 20, Column: 30, IsInlineFrame: false } + - - { Function: _Z3bbbv, LineOffset: 5, Column: 33, IsInlineFrame: false } ... -;--- memprof_annotate_yaml.ll -define dso_local ptr @_Z3foov() !dbg !4 { -; CHECK-LABEL: @_Z3foov +;--- memprof_undrift.ll +define dso_local ptr @_Z3foov() !dbg !5 { +; CHECK-LABEL: @_Z3foov() entry: - %call = call ptr @_Znam(i64 4) #0, !dbg !5 -; CHECK: = call {{.*}} #[[ATTR:[0-9]+]] - ret ptr %call + %call = call ptr @_Znam(i64 4) #1, !dbg !8 +; CHECK: call ptr @_Znam(i64 4) #[[ATTR_COLD:[0-9]+]] + ret ptr %call, !dbg !9 } -declare ptr @_Znam(i64 noundef) +; Function Attrs: nobuiltin allocsize(0) +declare ptr @_Znam(i64 noundef) #0 -define dso_local ptr @_Z3barv() !dbg !6 { -; CHECK-LABEL: @_Z3barv +; Call hierarchy: leaf -> ::new +define dso_local ptr @_Z4leafv() !dbg !10 { +; CHECK-LABEL: @_Z4leafv() entry: - %call.i = call ptr @_Znam(i64 4) #0, !dbg !7 -; CHECK: = call {{.*}} #[[ATTR]] - ret ptr %call.i + %call = call ptr @_Znam(i64 4) #1, !dbg !11 +; CHECK: call ptr @_Znam(i64 4) {{.*}}, !memprof ![[M1:[0-9]+]], !callsite ![[C1:[0-9]+]] + ret ptr %call, !dbg !12 } -attributes #0 = { builtin allocsize(0) } -; CHECK: attributes #[[ATTR]] = { builtin allocsize(0) "memprof"="cold" } +; Call hierarchy: middle -> leaf -> ::new +define dso_local ptr @_Z6middlev() !dbg !13 { +; CHECK-LABEL: @_Z6middlev() +entry: + %call.i = call ptr @_Znam(i64 4) #1, !dbg !14 +; CHECK: call ptr @_Znam(i64 4) {{.*}}, !callsite ![[C2:[0-9]+]] + ret ptr %call.i, !dbg !16 +} + +; Call hierarchy: aaa -> middle -> leaf -> ::new +define dso_local ptr @_Z3aaav() !dbg !17 { +; CHECK-LABEL: @_Z3aaav() +entry: + %call.i.i = call ptr @_Znam(i64 4) #1, !dbg !18 +; CHECK: call ptr @_Znam(i64 4) {{.*}}, !callsite ![[C3:[0-9]+]] + ret ptr %call.i.i, !dbg !21 +} + +; Call hierarchy: bbb -> middle -> leaf -> ::new +define dso_local ptr @_Z3bbbv() !dbg !22 { +; CHECK-LABEL: @_Z3bbbv() +entry: + %call.i.i = call ptr @_Znam(i64 4) #1, !dbg !23 +; CHECK: call ptr @_Znam(i64 4) {{.*}}, !callsite ![[C4:[0-9]+]] + ret ptr %call.i.i, !dbg !26 +} + +attributes #0 = { nobuiltin allocsize(0) } +attributes #1 = { builtin allocsize(0) } !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!2, !3} @@ -66,8 +115,40 @@ attributes #0 = { builtin allocsize(0) } !1 = !DIFile(filename: "undrift.cc", directory: "/") !2 = !{i32 7, !"Dwarf Version", i32 5} !3 = !{i32 2, !"Debug Info Version", i32 3} -!4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !1, file: !1, line: 55, unit: !0) -!5 = !DILocation(line: 55, column: 53, scope: !4) -!6 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !1, file: !1, line: 56, unit: !0) -!7 = !DILocation(line: 55, column: 53, scope: !4, inlinedAt: !8) -!8 = distinct !DILocation(line: 56, column: 22, scope: !6) +!4 = !{} +!5 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !1, file: !1, line: 56, type: !6, unit: !0) +!6 = !DISubroutineType(types: !7) +!7 = !{} +!8 = !DILocation(line: 56, column: 22, scope: !5) +!9 = !DILocation(line: 56, column: 15, scope: !5) +!10 = distinct !DISubprogram(name: "leaf", linkageName: "_Z4leafv", scope: !1, file: !1, line: 58, type: !6, unit: !0) +!11 = !DILocation(line: 58, column: 23, scope: !10) +!12 = !DILocation(line: 58, column: 16, scope: !10) +!13 = distinct !DISubprogram(name: "middle", linkageName: "_Z6middlev", scope: !1, file: !1, line: 59, type: !6, unit: !0) +!14 = !DILocation(line: 58, column: 23, scope: !10, inlinedAt: !15) +!15 = distinct !DILocation(line: 59, column: 25, scope: !13) +!16 = !DILocation(line: 59, column: 18, scope: !13) +!17 = distinct !DISubprogram(name: "aaa", linkageName: "_Z3aaav", scope: !1, file: !1, line: 61, type: !6, unit: !0) +!18 = !DILocation(line: 58, column: 23, scope: !10, inlinedAt: !19) +!19 = distinct !DILocation(line: 59, column: 25, scope: !13, inlinedAt: !20) +!20 = distinct !DILocation(line: 61, column: 22, scope: !17) +!21 = !DILocation(line: 61, column: 15, scope: !17) +!22 = distinct !DISubprogram(name: "bbb", linkageName: "_Z3bbbv", scope: !1, file: !1, line: 62, type: !6, unit: !0) +!23 = !DILocation(line: 58, column: 23, scope: !10, inlinedAt: !24) +!24 = distinct !DILocation(line: 59, column: 25, scope: !13, inlinedAt: !25) +!25 = distinct !DILocation(line: 62, column: 22, scope: !22) +!26 = !DILocation(line: 62, column: 15, scope: !22) + +; CHECK: ![[M1]] = !{![[M1L:[0-9]+]], ![[M1R:[0-9]+]]} +; CHECK: ![[M1L]] = !{![[M1LL:[0-9]+]], !"cold"} +; CHECK: ![[M1LL]] = !{i64 -7165227774426488445, i64 6179674587295384169, i64 7749555980993309703} +; CHECK: ![[M1R]] = !{![[M1RL:[0-9]+]], !"notcold"} +; CHECK: ![[M1RL]] = !{i64 -7165227774426488445, i64 6179674587295384169, i64 -4748707735015301746} + +; CHECK: ![[C1]] = !{i64 -7165227774426488445} + +; CHECK: ![[C2]] = !{i64 6179674587295384169} + +; CHECK: ![[C3]] = !{i64 -4748707735015301746} + +; CHECK: ![[C4]] = !{i64 7749555980993309703} From 8a6294bed8ef6cb8f63697c7031ebde5b9fb699b Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Wed, 18 Dec 2024 00:24:54 -0800 Subject: [PATCH 5/6] Check ATTR. --- llvm/test/Transforms/PGOProfile/memprof-undrift.test | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/llvm/test/Transforms/PGOProfile/memprof-undrift.test b/llvm/test/Transforms/PGOProfile/memprof-undrift.test index 6a6bdb6037cee..3f686530228ec 100644 --- a/llvm/test/Transforms/PGOProfile/memprof-undrift.test +++ b/llvm/test/Transforms/PGOProfile/memprof-undrift.test @@ -62,7 +62,7 @@ define dso_local ptr @_Z3foov() !dbg !5 { ; CHECK-LABEL: @_Z3foov() entry: %call = call ptr @_Znam(i64 4) #1, !dbg !8 -; CHECK: call ptr @_Znam(i64 4) #[[ATTR_COLD:[0-9]+]] +; CHECK: call ptr @_Znam(i64 4) #[[ATTR:[0-9]+]] ret ptr %call, !dbg !9 } @@ -139,6 +139,8 @@ attributes #1 = { builtin allocsize(0) } !25 = distinct !DILocation(line: 62, column: 22, scope: !22) !26 = !DILocation(line: 62, column: 15, scope: !22) +; CHECK: attributes #[[ATTR]] = { builtin allocsize(0) "memprof"="cold" } + ; CHECK: ![[M1]] = !{![[M1L:[0-9]+]], ![[M1R:[0-9]+]]} ; CHECK: ![[M1L]] = !{![[M1LL:[0-9]+]], !"cold"} ; CHECK: ![[M1LL]] = !{i64 -7165227774426488445, i64 6179674587295384169, i64 7749555980993309703} From b9ae5630a8dd8224a2401adc0199802ecd08f899 Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Wed, 18 Dec 2024 11:23:48 -0800 Subject: [PATCH 6/6] Address comments. --- .../PGOProfile/memprof-undrift.test | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/llvm/test/Transforms/PGOProfile/memprof-undrift.test b/llvm/test/Transforms/PGOProfile/memprof-undrift.test index 3f686530228ec..45fb2f2137719 100644 --- a/llvm/test/Transforms/PGOProfile/memprof-undrift.test +++ b/llvm/test/Transforms/PGOProfile/memprof-undrift.test @@ -2,6 +2,28 @@ ; Make sure that we can undrift the MemProf profile and annotate the IR ; accordingly. +; +; The IR was generated from: +; +; char *foo() { return ::new char[4]; } +; char *leaf() { return ::new char[4]; } +; char *middle() { return leaf(); } +; char *aaa() { return middle(); } +; char *bbb() { return middle(); } +; +; int main() { +; foo(); +; +; char *a = aaa(); +; char *b = bbb(); +; a[0] = 'a'; +; b[0] = 'b'; +; delete[] a; +; sleep(10); +; delete[] b; +; +; return 0; +; } ; RUN: split-file %s %t ; RUN: llvm-profdata merge %t/memprof_undrift.yaml -o %t/memprof_undrift.memprofdata @@ -69,7 +91,6 @@ entry: ; Function Attrs: nobuiltin allocsize(0) declare ptr @_Znam(i64 noundef) #0 -; Call hierarchy: leaf -> ::new define dso_local ptr @_Z4leafv() !dbg !10 { ; CHECK-LABEL: @_Z4leafv() entry: @@ -78,7 +99,6 @@ entry: ret ptr %call, !dbg !12 } -; Call hierarchy: middle -> leaf -> ::new define dso_local ptr @_Z6middlev() !dbg !13 { ; CHECK-LABEL: @_Z6middlev() entry: @@ -87,7 +107,6 @@ entry: ret ptr %call.i, !dbg !16 } -; Call hierarchy: aaa -> middle -> leaf -> ::new define dso_local ptr @_Z3aaav() !dbg !17 { ; CHECK-LABEL: @_Z3aaav() entry: @@ -96,7 +115,6 @@ entry: ret ptr %call.i.i, !dbg !21 } -; Call hierarchy: bbb -> middle -> leaf -> ::new define dso_local ptr @_Z3bbbv() !dbg !22 { ; CHECK-LABEL: @_Z3bbbv() entry: