@@ -164,6 +164,10 @@ void DataAggregator::findPerfExecutable() {
164164void DataAggregator::start () {
165165 outs () << " PERF2BOLT: Starting data aggregation job for " << Filename << " \n " ;
166166
167+ // Turn on heatmap building if requested by --heatmap flag.
168+ if (!opts::HeatmapMode && opts::HeatmapOutput.getNumOccurrences ())
169+ opts::HeatmapMode = opts::HeatmapModeKind::HM_Optional;
170+
167171 // Don't launch perf for pre-aggregated files or when perf input is specified
168172 // by the user.
169173 if (opts::ReadPreAggregated || !opts::ReadPerfEvents.empty ())
@@ -502,24 +506,25 @@ Error DataAggregator::preprocessProfile(BinaryContext &BC) {
502506 errs () << " PERF2BOLT: failed to parse samples\n " ;
503507
504508 // Special handling for memory events
505- if (prepareToParse (" mem events" , MemEventsPPI, MemEventsErrorCallback))
506- return Error::success ();
507-
508- if (const std::error_code EC = parseMemEvents ())
509- errs () << " PERF2BOLT: failed to parse memory events: " << EC.message ()
510- << ' \n ' ;
509+ if (!prepareToParse (" mem events" , MemEventsPPI, MemEventsErrorCallback))
510+ if (const std::error_code EC = parseMemEvents ())
511+ errs () << " PERF2BOLT: failed to parse memory events: " << EC.message ()
512+ << ' \n ' ;
511513
512514 deleteTempFiles ();
513515
514516heatmap:
515- if (opts::HeatmapMode) {
516- if (std::error_code EC = printLBRHeatMap ()) {
517- errs () << " ERROR: failed to print heat map: " << EC.message () << ' \n ' ;
518- exit (1 );
519- }
520- exit (0 );
521- }
522- return Error::success ();
517+ if (!opts::HeatmapMode)
518+ return Error::success ();
519+
520+ if (std::error_code EC = printLBRHeatMap ())
521+ return errorCodeToError (EC);
522+
523+ if (opts::HeatmapMode == opts::HeatmapModeKind::HM_Optional)
524+ return Error::success ();
525+
526+ assert (opts::HeatmapMode == opts::HeatmapModeKind::HM_Exclusive);
527+ exit (0 );
523528}
524529
525530Error DataAggregator::readProfile (BinaryContext &BC) {
@@ -635,8 +640,6 @@ bool DataAggregator::doBasicSample(BinaryFunction &OrigFunc, uint64_t Address,
635640
636641 BinaryFunction *ParentFunc = getBATParentFunction (OrigFunc);
637642 BinaryFunction &Func = ParentFunc ? *ParentFunc : OrigFunc;
638- if (ParentFunc || (BAT && !BAT->isBATFunction (Func.getAddress ())))
639- NumColdSamples += Count;
640643 // Attach executed bytes to parent function in case of cold fragment.
641644 Func.SampleCountInBytes += Count * BlockSize;
642645
@@ -740,15 +743,10 @@ bool DataAggregator::doBranch(uint64_t From, uint64_t To, uint64_t Count,
740743 if (BAT)
741744 Addr = BAT->translate (Func->getAddress (), Addr, IsFrom);
742745
743- BinaryFunction *ParentFunc = getBATParentFunction (*Func);
744- if (IsFrom &&
745- (ParentFunc || (BAT && !BAT->isBATFunction (Func->getAddress ()))))
746- NumColdSamples += Count;
747-
748- if (!ParentFunc)
749- return std::pair{Func, IsRet};
746+ if (BinaryFunction *ParentFunc = getBATParentFunction (*Func))
747+ Func = ParentFunc;
750748
751- return std::pair{ParentFunc , IsRet};
749+ return std::pair{Func , IsRet};
752750 };
753751
754752 auto [FromFunc, IsReturn] = handleAddress (From, /* IsFrom*/ true );
@@ -1351,15 +1349,14 @@ std::error_code DataAggregator::printLBRHeatMap() {
13511349 exit (1 );
13521350 }
13531351
1354- HM.print (opts::OutputFilename);
1355- if (opts::OutputFilename == " -" )
1356- HM.printCDF (opts::OutputFilename);
1357- else
1358- HM.printCDF (opts::OutputFilename + " .csv" );
1359- if (opts::OutputFilename == " -" )
1360- HM.printSectionHotness (opts::OutputFilename);
1361- else
1362- HM.printSectionHotness (opts::OutputFilename + " -section-hotness.csv" );
1352+ HM.print (opts::HeatmapOutput);
1353+ if (opts::HeatmapOutput == " -" ) {
1354+ HM.printCDF (opts::HeatmapOutput);
1355+ HM.printSectionHotness (opts::HeatmapOutput);
1356+ } else {
1357+ HM.printCDF (opts::HeatmapOutput + " .csv" );
1358+ HM.printSectionHotness (opts::HeatmapOutput + " -section-hotness.csv" );
1359+ }
13631360
13641361 return std::error_code ();
13651362}
@@ -1386,7 +1383,7 @@ void DataAggregator::parseLBRSample(const PerfBranchSample &Sample,
13861383 const uint64_t TraceTo = NextLBR->From ;
13871384 const BinaryFunction *TraceBF =
13881385 getBinaryFunctionContainingAddress (TraceFrom);
1389- if (opts::HeatmapMode) {
1386+ if (opts::HeatmapMode == opts::HeatmapModeKind::HM_Exclusive ) {
13901387 FTInfo &Info = FallthroughLBRs[Trace (TraceFrom, TraceTo)];
13911388 ++Info.InternCount ;
13921389 } else if (TraceBF && TraceBF->containsAddress (TraceTo)) {
@@ -1424,7 +1421,7 @@ void DataAggregator::parseLBRSample(const PerfBranchSample &Sample,
14241421 NextLBR = &LBR;
14251422
14261423 // Record branches outside binary functions for heatmap.
1427- if (opts::HeatmapMode) {
1424+ if (opts::HeatmapMode == opts::HeatmapModeKind::HM_Exclusive ) {
14281425 TakenBranchInfo &Info = BranchLBRs[Trace (LBR.From , LBR.To )];
14291426 ++Info.TakenCount ;
14301427 continue ;
@@ -1439,26 +1436,13 @@ void DataAggregator::parseLBRSample(const PerfBranchSample &Sample,
14391436 }
14401437 // Record LBR addresses not covered by fallthroughs (bottom-of-stack source
14411438 // and top-of-stack target) as basic samples for heatmap.
1442- if (opts::HeatmapMode && !Sample.LBR .empty ()) {
1439+ if (opts::HeatmapMode == opts::HeatmapModeKind::HM_Exclusive &&
1440+ !Sample.LBR .empty ()) {
14431441 ++BasicSamples[Sample.LBR .front ().To ];
14441442 ++BasicSamples[Sample.LBR .back ().From ];
14451443 }
14461444}
14471445
1448- void DataAggregator::printColdSamplesDiagnostic () const {
1449- if (NumColdSamples > 0 ) {
1450- const float ColdSamples = NumColdSamples * 100 .0f / NumTotalSamples;
1451- outs () << " PERF2BOLT: " << NumColdSamples
1452- << format (" (%.1f%%)" , ColdSamples)
1453- << " samples recorded in cold regions of split functions.\n " ;
1454- if (ColdSamples > 5 .0f )
1455- outs ()
1456- << " WARNING: The BOLT-processed binary where samples were collected "
1457- " likely used bad data or your service observed a large shift in "
1458- " profile. You may want to audit this\n " ;
1459- }
1460- }
1461-
14621446void DataAggregator::printLongRangeTracesDiagnostic () const {
14631447 outs () << " PERF2BOLT: out of range traces involving unknown regions: "
14641448 << NumLongRangeTraces;
@@ -1499,7 +1483,6 @@ void DataAggregator::printBranchSamplesDiagnostics() const {
14991483 " collection. The generated data may be ineffective for improving "
15001484 " performance\n\n " ;
15011485 printLongRangeTracesDiagnostic ();
1502- printColdSamplesDiagnostic ();
15031486}
15041487
15051488void DataAggregator::printBasicSamplesDiagnostics (
@@ -1511,7 +1494,6 @@ void DataAggregator::printBasicSamplesDiagnostics(
15111494 " binary is probably not the same binary used during profiling "
15121495 " collection. The generated data may be ineffective for improving "
15131496 " performance\n\n " ;
1514- printColdSamplesDiagnostic ();
15151497}
15161498
15171499void DataAggregator::printBranchStacksDiagnostics (
0 commit comments