@@ -197,34 +197,27 @@ void DataAggregator::start() {
197
197
198
198
if (opts::BasicAggregation) {
199
199
launchPerfProcess (" events without LBR" , MainEventsPPI,
200
- " script -F pid,event,ip" ,
201
- /* Wait = */ false );
200
+ " script -F pid,event,ip" );
202
201
} else if (!opts::ITraceAggregation.empty ()) {
203
202
// Disable parsing memory profile from trace data, unless requested by user.
204
203
if (!opts::ParseMemProfile.getNumOccurrences ())
205
204
opts::ParseMemProfile = false ;
206
-
207
- std::string ItracePerfScriptArgs = llvm::formatv (
208
- " script -F pid,brstack --itrace={0}" , opts::ITraceAggregation);
209
205
launchPerfProcess (" branch events with itrace" , MainEventsPPI,
210
- ItracePerfScriptArgs. c_str (),
211
- /* Wait = */ false );
206
+ " script -F pid,brstack --itrace= " +
207
+ opts::ITraceAggregation );
212
208
} else {
213
- launchPerfProcess (" branch events" , MainEventsPPI, " script -F pid,brstack" ,
214
- /* Wait = */ false );
209
+ launchPerfProcess (" branch events" , MainEventsPPI, " script -F pid,brstack" );
215
210
}
216
211
217
212
if (opts::ParseMemProfile)
218
- launchPerfProcess (" mem events" , MemEventsPPI, " script -F pid,event,addr,ip " ,
219
- /* Wait = */ false );
213
+ launchPerfProcess (" mem events" , MemEventsPPI,
214
+ " script -F pid,event,addr,ip " );
220
215
221
216
launchPerfProcess (" process events" , MMapEventsPPI,
222
- " script --show-mmap-events --no-itrace" ,
223
- /* Wait = */ false );
217
+ " script --show-mmap-events --no-itrace" );
224
218
225
219
launchPerfProcess (" task events" , TaskEventsPPI,
226
- " script --show-task-events --no-itrace" ,
227
- /* Wait = */ false );
220
+ " script --show-task-events --no-itrace" );
228
221
}
229
222
230
223
void DataAggregator::abort () {
@@ -246,13 +239,13 @@ void DataAggregator::abort() {
246
239
}
247
240
248
241
void DataAggregator::launchPerfProcess (StringRef Name, PerfProcessInfo &PPI,
249
- const char *ArgsString, bool Wait ) {
242
+ StringRef Args ) {
250
243
SmallVector<StringRef, 4 > Argv;
251
244
252
245
outs () << " PERF2BOLT: spawning perf job to read " << Name << ' \n ' ;
253
246
Argv.push_back (PerfPath.data ());
254
247
255
- StringRef (ArgsString) .split (Argv, ' ' );
248
+ Args .split (Argv, ' ' );
256
249
Argv.push_back (" -f" );
257
250
Argv.push_back (" -i" );
258
251
Argv.push_back (Filename.c_str ());
@@ -286,64 +279,45 @@ void DataAggregator::launchPerfProcess(StringRef Name, PerfProcessInfo &PPI,
286
279
<< " \n " ;
287
280
});
288
281
289
- if (Wait)
290
- PPI.PI .ReturnCode = sys::ExecuteAndWait (PerfPath.data (), Argv,
291
- /* envp*/ std::nullopt, Redirects);
292
- else
293
- PPI.PI = sys::ExecuteNoWait (PerfPath.data (), Argv, /* envp*/ std::nullopt,
294
- Redirects);
282
+ PPI.PI = sys::ExecuteNoWait (PerfPath.data (), Argv, /* envp*/ std::nullopt,
283
+ Redirects);
295
284
}
296
285
297
286
void DataAggregator::processFileBuildID (StringRef FileBuildID) {
287
+ auto WarningCallback = [](int ReturnCode, StringRef ErrBuf) {
288
+ errs () << " PERF-ERROR: return code " << ReturnCode << " \n " << ErrBuf;
289
+ };
290
+
298
291
PerfProcessInfo BuildIDProcessInfo;
299
- launchPerfProcess (" buildid list" ,
300
- BuildIDProcessInfo,
301
- " buildid-list" ,
302
- /* Wait = */ true );
303
-
304
- if (BuildIDProcessInfo.PI .ReturnCode != 0 ) {
305
- ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
306
- MemoryBuffer::getFileOrSTDIN (BuildIDProcessInfo.StderrPath .data ());
307
- StringRef ErrBuf = (*MB)->getBuffer ();
308
-
309
- errs () << " PERF-ERROR: return code " << BuildIDProcessInfo.PI .ReturnCode
310
- << ' \n ' ;
311
- errs () << ErrBuf;
292
+ launchPerfProcess (" buildid list" , BuildIDProcessInfo, " buildid-list" );
293
+ if (prepareToParse (" buildid" , BuildIDProcessInfo, WarningCallback))
312
294
return ;
313
- }
314
295
315
- ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
316
- MemoryBuffer::getFileOrSTDIN (BuildIDProcessInfo.StdoutPath .data ());
317
- if (std::error_code EC = MB.getError ()) {
318
- errs () << " Cannot open " << BuildIDProcessInfo.StdoutPath .data () << " : "
319
- << EC.message () << " \n " ;
296
+ std::optional<StringRef> FileName = getFileNameForBuildID (FileBuildID);
297
+ if (FileName && *FileName == sys::path::filename (BC->getFilename ())) {
298
+ outs () << " PERF2BOLT: matched build-id and file name\n " ;
320
299
return ;
321
300
}
322
301
323
- FileBuf = std::move (*MB);
324
- ParsingBuf = FileBuf->getBuffer ();
325
-
326
- std::optional<StringRef> FileName = getFileNameForBuildID (FileBuildID);
327
- if (!FileName) {
328
- if (hasAllBuildIDs ()) {
329
- errs () << " PERF2BOLT-ERROR: failed to match build-id from perf output. "
330
- " This indicates the input binary supplied for data aggregation "
331
- " is not the same recorded by perf when collecting profiling "
332
- " data, or there were no samples recorded for the binary. "
333
- " Use -ignore-build-id option to override.\n " ;
334
- if (!opts::IgnoreBuildID)
335
- abort ();
336
- } else {
337
- errs () << " PERF2BOLT-WARNING: build-id will not be checked because perf "
338
- " data was recorded without it\n " ;
339
- return ;
340
- }
341
- } else if (*FileName != llvm::sys::path::filename (BC->getFilename ())) {
302
+ if (FileName) {
342
303
errs () << " PERF2BOLT-WARNING: build-id matched a different file name\n " ;
343
304
BuildIDBinaryName = std::string (*FileName);
344
- } else {
345
- outs () << " PERF2BOLT: matched build-id and file name\n " ;
305
+ return ;
346
306
}
307
+
308
+ if (!hasAllBuildIDs ()) {
309
+ errs () << " PERF2BOLT-WARNING: build-id will not be checked because perf "
310
+ " data was recorded without it\n " ;
311
+ return ;
312
+ }
313
+
314
+ errs () << " PERF2BOLT-ERROR: failed to match build-id from perf output. "
315
+ " This indicates the input binary supplied for data aggregation "
316
+ " is not the same recorded by perf when collecting profiling "
317
+ " data, or there were no samples recorded for the binary. "
318
+ " Use -ignore-build-id option to override.\n " ;
319
+ if (!opts::IgnoreBuildID)
320
+ abort ();
347
321
}
348
322
349
323
bool DataAggregator::checkPerfDataMagic (StringRef FileName) {
@@ -432,14 +406,24 @@ int DataAggregator::prepareToParse(StringRef Name, PerfProcessInfo &Process,
432
406
std::string Error;
433
407
outs () << " PERF2BOLT: waiting for perf " << Name
434
408
<< " collection to finish...\n " ;
435
- sys::ProcessInfo PI = sys::Wait (Process.PI , std::nullopt, &Error);
409
+ std::optional<sys::ProcessStatistics> PS;
410
+ sys::ProcessInfo PI = sys::Wait (Process.PI , std::nullopt, &Error, &PS);
436
411
437
412
if (!Error.empty ()) {
438
413
errs () << " PERF-ERROR: " << PerfPath << " : " << Error << " \n " ;
439
414
deleteTempFiles ();
440
415
exit (1 );
441
416
}
442
417
418
+ LLVM_DEBUG ({
419
+ const float UserSec = 1 .f * PS->UserTime .count () / 1e6 ;
420
+ const float TotalSec = 1 .f * PS->TotalTime .count () / 1e6 ;
421
+ const float PeakGiB = 1 .f * PS->PeakMemory / (1 << 20 );
422
+ dbgs () << formatv (" Finished in {0:f2}s user time, {1:f2}s total time, "
423
+ " {2:f2} GiB peak RSS\n " ,
424
+ UserSec, TotalSec, PeakGiB);
425
+ });
426
+
443
427
if (PI.ReturnCode != 0 ) {
444
428
ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorMB =
445
429
MemoryBuffer::getFileOrSTDIN (Process.StderrPath .data ());
0 commit comments