@@ -153,12 +153,13 @@ APInt BoltAddressTranslation::calculateBranchEntriesBitMask(MapTy &Map,
153
153
return BitMask;
154
154
}
155
155
156
- size_t BoltAddressTranslation::getNumEqualOffsets (const MapTy &Map) const {
156
+ size_t BoltAddressTranslation::getNumEqualOffsets (const MapTy &Map,
157
+ uint32_t Skew) const {
157
158
size_t EqualOffsets = 0 ;
158
159
for (const std::pair<const uint32_t , uint32_t > &KeyVal : Map) {
159
160
const uint32_t OutputOffset = KeyVal.first ;
160
161
const uint32_t InputOffset = KeyVal.second >> 1 ;
161
- if (OutputOffset == InputOffset)
162
+ if (OutputOffset == InputOffset - Skew )
162
163
++EqualOffsets;
163
164
else
164
165
break ;
@@ -196,12 +197,17 @@ void BoltAddressTranslation::writeMaps(std::map<uint64_t, MapTy> &Maps,
196
197
SecondaryEntryPointsMap.count (Address)
197
198
? SecondaryEntryPointsMap[Address].size ()
198
199
: 0 ;
200
+ uint32_t Skew = 0 ;
199
201
if (Cold) {
200
202
auto HotEntryIt = Maps.find (ColdPartSource[Address]);
201
203
assert (HotEntryIt != Maps.end ());
202
204
size_t HotIndex = std::distance (Maps.begin (), HotEntryIt);
203
205
encodeULEB128 (HotIndex - PrevIndex, OS);
204
206
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);
205
211
} else {
206
212
// Function hash
207
213
size_t BFHash = getBFHash (HotInputAddress);
@@ -217,24 +223,21 @@ void BoltAddressTranslation::writeMaps(std::map<uint64_t, MapTy> &Maps,
217
223
<< ' \n ' );
218
224
}
219
225
encodeULEB128 (NumEntries, OS);
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
- }
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
+ });
238
241
}
239
242
const BBHashMapTy &BBHashMap = getBBHashMap (HotInputAddress);
240
243
size_t Index = 0 ;
@@ -315,10 +318,12 @@ void BoltAddressTranslation::parseMaps(std::vector<uint64_t> &HotFuncs,
315
318
uint64_t HotAddress = Cold ? 0 : Address;
316
319
PrevAddress = Address;
317
320
uint32_t SecondaryEntryPoints = 0 ;
321
+ uint64_t ColdInputSkew = 0 ;
318
322
if (Cold) {
319
323
HotIndex += DE.getULEB128 (&Offset, &Err);
320
324
HotAddress = HotFuncs[HotIndex];
321
325
ColdPartSource.emplace (Address, HotAddress);
326
+ ColdInputSkew = DE.getULEB128 (&Offset, &Err);
322
327
} else {
323
328
HotFuncs.push_back (Address);
324
329
// Function hash
@@ -339,28 +344,25 @@ void BoltAddressTranslation::parseMaps(std::vector<uint64_t> &HotFuncs,
339
344
getULEB128Size (SecondaryEntryPoints)));
340
345
}
341
346
const uint32_t NumEntries = DE.getULEB128 (&Offset, &Err);
342
- // Equal offsets, hot fragments only .
343
- size_t EqualElems = 0 ;
347
+ // Equal offsets.
348
+ const size_t EqualElems = DE. getULEB128 (&Offset, &Err) ;
344
349
APInt BEBitMask;
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
- }
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
+ });
364
366
}
365
367
MapTy Map;
366
368
@@ -375,7 +377,7 @@ void BoltAddressTranslation::parseMaps(std::vector<uint64_t> &HotFuncs,
375
377
PrevAddress = OutputAddress;
376
378
int64_t InputDelta = 0 ;
377
379
if (J < EqualElems) {
378
- InputOffset = (OutputOffset << 1 ) | BEBitMask[J];
380
+ InputOffset = (OutputOffset + ColdInputSkew << 1 ) | BEBitMask[J];
379
381
} else {
380
382
InputDelta = DE.getSLEB128 (&Offset, &Err);
381
383
InputOffset += InputDelta;
0 commit comments