Skip to content

Commit d5a5cd0

Browse files
committed
[MemProf] Add option to hint allocations at a given cold byte percentage
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 d7d0e74 commit d5a5cd0

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)