@@ -711,7 +711,7 @@ bool DataAggregator::doInterBranch(BinaryFunction *FromFunc,
711711}
712712
713713bool DataAggregator::doBranch (uint64_t From, uint64_t To, uint64_t Count,
714- uint64_t Mispreds, bool IsPreagg ) {
714+ uint64_t Mispreds) {
715715 // Returns whether \p Offset in \p Func contains a return instruction.
716716 auto checkReturn = [&](const BinaryFunction &Func, const uint64_t Offset) {
717717 auto isReturn = [&](auto MI) { return MI && BC->MIB ->isReturn (*MI); };
@@ -772,7 +772,8 @@ bool DataAggregator::doBranch(uint64_t From, uint64_t To, uint64_t Count,
772772 return false ;
773773
774774 // Record call to continuation trace.
775- if (IsPreagg && FromFunc != ToFunc && (IsReturn || IsCallCont)) {
775+ if (NeedsConvertRetProfileToCallCont && FromFunc != ToFunc &&
776+ (IsReturn || IsCallCont)) {
776777 LBREntry First{ToOrig - 1 , ToOrig - 1 , false };
777778 LBREntry Second{ToOrig, ToOrig, false };
778779 return doTrace (First, Second, Count);
@@ -1216,23 +1217,30 @@ ErrorOr<Location> DataAggregator::parseLocationOrOffset() {
12161217 return Location (true , BuildID.get (), Offset.get ());
12171218}
12181219
1219- ErrorOr<DataAggregator::AggregatedLBREntry>
1220- DataAggregator::parseAggregatedLBREntry () {
1220+ std::error_code DataAggregator::parseAggregatedLBREntry () {
12211221 while (checkAndConsumeFS ()) {
12221222 }
12231223
12241224 ErrorOr<StringRef> TypeOrErr = parseString (FieldSeparator);
12251225 if (std::error_code EC = TypeOrErr.getError ())
12261226 return EC;
1227+ // Pre-aggregated profile with branches and fallthroughs needs to convert
1228+ // return profile into call to continuation fall-through.
12271229 auto Type = AggregatedLBREntry::BRANCH;
12281230 if (TypeOrErr.get () == " B" ) {
1231+ NeedsConvertRetProfileToCallCont = true ;
12291232 Type = AggregatedLBREntry::BRANCH;
12301233 } else if (TypeOrErr.get () == " F" ) {
1234+ NeedsConvertRetProfileToCallCont = true ;
12311235 Type = AggregatedLBREntry::FT;
12321236 } else if (TypeOrErr.get () == " f" ) {
1237+ NeedsConvertRetProfileToCallCont = true ;
12331238 Type = AggregatedLBREntry::FT_EXTERNAL_ORIGIN;
1239+ } else if (TypeOrErr.get () == " T" ) {
1240+ // Trace is expanded into B and [Ff]
1241+ Type = AggregatedLBREntry::TRACE;
12341242 } else {
1235- reportError (" expected B, F or f" );
1243+ reportError (" expected T, B, F or f" );
12361244 return make_error_code (llvm::errc::io_error);
12371245 }
12381246
@@ -1248,6 +1256,15 @@ DataAggregator::parseAggregatedLBREntry() {
12481256 if (std::error_code EC = To.getError ())
12491257 return EC;
12501258
1259+ ErrorOr<Location> TraceFtEnd = std::error_code ();
1260+ if (Type == AggregatedLBREntry::TRACE) {
1261+ while (checkAndConsumeFS ()) {
1262+ }
1263+ TraceFtEnd = parseLocationOrOffset ();
1264+ if (std::error_code EC = TraceFtEnd.getError ())
1265+ return EC;
1266+ }
1267+
12511268 while (checkAndConsumeFS ()) {
12521269 }
12531270 ErrorOr<int64_t > Frequency =
@@ -1270,9 +1287,24 @@ DataAggregator::parseAggregatedLBREntry() {
12701287 return make_error_code (llvm::errc::io_error);
12711288 }
12721289
1273- return AggregatedLBREntry{From.get (), To.get (),
1274- static_cast <uint64_t >(Frequency.get ()), Mispreds,
1275- Type};
1290+ BinaryFunction *FromFunc = getBinaryFunctionContainingAddress (From->Offset );
1291+ BinaryFunction *ToFunc = getBinaryFunctionContainingAddress (To->Offset );
1292+
1293+ for (BinaryFunction *BF : {FromFunc, ToFunc})
1294+ if (BF)
1295+ BF->setHasProfileAvailable ();
1296+
1297+ uint64_t Count = static_cast <uint64_t >(Frequency.get ());
1298+ AggregatedLBREntry Entry{From.get (), To.get (), Count, Mispreds, Type};
1299+ AggregatedLBRs.emplace_back (Entry);
1300+ if (Type == AggregatedLBREntry::TRACE) {
1301+ auto FtType = (FromFunc == ToFunc) ? AggregatedLBREntry::FT
1302+ : AggregatedLBREntry::FT_EXTERNAL_ORIGIN;
1303+ AggregatedLBREntry TraceFt{To.get (), TraceFtEnd.get (), Count, 0 , FtType};
1304+ AggregatedLBRs.emplace_back (TraceFt);
1305+ }
1306+
1307+ return std::error_code ();
12761308}
12771309
12781310bool DataAggregator::ignoreKernelInterrupt (LBREntry &LBR) const {
@@ -1585,8 +1617,7 @@ void DataAggregator::processBranchEvents() {
15851617 for (const auto &AggrLBR : BranchLBRs) {
15861618 const Trace &Loc = AggrLBR.first ;
15871619 const TakenBranchInfo &Info = AggrLBR.second ;
1588- doBranch (Loc.From , Loc.To , Info.TakenCount , Info.MispredCount ,
1589- /* IsPreagg*/ false );
1620+ doBranch (Loc.From , Loc.To , Info.TakenCount , Info.MispredCount );
15901621 }
15911622}
15921623
@@ -1722,18 +1753,10 @@ std::error_code DataAggregator::parsePreAggregatedLBRSamples() {
17221753 outs () << " PERF2BOLT: parsing pre-aggregated profile...\n " ;
17231754 NamedRegionTimer T (" parseAggregated" , " Parsing aggregated branch events" ,
17241755 TimerGroupName, TimerGroupDesc, opts::TimeAggregator);
1725- while (hasData ()) {
1726- ErrorOr<AggregatedLBREntry> AggrEntry = parseAggregatedLBREntry ();
1727- if (std::error_code EC = AggrEntry.getError ())
1756+ while (hasData ())
1757+ if (std::error_code EC = parseAggregatedLBREntry ())
17281758 return EC;
17291759
1730- for (const uint64_t Addr : {AggrEntry->From .Offset , AggrEntry->To .Offset })
1731- if (BinaryFunction *BF = getBinaryFunctionContainingAddress (Addr))
1732- BF->setHasProfileAvailable ();
1733-
1734- AggregatedLBRs.emplace_back (std::move (AggrEntry.get ()));
1735- }
1736-
17371760 return std::error_code ();
17381761}
17391762
@@ -1746,8 +1769,9 @@ void DataAggregator::processPreAggregated() {
17461769 for (const AggregatedLBREntry &AggrEntry : AggregatedLBRs) {
17471770 switch (AggrEntry.EntryType ) {
17481771 case AggregatedLBREntry::BRANCH:
1772+ case AggregatedLBREntry::TRACE:
17491773 doBranch (AggrEntry.From .Offset , AggrEntry.To .Offset , AggrEntry.Count ,
1750- AggrEntry.Mispreds , /* IsPreagg */ true );
1774+ AggrEntry.Mispreds );
17511775 break ;
17521776 case AggregatedLBREntry::FT:
17531777 case AggregatedLBREntry::FT_EXTERNAL_ORIGIN: {
0 commit comments