@@ -342,6 +342,13 @@ Error YAMLProfileReader::preprocessProfile(BinaryContext &BC) {
342
342
return Error::success ();
343
343
}
344
344
345
+ bool YAMLProfileReader::profileMatches (
346
+ const yaml::bolt::BinaryFunctionProfile &Profile, const BinaryFunction &BF) {
347
+ if (opts::IgnoreHash)
348
+ return Profile.NumBasicBlocks == BF.size ();
349
+ return Profile.Hash == static_cast <uint64_t >(BF.getHash ());
350
+ }
351
+
345
352
bool YAMLProfileReader::mayHaveProfileData (const BinaryFunction &BF) {
346
353
if (opts::MatchProfileWithFunctionHash)
347
354
return true ;
@@ -358,8 +365,92 @@ bool YAMLProfileReader::mayHaveProfileData(const BinaryFunction &BF) {
358
365
return false ;
359
366
}
360
367
361
- uint64_t YAMLProfileReader::matchWithNameSimilarity (BinaryContext &BC) {
362
- uint64_t MatchedWithNameSimilarity = 0 ;
368
+ size_t YAMLProfileReader::matchWithExactName () {
369
+ size_t MatchedWithExactName = 0 ;
370
+ // This first pass assigns profiles that match 100% by name and by hash.
371
+ for (auto [YamlBF, BF] : llvm::zip_equal (YamlBP.Functions , ProfileBFs)) {
372
+ if (!BF)
373
+ continue ;
374
+ BinaryFunction &Function = *BF;
375
+ // Clear function call count that may have been set while pre-processing
376
+ // the profile.
377
+ Function.setExecutionCount (BinaryFunction::COUNT_NO_PROFILE);
378
+
379
+ if (profileMatches (YamlBF, Function)) {
380
+ matchProfileToFunction (YamlBF, Function);
381
+ ++MatchedWithExactName;
382
+ }
383
+ }
384
+ return MatchedWithExactName;
385
+ }
386
+
387
+ size_t YAMLProfileReader::matchWithHash (BinaryContext &BC) {
388
+ // Iterates through profiled functions to match the first binary function with
389
+ // the same exact hash. Serves to match identical, renamed functions.
390
+ // Collisions are possible where multiple functions share the same exact hash.
391
+ size_t MatchedWithHash = 0 ;
392
+ if (opts::MatchProfileWithFunctionHash) {
393
+ DenseMap<size_t , BinaryFunction *> StrictHashToBF;
394
+ StrictHashToBF.reserve (BC.getBinaryFunctions ().size ());
395
+
396
+ for (auto &[_, BF] : BC.getBinaryFunctions ())
397
+ StrictHashToBF[BF.getHash ()] = &BF;
398
+
399
+ for (yaml::bolt::BinaryFunctionProfile &YamlBF : YamlBP.Functions ) {
400
+ if (YamlBF.Used )
401
+ continue ;
402
+ auto It = StrictHashToBF.find (YamlBF.Hash );
403
+ if (It != StrictHashToBF.end () && !ProfiledFunctions.count (It->second )) {
404
+ BinaryFunction *BF = It->second ;
405
+ matchProfileToFunction (YamlBF, *BF);
406
+ ++MatchedWithHash;
407
+ }
408
+ }
409
+ }
410
+ return MatchedWithHash;
411
+ }
412
+
413
+ size_t YAMLProfileReader::matchWithLTOCommonName () {
414
+ // This second pass allows name ambiguity for LTO private functions.
415
+ size_t MatchedWithLTOCommonName = 0 ;
416
+ for (const auto &[CommonName, LTOProfiles] : LTOCommonNameMap) {
417
+ if (!LTOCommonNameFunctionMap.contains (CommonName))
418
+ continue ;
419
+ std::unordered_set<BinaryFunction *> &Functions =
420
+ LTOCommonNameFunctionMap[CommonName];
421
+ // Return true if a given profile is matched to one of BinaryFunctions with
422
+ // matching LTO common name.
423
+ auto matchProfile = [&](yaml::bolt::BinaryFunctionProfile *YamlBF) {
424
+ if (YamlBF->Used )
425
+ return false ;
426
+ for (BinaryFunction *BF : Functions) {
427
+ if (!ProfiledFunctions.count (BF) && profileMatches (*YamlBF, *BF)) {
428
+ matchProfileToFunction (*YamlBF, *BF);
429
+ ++MatchedWithLTOCommonName;
430
+ return true ;
431
+ }
432
+ }
433
+ return false ;
434
+ };
435
+ bool ProfileMatched = llvm::any_of (LTOProfiles, matchProfile);
436
+
437
+ // If there's only one function with a given name, try to match it
438
+ // partially.
439
+ if (!ProfileMatched && LTOProfiles.size () == 1 && Functions.size () == 1 &&
440
+ !LTOProfiles.front ()->Used &&
441
+ !ProfiledFunctions.count (*Functions.begin ())) {
442
+ matchProfileToFunction (*LTOProfiles.front (), **Functions.begin ());
443
+ ++MatchedWithLTOCommonName;
444
+ }
445
+ }
446
+ return MatchedWithLTOCommonName;
447
+ }
448
+
449
+ size_t YAMLProfileReader::matchWithNameSimilarity (BinaryContext &BC) {
450
+ if (opts::NameSimilarityFunctionMatchingThreshold == 0 )
451
+ return 0 ;
452
+
453
+ size_t MatchedWithNameSimilarity = 0 ;
363
454
ItaniumPartialDemangler Demangler;
364
455
365
456
// Demangle and derive namespace from function name.
@@ -477,17 +568,6 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
477
568
}
478
569
YamlProfileToFunction.resize (YamlBP.Functions .size () + 1 );
479
570
480
- auto profileMatches = [](const yaml::bolt::BinaryFunctionProfile &Profile,
481
- BinaryFunction &BF) {
482
- if (opts::IgnoreHash)
483
- return Profile.NumBasicBlocks == BF.size ();
484
- return Profile.Hash == static_cast <uint64_t >(BF.getHash ());
485
- };
486
-
487
- uint64_t MatchedWithExactName = 0 ;
488
- uint64_t MatchedWithHash = 0 ;
489
- uint64_t MatchedWithLTOCommonName = 0 ;
490
-
491
571
// Computes hash for binary functions.
492
572
if (opts::MatchProfileWithFunctionHash) {
493
573
for (auto &[_, BF] : BC.getBinaryFunctions ()) {
@@ -501,84 +581,15 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
501
581
}
502
582
}
503
583
504
- // This first pass assigns profiles that match 100% by name and by hash.
505
- for (auto [YamlBF, BF] : llvm::zip_equal (YamlBP.Functions , ProfileBFs)) {
506
- if (!BF)
507
- continue ;
508
- BinaryFunction &Function = *BF;
509
- // Clear function call count that may have been set while pre-processing
510
- // the profile.
511
- Function.setExecutionCount (BinaryFunction::COUNT_NO_PROFILE);
512
-
513
- if (profileMatches (YamlBF, Function)) {
514
- matchProfileToFunction (YamlBF, Function);
515
- ++MatchedWithExactName;
516
- }
517
- }
518
-
519
- // Iterates through profiled functions to match the first binary function with
520
- // the same exact hash. Serves to match identical, renamed functions.
521
- // Collisions are possible where multiple functions share the same exact hash.
522
- if (opts::MatchProfileWithFunctionHash) {
523
- DenseMap<size_t , BinaryFunction *> StrictHashToBF;
524
- StrictHashToBF.reserve (BC.getBinaryFunctions ().size ());
525
-
526
- for (auto &[_, BF] : BC.getBinaryFunctions ())
527
- StrictHashToBF[BF.getHash ()] = &BF;
528
-
529
- for (yaml::bolt::BinaryFunctionProfile &YamlBF : YamlBP.Functions ) {
530
- if (YamlBF.Used )
531
- continue ;
532
- auto It = StrictHashToBF.find (YamlBF.Hash );
533
- if (It != StrictHashToBF.end () && !ProfiledFunctions.count (It->second )) {
534
- BinaryFunction *BF = It->second ;
535
- matchProfileToFunction (YamlBF, *BF);
536
- ++MatchedWithHash;
537
- }
538
- }
539
- }
540
-
541
- // This second pass allows name ambiguity for LTO private functions.
542
- for (const auto &[CommonName, LTOProfiles] : LTOCommonNameMap) {
543
- if (!LTOCommonNameFunctionMap.contains (CommonName))
544
- continue ;
545
- std::unordered_set<BinaryFunction *> &Functions =
546
- LTOCommonNameFunctionMap[CommonName];
547
- // Return true if a given profile is matched to one of BinaryFunctions with
548
- // matching LTO common name.
549
- auto matchProfile = [&](yaml::bolt::BinaryFunctionProfile *YamlBF) {
550
- if (YamlBF->Used )
551
- return false ;
552
- for (BinaryFunction *BF : Functions) {
553
- if (!ProfiledFunctions.count (BF) && profileMatches (*YamlBF, *BF)) {
554
- matchProfileToFunction (*YamlBF, *BF);
555
- ++MatchedWithLTOCommonName;
556
- return true ;
557
- }
558
- }
559
- return false ;
560
- };
561
- bool ProfileMatched = llvm::any_of (LTOProfiles, matchProfile);
562
-
563
- // If there's only one function with a given name, try to match it
564
- // partially.
565
- if (!ProfileMatched && LTOProfiles.size () == 1 && Functions.size () == 1 &&
566
- !LTOProfiles.front ()->Used &&
567
- !ProfiledFunctions.count (*Functions.begin ())) {
568
- matchProfileToFunction (*LTOProfiles.front (), **Functions.begin ());
569
- ++MatchedWithLTOCommonName;
570
- }
571
- }
584
+ const size_t MatchedWithExactName = matchWithExactName ();
585
+ const size_t MatchedWithHash = matchWithHash (BC);
586
+ const size_t MatchedWithLTOCommonName = matchWithLTOCommonName ();
587
+ const size_t MatchedWithNameSimilarity = matchWithNameSimilarity (BC);
572
588
573
589
for (auto [YamlBF, BF] : llvm::zip_equal (YamlBP.Functions , ProfileBFs))
574
590
if (!YamlBF.Used && BF && !ProfiledFunctions.count (BF))
575
591
matchProfileToFunction (YamlBF, *BF);
576
592
577
- // Uses name similarity to match functions that were not matched by name.
578
- uint64_t MatchedWithNameSimilarity =
579
- opts::NameSimilarityFunctionMatchingThreshold > 0
580
- ? matchWithNameSimilarity (BC)
581
- : 0 ;
582
593
583
594
for (yaml::bolt::BinaryFunctionProfile &YamlBF : YamlBP.Functions )
584
595
if (!YamlBF.Used && opts::Verbosity >= 1 )
0 commit comments