Skip to content

[BOLT] Delta-encode function start addresses in BAT #76902

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
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
4 changes: 3 additions & 1 deletion bolt/docs/BAT.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,11 @@ Header:
| `NumFuncs` | ULEB128 | Number of functions in the functions table |

The header is followed by Functions table with `NumFuncs` entries.
Output binary addresses are delta encoded, meaning that only the difference with
the previous output address is stored. Addresses implicitly start at zero.
| Entry | Encoding | Description |
| ------ | ------| ----------- |
| `Address` | ULEB128 | Function address in the output binary |
| `Address` | Delta, ULEB128 | Function address in the output binary |
| `NumEntries` | ULEB128 | Number of address translation entries for a function |

Function header is followed by `NumEntries` pairs of offsets for current
Expand Down
8 changes: 6 additions & 2 deletions bolt/lib/Profile/BoltAddressTranslation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,15 @@ void BoltAddressTranslation::write(const BinaryContext &BC, raw_ostream &OS) {
const uint32_t NumFuncs = Maps.size();
encodeULEB128(NumFuncs, OS);
LLVM_DEBUG(dbgs() << "Writing " << NumFuncs << " functions for BAT.\n");
uint64_t PrevAddress = 0;
for (auto &MapEntry : Maps) {
const uint64_t Address = MapEntry.first;
MapTy &Map = MapEntry.second;
const uint32_t NumEntries = Map.size();
LLVM_DEBUG(dbgs() << "Writing " << NumEntries << " entries for 0x"
<< Twine::utohexstr(Address) << ".\n");
encodeULEB128(Address, OS);
encodeULEB128(Address - PrevAddress, OS);
PrevAddress = Address;
encodeULEB128(NumEntries, OS);
uint64_t InOffset = 0, OutOffset = 0;
// Output and Input addresses and delta-encoded
Expand Down Expand Up @@ -160,8 +162,10 @@ std::error_code BoltAddressTranslation::parse(StringRef Buf) {
Error Err(Error::success());
const uint32_t NumFunctions = DE.getULEB128(&Offset, &Err);
LLVM_DEBUG(dbgs() << "Parsing " << NumFunctions << " functions\n");
uint64_t PrevAddress = 0;
for (uint32_t I = 0; I < NumFunctions; ++I) {
const uint64_t Address = DE.getULEB128(&Offset, &Err);
const uint64_t Address = PrevAddress + DE.getULEB128(&Offset, &Err);
PrevAddress = Address;
const uint32_t NumEntries = DE.getULEB128(&Offset, &Err);
MapTy Map;

Expand Down
2 changes: 1 addition & 1 deletion bolt/test/X86/bolt-address-translation.test
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
# CHECK: BOLT: 3 out of 7 functions were overwritten.
# CHECK: BOLT-INFO: Wrote 6 BAT maps
# CHECK: BOLT-INFO: Wrote 3 BAT cold-to-hot entries
# CHECK: BOLT-INFO: BAT section size (bytes): 436
# CHECK: BOLT-INFO: BAT section size (bytes): 428
#
# usqrt mappings (hot part). We match against any key (left side containing
# the bolted binary offsets) because BOLT may change where it puts instructions
Expand Down