@@ -101,4 +101,123 @@ declare !dbg !19 void @_Z2f3v()
101
101
EXPECT_THAT (CallSites[2 ],
102
102
Pair (FieldsAre (2U , 9U ), IndexedMemProfRecord::getGUID (" _Z2f3v" )));
103
103
}
104
+
105
+ TEST (MemProf, ExtractDirectCallsFromIRInline) {
106
+ // The following IR is generated from:
107
+ //
108
+ // void f1();
109
+ // static inline void f2() {
110
+ // // For an interesting line number.
111
+ // f1();
112
+ // }
113
+ // static inline void f3() {
114
+ // /****/ f2(); // For an interesting column number.
115
+ // }
116
+ //
117
+ // void g1();
118
+ // void g2();
119
+ // static inline void g3() {
120
+ // /**/ g1(); // For an interesting column number.
121
+ // g2();
122
+ // }
123
+ //
124
+ // void foo() {
125
+ // f3();
126
+ // /***/ g3(); // For an interesting column number.
127
+ // }
128
+ StringRef IR = R"IR(
129
+ define dso_local void @_Z3foov() local_unnamed_addr !dbg !10 {
130
+ entry:
131
+ tail call void @_Z2f1v(), !dbg !13
132
+ tail call void @_Z2g1v(), !dbg !18
133
+ tail call void @_Z2g2v(), !dbg !21
134
+ ret void, !dbg !22
135
+ }
136
+
137
+ declare !dbg !23 void @_Z2f1v() local_unnamed_addr
138
+
139
+ declare !dbg !24 void @_Z2g1v() local_unnamed_addr
140
+
141
+ declare !dbg !25 void @_Z2g2v() local_unnamed_addr
142
+
143
+ !llvm.dbg.cu = !{!0}
144
+ !llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8}
145
+ !llvm.ident = !{!9}
146
+
147
+ !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, splitDebugInlining: false, debugInfoForProfiling: true, nameTableKind: None)
148
+ !1 = !DIFile(filename: "foobar.cc", directory: "/")
149
+ !2 = !{i32 7, !"Dwarf Version", i32 5}
150
+ !3 = !{i32 2, !"Debug Info Version", i32 3}
151
+ !4 = !{i32 1, !"wchar_size", i32 4}
152
+ !5 = !{i32 1, !"MemProfProfileFilename", !"memprof.profraw"}
153
+ !6 = !{i32 8, !"PIC Level", i32 2}
154
+ !7 = !{i32 7, !"PIE Level", i32 2}
155
+ !8 = !{i32 7, !"uwtable", i32 2}
156
+ !9 = !{!"clang"}
157
+ !10 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !1, file: !1, line: 17, type: !11, scopeLine: 17, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
158
+ !11 = !DISubroutineType(types: !12)
159
+ !12 = !{}
160
+ !13 = !DILocation(line: 4, column: 3, scope: !14, inlinedAt: !15)
161
+ !14 = distinct !DISubprogram(name: "f2", linkageName: "_ZL2f2v", scope: !1, file: !1, line: 2, type: !11, scopeLine: 2, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0)
162
+ !15 = distinct !DILocation(line: 7, column: 10, scope: !16, inlinedAt: !17)
163
+ !16 = distinct !DISubprogram(name: "f3", linkageName: "_ZL2f3v", scope: !1, file: !1, line: 6, type: !11, scopeLine: 6, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0)
164
+ !17 = distinct !DILocation(line: 18, column: 3, scope: !10)
165
+ !18 = !DILocation(line: 13, column: 8, scope: !19, inlinedAt: !20)
166
+ !19 = distinct !DISubprogram(name: "g3", linkageName: "_ZL2g3v", scope: !1, file: !1, line: 12, type: !11, scopeLine: 12, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0)
167
+ !20 = distinct !DILocation(line: 19, column: 9, scope: !10)
168
+ !21 = !DILocation(line: 14, column: 3, scope: !19, inlinedAt: !20)
169
+ !22 = !DILocation(line: 20, column: 1, scope: !10)
170
+ !23 = !DISubprogram(name: "f1", linkageName: "_Z2f1v", scope: !1, file: !1, line: 1, type: !11, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized)
171
+ !24 = !DISubprogram(name: "g1", linkageName: "_Z2g1v", scope: !1, file: !1, line: 10, type: !11, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized)
172
+ !25 = !DISubprogram(name: "g2", linkageName: "_Z2g2v", scope: !1, file: !1, line: 11, type: !11, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized)
173
+ )IR" ;
174
+
175
+ LLVMContext Ctx;
176
+ SMDiagnostic Err;
177
+ std::unique_ptr<Module> M = parseAssemblyString (IR, Err, Ctx);
178
+ ASSERT_TRUE (M);
179
+
180
+ auto Calls = extractCallsFromIR (*M);
181
+
182
+ // Expect exactly 4 callers.
183
+ ASSERT_THAT (Calls, SizeIs (4 ));
184
+
185
+ // Verify each key-value pair.
186
+
187
+ auto FooIt = Calls.find (IndexedMemProfRecord::getGUID (" _Z3foov" ));
188
+ ASSERT_NE (FooIt, Calls.end ());
189
+ const auto &[FooCallerGUID, FooCallSites] = *FooIt;
190
+ EXPECT_EQ (FooCallerGUID, IndexedMemProfRecord::getGUID (" _Z3foov" ));
191
+ ASSERT_THAT (FooCallSites, SizeIs (2 ));
192
+ EXPECT_THAT (FooCallSites[0 ], Pair (FieldsAre (1U , 3U ),
193
+ IndexedMemProfRecord::getGUID (" _ZL2f3v" )));
194
+ EXPECT_THAT (FooCallSites[1 ], Pair (FieldsAre (2U , 9U ),
195
+ IndexedMemProfRecord::getGUID (" _ZL2g3v" )));
196
+
197
+ auto F2It = Calls.find (IndexedMemProfRecord::getGUID (" _ZL2f2v" ));
198
+ ASSERT_NE (F2It, Calls.end ());
199
+ const auto &[F2CallerGUID, F2CallSites] = *F2It;
200
+ EXPECT_EQ (F2CallerGUID, IndexedMemProfRecord::getGUID (" _ZL2f2v" ));
201
+ ASSERT_THAT (F2CallSites, SizeIs (1 ));
202
+ EXPECT_THAT (F2CallSites[0 ],
203
+ Pair (FieldsAre (2U , 3U ), IndexedMemProfRecord::getGUID (" _Z2f1v" )));
204
+
205
+ auto F3It = Calls.find (IndexedMemProfRecord::getGUID (" _ZL2f3v" ));
206
+ ASSERT_NE (F3It, Calls.end ());
207
+ const auto &[F3CallerGUID, F3CallSites] = *F3It;
208
+ EXPECT_EQ (F3CallerGUID, IndexedMemProfRecord::getGUID (" _ZL2f3v" ));
209
+ ASSERT_THAT (F3CallSites, SizeIs (1 ));
210
+ EXPECT_THAT (F3CallSites[0 ], Pair (FieldsAre (1U , 10U ),
211
+ IndexedMemProfRecord::getGUID (" _ZL2f2v" )));
212
+
213
+ auto G3It = Calls.find (IndexedMemProfRecord::getGUID (" _ZL2g3v" ));
214
+ ASSERT_NE (G3It, Calls.end ());
215
+ const auto &[G3CallerGUID, G3CallSites] = *G3It;
216
+ EXPECT_EQ (G3CallerGUID, IndexedMemProfRecord::getGUID (" _ZL2g3v" ));
217
+ ASSERT_THAT (G3CallSites, SizeIs (2 ));
218
+ EXPECT_THAT (G3CallSites[0 ],
219
+ Pair (FieldsAre (1U , 8U ), IndexedMemProfRecord::getGUID (" _Z2g1v" )));
220
+ EXPECT_THAT (G3CallSites[1 ],
221
+ Pair (FieldsAre (2U , 3U ), IndexedMemProfRecord::getGUID (" _Z2g2v" )));
222
+ }
104
223
} // namespace
0 commit comments