Skip to content

[BOLT][NFCI] Speedup BAT::writeMaps #112061

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions bolt/include/bolt/Profile/BoltAddressTranslation.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,15 +141,13 @@ class BoltAddressTranslation {
uint64_t FuncOutputAddress) const;

/// Write the serialized address translation table for a function.
template <bool Cold>
void writeMaps(std::map<uint64_t, MapTy> &Maps, uint64_t &PrevAddress,
raw_ostream &OS);
template <bool Cold> void writeMaps(uint64_t &PrevAddress, raw_ostream &OS);

/// Read the serialized address translation table for a function.
/// Return a parse error if failed.
template <bool Cold>
void parseMaps(std::vector<uint64_t> &HotFuncs, uint64_t &PrevAddress,
DataExtractor &DE, uint64_t &Offset, Error &Err);
void parseMaps(uint64_t &PrevAddress, DataExtractor &DE, uint64_t &Offset,
Error &Err);

/// Returns the bitmask with set bits corresponding to indices of BRANCHENTRY
/// entries in function address translation map.
Expand All @@ -161,6 +159,9 @@ class BoltAddressTranslation {

std::map<uint64_t, MapTy> Maps;

/// Ordered vector with addresses of hot functions.
std::vector<uint64_t> HotFuncs;

/// Map a function to its basic blocks count
std::unordered_map<uint64_t, size_t> NumBasicBlocksMap;

Expand Down
22 changes: 10 additions & 12 deletions bolt/lib/Profile/BoltAddressTranslation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ void BoltAddressTranslation::write(const BinaryContext &BC, raw_ostream &OS) {

// Output addresses are delta-encoded
uint64_t PrevAddress = 0;
writeMaps</*Cold=*/false>(Maps, PrevAddress, OS);
writeMaps</*Cold=*/true>(Maps, PrevAddress, OS);
writeMaps</*Cold=*/false>(PrevAddress, OS);
writeMaps</*Cold=*/true>(PrevAddress, OS);

BC.outs() << "BOLT-INFO: Wrote " << Maps.size() << " BAT maps\n";
BC.outs() << "BOLT-INFO: Wrote " << FuncHashes.getNumFunctions()
Expand Down Expand Up @@ -182,8 +182,7 @@ size_t BoltAddressTranslation::getNumEqualOffsets(const MapTy &Map,
}

template <bool Cold>
void BoltAddressTranslation::writeMaps(std::map<uint64_t, MapTy> &Maps,
uint64_t &PrevAddress, raw_ostream &OS) {
void BoltAddressTranslation::writeMaps(uint64_t &PrevAddress, raw_ostream &OS) {
const uint32_t NumFuncs =
llvm::count_if(llvm::make_first_range(Maps), [&](const uint64_t Address) {
return Cold == ColdPartSource.count(Address);
Expand Down Expand Up @@ -213,16 +212,17 @@ void BoltAddressTranslation::writeMaps(std::map<uint64_t, MapTy> &Maps,
: 0;
uint32_t Skew = 0;
if (Cold) {
auto HotEntryIt = Maps.find(ColdPartSource[Address]);
assert(HotEntryIt != Maps.end());
size_t HotIndex = std::distance(Maps.begin(), HotEntryIt);
auto HotEntryIt = llvm::lower_bound(HotFuncs, ColdPartSource[Address]);
assert(HotEntryIt != HotFuncs.end());
size_t HotIndex = std::distance(HotFuncs.begin(), HotEntryIt);
encodeULEB128(HotIndex - PrevIndex, OS);
PrevIndex = HotIndex;
// Skew of all input offsets for cold fragments is simply the first input
// offset.
Skew = Map.begin()->second >> 1;
encodeULEB128(Skew, OS);
} else {
HotFuncs.push_back(Address);
// Function hash
size_t BFHash = getBFHash(HotInputAddress);
LLVM_DEBUG(dbgs() << "Hash: " << formatv("{0:x}\n", BFHash));
Expand Down Expand Up @@ -311,17 +311,15 @@ std::error_code BoltAddressTranslation::parse(raw_ostream &OS, StringRef Buf) {
return make_error_code(llvm::errc::io_error);

Error Err(Error::success());
std::vector<uint64_t> HotFuncs;
uint64_t PrevAddress = 0;
parseMaps</*Cold=*/false>(HotFuncs, PrevAddress, DE, Offset, Err);
parseMaps</*Cold=*/true>(HotFuncs, PrevAddress, DE, Offset, Err);
parseMaps</*Cold=*/false>(PrevAddress, DE, Offset, Err);
parseMaps</*Cold=*/true>(PrevAddress, DE, Offset, Err);
OS << "BOLT-INFO: Parsed " << Maps.size() << " BAT entries\n";
return errorToErrorCode(std::move(Err));
}

template <bool Cold>
void BoltAddressTranslation::parseMaps(std::vector<uint64_t> &HotFuncs,
uint64_t &PrevAddress, DataExtractor &DE,
void BoltAddressTranslation::parseMaps(uint64_t &PrevAddress, DataExtractor &DE,
uint64_t &Offset, Error &Err) {
const uint32_t NumFunctions = DE.getULEB128(&Offset, &Err);
LLVM_DEBUG(dbgs() << "Parsing " << NumFunctions << (Cold ? " cold" : "")
Expand Down
Loading