@@ -78,6 +78,13 @@ class DataAggregator : public DataReader {
7878 static bool checkPerfDataMagic (StringRef FileName);
7979
8080private:
81+ struct LBREntry {
82+ uint64_t From;
83+ uint64_t To;
84+ bool Mispred;
85+ };
86+ friend raw_ostream &operator <<(raw_ostream &OS, const LBREntry &);
87+
8188 struct PerfBranchSample {
8289 SmallVector<LBREntry, 32 > LBR;
8390 };
@@ -92,35 +99,43 @@ class DataAggregator : public DataReader {
9299 uint64_t Addr;
93100 };
94101
102+ // / Container for the unit of branch data.
103+ // / Backwards compatible with legacy use for branches and fall-throughs:
104+ // / - if \p Branch is FT_ONLY or FT_EXTERNAL_ORIGIN, the trace only contains
105+ // / fall-through data,
106+ // / - if \p To is EXTERNAL, the trace only contains branch data.
95107 struct Trace {
108+ static constexpr const uint64_t EXTERNAL = 0ULL ;
109+ static constexpr const uint64_t FT_ONLY = -1ULL ;
110+ static constexpr const uint64_t FT_EXTERNAL_ORIGIN = -2ULL ;
111+
112+ uint64_t Branch;
96113 uint64_t From;
97114 uint64_t To;
98- Trace (uint64_t From, uint64_t To) : From(From), To(To) {}
99115 bool operator ==(const Trace &Other) const {
100- return From == Other.From && To == Other.To ;
116+ return Branch == Other. Branch && From == Other.From && To == Other.To ;
101117 }
102118 };
119+ friend raw_ostream &operator <<(raw_ostream &OS, const Trace &);
103120
104121 struct TraceHash {
105122 size_t operator ()(const Trace &L) const {
106- return std::hash< uint64_t >()(L. From << 32 | L.To );
123+ return llvm::hash_combine (L. Branch , L. From , L.To );
107124 }
108125 };
109126
110- struct FTInfo {
111- uint64_t InternCount{0 };
112- uint64_t ExternCount{0 };
113- };
114-
115127 struct TakenBranchInfo {
116128 uint64_t TakenCount{0 };
117129 uint64_t MispredCount{0 };
118130 };
119131
120132 // / Intermediate storage for profile data. We save the results of parsing
121133 // / and use them later for processing and assigning profile.
122- std::unordered_map<Trace, TakenBranchInfo, TraceHash> BranchLBRs;
123- std::unordered_map<Trace, FTInfo, TraceHash> FallthroughLBRs;
134+ std::unordered_map<Trace, TakenBranchInfo, TraceHash> TraceMap;
135+ std::vector<std::pair<Trace, TakenBranchInfo>> Traces;
136+ // / Pre-populated addresses of returns, coming from pre-aggregated data or
137+ // / disassembly. Used to disambiguate call-continuation fall-throughs.
138+ std::unordered_set<uint64_t > Returns;
124139 std::unordered_map<uint64_t , uint64_t > BasicSamples;
125140 std::vector<PerfMemSample> MemSamples;
126141
@@ -193,8 +208,8 @@ class DataAggregator : public DataReader {
193208 // / Return a vector of offsets corresponding to a trace in a function
194209 // / if the trace is valid, std::nullopt otherwise.
195210 std::optional<SmallVector<std::pair<uint64_t , uint64_t >, 16 >>
196- getFallthroughsInTrace (BinaryFunction &BF, const LBREntry &First ,
197- const LBREntry &Second, uint64_t Count = 1 ) const ;
211+ getFallthroughsInTrace (BinaryFunction &BF, const Trace &Trace, uint64_t Count ,
212+ bool IsReturn ) const ;
198213
199214 // / Record external entry into the function \p BF.
200215 // /
@@ -255,11 +270,10 @@ class DataAggregator : public DataReader {
255270 uint64_t Mispreds);
256271
257272 // / Register a \p Branch.
258- bool doBranch (uint64_t From, uint64_t To , uint64_t Count, uint64_t Mispreds);
273+ bool doBranch (const Trace &Trace , uint64_t Count, uint64_t Mispreds);
259274
260275 // / Register a trace between two LBR entries supplied in execution order.
261- bool doTrace (const LBREntry &First, const LBREntry &Second,
262- uint64_t Count = 1 );
276+ bool doTrace (const Trace &Trace, uint64_t Count);
263277
264278 // / Parser helpers
265279 // / Return false if we exhausted our parser buffer and finished parsing
@@ -476,7 +490,6 @@ class DataAggregator : public DataReader {
476490
477491 // / Debugging dump methods
478492 void dump () const ;
479- void dump (const LBREntry &LBR) const ;
480493 void dump (const PerfBranchSample &Sample) const ;
481494 void dump (const PerfMemSample &Sample) const ;
482495
@@ -504,6 +517,27 @@ class DataAggregator : public DataReader {
504517
505518 friend class YAMLProfileWriter ;
506519};
520+
521+ inline raw_ostream &operator <<(raw_ostream &OS,
522+ const DataAggregator::LBREntry &L) {
523+ OS << formatv (" {0:x} -> {1:x}/{2}" , L.From , L.To , L.Mispred ? ' M' : ' P' );
524+ return OS;
525+ }
526+
527+ inline raw_ostream &operator <<(raw_ostream &OS,
528+ const DataAggregator::Trace &T) {
529+ switch (T.Branch ) {
530+ case DataAggregator::Trace::FT_ONLY:
531+ case DataAggregator::Trace::FT_EXTERNAL_ORIGIN:
532+ break ;
533+ default :
534+ OS << Twine::utohexstr (T.Branch ) << " -> " ;
535+ }
536+ OS << Twine::utohexstr (T.From );
537+ if (T.To )
538+ OS << " ... " << Twine::utohexstr (T.To );
539+ return OS;
540+ }
507541} // namespace bolt
508542} // namespace llvm
509543
0 commit comments