@@ -153,12 +153,13 @@ APInt BoltAddressTranslation::calculateBranchEntriesBitMask(MapTy &Map,
153153 return BitMask;
154154}
155155
156- size_t BoltAddressTranslation::getNumEqualOffsets (const MapTy &Map) const {
156+ size_t BoltAddressTranslation::getNumEqualOffsets (const MapTy &Map,
157+ uint32_t Skew) const {
157158 size_t EqualOffsets = 0 ;
158159 for (const std::pair<const uint32_t , uint32_t > &KeyVal : Map) {
159160 const uint32_t OutputOffset = KeyVal.first ;
160161 const uint32_t InputOffset = KeyVal.second >> 1 ;
161- if (OutputOffset == InputOffset)
162+ if (OutputOffset == InputOffset - Skew )
162163 ++EqualOffsets;
163164 else
164165 break ;
@@ -196,12 +197,17 @@ void BoltAddressTranslation::writeMaps(std::map<uint64_t, MapTy> &Maps,
196197 SecondaryEntryPointsMap.count (Address)
197198 ? SecondaryEntryPointsMap[Address].size ()
198199 : 0 ;
200+ uint32_t Skew = 0 ;
199201 if (Cold) {
200202 auto HotEntryIt = Maps.find (ColdPartSource[Address]);
201203 assert (HotEntryIt != Maps.end ());
202204 size_t HotIndex = std::distance (Maps.begin (), HotEntryIt);
203205 encodeULEB128 (HotIndex - PrevIndex, OS);
204206 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);
205211 } else {
206212 // Function hash
207213 size_t BFHash = getBFHash (HotInputAddress);
@@ -217,24 +223,21 @@ void BoltAddressTranslation::writeMaps(std::map<uint64_t, MapTy> &Maps,
217223 << ' \n ' );
218224 }
219225 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+ });
238241 }
239242 const BBHashMapTy &BBHashMap = getBBHashMap (HotInputAddress);
240243 size_t Index = 0 ;
@@ -315,10 +318,12 @@ void BoltAddressTranslation::parseMaps(std::vector<uint64_t> &HotFuncs,
315318 uint64_t HotAddress = Cold ? 0 : Address;
316319 PrevAddress = Address;
317320 uint32_t SecondaryEntryPoints = 0 ;
321+ uint64_t ColdInputSkew = 0 ;
318322 if (Cold) {
319323 HotIndex += DE.getULEB128 (&Offset, &Err);
320324 HotAddress = HotFuncs[HotIndex];
321325 ColdPartSource.emplace (Address, HotAddress);
326+ ColdInputSkew = DE.getULEB128 (&Offset, &Err);
322327 } else {
323328 HotFuncs.push_back (Address);
324329 // Function hash
@@ -339,28 +344,25 @@ void BoltAddressTranslation::parseMaps(std::vector<uint64_t> &HotFuncs,
339344 getULEB128Size (SecondaryEntryPoints)));
340345 }
341346 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) ;
344349 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+ });
364366 }
365367 MapTy Map;
366368
@@ -375,7 +377,7 @@ void BoltAddressTranslation::parseMaps(std::vector<uint64_t> &HotFuncs,
375377 PrevAddress = OutputAddress;
376378 int64_t InputDelta = 0 ;
377379 if (J < EqualElems) {
378- InputOffset = (OutputOffset << 1 ) | BEBitMask[J];
380+ InputOffset = (( OutputOffset + ColdInputSkew) << 1 ) | BEBitMask[J];
379381 } else {
380382 InputDelta = DE.getSLEB128 (&Offset, &Err);
381383 InputOffset += InputDelta;
0 commit comments