aboutsummaryrefslogtreecommitdiff
path: root/llvm/test/Transforms/PGOProfile/memprof_missing_leaf.ll
blob: e6fb1863acbce1e8a1601979368313096102461c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
;; Tests memprof profile matching when the leaf frame is missing in the
;; profile. In this case the call to operator new was inlined before
;; matching and we are able to match the next call frame up the inlined
;; context.

;; Avoid failures on big-endian systems that can't read the profile properly
; REQUIRES: x86_64-linux

;; # To generate below LLVM IR for use in matching.
;; $ clang++ -gmlt -fdebug-info-for-profiling -S memprof_missing_leaf.cc \
;; 	-O2 -emit-llvm
;;
;; where memprof_missing_leaf.cc is as follows:
;;
;; #include <new>
;;
;; // Use musttail to simulate a missing leaf debug frame in the profiled binary.
;; // Note we don't currently match onto explicit ::operator new calls, which is
;; // why the non-musttail case uses implicit new (which doesn't support musttail).
;; // Note that changes in the code below which affect relative line number
;; // offsets of calls from their parent function can affect callsite matching in
;; // the LLVM IR.
;; #ifndef USE_MUSTTAIL
;; #define USE_MUSTTAIL 0
;; #endif
;;
;; // clang::musttail requires that the argument signature matches that of the caller.
;; void *bar(std::size_t s) {
;; #if USE_MUSTTAIL
;;   [[clang::musttail]] return ::operator new (s);
;; #else
;;   return new char[s];
;; #endif
;; }
;;
;; int main() {
;;   char *a = (char *)bar(1);
;;   delete a;
;;   return 0;
;;}

; RUN: split-file %s %t
; RUN: llvm-profdata merge %t/memprof_missing_leaf.yaml -o %t/memprof_missing_leaf.memprofdata
; RUN: opt < %t/memprof_missing_leaf.ll -passes='memprof-use<profile-filename=%t/memprof_missing_leaf.memprofdata>' -S | FileCheck %s

;--- memprof_missing_leaf.yaml
---
HeapProfileRecords:
  - GUID:            main
    AllocSites:
      - Callstack:
          - { Function: main, LineOffset: 1, Column: 21, IsInlineFrame: false }
        MemInfoBlock:
          AllocCount:      1
          TotalSize:       1
          TotalLifetime:   0
          TotalLifetimeAccessDensity: 0
    CallSites:       []
...
;--- memprof_missing_leaf.ll
; CHECK: call {{.*}} @_Znam{{.*}} #[[ATTR:[0-9]+]]
; CHECK: attributes #[[ATTR]] = {{.*}} "memprof"="notcold"

; ModuleID = '<stdin>'
source_filename = "memprof_missing_leaf.cc"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: nobuiltin allocsize(0)
declare noundef nonnull ptr @_Znam(i64 noundef) #0

; Function Attrs: mustprogress norecurse uwtable
define dso_local noundef i32 @main() #1 !dbg !8 {
entry:
  %s.addr.i = alloca i64, align 8
  %retval = alloca i32, align 4
  %a = alloca ptr, align 8
  store i32 0, ptr %retval, align 4
  store i64 1, ptr %s.addr.i, align 8, !tbaa !11
  %0 = load i64, ptr %s.addr.i, align 8, !dbg !15, !tbaa !11
  %call.i = call noalias noundef nonnull ptr @_Znam(i64 noundef %0) #3, !dbg !18
  store ptr %call.i, ptr %a, align 8, !dbg !19, !tbaa !20
  %1 = load ptr, ptr %a, align 8, !dbg !22, !tbaa !20
  %isnull = icmp eq ptr %1, null, !dbg !23
  br i1 %isnull, label %delete.end, label %delete.notnull, !dbg !23

delete.notnull:                                   ; preds = %entry
  call void @_ZdlPv(ptr noundef %1) #4, !dbg !23
  br label %delete.end, !dbg !23

delete.end:                                       ; preds = %delete.notnull, %entry
  ret i32 0, !dbg !24
}

; Function Attrs: nobuiltin nounwind
declare void @_ZdlPv(ptr noundef) #2

attributes #0 = { nobuiltin allocsize(0) "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { mustprogress norecurse uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #2 = { nobuiltin nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #3 = { builtin allocsize(0) }
attributes #4 = { builtin nounwind }

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!2, !3, !4, !5, !6, !7}

!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 71bf052ec90e77cb4aa66505d47cbc4b6016ac1d)", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, splitDebugInlining: false, debugInfoForProfiling: true, nameTableKind: None)
!1 = !DIFile(filename: "memprof_missing_leaf.cc", directory: ".", checksumkind: CSK_MD5, checksum: "f1445a8699406a6b826128704d257677")
!2 = !{i32 7, !"Dwarf Version", i32 5}
!3 = !{i32 2, !"Debug Info Version", i32 3}
!4 = !{i32 1, !"wchar_size", i32 4}
!5 = !{i32 8, !"PIC Level", i32 2}
!6 = !{i32 7, !"PIE Level", i32 2}
!7 = !{i32 7, !"uwtable", i32 2}
!8 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !9, scopeLine: 15, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
!9 = !DISubroutineType(types: !10)
!10 = !{}
!11 = !{!12, !12, i64 0}
!12 = !{!"long", !13, i64 0}
!13 = !{!"omnipotent char", !14, i64 0}
!14 = !{!"Simple C++ TBAA"}
!15 = !DILocation(line: 11, column: 19, scope: !16, inlinedAt: !17)
!16 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barm", scope: !1, file: !1, line: 7, type: !9, scopeLine: 7, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
!17 = distinct !DILocation(line: 16, column: 21, scope: !8)
!18 = !DILocation(line: 11, column: 10, scope: !16, inlinedAt: !17)
!19 = !DILocation(line: 16, column: 9, scope: !8)
!20 = !{!21, !21, i64 0}
!21 = !{!"any pointer", !13, i64 0}
!22 = !DILocation(line: 17, column: 10, scope: !8)
!23 = !DILocation(line: 17, column: 3, scope: !8)
!24 = !DILocation(line: 18, column: 3, scope: !8)