[llvm] [MemProf] Optionally save context size info on largest cold allocations (PR #142507)

Snehasish Kumar via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 2 22:23:10 PDT 2025


================
@@ -0,0 +1,131 @@
+;; Test the -memprof-min-percent-max-cold-size flag for annotating only the
+;; largest contexts with size info.
+
+; REQUIRES: x86_64-linux
+
+; RUN: split-file %s %t
+
+;; Specify version 4 so that a summary is generated.
+; RUN: llvm-profdata merge --memprof-version=4 %t/memprof_max_cold_threshold.yaml -o %t/memprof_max_cold_threshold.memprofdata
+
+; RUN: llvm-profdata show --memory %t/memprof_max_cold_threshold.memprofdata | FileCheck %s --check-prefixes=SUMMARY
+; SUMMARY: # MemProfSummary:
+; SUMMARY: #   Total contexts: 5
+; SUMMARY: #   Total cold contexts: 4
+; SUMMARY: #   Total hot contexts: 0
+; SUMMARY: #   Maximum cold context total size: 400
+; SUMMARY: #   Maximum warm context total size: 500
+; SUMMARY: #   Maximum hot context total size: 0
+
+;; Test with various thresholds, starting with the baseline of no context size
+;; info.
+; RUN: opt < %t/memprof_max_cold_threshold.ll -passes='memprof-use<profile-filename=%t/memprof_max_cold_threshold.memprofdata>' -S | FileCheck %s --check-prefixes=ALL,EXCL100,EXCL75,EXCL50
+; RUN: opt < %t/memprof_max_cold_threshold.ll -memprof-min-percent-max-cold-size=99 -passes='memprof-use<profile-filename=%t/memprof_max_cold_threshold.memprofdata>' -S | FileCheck %s --check-prefixes=ALL,INCL100,EXCL75,EXCL50
+; RUN: opt < %t/memprof_max_cold_threshold.ll -memprof-min-percent-max-cold-size=75 -passes='memprof-use<profile-filename=%t/memprof_max_cold_threshold.memprofdata>' -S | FileCheck %s --check-prefixes=ALL,INCL100,INCL75,EXCL50
+; RUN: opt < %t/memprof_max_cold_threshold.ll -memprof-min-percent-max-cold-size=50 -passes='memprof-use<profile-filename=%t/memprof_max_cold_threshold.memprofdata>' -S | FileCheck %s --check-prefixes=ALL,INCL100,INCL75,INCL50
+
+;; Make sure serializing / deserializing through bitcode works
+; RUN: opt < %t/memprof_max_cold_threshold.ll -memprof-min-percent-max-cold-size=75 -passes='memprof-use<profile-filename=%t/memprof_max_cold_threshold.memprofdata>' -o %t/out.bc
+; RUN: llvm-dis %t/out.bc -o - | FileCheck %s --check-prefixes=ALL,INCL100,INCL75,EXCL50
+
+;--- memprof_max_cold_threshold.yaml
+---
+HeapProfileRecords:
+  - GUID:            _Z3foov
+    AllocSites:
+      - Callstack:
+          - { Function: _Z3foov, LineOffset: 0, Column: 22, IsInlineFrame: false }
+          - { Function: main, LineOffset: 2, Column: 5, IsInlineFrame: false }
+        MemInfoBlock:
+	  # Smallest cold, 25% of largest cold size
+          TotalSize:                  100
+          AllocCount:                 1
+          TotalLifetimeAccessDensity: 1
+          TotalLifetime:              1000000
+      - Callstack:
+          - { Function: _Z3foov, LineOffset: 0, Column: 22, IsInlineFrame: false }
+          - { Function: main, LineOffset: 3, Column: 5, IsInlineFrame: false }
+        MemInfoBlock:
+	  # Largest cold
+          TotalSize:                  400
+          AllocCount:                 1
+          TotalLifetimeAccessDensity: 1
+          TotalLifetime:              1000000
+      - Callstack:
+          - { Function: _Z3foov, LineOffset: 0, Column: 22, IsInlineFrame: false }
+          - { Function: main, LineOffset: 4, Column: 5, IsInlineFrame: false }
+        MemInfoBlock:
+	  # Second largest cold, 75% of largest cold size
+          TotalSize:                  300
+          AllocCount:                 1
+          TotalLifetimeAccessDensity: 1
+          TotalLifetime:              1000000
+      - Callstack:
+          - { Function: _Z3foov, LineOffset: 0, Column: 22, IsInlineFrame: false }
+          - { Function: main, LineOffset: 5, Column: 5, IsInlineFrame: false }
+        MemInfoBlock:
+	  # Second smallest cold, 50% of largest cold size
+          TotalSize:                  200
+          AllocCount:                 1
+          TotalLifetimeAccessDensity: 1
+          TotalLifetime:              1000000
+      - Callstack:
+          - { Function: _Z3foov, LineOffset: 0, Column: 22, IsInlineFrame: false }
+          - { Function: main, LineOffset: 6, Column: 5, IsInlineFrame: false }
+        MemInfoBlock:
+	  # Largest context, which is non-cold (due to short lifetime)
+          TotalSize:                  500
+          AllocCount:                 1
+          TotalLifetimeAccessDensity: 1
+          TotalLifetime:              1
+    CallSites:       []
+...
+;--- memprof_max_cold_threshold.ll
+define dso_local ptr @_Z3foov() !dbg !4 {
+entry:
+  %call = call ptr @_Znam(i64 4) #0, !dbg !5
+; ALL: call ptr @_Znam(i64 4) {{.*}} !memprof ![[M1:[0-9]+]]
+  ret ptr %call
+}
+
+; ALL: ![[M1]] = !{![[M2:[0-9]+]], ![[M3:[0-9]+]], ![[M4:[0-9]+]], ![[M5:[0-9]+]], ![[M6:[0-9]+]]}
+;; The smallest never gets context size info.
+; ALL: ![[M2]] = !{![[C2:[0-9]+]], !"cold"}
+; ALL: ![[C2]] = !{i64 590523745590780990, i64 720385627691022109}
+; ALL: ![[M3]] = !{![[C3:[0-9]+]], !"cold"
+; EXCL100-NOT: !
+; EXCL100-SAME: }
+; INCL100-SAME: , ![[S3:[0-9]+]]}
+; ALL: ![[C3]] = !{i64 590523745590780990, i64 8256520048276991898}
+; INCL100: ![[S3]] = !{i64 6509573709067523871, i64 400}
+; ALL: ![[M4]] = !{![[C4:[0-9]+]], !"cold"
+; EXCL50-NOT: !
+; EXCL50-SAME: }
+; INCL50-SAME: , ![[S4:[0-9]+]]}
+; ALL: ![[C4]] = !{i64 590523745590780990, i64 -6953100768213558995}
+; INCL50: ![[S4]] = !{i64 -2629930016428010893, i64 200}
+; ALL: ![[M5]] = !{![[C5:[0-9]+]], !"cold"
+; EXCL75-NOT: !
+; EXCL75-SAME: }
+; INCL75-SAME: , ![[S5:[0-9]+]]}
----------------
snehasish wrote:

This is pretty hard to read and update in the future. I wonder if we can simplify this by having separate CHECKS on the RUN lines above?

https://github.com/llvm/llvm-project/pull/142507


More information about the llvm-commits mailing list