Skip to content

Commit a15e7b1

Browse files
[MemProf] Add option to hint allocations at a given cold byte percentage (#120301)
Optionally unconditionally hint allocations as cold or not cold during the matching step if the percentage of bytes allocated is at least that of the given threshold.
1 parent f3a8f87 commit a15e7b1

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

llvm/lib/Transforms/Instrumentation/MemProfiler.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,10 @@ static cl::opt<std::string>
173173

174174
extern cl::opt<bool> MemProfReportHintedSizes;
175175

176+
static cl::opt<unsigned> MinMatchedColdBytePercent(
177+
"memprof-matching-cold-threshold", cl::init(100), cl::Hidden,
178+
cl::desc("Min percent of cold bytes matched to hint allocation cold"));
179+
176180
// Instrumentation statistics
177181
STATISTIC(NumInstrumentedReads, "Number of instrumented reads");
178182
STATISTIC(NumInstrumentedWrites, "Number of instrumented writes");
@@ -1074,6 +1078,8 @@ readMemprof(Module &M, Function &F, IndexedInstrProfReader *MemProfReader,
10741078
// contexts. Add them to a Trie specialized for trimming the contexts to
10751079
// the minimal needed to disambiguate contexts with unique behavior.
10761080
CallStackTrie AllocTrie;
1081+
uint64_t TotalSize = 0;
1082+
uint64_t TotalColdSize = 0;
10771083
for (auto *AllocInfo : AllocInfoIter->second) {
10781084
// Check the full inlined call stack against this one.
10791085
// If we found and thus matched all frames on the call, include
@@ -1085,6 +1091,9 @@ readMemprof(Module &M, Function &F, IndexedInstrProfReader *MemProfReader,
10851091
if (ClPrintMemProfMatchInfo || MemProfReportHintedSizes)
10861092
FullStackId = computeFullStackId(AllocInfo->CallStack);
10871093
auto AllocType = addCallStack(AllocTrie, AllocInfo, FullStackId);
1094+
TotalSize += AllocInfo->Info.getTotalSize();
1095+
if (AllocType == AllocationType::Cold)
1096+
TotalColdSize += AllocInfo->Info.getTotalSize();
10881097
// Record information about the allocation if match info printing
10891098
// was requested.
10901099
if (ClPrintMemProfMatchInfo) {
@@ -1094,6 +1103,16 @@ readMemprof(Module &M, Function &F, IndexedInstrProfReader *MemProfReader,
10941103
}
10951104
}
10961105
}
1106+
// If the threshold for the percent of cold bytes is less than 100%,
1107+
// and not all bytes are cold, see if we should still hint this
1108+
// allocation as cold without context sensitivity.
1109+
if (TotalColdSize < TotalSize && MinMatchedColdBytePercent < 100 &&
1110+
TotalColdSize * 100 >= MinMatchedColdBytePercent * TotalSize) {
1111+
AllocTrie.addSingleAllocTypeAttribute(CI, AllocationType::Cold,
1112+
"dominant");
1113+
continue;
1114+
}
1115+
10971116
// We might not have matched any to the full inlined call stack.
10981117
// But if we did, create and attach metadata, or a function attribute if
10991118
// all contexts have identical profiled behavior.

llvm/test/Transforms/PGOProfile/memprof.ll

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,10 @@
6464
; RUN: opt < %s -passes='pgo-instr-use,memprof-use<profile-filename=%t.pgomemprofdata>' -pgo-test-profile-file=%t.pgomemprofdata -pgo-warn-missing-function -S 2>&1 | FileCheck %s --check-prefixes=MEMPROF,ALL,PGO
6565

6666
;; Check that the total sizes are reported if requested.
67-
; RUN: opt < %s -passes='memprof-use<profile-filename=%t.memprofdata>' -pgo-warn-missing-function -S -memprof-report-hinted-sizes 2>&1 | FileCheck %s --check-prefixes=TOTALSIZES
67+
; RUN: opt < %s -passes='memprof-use<profile-filename=%t.memprofdata>' -pgo-warn-missing-function -S -memprof-report-hinted-sizes 2>&1 | FileCheck %s --check-prefixes=TOTALSIZESSINGLE,TOTALSIZES
68+
69+
;; Check that we hint additional allocations with a threshold < 100%
70+
; RUN: opt < %s -passes='memprof-use<profile-filename=%t.memprofdata>' -pgo-warn-missing-function -S -memprof-report-hinted-sizes -memprof-matching-cold-threshold=60 2>&1 | FileCheck %s --check-prefixes=TOTALSIZESSINGLE,TOTALSIZESTHRESH60
6871

6972
;; Make sure we emit a random hotness seed if requested.
7073
; RUN: llvm-profdata merge -memprof-random-hotness %S/Inputs/memprof.memprofraw --profiled-binary %S/Inputs/memprof.exe -o %t.memprofdatarand 2>&1 | FileCheck %s --check-prefix=RAND
@@ -348,8 +351,14 @@ for.end: ; preds = %for.cond
348351

349352
;; For non-context sensitive allocations that get attributes we emit a message
350353
;; with the full allocation context hash, type, and size in bytes.
351-
; TOTALSIZES: Total size for full allocation context hash 6792096022461663180 and single alloc type notcold: 10
352-
; TOTALSIZES: Total size for full allocation context hash 15737101490731057601 and single alloc type cold: 10
354+
; TOTALSIZESTHRESH60: Total size for full allocation context hash 8525406123785421946 and dominant alloc type cold: 10
355+
; TOTALSIZESTHRESH60: Total size for full allocation context hash 11714230664165068698 and dominant alloc type cold: 10
356+
; TOTALSIZESTHRESH60: Total size for full allocation context hash 5725971306423925017 and dominant alloc type cold: 10
357+
; TOTALSIZESTHRESH60: Total size for full allocation context hash 16342802530253093571 and dominant alloc type cold: 10
358+
; TOTALSIZESTHRESH60: Total size for full allocation context hash 18254812774972004394 and dominant alloc type cold: 10
359+
; TOTALSIZESTHRESH60: Total size for full allocation context hash 1093248920606587996 and dominant alloc type cold: 10
360+
; TOTALSIZESSINGLE: Total size for full allocation context hash 6792096022461663180 and single alloc type notcold: 10
361+
; TOTALSIZESSINGLE: Total size for full allocation context hash 15737101490731057601 and single alloc type cold: 10
353362
;; For context sensitive allocations the full context hash and size in bytes
354363
;; are in separate metadata nodes included on the MIB metadata.
355364
; TOTALSIZES: !"cold", ![[CONTEXT1:[0-9]+]]}

0 commit comments

Comments
 (0)