Skip to content
54 changes: 36 additions & 18 deletions bolt/include/bolt/Profile/DataAggregator.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,24 +99,28 @@ class DataAggregator : public DataReader {
uint64_t Addr;
};

/// Container for the unit of branch data.
/// Backwards compatible with legacy use for branches and fall-throughs:
/// - if \p Branch is FT_ONLY or FT_EXTERNAL_ORIGIN, the trace only
/// contains fall-through data,
/// - if \p To is BR_ONLY, the trace only contains branch data.
struct Trace {
static constexpr const uint64_t EXTERNAL = 0ULL;
static constexpr const uint64_t BR_ONLY = -1ULL;
static constexpr const uint64_t FT_ONLY = -1ULL;
static constexpr const uint64_t FT_EXTERNAL_ORIGIN = -2ULL;

uint64_t Branch;
uint64_t From;
uint64_t To;
Trace(uint64_t From, uint64_t To) : From(From), To(To) {}
bool operator==(const Trace &Other) const {
return From == Other.From && To == Other.To;
}
auto tie() const { return std::tie(Branch, From, To); }
bool operator==(const Trace &Other) const { return tie() == Other.tie(); }
bool operator<(const Trace &Other) const { return tie() < Other.tie(); }
};
friend raw_ostream &operator<<(raw_ostream &OS, const Trace &);

struct TraceHash {
size_t operator()(const Trace &L) const {
return std::hash<uint64_t>()(L.From << 32 | L.To);
}
};

struct FTInfo {
uint64_t InternCount{0};
uint64_t ExternCount{0};
size_t operator()(const Trace &L) const { return hash_combine(L.tie()); }
};

struct TakenBranchInfo {
Expand All @@ -126,8 +130,8 @@ class DataAggregator : public DataReader {

/// Intermediate storage for profile data. We save the results of parsing
/// and use them later for processing and assigning profile.
std::unordered_map<Trace, TakenBranchInfo, TraceHash> BranchLBRs;
std::unordered_map<Trace, FTInfo, TraceHash> FallthroughLBRs;
std::unordered_map<Trace, TakenBranchInfo, TraceHash> TraceMap;
std::vector<std::pair<Trace, TakenBranchInfo>> Traces;
std::unordered_map<uint64_t, uint64_t> BasicSamples;
std::vector<PerfMemSample> MemSamples;

Expand Down Expand Up @@ -200,8 +204,8 @@ class DataAggregator : public DataReader {
/// Return a vector of offsets corresponding to a trace in a function
/// if the trace is valid, std::nullopt otherwise.
std::optional<SmallVector<std::pair<uint64_t, uint64_t>, 16>>
getFallthroughsInTrace(BinaryFunction &BF, const LBREntry &First,
const LBREntry &Second, uint64_t Count = 1) const;
getFallthroughsInTrace(BinaryFunction &BF, const Trace &Trace,
uint64_t Count) const;

/// Record external entry into the function \p BF.
///
Expand Down Expand Up @@ -265,8 +269,7 @@ class DataAggregator : public DataReader {
bool doBranch(uint64_t From, uint64_t To, uint64_t Count, uint64_t Mispreds);

/// Register a trace between two LBR entries supplied in execution order.
bool doTrace(const LBREntry &First, const LBREntry &Second,
uint64_t Count = 1);
bool doTrace(const Trace &Trace, uint64_t Count);

/// Parser helpers
/// Return false if we exhausted our parser buffer and finished parsing
Expand Down Expand Up @@ -516,6 +519,21 @@ inline raw_ostream &operator<<(raw_ostream &OS,
OS << formatv("{0:x} -> {1:x}/{2}", L.From, L.To, L.Mispred ? 'M' : 'P');
return OS;
}

inline raw_ostream &operator<<(raw_ostream &OS,
const DataAggregator::Trace &T) {
switch (T.Branch) {
case DataAggregator::Trace::FT_ONLY:
case DataAggregator::Trace::FT_EXTERNAL_ORIGIN:
break;
default:
OS << Twine::utohexstr(T.Branch) << " -> ";
}
OS << Twine::utohexstr(T.From);
if (T.To != DataAggregator::Trace::BR_ONLY)
OS << " ... " << Twine::utohexstr(T.To);
return OS;
}
} // namespace bolt
} // namespace llvm

Expand Down
Loading
Loading