Skip to content

Commit 72bf9f9

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.5
2 parents 145176d + b7457cc commit 72bf9f9

File tree

10 files changed

+256
-94
lines changed

10 files changed

+256
-94
lines changed

bolt/docs/BAT.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,9 @@ Hot indices are delta encoded, implicitly starting at zero.
8181
| `FuncHash` | 8b | Function hash for input function | Hot |
8282
| `NumBlocks` | ULEB128 | Number of basic blocks in the original function | Hot |
8383
| `NumSecEntryPoints` | ULEB128 | Number of secondary entry points in the original function | Hot |
84-
| `ColdInputSkew` | ULEB128 | Skew to apply to all input offsets | Cold |
8584
| `NumEntries` | ULEB128 | Number of address translation entries for a function | Both |
86-
| `EqualElems` | ULEB128 | Number of equal offsets in the beginning of a function | Both |
87-
| `BranchEntries` | Bitmask, `alignTo(EqualElems, 8)` bits | If `EqualElems` is non-zero, bitmask denoting entries with `BRANCHENTRY` bit | Both |
85+
| `EqualElems` | ULEB128 | Number of equal offsets in the beginning of a function | Hot |
86+
| `BranchEntries` | Bitmask, `alignTo(EqualElems, 8)` bits | If `EqualElems` is non-zero, bitmask denoting entries with `BRANCHENTRY` bit | Hot |
8887

8988
Function header is followed by *Address Translation Table* with `NumEntries`
9089
total entries, and *Secondary Entry Points* table with `NumSecEntryPoints`
@@ -100,8 +99,8 @@ entry is encoded. Input offsets implicitly start at zero.
10099
| `BBHash` | Optional, 8b | Basic block hash in input binary | BB |
101100
| `BBIdx` | Optional, Delta, ULEB128 | Basic block index in input binary | BB |
102101

103-
The table omits the first `EqualElems` input offsets where the input offset
104-
equals output offset.
102+
For hot fragments, the table omits the first `EqualElems` input offsets
103+
where the input offset equals output offset.
105104

106105
`BRANCHENTRY` bit denotes whether a given offset pair is a control flow source
107106
(branch or call instruction). If not set, it signifies a control flow target

