@@ -197,34 +197,27 @@ void DataAggregator::start() {
197197
198198 if (opts::BasicAggregation) {
199199 launchPerfProcess (" events without LBR" , MainEventsPPI,
200- " script -F pid,event,ip" ,
201- /* Wait = */ false );
200+ " script -F pid,event,ip" );
202201 } else if (!opts::ITraceAggregation.empty ()) {
203202 // Disable parsing memory profile from trace data, unless requested by user.
204203 if (!opts::ParseMemProfile.getNumOccurrences ())
205204 opts::ParseMemProfile = false ;
206-
207- std::string ItracePerfScriptArgs = llvm::formatv (
208- " script -F pid,brstack --itrace={0}" , opts::ITraceAggregation);
209205 launchPerfProcess (" branch events with itrace" , MainEventsPPI,
210- ItracePerfScriptArgs. c_str (),
211- /* Wait = */ false );
206+ " script -F pid,brstack --itrace= " +
207+ opts::ITraceAggregation );
212208 } else {
213- launchPerfProcess (" branch events" , MainEventsPPI, " script -F pid,brstack" ,
214- /* Wait = */ false );
209+ launchPerfProcess (" branch events" , MainEventsPPI, " script -F pid,brstack" );
215210 }
216211
217212 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 " );
220215
221216 launchPerfProcess (" process events" , MMapEventsPPI,
222- " script --show-mmap-events --no-itrace" ,
223- /* Wait = */ false );
217+ " script --show-mmap-events --no-itrace" );
224218
225219 launchPerfProcess (" task events" , TaskEventsPPI,
226- " script --show-task-events --no-itrace" ,
227- /* Wait = */ false );
220+ " script --show-task-events --no-itrace" );
228221}
229222
230223void DataAggregator::abort () {
@@ -246,13 +239,13 @@ void DataAggregator::abort() {
246239}
247240
248241void DataAggregator::launchPerfProcess (StringRef Name, PerfProcessInfo &PPI,
249- const char *ArgsString, bool Wait ) {
242+ StringRef Args ) {
250243 SmallVector<StringRef, 4 > Argv;
251244
252245 outs () << " PERF2BOLT: spawning perf job to read " << Name << ' \n ' ;
253246 Argv.push_back (PerfPath.data ());
254247
255- StringRef (ArgsString) .split (Argv, ' ' );
248+ Args .split (Argv, ' ' );
256249 Argv.push_back (" -f" );
257250 Argv.push_back (" -i" );
258251 Argv.push_back (Filename.c_str ());
@@ -286,64 +279,45 @@ void DataAggregator::launchPerfProcess(StringRef Name, PerfProcessInfo &PPI,
286279 << " \n " ;
287280 });
288281
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);
295284}
296285
297286void DataAggregator::processFileBuildID (StringRef FileBuildID) {
287+ auto WarningCallback = [](int ReturnCode, StringRef ErrBuf) {
288+ errs () << " PERF-ERROR: return code " << ReturnCode << " \n " << ErrBuf;
289+ };
290+
298291 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))
312294 return ;
313- }
314295
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 " ;
320299 return ;
321300 }
322301
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) {
342303 errs () << " PERF2BOLT-WARNING: build-id matched a different file name\n " ;
343304 BuildIDBinaryName = std::string (*FileName);
344- } else {
345- outs () << " PERF2BOLT: matched build-id and file name\n " ;
305+ return ;
346306 }
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 ();
347321}
348322
349323bool DataAggregator::checkPerfDataMagic (StringRef FileName) {
@@ -432,14 +406,24 @@ int DataAggregator::prepareToParse(StringRef Name, PerfProcessInfo &Process,
432406 std::string Error;
433407 outs () << " PERF2BOLT: waiting for perf " << Name
434408 << " 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);
436411
437412 if (!Error.empty ()) {
438413 errs () << " PERF-ERROR: " << PerfPath << " : " << Error << " \n " ;
439414 deleteTempFiles ();
440415 exit (1 );
441416 }
442417
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+
443427 if (PI.ReturnCode != 0 ) {
444428 ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorMB =
445429 MemoryBuffer::getFileOrSTDIN (Process.StderrPath .data ());
0 commit comments