@@ -2341,87 +2341,68 @@ std::error_code DataAggregator::writeBATYAML(BinaryContext &BC,
2341
2341
YamlBF.NumBasicBlocks = BAT->getNumBasicBlocks (FuncAddress);
2342
2342
const BoltAddressTranslation::BBHashMapTy &BlockMap =
2343
2343
BAT->getBBHashMap (FuncAddress);
2344
+ YamlBF.Blocks .resize (YamlBF.NumBasicBlocks );
2344
2345
2345
- auto addSuccProfile = [&](yaml::bolt::BinaryBasicBlockProfile &YamlBB,
2346
- uint64_t SuccOffset, unsigned SuccDataIdx) {
2346
+ for (auto &&[Idx, YamlBB] : llvm::enumerate (YamlBF.Blocks ))
2347
+ YamlBB.Index = Idx;
2348
+
2349
+ for (auto BI = BlockMap.begin (), BE = BlockMap.end (); BI != BE; ++BI)
2350
+ YamlBF.Blocks [BI->second .getBBIndex ()].Hash = BI->second .getBBHash ();
2351
+
2352
+ auto getSuccessorInfo = [&](uint32_t SuccOffset, unsigned SuccDataIdx) {
2347
2353
const llvm::bolt::BranchInfo &BI = Branches.Data .at (SuccDataIdx);
2348
2354
yaml::bolt::SuccessorInfo SI;
2349
2355
SI.Index = BlockMap.getBBIndex (SuccOffset);
2350
2356
SI.Count = BI.Branches ;
2351
2357
SI.Mispreds = BI.Mispreds ;
2352
- YamlBB. Successors . emplace_back (SI) ;
2358
+ return SI ;
2353
2359
};
2354
2360
2355
- std::unordered_map<uint32_t , std::vector<uint32_t >> BFBranches =
2356
- BAT->getBFBranches (FuncAddress);
2357
-
2358
- auto addCallsProfile = [&](yaml::bolt::BinaryBasicBlockProfile &YamlBB,
2359
- uint64_t Offset) {
2360
- // Iterate over BRANCHENTRY records in the current block
2361
- for (uint32_t BranchOffset : BFBranches[Offset]) {
2362
- if (!Branches.InterIndex .contains (BranchOffset))
2363
- continue ;
2364
- for (const auto &[CallToLoc, CallToIdx] :
2365
- Branches.InterIndex .at (BranchOffset)) {
2366
- const llvm::bolt::BranchInfo &BI = Branches.Data .at (CallToIdx);
2367
- yaml::bolt::CallSiteInfo YamlCSI;
2368
- YamlCSI.DestId = 0 ; // designated for unknown functions
2369
- YamlCSI.EntryDiscriminator = 0 ;
2370
- YamlCSI.Count = BI.Branches ;
2371
- YamlCSI.Mispreds = BI.Mispreds ;
2372
- YamlCSI.Offset = BranchOffset - Offset;
2373
- BinaryData *CallTargetBD = BC.getBinaryDataByName (CallToLoc.Name );
2374
- if (!CallTargetBD) {
2375
- YamlBB.CallSites .emplace_back (YamlCSI);
2376
- continue ;
2377
- }
2378
- uint64_t CallTargetAddress = CallTargetBD->getAddress ();
2379
- BinaryFunction *CallTargetBF =
2380
- BC.getBinaryFunctionAtAddress (CallTargetAddress);
2381
- if (!CallTargetBF) {
2382
- YamlBB.CallSites .emplace_back (YamlCSI);
2383
- continue ;
2384
- }
2385
- // Calls between hot and cold fragments must be handled in
2386
- // fixupBATProfile.
2387
- assert (CallTargetBF != BF && " invalid CallTargetBF" );
2388
- YamlCSI.DestId = CallTargetBF->getFunctionNumber ();
2389
- if (CallToLoc.Offset ) {
2390
- if (BAT->isBATFunction (CallTargetAddress)) {
2391
- LLVM_DEBUG (dbgs () << " BOLT-DEBUG: Unsupported secondary "
2392
- " entry point in BAT function "
2393
- << CallToLoc.Name << ' \n ' );
2394
- } else if (const BinaryBasicBlock *CallTargetBB =
2395
- CallTargetBF->getBasicBlockAtOffset (
2396
- CallToLoc.Offset )) {
2397
- // Only record true call information, ignoring returns (normally
2398
- // won't have a target basic block) and jumps to the landing
2399
- // pads (not an entry point).
2400
- if (CallTargetBB->isEntryPoint ()) {
2401
- YamlCSI.EntryDiscriminator =
2402
- CallTargetBF->getEntryIDForSymbol (
2403
- CallTargetBB->getLabel ());
2404
- }
2405
- }
2406
- }
2407
- YamlBB.CallSites .emplace_back (YamlCSI);
2408
- }
2409
- }
2361
+ auto getCallSiteInfo = [&](Location CallToLoc, unsigned CallToIdx,
2362
+ uint32_t Offset) {
2363
+ const llvm::bolt::BranchInfo &BI = Branches.Data .at (CallToIdx);
2364
+ yaml::bolt::CallSiteInfo CSI;
2365
+ CSI.DestId = 0 ; // designated for unknown functions
2366
+ CSI.EntryDiscriminator = 0 ;
2367
+ CSI.Count = BI.Branches ;
2368
+ CSI.Mispreds = BI.Mispreds ;
2369
+ CSI.Offset = Offset;
2370
+ if (BinaryData *BD = BC.getBinaryDataByName (CallToLoc.Name ))
2371
+ YAMLProfileWriter::setCSIDestination (BC, CSI, BD->getSymbol (), BAT,
2372
+ CallToLoc.Offset );
2373
+ return CSI;
2410
2374
};
2411
2375
2412
2376
for (const auto &[FromOffset, SuccKV] : Branches.IntraIndex ) {
2413
- yaml::bolt::BinaryBasicBlockProfile YamlBB;
2414
2377
if (!BlockMap.isInputBlock (FromOffset))
2415
2378
continue ;
2416
- YamlBB. Index = BlockMap.getBBIndex (FromOffset);
2417
- YamlBB. Hash = BlockMap. getBBHash (FromOffset) ;
2379
+ const unsigned Index = BlockMap.getBBIndex (FromOffset);
2380
+ yaml::bolt::BinaryBasicBlockProfile & YamlBB = YamlBF. Blocks [Index] ;
2418
2381
for (const auto &[SuccOffset, SuccDataIdx] : SuccKV)
2419
- addSuccProfile (YamlBB, SuccOffset, SuccDataIdx);
2420
- addCallsProfile (YamlBB, FromOffset);
2421
- if (YamlBB.ExecCount || !YamlBB.Successors .empty () ||
2422
- !YamlBB.CallSites .empty ())
2423
- YamlBF.Blocks .emplace_back (YamlBB);
2382
+ if (BlockMap.isInputBlock (SuccOffset))
2383
+ YamlBB.Successors .emplace_back (
2384
+ getSuccessorInfo (SuccOffset, SuccDataIdx));
2385
+ }
2386
+ for (const auto &[FromOffset, CallTo] : Branches.InterIndex ) {
2387
+ auto BlockIt = BlockMap.upper_bound (FromOffset);
2388
+ --BlockIt;
2389
+ const unsigned BlockOffset = BlockIt->first ;
2390
+ const unsigned BlockIndex = BlockIt->second .getBBIndex ();
2391
+ yaml::bolt::BinaryBasicBlockProfile &YamlBB = YamlBF.Blocks [BlockIndex];
2392
+ const uint32_t Offset = FromOffset - BlockOffset;
2393
+ for (const auto &[CallToLoc, CallToIdx] : CallTo)
2394
+ YamlBB.CallSites .emplace_back (
2395
+ getCallSiteInfo (CallToLoc, CallToIdx, Offset));
2396
+ llvm::sort (YamlBB.CallSites , [](yaml::bolt::CallSiteInfo &A,
2397
+ yaml::bolt::CallSiteInfo &B) {
2398
+ return A.Offset < B.Offset ;
2399
+ });
2424
2400
}
2401
+ // Drop blocks without a hash, won't be useful for stale matching.
2402
+ llvm::erase_if (YamlBF.Blocks ,
2403
+ [](const yaml::bolt::BinaryBasicBlockProfile &YamlBB) {
2404
+ return YamlBB.Hash == (yaml::Hex64)0 ;
2405
+ });
2425
2406
BP.Functions .emplace_back (YamlBF);
2426
2407
}
2427
2408
}
0 commit comments