@@ -22,12 +22,10 @@ const char *BoltAddressTranslation::SECTION_NAME = ".note.bolt_bat";
22
22
23
23
void BoltAddressTranslation::writeEntriesForBB (MapTy &Map,
24
24
const BinaryBasicBlock &BB,
25
- uint64_t FuncAddress) {
26
- uint64_t HotFuncAddress = ColdPartSource.count (FuncAddress)
27
- ? ColdPartSource[FuncAddress]
28
- : FuncAddress;
25
+ uint64_t FuncInputAddress,
26
+ uint64_t FuncOutputAddress) {
29
27
const uint64_t BBOutputOffset =
30
- BB.getOutputAddressRange ().first - FuncAddress ;
28
+ BB.getOutputAddressRange ().first - FuncOutputAddress ;
31
29
const uint32_t BBInputOffset = BB.getInputOffset ();
32
30
33
31
// Every output BB must track back to an input BB for profile collection
@@ -42,11 +40,14 @@ void BoltAddressTranslation::writeEntriesForBB(MapTy &Map,
42
40
LLVM_DEBUG (dbgs () << " BB " << BB.getName () << " \n " );
43
41
LLVM_DEBUG (dbgs () << " Key: " << Twine::utohexstr (BBOutputOffset)
44
42
<< " Val: " << Twine::utohexstr (BBInputOffset) << " \n " );
45
- LLVM_DEBUG (dbgs () << formatv (" Hash: {0:x}\n " ,
46
- getBBHash (HotFuncAddress, BBInputOffset)));
47
- (void )HotFuncAddress;
48
- LLVM_DEBUG (dbgs () << formatv (" Index: {0}\n " ,
49
- getBBIndex (HotFuncAddress, BBInputOffset)));
43
+ // NB: in `writeEntriesForBB` we use the input address because hashes are
44
+ // saved early in `saveMetadata` before output addresses are assigned.
45
+ const BBHashMapTy &BBHashMap = getBBHashMap (FuncInputAddress);
46
+ (void )BBHashMap;
47
+ LLVM_DEBUG (
48
+ dbgs () << formatv (" Hash: {0:x}\n " , BBHashMap.getBBHash (BBInputOffset)));
49
+ LLVM_DEBUG (
50
+ dbgs () << formatv (" Index: {0}\n " , BBHashMap.getBBIndex (BBInputOffset)));
50
51
// In case of conflicts (same Key mapping to different Vals), the last
51
52
// update takes precedence. Of course it is not ideal to have conflicts and
52
53
// those happen when we have an empty BB that either contained only
@@ -63,7 +64,7 @@ void BoltAddressTranslation::writeEntriesForBB(MapTy &Map,
63
64
const auto InputAddress = BB.getFunction ()->getAddress () + InputOffset;
64
65
const auto OutputAddress = IOAddressMap.lookup (InputAddress);
65
66
assert (OutputAddress && " Unknown instruction address" );
66
- const auto OutputOffset = *OutputAddress - FuncAddress ;
67
+ const auto OutputOffset = *OutputAddress - FuncOutputAddress ;
67
68
68
69
// Is this the first instruction in the BB? No need to duplicate the entry.
69
70
if (OutputOffset == BBOutputOffset)
@@ -99,7 +100,7 @@ void BoltAddressTranslation::write(const BinaryContext &BC, raw_ostream &OS) {
99
100
MapTy Map;
100
101
for (const BinaryBasicBlock *const BB :
101
102
Function.getLayout ().getMainFragment ())
102
- writeEntriesForBB (Map, *BB, Function. getOutputAddress () );
103
+ writeEntriesForBB (Map, *BB, InputAddress, OutputAddress );
103
104
Maps.emplace (Function.getOutputAddress (), std::move (Map));
104
105
ReverseMap.emplace (OutputAddress, InputAddress);
105
106
@@ -113,7 +114,7 @@ void BoltAddressTranslation::write(const BinaryContext &BC, raw_ostream &OS) {
113
114
ColdPartSource.emplace (FF.getAddress (), Function.getOutputAddress ());
114
115
Map.clear ();
115
116
for (const BinaryBasicBlock *const BB : FF)
116
- writeEntriesForBB (Map, *BB, FF.getAddress ());
117
+ writeEntriesForBB (Map, *BB, InputAddress, FF.getAddress ());
117
118
118
119
Maps.emplace (FF.getAddress (), std::move (Map));
119
120
}
@@ -125,11 +126,9 @@ void BoltAddressTranslation::write(const BinaryContext &BC, raw_ostream &OS) {
125
126
writeMaps</* Cold=*/ true >(Maps, PrevAddress, OS);
126
127
127
128
BC.outs () << " BOLT-INFO: Wrote " << Maps.size () << " BAT maps\n " ;
128
- const uint64_t NumBBHashes = std::accumulate (
129
- FuncHashes.begin (), FuncHashes.end (), 0ull ,
130
- [](size_t Acc, const auto &B) { return Acc + B.second .second .size (); });
131
- BC.outs () << " BOLT-INFO: Wrote " << FuncHashes.size () << " function and "
132
- << NumBBHashes << " basic block hashes\n " ;
129
+ BC.outs () << " BOLT-INFO: Wrote " << FuncHashes.getNumFunctions ()
130
+ << " function and " << FuncHashes.getNumBasicBlocks ()
131
+ << " basic block hashes\n " ;
133
132
}
134
133
135
134
APInt BoltAddressTranslation::calculateBranchEntriesBitMask (MapTy &Map,
@@ -176,11 +175,10 @@ void BoltAddressTranslation::writeMaps(std::map<uint64_t, MapTy> &Maps,
176
175
// Only process cold fragments in cold mode, and vice versa.
177
176
if (Cold != ColdPartSource.count (Address))
178
177
continue ;
179
- // NB: here we use the input address because hashes are saved early (in
180
- // `saveMetadata`) before output addresses are assigned.
178
+ // NB: in `writeMaps` we use the input address because hashes are saved
179
+ // early in `saveMetadata` before output addresses are assigned.
181
180
const uint64_t HotInputAddress =
182
181
ReverseMap[Cold ? ColdPartSource[Address] : Address];
183
- std::pair<size_t , BBHashMap> &FuncHashPair = FuncHashes[HotInputAddress];
184
182
MapTy &Map = MapEntry.second ;
185
183
const uint32_t NumEntries = Map.size ();
186
184
LLVM_DEBUG (dbgs () << " Writing " << NumEntries << " entries for 0x"
@@ -194,10 +192,11 @@ void BoltAddressTranslation::writeMaps(std::map<uint64_t, MapTy> &Maps,
194
192
PrevIndex = HotIndex;
195
193
} else {
196
194
// Function hash
197
- LLVM_DEBUG (dbgs () << " Hash: " << formatv (" {0:x}\n " , FuncHashPair.first ));
198
- OS.write (reinterpret_cast <char *>(&FuncHashPair.first ), 8 );
195
+ size_t BFHash = getBFHash (HotInputAddress);
196
+ LLVM_DEBUG (dbgs () << " Hash: " << formatv (" {0:x}\n " , BFHash));
197
+ OS.write (reinterpret_cast <char *>(&BFHash), 8 );
199
198
// Number of basic blocks
200
- size_t NumBasicBlocks = FuncHashPair. second . size ();
199
+ size_t NumBasicBlocks = getBBHashMap (HotInputAddress). getNumBasicBlocks ();
201
200
LLVM_DEBUG (dbgs () << " Basic blocks: " << NumBasicBlocks << ' \n ' );
202
201
encodeULEB128 (NumBasicBlocks, OS);
203
202
}
@@ -221,6 +220,7 @@ void BoltAddressTranslation::writeMaps(std::map<uint64_t, MapTy> &Maps,
221
220
});
222
221
}
223
222
}
223
+ const BBHashMapTy &BBHashMap = getBBHashMap (HotInputAddress);
224
224
size_t Index = 0 ;
225
225
uint64_t InOffset = 0 ;
226
226
size_t PrevBBIndex = 0 ;
@@ -233,9 +233,9 @@ void BoltAddressTranslation::writeMaps(std::map<uint64_t, MapTy> &Maps,
233
233
encodeSLEB128 (KeyVal.second - InOffset, OS);
234
234
InOffset = KeyVal.second ; // Keeping InOffset as if BRANCHENTRY is encoded
235
235
if ((InOffset & BRANCHENTRY) == 0 ) {
236
- unsigned BBIndex ;
237
- size_t BBHash ;
238
- std::tie (BBIndex, BBHash) = FuncHashPair. second [ InOffset >> 1 ] ;
236
+ const bool IsBlock = BBHashMap. isInputBlock (InOffset >> 1 ) ;
237
+ unsigned BBIndex = IsBlock ? BBHashMap. getBBIndex (InOffset >> 1 ) : 0 ;
238
+ size_t BBHash = IsBlock ? BBHashMap. getBBHash ( InOffset >> 1 ) : 0 ;
239
239
OS.write (reinterpret_cast <char *>(&BBHash), 8 );
240
240
// Basic block index in the input binary
241
241
encodeULEB128 (BBIndex - PrevBBIndex, OS);
@@ -295,7 +295,7 @@ void BoltAddressTranslation::parseMaps(std::vector<uint64_t> &HotFuncs,
295
295
HotFuncs.push_back (Address);
296
296
// Function hash
297
297
const size_t FuncHash = DE.getU64 (&Offset, &Err);
298
- FuncHashes[Address]. first = FuncHash;
298
+ FuncHashes. addEntry (Address, FuncHash) ;
299
299
LLVM_DEBUG (dbgs () << formatv (" {0:x}: hash {1:x}\n " , Address, FuncHash));
300
300
// Number of basic blocks
301
301
const size_t NumBasicBlocks = DE.getULEB128 (&Offset, &Err);
@@ -355,8 +355,7 @@ void BoltAddressTranslation::parseMaps(std::vector<uint64_t> &HotFuncs,
355
355
BBIndexDelta = DE.getULEB128 (&Offset, &Err);
356
356
BBIndex += BBIndexDelta;
357
357
// Map basic block hash to hot fragment by input offset
358
- FuncHashes[HotAddress].second .emplace (InputOffset >> 1 ,
359
- std::pair (BBIndex, BBHash));
358
+ getBBHashMap (HotAddress).addEntry (InputOffset >> 1 , BBIndex, BBHash);
360
359
}
361
360
LLVM_DEBUG ({
362
361
dbgs () << formatv (
@@ -385,6 +384,8 @@ void BoltAddressTranslation::dump(raw_ostream &OS) {
385
384
OS << formatv (" , hash: {0:x}" , getBFHash (Address));
386
385
OS << " \n " ;
387
386
OS << " BB mappings:\n " ;
387
+ const BBHashMapTy &BBHashMap =
388
+ getBBHashMap (HotAddress ? HotAddress : Address);
388
389
for (const auto &Entry : MapEntry.second ) {
389
390
const bool IsBranch = Entry.second & BRANCHENTRY;
390
391
const uint32_t Val = Entry.second >> 1 ; // dropping BRANCHENTRY bit
@@ -393,8 +394,7 @@ void BoltAddressTranslation::dump(raw_ostream &OS) {
393
394
if (IsBranch)
394
395
OS << " (branch)" ;
395
396
else
396
- OS << formatv (" hash: {0:x}" ,
397
- getBBHash (HotAddress ? HotAddress : Address, Val));
397
+ OS << formatv (" hash: {0:x}" , BBHashMap.getBBHash (Val));
398
398
OS << " \n " ;
399
399
}
400
400
OS << " \n " ;
@@ -515,27 +515,14 @@ void BoltAddressTranslation::saveMetadata(BinaryContext &BC) {
515
515
if (BF.isIgnored () || (!BC.HasRelocations && !BF.isSimple ()))
516
516
continue ;
517
517
// Prepare function and block hashes
518
- FuncHashes[ BF.getAddress ()]. first = BF.computeHash ();
518
+ FuncHashes. addEntry ( BF.getAddress (), BF.computeHash () );
519
519
BF.computeBlockHashes ();
520
+ BBHashMapTy &BBHashMap = getBBHashMap (BF.getAddress ());
521
+ // Set BF/BB metadata
520
522
for (const BinaryBasicBlock &BB : BF)
521
- FuncHashes[BF.getAddress ()].second .emplace (
522
- BB.getInputOffset (), std::pair (BB.getIndex (), BB.getHash ()));
523
+ BBHashMap.addEntry (BB.getInputOffset (), BB.getIndex (), BB.getHash ());
523
524
}
524
525
}
525
526
526
- unsigned BoltAddressTranslation::getBBIndex (uint64_t FuncOutputAddress,
527
- uint32_t BBInputOffset) const {
528
- return FuncHashes.at (FuncOutputAddress).second .at (BBInputOffset).first ;
529
- }
530
-
531
- size_t BoltAddressTranslation::getBBHash (uint64_t FuncOutputAddress,
532
- uint32_t BBInputOffset) const {
533
- return FuncHashes.at (FuncOutputAddress).second .at (BBInputOffset).second ;
534
- }
535
-
536
- size_t BoltAddressTranslation::getBFHash (uint64_t OutputAddress) const {
537
- return FuncHashes.at (OutputAddress).first ;
538
- }
539
-
540
527
} // namespace bolt
541
528
} // namespace llvm
0 commit comments