@@ -99,24 +99,28 @@ class DataAggregator : public DataReader {
99
99
uint64_t Addr;
100
100
};
101
101
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
105
+ // / contains fall-through data,
106
+ // / - if \p To is BR_ONLY, the trace only contains branch data.
102
107
struct Trace {
108
+ static constexpr const uint64_t EXTERNAL = 0ULL ;
109
+ static constexpr const uint64_t BR_ONLY = -1ULL ;
110
+ static constexpr const uint64_t FT_ONLY = -1ULL ;
111
+ static constexpr const uint64_t FT_EXTERNAL_ORIGIN = -2ULL ;
112
+
113
+ uint64_t Branch;
103
114
uint64_t From;
104
115
uint64_t To;
105
- Trace (uint64_t From, uint64_t To) : From(From), To(To) {}
106
- bool operator ==(const Trace &Other) const {
107
- return From == Other.From && To == Other.To ;
108
- }
116
+ auto tie () const { return std::tie (Branch, From, To); }
117
+ bool operator ==(const Trace &Other) const { return tie () == Other.tie (); }
118
+ bool operator <(const Trace &Other) const { return tie () < Other.tie (); }
109
119
};
120
+ friend raw_ostream &operator <<(raw_ostream &OS, const Trace &);
110
121
111
122
struct TraceHash {
112
- size_t operator ()(const Trace &L) const {
113
- return std::hash<uint64_t >()(L.From << 32 | L.To );
114
- }
115
- };
116
-
117
- struct FTInfo {
118
- uint64_t InternCount{0 };
119
- uint64_t ExternCount{0 };
123
+ size_t operator ()(const Trace &L) const { return hash_combine (L.tie ()); }
120
124
};
121
125
122
126
struct TakenBranchInfo {
@@ -126,8 +130,8 @@ class DataAggregator : public DataReader {
126
130
127
131
// / Intermediate storage for profile data. We save the results of parsing
128
132
// / and use them later for processing and assigning profile.
129
- std::unordered_map<Trace, TakenBranchInfo, TraceHash> BranchLBRs ;
130
- std::unordered_map< Trace, FTInfo, TraceHash> FallthroughLBRs ;
133
+ std::unordered_map<Trace, TakenBranchInfo, TraceHash> TraceMap ;
134
+ std::vector<std::pair< Trace, TakenBranchInfo>> Traces ;
131
135
std::unordered_map<uint64_t , uint64_t > BasicSamples;
132
136
std::vector<PerfMemSample> MemSamples;
133
137
@@ -200,8 +204,8 @@ class DataAggregator : public DataReader {
200
204
// / Return a vector of offsets corresponding to a trace in a function
201
205
// / if the trace is valid, std::nullopt otherwise.
202
206
std::optional<SmallVector<std::pair<uint64_t , uint64_t >, 16 >>
203
- getFallthroughsInTrace (BinaryFunction &BF, const LBREntry &First ,
204
- const LBREntry &Second, uint64_t Count = 1 ) const ;
207
+ getFallthroughsInTrace (BinaryFunction &BF, const Trace &Trace ,
208
+ uint64_t Count) const ;
205
209
206
210
// / Record external entry into the function \p BF.
207
211
// /
@@ -265,8 +269,7 @@ class DataAggregator : public DataReader {
265
269
bool doBranch (uint64_t From, uint64_t To, uint64_t Count, uint64_t Mispreds);
266
270
267
271
// / Register a trace between two LBR entries supplied in execution order.
268
- bool doTrace (const LBREntry &First, const LBREntry &Second,
269
- uint64_t Count = 1 );
272
+ bool doTrace (const Trace &Trace, uint64_t Count);
270
273
271
274
// / Parser helpers
272
275
// / Return false if we exhausted our parser buffer and finished parsing
@@ -516,6 +519,21 @@ inline raw_ostream &operator<<(raw_ostream &OS,
516
519
OS << formatv (" {0:x} -> {1:x}/{2}" , L.From , L.To , L.Mispred ? ' M' : ' P' );
517
520
return OS;
518
521
}
522
+
523
+ inline raw_ostream &operator <<(raw_ostream &OS,
524
+ const DataAggregator::Trace &T) {
525
+ switch (T.Branch ) {
526
+ case DataAggregator::Trace::FT_ONLY:
527
+ case DataAggregator::Trace::FT_EXTERNAL_ORIGIN:
528
+ break ;
529
+ default :
530
+ OS << Twine::utohexstr (T.Branch ) << " -> " ;
531
+ }
532
+ OS << Twine::utohexstr (T.From );
533
+ if (T.To != DataAggregator::Trace::BR_ONLY)
534
+ OS << " ... " << Twine::utohexstr (T.To );
535
+ return OS;
536
+ }
519
537
} // namespace bolt
520
538
} // namespace llvm
521
539
0 commit comments