bolt/include/bolt/Profile/BoltAddressTranslation.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,9 @@ class BoltAddressTranslation {
149149
/// entries in function address translation map.
150150
APInt calculateBranchEntriesBitMask(MapTy &Map, size_t EqualElems);
151151

152-
/// Calculate the number of equal offsets (output = input - skew) in the
153-
/// beginning of the function.
154-
size_t getNumEqualOffsets(const MapTy &Map, uint32_t Skew) const;
152+
/// Calculate the number of equal offsets (output = input) in the beginning
153+
/// of the function.
154+
size_t getNumEqualOffsets(const MapTy &Map) const;
155155

156156
std::map<uint64_t, MapTy> Maps;
157157

bolt/include/bolt/Rewrite/RewriteInstance.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,9 @@ class RewriteInstance {
494494
/// Store all non-zero symbols in this map for a quick address lookup.
495495
std::map<uint64_t, llvm::object::SymbolRef> FileSymRefs;
496496

497+
/// FILE symbols used for disambiguating split function parents.
498+
std::vector<ELFSymbolRef> FileSymbols;
499+
497500
std::unique_ptr<DWARFRewriter> DebugInfoRewriter;
498501

499502
std::unique_ptr<BoltAddressTranslation> BAT;

bolt/include/bolt/Utils/NameResolver.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,23 @@ class NameResolver {
2828
static constexpr char Sep = '/';
2929

3030
public:
31-
/// Return unique version of the \p Name in the form "Name<Sep><Number>".
31+
/// Return the number of uniquified versions of a given \p Name.
32+
uint64_t getUniquifiedNameCount(StringRef Name) const {
33+
if (Counters.contains(Name))
34+
return Counters.at(Name);
35+
return 0;
36+
}
37+
38+
/// Return unique version of the \p Name in the form "Name<Sep><ID>".
39+
std::string getUniqueName(StringRef Name, const uint64_t ID) const {
40+
return (Name + Twine(Sep) + Twine(ID)).str();
41+
}
42+
43+
/// Register new version of \p Name and return unique version in the form
44+
/// "Name<Sep><Number>".
3245
std::string uniquify(StringRef Name) {
3346
const uint64_t ID = ++Counters[Name];
34-
return (Name + Twine(Sep) + Twine(ID)).str();
47+
return getUniqueName(Name, ID);
3548
}
3649

3750
/// For uniquified \p Name, return the original form (that may no longer be

bolt/lib/Profile/BoltAddressTranslation.cpp

Lines changed: 42 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,12 @@ APInt BoltAddressTranslation::calculateBranchEntriesBitMask(MapTy &Map,
153153
return BitMask;
154154
}
155155

156-
size_t BoltAddressTranslation::getNumEqualOffsets(const MapTy &Map,
157-
uint32_t Skew) const {
156+
size_t BoltAddressTranslation::getNumEqualOffsets(const MapTy &Map) const {
158157
size_t EqualOffsets = 0;
159158
for (const std::pair<const uint32_t, uint32_t> &KeyVal : Map) {
160159
const uint32_t OutputOffset = KeyVal.first;
161160
const uint32_t InputOffset = KeyVal.second >> 1;
162-
if (OutputOffset == InputOffset - Skew)
161+
if (OutputOffset == InputOffset)
163162
++EqualOffsets;
164163
else
165164
break;
@@ -197,17 +196,12 @@ void BoltAddressTranslation::writeMaps(std::map<uint64_t, MapTy> &Maps,
197196
SecondaryEntryPointsMap.count(Address)
198197
? SecondaryEntryPointsMap[Address].size()
199198
: 0;
200-
uint32_t Skew = 0;
201199
if (Cold) {
202200
auto HotEntryIt = Maps.find(ColdPartSource[Address]);
203201
assert(HotEntryIt != Maps.end());
204202
size_t HotIndex = std::distance(Maps.begin(), HotEntryIt);
205203
encodeULEB128(HotIndex - PrevIndex, OS);
206204
PrevIndex = HotIndex;
207-
// Skew of all input offsets for cold fragments is simply the first input
208-
// offset.
209-
Skew = Map.begin()->second >> 1;
210-
encodeULEB128(Skew, OS);
211205
} else {
212206
// Function hash
213207
size_t BFHash = getBFHash(HotInputAddress);
@@ -223,21 +217,24 @@ void BoltAddressTranslation::writeMaps(std::map<uint64_t, MapTy> &Maps,
223217
<< '\n');
224218
}
225219
encodeULEB128(NumEntries, OS);
226-
// Encode the number of equal offsets (output = input - skew) in the
227-
// beginning of the function. Only encode one offset in these cases.
228-
const size_t EqualElems = getNumEqualOffsets(Map, Skew);
229-
encodeULEB128(EqualElems, OS);
230-
if (EqualElems) {
231-
const size_t BranchEntriesBytes = alignTo(EqualElems, 8) / 8;
232-
APInt BranchEntries = calculateBranchEntriesBitMask(Map, EqualElems);
233-
OS.write(reinterpret_cast<const char *>(BranchEntries.getRawData()),
234-
BranchEntriesBytes);
235-
LLVM_DEBUG({
236-
dbgs() << "BranchEntries: ";
237-
SmallString<8> BitMaskStr;
238-
BranchEntries.toString(BitMaskStr, 2, false);
239-
dbgs() << BitMaskStr << '\n';
240-
});
220+
// For hot fragments only: encode the number of equal offsets
221+
// (output = input) in the beginning of the function. Only encode one offset
222+
// in these cases.
223+
const size_t EqualElems = Cold ? 0 : getNumEqualOffsets(Map);
224+
if (!Cold) {
225+
encodeULEB128(EqualElems, OS);
226+
if (EqualElems) {
227+
const size_t BranchEntriesBytes = alignTo(EqualElems, 8) / 8;
228+
APInt BranchEntries = calculateBranchEntriesBitMask(Map, EqualElems);
229+
OS.write(reinterpret_cast<const char *>(BranchEntries.getRawData()),
230+
BranchEntriesBytes);
231+
LLVM_DEBUG({
232+
dbgs() << "BranchEntries: ";
233+
SmallString<8> BitMaskStr;
234+
BranchEntries.toString(BitMaskStr, 2, false);
235+
dbgs() << BitMaskStr << '\n';
236+
});
237+
}
241238
}
242239
const BBHashMapTy &BBHashMap = getBBHashMap(HotInputAddress);
243240
size_t Index = 0;
@@ -318,12 +315,10 @@ void BoltAddressTranslation::parseMaps(std::vector<uint64_t> &HotFuncs,
318315
uint64_t HotAddress = Cold ? 0 : Address;
319316
PrevAddress = Address;
320317
uint32_t SecondaryEntryPoints = 0;
321-
uint64_t ColdInputSkew = 0;
322318
if (Cold) {
323319
HotIndex += DE.getULEB128(&Offset, &Err);
324320
HotAddress = HotFuncs[HotIndex];
325321
ColdPartSource.emplace(Address, HotAddress);
326-
ColdInputSkew = DE.getULEB128(&Offset, &Err);
327322
} else {
328323
HotFuncs.push_back(Address);
329324
// Function hash
@@ -344,25 +339,28 @@ void BoltAddressTranslation::parseMaps(std::vector<uint64_t> &HotFuncs,
344339
getULEB128Size(SecondaryEntryPoints)));
345340
}
346341
const uint32_t NumEntries = DE.getULEB128(&Offset, &Err);
347-
// Equal offsets.
348-
const size_t EqualElems = DE.getULEB128(&Offset, &Err);
342+
// Equal offsets, hot fragments only.
343+
size_t EqualElems = 0;
349344
APInt BEBitMask;
350-
LLVM_DEBUG(dbgs() << formatv("Equal offsets: {0}, {1} bytes\n", EqualElems,
351-
getULEB128Size(EqualElems)));
352-
if (EqualElems) {
353-
const size_t BranchEntriesBytes = alignTo(EqualElems, 8) / 8;
354-
BEBitMask = APInt(alignTo(EqualElems, 8), 0);
355-
LoadIntFromMemory(
356-
BEBitMask,
357-
reinterpret_cast<const uint8_t *>(
358-
DE.getBytes(&Offset, BranchEntriesBytes, &Err).data()),
359-
BranchEntriesBytes);
360-
LLVM_DEBUG({
361-
dbgs() << "BEBitMask: ";
362-
SmallString<8> BitMaskStr;
363-
BEBitMask.toString(BitMaskStr, 2, false);
364-
dbgs() << BitMaskStr << ", " << BranchEntriesBytes << " bytes\n";
365-
});
345+
if (!Cold) {
346+
EqualElems = DE.getULEB128(&Offset, &Err);
347+
LLVM_DEBUG(dbgs() << formatv("Equal offsets: {0}, {1} bytes\n",
348+
EqualElems, getULEB128Size(EqualElems)));
349+
if (EqualElems) {
350+
const size_t BranchEntriesBytes = alignTo(EqualElems, 8) / 8;
351+
BEBitMask = APInt(alignTo(EqualElems, 8), 0);
352+
LoadIntFromMemory(
353+
BEBitMask,
354+
reinterpret_cast<const uint8_t *>(
355+
DE.getBytes(&Offset, BranchEntriesBytes, &Err).data()),
356+
BranchEntriesBytes);
357+
LLVM_DEBUG({
358+
dbgs() << "BEBitMask: ";
359+
SmallString<8> BitMaskStr;
360+
BEBitMask.toString(BitMaskStr, 2, false);
361+
dbgs() << BitMaskStr << ", " << BranchEntriesBytes << " bytes\n";
362+
});
363+
}
366364
}
367365
MapTy Map;
368366

@@ -377,7 +375,7 @@ void BoltAddressTranslation::parseMaps(std::vector<uint64_t> &HotFuncs,
377375
PrevAddress = OutputAddress;
378376
int64_t InputDelta = 0;
379377
if (J < EqualElems) {
380-
InputOffset = ((OutputOffset + ColdInputSkew) << 1) | BEBitMask[J];
378+
InputOffset = (OutputOffset << 1) | BEBitMask[J];
381379
} else {
382380
InputDelta = DE.getSLEB128(&Offset, &Err);
383381
InputOffset += InputDelta;

0 commit comments

Comments
 (0)