@@ -497,6 +497,10 @@ Error DataAggregator::preprocessProfile(BinaryContext &BC) {
497497 filterBinaryMMapInfo ();
498498 prepareToParse (" events" , MainEventsPPI, ErrorCallback);
499499
500+ if ((!opts::BasicAggregation && parseBranchEvents ()) ||
501+ (opts::BasicAggregation && parseBasicEvents ()))
502+ errs () << " PERF2BOLT: failed to parse samples\n " ;
503+
500504 if (opts::HeatmapMode) {
501505 if (std::error_code EC = printLBRHeatMap ()) {
502506 errs () << " ERROR: failed to print heat map: " << EC.message () << ' \n ' ;
@@ -505,10 +509,6 @@ Error DataAggregator::preprocessProfile(BinaryContext &BC) {
505509 exit (0 );
506510 }
507511
508- if ((!opts::BasicAggregation && parseBranchEvents ()) ||
509- (opts::BasicAggregation && parseBasicEvents ()))
510- errs () << " PERF2BOLT: failed to parse samples\n " ;
511-
512512 // Special handling for memory events
513513 if (prepareToParse (" mem events" , MemEventsPPI, MemEventsErrorCallback))
514514 return Error::success ();
@@ -1307,53 +1307,6 @@ std::error_code DataAggregator::printLBRHeatMap() {
13071307 }
13081308 Heatmap HM (opts::HeatmapBlock, opts::HeatmapMinAddress,
13091309 opts::HeatmapMaxAddress, getTextSections (BC));
1310- uint64_t NumTotalSamples = 0 ;
1311-
1312- if (opts::BasicAggregation) {
1313- while (hasData ()) {
1314- ErrorOr<PerfBasicSample> SampleRes = parseBasicSample ();
1315- if (std::error_code EC = SampleRes.getError ()) {
1316- if (EC == errc::no_such_process)
1317- continue ;
1318- return EC;
1319- }
1320- PerfBasicSample &Sample = SampleRes.get ();
1321- HM.registerAddress (Sample.PC );
1322- NumTotalSamples++;
1323- }
1324- outs () << " HEATMAP: read " << NumTotalSamples << " basic samples\n " ;
1325- } else {
1326- while (hasData ()) {
1327- ErrorOr<PerfBranchSample> SampleRes = parseBranchSample ();
1328- if (std::error_code EC = SampleRes.getError ()) {
1329- if (EC == errc::no_such_process)
1330- continue ;
1331- return EC;
1332- }
1333-
1334- PerfBranchSample &Sample = SampleRes.get ();
1335-
1336- // LBRs are stored in reverse execution order. NextLBR refers to the next
1337- // executed branch record.
1338- const LBREntry *NextLBR = nullptr ;
1339- for (const LBREntry &LBR : Sample.LBR ) {
1340- if (NextLBR) {
1341- // Record fall-through trace.
1342- const uint64_t TraceFrom = LBR.To ;
1343- const uint64_t TraceTo = NextLBR->From ;
1344- ++FallthroughLBRs[Trace (TraceFrom, TraceTo)].InternCount ;
1345- }
1346- NextLBR = &LBR;
1347- }
1348- if (!Sample.LBR .empty ()) {
1349- HM.registerAddress (Sample.LBR .front ().To );
1350- HM.registerAddress (Sample.LBR .back ().From );
1351- }
1352- NumTotalSamples += Sample.LBR .size ();
1353- }
1354- outs () << " HEATMAP: read " << NumTotalSamples << " LBR samples\n " ;
1355- outs () << " HEATMAP: " << FallthroughLBRs.size () << " unique traces\n " ;
1356- }
13571310
13581311 if (!NumTotalSamples) {
13591312 if (opts::BasicAggregation) {
@@ -1369,10 +1322,14 @@ std::error_code DataAggregator::printLBRHeatMap() {
13691322
13701323 outs () << " HEATMAP: building heat map...\n " ;
13711324
1325+ // Register basic samples and perf LBR addresses not covered by fallthroughs.
1326+ for (const auto &[PC, Hits] : BasicSamples)
1327+ HM.registerAddress (PC, Hits);
13721328 for (const auto &LBR : FallthroughLBRs) {
13731329 const Trace &Trace = LBR.first ;
13741330 const FTInfo &Info = LBR.second ;
1375- HM.registerAddressRange (Trace.From , Trace.To , Info.InternCount );
1331+ HM.registerAddressRange (Trace.From , Trace.To ,
1332+ Info.InternCount + Info.ExternCount );
13761333 }
13771334
13781335 if (HM.getNumInvalidRanges ())
@@ -1418,7 +1375,10 @@ void DataAggregator::parseLBRSample(const PerfBranchSample &Sample,
14181375 const uint64_t TraceTo = NextLBR->From ;
14191376 const BinaryFunction *TraceBF =
14201377 getBinaryFunctionContainingAddress (TraceFrom);
1421- if (TraceBF && TraceBF->containsAddress (TraceTo)) {
1378+ if (opts::HeatmapMode) {
1379+ FTInfo &Info = FallthroughLBRs[Trace (TraceFrom, TraceTo)];
1380+ ++Info.InternCount ;
1381+ } else if (TraceBF && TraceBF->containsAddress (TraceTo)) {
14221382 FTInfo &Info = FallthroughLBRs[Trace (TraceFrom, TraceTo)];
14231383 if (TraceBF->containsAddress (LBR.From ))
14241384 ++Info.InternCount ;
@@ -1452,6 +1412,12 @@ void DataAggregator::parseLBRSample(const PerfBranchSample &Sample,
14521412 }
14531413 NextLBR = &LBR;
14541414
1415+ // Record branches outside binary functions for heatmap.
1416+ if (opts::HeatmapMode) {
1417+ TakenBranchInfo &Info = BranchLBRs[Trace (LBR.From , LBR.To )];
1418+ ++Info.TakenCount ;
1419+ continue ;
1420+ }
14551421 uint64_t From = getBinaryFunctionContainingAddress (LBR.From ) ? LBR.From : 0 ;
14561422 uint64_t To = getBinaryFunctionContainingAddress (LBR.To ) ? LBR.To : 0 ;
14571423 if (!From && !To)
@@ -1460,6 +1426,12 @@ void DataAggregator::parseLBRSample(const PerfBranchSample &Sample,
14601426 ++Info.TakenCount ;
14611427 Info.MispredCount += LBR.Mispred ;
14621428 }
1429+ // Record LBR addresses not covered by fallthroughs (bottom-of-stack source
1430+ // and top-of-stack target) as basic samples for heatmap.
1431+ if (opts::HeatmapMode && !Sample.LBR .empty ()) {
1432+ ++BasicSamples[Sample.LBR .front ().To ];
1433+ ++BasicSamples[Sample.LBR .back ().From ];
1434+ }
14631435}
14641436
14651437void DataAggregator::printColdSamplesDiagnostic () const {
@@ -1636,13 +1608,15 @@ std::error_code DataAggregator::parseBasicEvents() {
16361608
16371609 if (!Sample->PC )
16381610 continue ;
1611+ ++NumTotalSamples;
16391612
16401613 if (BinaryFunction *BF = getBinaryFunctionContainingAddress (Sample->PC ))
16411614 BF->setHasProfileAvailable ();
16421615
16431616 ++BasicSamples[Sample->PC ];
16441617 EventNames.insert (Sample->EventName );
16451618 }
1619+ outs () << " PERF2BOLT: read " << NumTotalSamples << " basic samples\n " ;
16461620
16471621 return std::error_code ();
16481622}
@@ -1655,7 +1629,6 @@ void DataAggregator::processBasicEvents() {
16551629 for (auto &Sample : BasicSamples) {
16561630 const uint64_t PC = Sample.first ;
16571631 const uint64_t HitCount = Sample.second ;
1658- NumTotalSamples += HitCount;
16591632 BinaryFunction *Func = getBinaryFunctionContainingAddress (PC);
16601633 if (!Func) {
16611634 OutOfRangeSamples += HitCount;
@@ -1664,7 +1637,6 @@ void DataAggregator::processBasicEvents() {
16641637
16651638 doBasicSample (*Func, PC, HitCount);
16661639 }
1667- outs () << " PERF2BOLT: read " << NumTotalSamples << " samples\n " ;
16681640
16691641 printBasicSamplesDiagnostics (OutOfRangeSamples);
16701642}
0 commit comments