[llvm] 2446439 - [MemProf] Handle profiles with missing column numbers (#70520)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 30 13:19:41 PDT 2023
Author: Teresa Johnson
Date: 2023-10-30T13:19:37-07:00
New Revision: 2446439f51cf0d2dfb11c823436a930de7a4b8a2
URL: https://github.com/llvm/llvm-project/commit/2446439f51cf0d2dfb11c823436a930de7a4b8a2
DIFF: https://github.com/llvm/llvm-project/commit/2446439f51cf0d2dfb11c823436a930de7a4b8a2.diff
LOG: [MemProf] Handle profiles with missing column numbers (#70520)
Detect when we are matching a memprof profile with no column numbers,
and in that case treat all column numbers as 0 when matching. The
profiled binary might have been built with -gno-column-info, for
example.
Added:
llvm/test/Transforms/PGOProfile/Inputs/memprof.nocolinfo.exe
llvm/test/Transforms/PGOProfile/Inputs/memprof.nocolinfo.memprofraw
Modified:
llvm/lib/Transforms/Instrumentation/MemProfiler.cpp
llvm/test/Transforms/PGOProfile/Inputs/update_memprof_inputs.sh
llvm/test/Transforms/PGOProfile/memprof.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp b/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp
index 8cd06f878897b38..2b29ea2a65fdc87 100644
--- a/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp
@@ -729,6 +729,12 @@ static void readMemprof(Module &M, Function &F,
return;
}
+ // 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
+ // column numbers disabled, for example.
+ bool ProfileHasColumns = false;
+
// Build maps of the location hash to all profile data with that leaf location
// (allocation info and the callsites).
std::map<uint64_t, std::set<const AllocationInfo *>> LocHashToAllocInfo;
@@ -742,6 +748,7 @@ static void readMemprof(Module &M, Function &F,
// of call stack frames.
uint64_t StackId = computeStackId(AI.CallStack[0]);
LocHashToAllocInfo[StackId].insert(&AI);
+ ProfileHasColumns |= AI.CallStack[0].Column;
}
for (auto &CS : MemProfRec->CallSites) {
// Need to record all frames from leaf up to and including this function,
@@ -750,6 +757,7 @@ static void readMemprof(Module &M, Function &F,
for (auto &StackFrame : CS) {
uint64_t StackId = computeStackId(StackFrame);
LocHashToCallSites[StackId].insert(std::make_pair(&CS, Idx++));
+ ProfileHasColumns |= StackFrame.Column;
// Once we find this function, we can stop recording.
if (StackFrame.Function == FuncGUID)
break;
@@ -798,8 +806,8 @@ static void readMemprof(Module &M, Function &F,
if (Name.empty())
Name = DIL->getScope()->getSubprogram()->getName();
auto CalleeGUID = Function::getGUID(Name);
- auto StackId =
- computeStackId(CalleeGUID, GetOffset(DIL), DIL->getColumn());
+ auto StackId = computeStackId(CalleeGUID, GetOffset(DIL),
+ ProfileHasColumns ? DIL->getColumn() : 0);
// LeafFound will only be false on the first iteration, since we either
// set it true or break out of the loop below.
if (!LeafFound) {
diff --git a/llvm/test/Transforms/PGOProfile/Inputs/memprof.nocolinfo.exe b/llvm/test/Transforms/PGOProfile/Inputs/memprof.nocolinfo.exe
new file mode 100755
index 000000000000000..3000e2b8515a25c
Binary files /dev/null and b/llvm/test/Transforms/PGOProfile/Inputs/memprof.nocolinfo.exe
diff er
diff --git a/llvm/test/Transforms/PGOProfile/Inputs/memprof.nocolinfo.memprofraw b/llvm/test/Transforms/PGOProfile/Inputs/memprof.nocolinfo.memprofraw
new file mode 100644
index 000000000000000..c0db6d2e0f56ca6
Binary files /dev/null and b/llvm/test/Transforms/PGOProfile/Inputs/memprof.nocolinfo.memprofraw
diff er
diff --git a/llvm/test/Transforms/PGOProfile/Inputs/update_memprof_inputs.sh b/llvm/test/Transforms/PGOProfile/Inputs/update_memprof_inputs.sh
index a88e6d73ecb7171..cbf9a401a607235 100755
--- a/llvm/test/Transforms/PGOProfile/Inputs/update_memprof_inputs.sh
+++ b/llvm/test/Transforms/PGOProfile/Inputs/update_memprof_inputs.sh
@@ -82,6 +82,10 @@ COMMON_FLAGS="-fuse-ld=lld -Wl,--no-rosegment -gmlt -fdebug-info-for-profiling -
${CLANG} ${COMMON_FLAGS} -fmemory-profile ${OUTDIR}/memprof.cc -o ${OUTDIR}/memprof.exe
env MEMPROF_OPTIONS=log_path=stdout ${OUTDIR}/memprof.exe > ${OUTDIR}/memprof.memprofraw
+# Generate another profile without any column numbers.
+${CLANG} ${COMMON_FLAGS} -gno-column-info -fmemory-profile ${OUTDIR}/memprof.cc -o ${OUTDIR}/memprof.nocolinfo.exe
+env MEMPROF_OPTIONS=log_path=stdout ${OUTDIR}/memprof.nocolinfo.exe > ${OUTDIR}/memprof.nocolinfo.memprofraw
+
${CLANG} ${COMMON_FLAGS} -fprofile-generate=. \
${OUTDIR}/memprof.cc -o ${OUTDIR}/pgo.exe
env LLVM_PROFILE_FILE=${OUTDIR}/memprof_pgo.profraw ${OUTDIR}/pgo.exe
diff --git a/llvm/test/Transforms/PGOProfile/memprof.ll b/llvm/test/Transforms/PGOProfile/memprof.ll
index 5bd97b0e934af60..13f370a4071e8aa 100644
--- a/llvm/test/Transforms/PGOProfile/memprof.ll
+++ b/llvm/test/Transforms/PGOProfile/memprof.ll
@@ -16,6 +16,7 @@
; RUN: llvm-profdata merge %S/Inputs/memprof.memprofraw --profiled-binary %S/Inputs/memprof.exe -o %t.memprofdata
; RUN: llvm-profdata merge %S/Inputs/memprof_pgo.proftext %S/Inputs/memprof.memprofraw --profiled-binary %S/Inputs/memprof.exe -o %t.pgomemprofdata
; RUN: llvm-profdata merge %S/Inputs/memprof_pgo.proftext -o %t.pgoprofdata
+; RUN: llvm-profdata merge %S/Inputs/memprof.nocolinfo.memprofraw --profiled-binary %S/Inputs/memprof.nocolinfo.exe -o %t.nocolinfo.memprofdata
;; In all below cases we should not get any messages about missing profile data
;; for any functions. Either we are not performing any matching for a particular
@@ -28,6 +29,12 @@
; There should not be any PGO metadata
; MEMPROFONLY-NOT: !prof
+;; Try again but using a profile with missing columns. The memprof matcher
+;; should recognize that there are no non-zero columns in the profile and
+;; not attempt to include column numbers in the matching (which means that the
+;; stack ids will be
diff erent).
+; RUN: opt < %s -passes='memprof-use<profile-filename=%t.nocolinfo.memprofdata>' -pgo-warn-missing-function -S 2>&1 | FileCheck %s --check-prefixes=MEMPROFNOCOLINFO,ALL,MEMPROFONLY
+
;; Test the same thing but by passing the memory profile through to a default
;; pipeline via -memory-profile-file=, which should cause the necessary field
;; of the PGOOptions structure to be populated with the profile filename.
@@ -66,6 +73,7 @@ target triple = "x86_64-unknown-linux-gnu"
define dso_local noundef ptr @_Z3foov() #0 !dbg !10 {
entry:
; MEMPROF: call {{.*}} @_Znam{{.*}} !memprof ![[M1:[0-9]+]], !callsite ![[C1:[0-9]+]]
+ ; MEMPROFNOCOLINFO: call {{.*}} @_Znam{{.*}} !memprof ![[M1:[0-9]+]], !callsite ![[C1:[0-9]+]]
%call = call noalias noundef nonnull ptr @_Znam(i64 noundef 10) #6, !dbg !13
ret ptr %call, !dbg !14
}
@@ -78,6 +86,7 @@ declare noundef nonnull ptr @_Znam(i64 noundef) #1
define dso_local noundef ptr @_Z4foo2v() #0 !dbg !15 {
entry:
; MEMPROF: call {{.*}} @_Z3foov{{.*}} !callsite ![[C2:[0-9]+]]
+ ; MEMPROFNOCOLINFO: call {{.*}} @_Z3foov{{.*}} !callsite ![[C2:[0-9]+]]
%call = call noundef ptr @_Z3foov(), !dbg !16
ret ptr %call, !dbg !17
}
@@ -86,6 +95,7 @@ entry:
define dso_local noundef ptr @_Z3barv() #0 !dbg !18 {
entry:
; MEMPROF: call {{.*}} @_Z4foo2v{{.*}} !callsite ![[C3:[0-9]+]]
+ ; MEMPROFNOCOLINFO: call {{.*}} @_Z4foo2v{{.*}} !callsite ![[C3:[0-9]+]]
%call = call noundef ptr @_Z4foo2v(), !dbg !19
ret ptr %call, !dbg !20
}
@@ -94,6 +104,7 @@ entry:
define dso_local noundef ptr @_Z3bazv() #0 !dbg !21 {
entry:
; MEMPROF: call {{.*}} @_Z4foo2v{{.*}} !callsite ![[C4:[0-9]+]]
+ ; MEMPROFNOCOLINFO: call {{.*}} @_Z4foo2v{{.*}} !callsite ![[C4:[0-9]+]]
%call = call noundef ptr @_Z4foo2v(), !dbg !22
ret ptr %call, !dbg !23
}
@@ -110,6 +121,7 @@ entry:
if.then: ; preds = %entry
; MEMPROF: call {{.*}} @_Z3foov{{.*}} !callsite ![[C5:[0-9]+]]
+ ; MEMPROFNOCOLINFO: call {{.*}} @_Z3foov{{.*}} !callsite ![[C5:[0-9]+]]
%call = call noundef ptr @_Z3foov(), !dbg !27
store ptr %call, ptr %retval, align 8, !dbg !28
br label %return, !dbg !28
@@ -118,6 +130,7 @@ if.end: ; preds = %entry
%1 = load i32, ptr %n.addr, align 4, !dbg !29
%sub = sub i32 %1, 1, !dbg !30
; MEMPROF: call {{.*}} @_Z7recursej{{.*}} !callsite ![[C6:[0-9]+]]
+ ; MEMPROFNOCOLINFO: call {{.*}} @_Z7recursej{{.*}} !callsite ![[C6:[0-9]+]]
%call1 = call noundef ptr @_Z7recursej(i32 noundef %sub), !dbg !31
store ptr %call1, ptr %retval, align 8, !dbg !32
br label %return, !dbg !32
@@ -145,21 +158,27 @@ entry:
store i32 %argc, ptr %argc.addr, align 4
store ptr %argv, ptr %argv.addr, align 8
; MEMPROF: call {{.*}} @_Znam{{.*}} #[[A1:[0-9]+]]
+ ; MEMPROFNOCOLINFO: call {{.*}} @_Znam{{.*}} #[[A1:[0-9]+]]
%call = call noalias noundef nonnull ptr @_Znam(i64 noundef 10) #6, !dbg !35
store ptr %call, ptr %a, align 8, !dbg !36
; MEMPROF: call {{.*}} @_Znam{{.*}} #[[A2:[0-9]+]]
+ ; MEMPROFNOCOLINFO: call {{.*}} @_Znam{{.*}} #[[A2:[0-9]+]]
%call1 = call noalias noundef nonnull ptr @_Znam(i64 noundef 10) #6, !dbg !37
store ptr %call1, ptr %b, align 8, !dbg !38
; MEMPROF: call {{.*}} @_Z3foov{{.*}} !callsite ![[C7:[0-9]+]]
+ ; MEMPROFNOCOLINFO: call {{.*}} @_Z3foov{{.*}} !callsite ![[C7:[0-9]+]]
%call2 = call noundef ptr @_Z3foov(), !dbg !39
store ptr %call2, ptr %c, align 8, !dbg !40
; MEMPROF: call {{.*}} @_Z3foov{{.*}} !callsite ![[C8:[0-9]+]]
+ ; MEMPROFNOCOLINFO: call {{.*}} @_Z3foov{{.*}} !callsite ![[C8:[0-9]+]]
%call3 = call noundef ptr @_Z3foov(), !dbg !41
store ptr %call3, ptr %d, align 8, !dbg !42
; MEMPROF: call {{.*}} @_Z3barv{{.*}} !callsite ![[C9:[0-9]+]]
+ ; MEMPROFNOCOLINFO: call {{.*}} @_Z3barv{{.*}} !callsite ![[C9:[0-9]+]]
%call4 = call noundef ptr @_Z3barv(), !dbg !43
store ptr %call4, ptr %e, align 8, !dbg !44
; MEMPROF: call {{.*}} @_Z3bazv{{.*}} !callsite ![[C10:[0-9]+]]
+ ; MEMPROFNOCOLINFO: call {{.*}} @_Z3bazv{{.*}} !callsite ![[C10:[0-9]+]]
%call5 = call noundef ptr @_Z3bazv(), !dbg !45
store ptr %call5, ptr %f, align 8, !dbg !46
%0 = load ptr, ptr %a, align 8, !dbg !47
@@ -241,6 +260,7 @@ for.body: ; preds = %for.cond
%13 = load i32, ptr %i, align 4, !dbg !84
%add = add i32 %13, 3, !dbg !85
; MEMPROF: call {{.*}} @_Z7recursej{{.*}} !callsite ![[C11:[0-9]+]]
+ ; MEMPROFNOCOLINFO: call {{.*}} @_Z7recursej{{.*}} !callsite ![[C11:[0-9]+]]
%call22 = call noundef ptr @_Z7recursej(i32 noundef %add), !dbg !86
store ptr %call22, ptr %g, align 8, !dbg !87
%14 = load ptr, ptr %g, align 8, !dbg !88
@@ -300,6 +320,32 @@ for.end: ; preds = %for.cond
; MEMPROF: ![[C10]] = !{i64 2061451396820446691}
; MEMPROF: ![[C11]] = !{i64 1544787832369987002}
+
+; MEMPROFNOCOLINFO: #[[A1]] = { builtin allocsize(0) "memprof"="notcold" }
+; MEMPROFNOCOLINFO: #[[A2]] = { builtin allocsize(0) "memprof"="cold" }
+; MEMPROFNOCOLINFO: ![[M1]] = !{![[MIB1:[0-9]+]], ![[MIB2:[0-9]+]], ![[MIB3:[0-9]+]], ![[MIB4:[0-9]+]], ![[MIB5:[0-9]+]]}
+; MEMPROFNOCOLINFO: ![[MIB1]] = !{![[STACK1:[0-9]+]], !"cold"}
+; MEMPROFNOCOLINFO: ![[STACK1]] = !{i64 5281664982037379640, i64 6362220161075421157, i64 -5772587307814069790, i64 -5772587307814069790, i64 -5772587307814069790, i64 3577763375057267810}
+; MEMPROFNOCOLINFO: ![[MIB2]] = !{![[STACK2:[0-9]+]], !"notcold"}
+; MEMPROFNOCOLINFO: ![[STACK2]] = !{i64 5281664982037379640, i64 6362220161075421157, i64 -5772587307814069790, i64 -5772587307814069790, i64 -5772587307814069790, i64 -5772587307814069790}
+; MEMPROFNOCOLINFO: ![[MIB3]] = !{![[STACK3:[0-9]+]], !"notcold"}
+; MEMPROFNOCOLINFO: ![[STACK3]] = !{i64 5281664982037379640, i64 -6896091699916449732}
+; MEMPROFNOCOLINFO: ![[MIB4]] = !{![[STACK4:[0-9]+]], !"cold"}
+; MEMPROFNOCOLINFO: ![[STACK4]] = !{i64 5281664982037379640, i64 -6871734214936418908}
+; MEMPROFNOCOLINFO: ![[MIB5]] = !{![[STACK5:[0-9]+]], !"cold"}
+; MEMPROFNOCOLINFO: ![[STACK5]] = !{i64 5281664982037379640, i64 -6201180255894224618}
+; MEMPROFNOCOLINFO: ![[C1]] = !{i64 5281664982037379640}
+; MEMPROFNOCOLINFO: ![[C2]] = !{i64 -6871734214936418908}
+; MEMPROFNOCOLINFO: ![[C3]] = !{i64 -5588766871448036195}
+; MEMPROFNOCOLINFO: ![[C4]] = !{i64 -8990226808646054327}
+; MEMPROFNOCOLINFO: ![[C5]] = !{i64 6362220161075421157}
+; MEMPROFNOCOLINFO: ![[C6]] = !{i64 -5772587307814069790}
+; MEMPROFNOCOLINFO: ![[C7]] = !{i64 -6896091699916449732}
+; MEMPROFNOCOLINFO: ![[C8]] = !{i64 -6201180255894224618}
+; MEMPROFNOCOLINFO: ![[C9]] = !{i64 -962804290746547393}
+; MEMPROFNOCOLINFO: ![[C10]] = !{i64 -4535090212904553409}
+; MEMPROFNOCOLINFO: ![[C11]] = !{i64 3577763375057267810}
+
; Function Attrs: argmemonly nofree nounwind willreturn writeonly
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #3
More information about the llvm-commits
mailing list