[llvm-branch-commits] [llvm] [BOLT] Hash-based function matching (PR #95821)

shaw young via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Jun 20 15:05:23 PDT 2024


https://github.com/shawbyoung updated https://github.com/llvm/llvm-project/pull/95821

>From 92212c96ea169d26ac10bf8d750539bc5dd72c49 Mon Sep 17 00:00:00 2001
From: shawbyoung <shawbyoung at gmail.com>
Date: Mon, 17 Jun 2024 15:39:02 -0700
Subject: [PATCH 01/13] spr amend

Created using spr 1.3.4
---
 bolt/lib/Profile/YAMLProfileReader.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/bolt/lib/Profile/YAMLProfileReader.cpp b/bolt/lib/Profile/YAMLProfileReader.cpp
index f0fcb1c130002..2bca83c9d11ec 100644
--- a/bolt/lib/Profile/YAMLProfileReader.cpp
+++ b/bolt/lib/Profile/YAMLProfileReader.cpp
@@ -421,6 +421,8 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
   StrictBinaryFunctionHashes.reserve(BC.getBinaryFunctions().size());
 
   for (auto& [_, BF] : BC.getBinaryFunctions()) {
+    if (!ProfiledFunctions.count(&BF))
+      continue;
     StrictBinaryFunctionHashes[BF.getHash()] = &BF;
   }
 

>From 2497922ccc46e3189870563b1fe819b67172778d Mon Sep 17 00:00:00 2001
From: shawbyoung <shawbyoung at gmail.com>
Date: Mon, 17 Jun 2024 15:39:39 -0700
Subject: [PATCH 02/13] spr amend

Created using spr 1.3.4
---
 bolt/lib/Profile/YAMLProfileReader.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/bolt/lib/Profile/YAMLProfileReader.cpp b/bolt/lib/Profile/YAMLProfileReader.cpp
index 2bca83c9d11ec..56474a67307ed 100644
--- a/bolt/lib/Profile/YAMLProfileReader.cpp
+++ b/bolt/lib/Profile/YAMLProfileReader.cpp
@@ -417,10 +417,10 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
 
   // Uses the strict hash of profiled and binary functions to match functions
   // that are not matched by name or common name.
-  std::unordered_map<size_t, BinaryFunction*> StrictBinaryFunctionHashes;
+  std::unordered_map<size_t, BinaryFunction *> StrictBinaryFunctionHashes;
   StrictBinaryFunctionHashes.reserve(BC.getBinaryFunctions().size());
 
-  for (auto& [_, BF] : BC.getBinaryFunctions()) {
+  for (auto &[_, BF] : BC.getBinaryFunctions()) {
     if (!ProfiledFunctions.count(&BF))
       continue;
     StrictBinaryFunctionHashes[BF.getHash()] = &BF;
@@ -428,7 +428,8 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
 
   for (auto YamlBF : YamlBP.Functions) {
     auto It = StrictBinaryFunctionHashes.find(YamlBF.Hash);
-    if (It != StrictBinaryFunctionHashes.end() && !ProfiledFunctions.count(It->second)) {
+    if (It != StrictBinaryFunctionHashes.end() &&
+        !ProfiledFunctions.count(It->second)) {
       auto *BF = It->second;
       matchProfileToFunction(YamlBF, *BF);
     }

>From 8e7b2229a69c3795e723404c56e0d4298eef412a Mon Sep 17 00:00:00 2001
From: shawbyoung <shawbyoung at gmail.com>
Date: Mon, 17 Jun 2024 15:55:58 -0700
Subject: [PATCH 03/13] spr amend

Created using spr 1.3.4
---
 bolt/lib/Profile/YAMLProfileReader.cpp       | 2 +-
 bolt/test/X86/profile-passthrough-block.test | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/bolt/lib/Profile/YAMLProfileReader.cpp b/bolt/lib/Profile/YAMLProfileReader.cpp
index 56474a67307ed..779d60bce3b66 100644
--- a/bolt/lib/Profile/YAMLProfileReader.cpp
+++ b/bolt/lib/Profile/YAMLProfileReader.cpp
@@ -421,7 +421,7 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
   StrictBinaryFunctionHashes.reserve(BC.getBinaryFunctions().size());
 
   for (auto &[_, BF] : BC.getBinaryFunctions()) {
-    if (!ProfiledFunctions.count(&BF))
+    if (ProfiledFunctions.count(&BF))
       continue;
     StrictBinaryFunctionHashes[BF.getHash()] = &BF;
   }
diff --git a/bolt/test/X86/profile-passthrough-block.test b/bolt/test/X86/profile-passthrough-block.test
index 1b875885260dc..ed2a8117ddfc4 100644
--- a/bolt/test/X86/profile-passthrough-block.test
+++ b/bolt/test/X86/profile-passthrough-block.test
@@ -57,7 +57,7 @@ header:
 functions:
   - name:            main
     fid:             0
-    hash:            0x0000000000000000
+    hash:            0x0000000000000001
     exec:            1
     nblocks:         6
     blocks:

>From ef5f0dac9185dbb7a62345938d4f309c3379a85d Mon Sep 17 00:00:00 2001
From: shawbyoung <shawbyoung at gmail.com>
Date: Mon, 17 Jun 2024 15:58:22 -0700
Subject: [PATCH 04/13] spr amend

Created using spr 1.3.4
---
 bolt/lib/Profile/YAMLProfileReader.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/bolt/lib/Profile/YAMLProfileReader.cpp b/bolt/lib/Profile/YAMLProfileReader.cpp
index 779d60bce3b66..e3d30bfdb74e4 100644
--- a/bolt/lib/Profile/YAMLProfileReader.cpp
+++ b/bolt/lib/Profile/YAMLProfileReader.cpp
@@ -427,6 +427,8 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
   }
 
   for (auto YamlBF : YamlBP.Functions) {
+    if (YamlBF.Used)
+      continue;
     auto It = StrictBinaryFunctionHashes.find(YamlBF.Hash);
     if (It != StrictBinaryFunctionHashes.end() &&
         !ProfiledFunctions.count(It->second)) {

>From 41ce2897a445e47dfe685da66b4af080824e78ed Mon Sep 17 00:00:00 2001
From: shawbyoung <shawbyoung at gmail.com>
Date: Mon, 17 Jun 2024 16:00:27 -0700
Subject: [PATCH 05/13] spr amend

Created using spr 1.3.4
---
 bolt/test/X86/profile-passthrough-block.test | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bolt/test/X86/profile-passthrough-block.test b/bolt/test/X86/profile-passthrough-block.test
index ed2a8117ddfc4..1b875885260dc 100644
--- a/bolt/test/X86/profile-passthrough-block.test
+++ b/bolt/test/X86/profile-passthrough-block.test
@@ -57,7 +57,7 @@ header:
 functions:
   - name:            main
     fid:             0
-    hash:            0x0000000000000001
+    hash:            0x0000000000000000
     exec:            1
     nblocks:         6
     blocks:

>From 99cf8918e945356d12b5d29fe8174c610f305559 Mon Sep 17 00:00:00 2001
From: shawbyoung <shawbyoung at gmail.com>
Date: Tue, 18 Jun 2024 14:19:45 -0700
Subject: [PATCH 06/13] spr amend

Created using spr 1.3.4
---
 bolt/lib/Profile/YAMLProfileReader.cpp        | 51 +++++++-------
 .../X86/hashing-based-function-matching.test  | 67 +++++++++++++++++++
 2 files changed, 93 insertions(+), 25 deletions(-)
 create mode 100644 bolt/test/X86/hashing-based-function-matching.test

diff --git a/bolt/lib/Profile/YAMLProfileReader.cpp b/bolt/lib/Profile/YAMLProfileReader.cpp
index e3d30bfdb74e4..78d46eea5c728 100644
--- a/bolt/lib/Profile/YAMLProfileReader.cpp
+++ b/bolt/lib/Profile/YAMLProfileReader.cpp
@@ -363,9 +363,7 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
     return Profile.Hash == static_cast<uint64_t>(BF.getHash());
   };
 
-  // We have to do 2 passes since LTO introduces an ambiguity in function
-  // names. The first pass assigns profiles that match 100% by name and
-  // by hash. The second pass allows name ambiguity for LTO private functions.
+  // This first pass assigns profiles that match 100% by name and by hash.
   for (auto [YamlBF, BF] : llvm::zip_equal(YamlBP.Functions, ProfileBFs)) {
     if (!BF)
       continue;
@@ -383,6 +381,30 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
       matchProfileToFunction(YamlBF, Function);
   }
 
+  // Uses the strict hash of profiled and binary functions to match functions
+  // that are not matched by name or common name.
+  std::unordered_map<size_t, BinaryFunction *> StrictBinaryFunctionHashes;
+  StrictBinaryFunctionHashes.reserve(BC.getBinaryFunctions().size());
+
+  for (auto &[_, BF] : BC.getBinaryFunctions()) {
+    if (ProfiledFunctions.count(&BF))
+      continue;
+    BF.computeHash(YamlBP.Header.IsDFSOrder, YamlBP.Header.HashFunction);
+    StrictBinaryFunctionHashes[BF.getHash()] = &BF;
+  }
+
+  for (auto YamlBF : YamlBP.Functions) {
+    if (YamlBF.Used)
+      continue;
+    auto It = StrictBinaryFunctionHashes.find(YamlBF.Hash);
+    if (It != StrictBinaryFunctionHashes.end() &&
+        !ProfiledFunctions.count(It->second)) {
+      auto *BF = It->second;
+      matchProfileToFunction(YamlBF, *BF);
+    }
+  }
+
+  // This second pass allows name ambiguity for LTO private functions.
   for (const auto &[CommonName, LTOProfiles] : LTOCommonNameMap) {
     if (!LTOCommonNameFunctionMap.contains(CommonName))
       continue;
@@ -415,33 +437,12 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
     if (!YamlBF.Used && BF && !ProfiledFunctions.count(BF))
       matchProfileToFunction(YamlBF, *BF);
 
-  // Uses the strict hash of profiled and binary functions to match functions
-  // that are not matched by name or common name.
-  std::unordered_map<size_t, BinaryFunction *> StrictBinaryFunctionHashes;
-  StrictBinaryFunctionHashes.reserve(BC.getBinaryFunctions().size());
-
-  for (auto &[_, BF] : BC.getBinaryFunctions()) {
-    if (ProfiledFunctions.count(&BF))
-      continue;
-    StrictBinaryFunctionHashes[BF.getHash()] = &BF;
-  }
-
-  for (auto YamlBF : YamlBP.Functions) {
-    if (YamlBF.Used)
-      continue;
-    auto It = StrictBinaryFunctionHashes.find(YamlBF.Hash);
-    if (It != StrictBinaryFunctionHashes.end() &&
-        !ProfiledFunctions.count(It->second)) {
-      auto *BF = It->second;
-      matchProfileToFunction(YamlBF, *BF);
-    }
-  }
-
   for (yaml::bolt::BinaryFunctionProfile &YamlBF : YamlBP.Functions)
     if (!YamlBF.Used && opts::Verbosity >= 1)
       errs() << "BOLT-WARNING: profile ignored for function " << YamlBF.Name
              << '\n';
 
+
   // Set for parseFunctionProfile().
   NormalizeByInsnCount = usesEvent("cycles") || usesEvent("instructions");
   NormalizeByCalls = usesEvent("branches");
diff --git a/bolt/test/X86/hashing-based-function-matching.test b/bolt/test/X86/hashing-based-function-matching.test
new file mode 100644
index 0000000000000..3c2cd834f90bf
--- /dev/null
+++ b/bolt/test/X86/hashing-based-function-matching.test
@@ -0,0 +1,67 @@
+## Test YAMLProfileReader support for pass-through blocks in non-matching edges:
+## match the profile edge A -> C to the CFG with blocks A -> B -> C.
+
+# REQUIRES: system-linux
+# RUN: split-file %s %t
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %t/main.s -o %t.o
+# RUN: %clang %cflags %t.o -o %t.exe -Wl,-q -nostdlib
+# RUN: llvm-bolt %t.exe -o %t.out --data %t/yaml -v=1 \
+# RUN:   --print-cfg 2>&1 | FileCheck %s
+
+# CHECK: Binary Function "main" after building cfg
+# CHECK: Profile Acc : 100.0%
+# CHECK-NOT: BOLT-WARNING: no successor for block .LFT0 that matches index 3 or block .Ltmp0
+
+#--- main.s
+.globl main
+.type	main, @function
+main:
+  .cfi_startproc
+.LBB00:
+  pushq   %rbp
+  movq    %rsp, %rbp
+  subq    $16, %rsp
+  testq   %rax, %rax
+  js      .LBB03
+.LBB01:
+  jne     .LBB04
+.LBB02:
+  nop
+.LBB03:
+  xorl    %eax, %eax
+  addq    $16, %rsp
+  popq    %rbp
+  retq
+.LBB04:
+  xorl    %eax, %eax
+  addq    $16, %rsp
+  popq    %rbp
+  retq
+## For relocations against .text
+.LBB05:
+  call exit
+  .cfi_endproc
+  .size	main, .-main
+
+#--- yaml
+---
+header:
+  profile-version: 1
+  binary-name:     'profile-passthrough-block.s.tmp.exe'
+  binary-build-id: '<unknown>'
+  profile-flags:   [ lbr ]
+  profile-origin:  branch profile reader
+  profile-events:  ''
+  dfs-order:       false
+  hash-func:       xxh3
+functions:
+  - name:            main2
+    fid:             0
+    hash:            0x72f82deaa6fe65fb
+    exec:            1
+    nblocks:         6
+    blocks:
+      - bid:             1
+        insns:           1
+        succ:            [ { bid: 3, cnt: 1} ]
+...

>From e11820ff0121d9481a24b825f1910935e6d5789d Mon Sep 17 00:00:00 2001
From: shawbyoung <shawbyoung at gmail.com>
Date: Thu, 20 Jun 2024 08:28:02 -0700
Subject: [PATCH 07/13] spr amend

Created using spr 1.3.4
---
 bolt/lib/Profile/YAMLProfileReader.cpp        | 42 +++++++++----------
 .../X86/hashing-based-function-matching.test  |  4 +-
 2 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/bolt/lib/Profile/YAMLProfileReader.cpp b/bolt/lib/Profile/YAMLProfileReader.cpp
index 78d46eea5c728..7209168c0f81d 100644
--- a/bolt/lib/Profile/YAMLProfileReader.cpp
+++ b/bolt/lib/Profile/YAMLProfileReader.cpp
@@ -363,6 +363,11 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
     return Profile.Hash == static_cast<uint64_t>(BF.getHash());
   };
 
+  // Computes hash for binary functions.
+  if (!opts::IgnoreHash)
+    for (auto &[_, BF] : BC.getBinaryFunctions())
+      BF.computeHash(YamlBP.Header.IsDFSOrder, YamlBP.Header.HashFunction);
+
   // This first pass assigns profiles that match 100% by name and by hash.
   for (auto [YamlBF, BF] : llvm::zip_equal(YamlBP.Functions, ProfileBFs)) {
     if (!BF)
@@ -372,35 +377,29 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
     // the profile.
     Function.setExecutionCount(BinaryFunction::COUNT_NO_PROFILE);
 
-    // Recompute hash once per function.
-    if (!opts::IgnoreHash)
-      Function.computeHash(YamlBP.Header.IsDFSOrder,
-                           YamlBP.Header.HashFunction);
-
     if (profileMatches(YamlBF, Function))
       matchProfileToFunction(YamlBF, Function);
   }
 
   // Uses the strict hash of profiled and binary functions to match functions
   // that are not matched by name or common name.
-  std::unordered_map<size_t, BinaryFunction *> StrictBinaryFunctionHashes;
-  StrictBinaryFunctionHashes.reserve(BC.getBinaryFunctions().size());
+  if (!opts::IgnoreHash) {
+    std::unordered_map<size_t, BinaryFunction *> StrictHashToBF;
+    StrictHashToBF.reserve(BC.getBinaryFunctions().size());
 
-  for (auto &[_, BF] : BC.getBinaryFunctions()) {
-    if (ProfiledFunctions.count(&BF))
-      continue;
-    BF.computeHash(YamlBP.Header.IsDFSOrder, YamlBP.Header.HashFunction);
-    StrictBinaryFunctionHashes[BF.getHash()] = &BF;
-  }
+    for (auto &[_, BF] : BC.getBinaryFunctions()) {
+      StrictHashToBF[BF.getHash()] = &BF;
+    }
 
-  for (auto YamlBF : YamlBP.Functions) {
-    if (YamlBF.Used)
-      continue;
-    auto It = StrictBinaryFunctionHashes.find(YamlBF.Hash);
-    if (It != StrictBinaryFunctionHashes.end() &&
-        !ProfiledFunctions.count(It->second)) {
-      auto *BF = It->second;
-      matchProfileToFunction(YamlBF, *BF);
+    for (auto YamlBF : YamlBP.Functions) {
+      if (YamlBF.Used)
+        continue;
+      auto It = StrictHashToBF.find(YamlBF.Hash);
+      if (It != StrictHashToBF.end() &&
+          !ProfiledFunctions.count(It->second)) {
+        auto *BF = It->second;
+        matchProfileToFunction(YamlBF, *BF);
+      }
     }
   }
 
@@ -442,7 +441,6 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
       errs() << "BOLT-WARNING: profile ignored for function " << YamlBF.Name
              << '\n';
 
-
   // Set for parseFunctionProfile().
   NormalizeByInsnCount = usesEvent("cycles") || usesEvent("instructions");
   NormalizeByCalls = usesEvent("branches");
diff --git a/bolt/test/X86/hashing-based-function-matching.test b/bolt/test/X86/hashing-based-function-matching.test
index 3c2cd834f90bf..833450047284a 100644
--- a/bolt/test/X86/hashing-based-function-matching.test
+++ b/bolt/test/X86/hashing-based-function-matching.test
@@ -5,7 +5,7 @@
 # RUN: split-file %s %t
 # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %t/main.s -o %t.o
 # RUN: %clang %cflags %t.o -o %t.exe -Wl,-q -nostdlib
-# RUN: llvm-bolt %t.exe -o %t.out --data %t/yaml -v=1 \
+# RUN: llvm-bolt %t.exe -o %t.out --data %t/yaml -v=2 \
 # RUN:   --print-cfg 2>&1 | FileCheck %s
 
 # CHECK: Binary Function "main" after building cfg
@@ -57,7 +57,7 @@ header:
 functions:
   - name:            main2
     fid:             0
-    hash:            0x72f82deaa6fe65fb
+    hash:            0x72F82DEAA6FE65FB
     exec:            1
     nblocks:         6
     blocks:

>From 83858e2fcc565673bf10b030199d30153ba015b3 Mon Sep 17 00:00:00 2001
From: shawbyoung <shawbyoung at gmail.com>
Date: Thu, 20 Jun 2024 10:45:17 -0700
Subject: [PATCH 08/13] spr amend

Created using spr 1.3.4
---
 bolt/lib/Profile/YAMLProfileReader.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/bolt/lib/Profile/YAMLProfileReader.cpp b/bolt/lib/Profile/YAMLProfileReader.cpp
index 7209168c0f81d..124af2c25b9e4 100644
--- a/bolt/lib/Profile/YAMLProfileReader.cpp
+++ b/bolt/lib/Profile/YAMLProfileReader.cpp
@@ -329,6 +329,9 @@ Error YAMLProfileReader::preprocessProfile(BinaryContext &BC) {
 }
 
 bool YAMLProfileReader::mayHaveProfileData(const BinaryFunction &BF) {
+  if (!opts::IgnoreHash) {
+    return true;
+  }
   for (StringRef Name : BF.getNames())
     if (ProfileFunctionNames.contains(Name))
       return true;

>From 73871266cf7709ae335be22428290cdc1efe410b Mon Sep 17 00:00:00 2001
From: shawbyoung <shawbyoung at gmail.com>
Date: Thu, 20 Jun 2024 14:35:45 -0700
Subject: [PATCH 09/13] spr amend

Created using spr 1.3.4
---
 bolt/lib/Profile/YAMLProfileReader.cpp        | 41 ++++++++++++++++---
 bolt/lib/Rewrite/RewriteInstance.cpp          |  6 ++-
 bolt/lib/Utils/CommandLineOpts.cpp            |  5 +++
 .../X86/hashing-based-function-matching.test  |  6 +--
 4 files changed, 47 insertions(+), 11 deletions(-)

diff --git a/bolt/lib/Profile/YAMLProfileReader.cpp b/bolt/lib/Profile/YAMLProfileReader.cpp
index 124af2c25b9e4..603620aa483d7 100644
--- a/bolt/lib/Profile/YAMLProfileReader.cpp
+++ b/bolt/lib/Profile/YAMLProfileReader.cpp
@@ -22,6 +22,7 @@ namespace opts {
 extern cl::opt<unsigned> Verbosity;
 extern cl::OptionCategory BoltOptCategory;
 extern cl::opt<bool> InferStaleProfile;
+extern cl::opt<bool> MatchingFunctionsWithHash;
 
 static llvm::cl::opt<bool>
     IgnoreHash("profile-ignore-hash",
@@ -329,9 +330,6 @@ Error YAMLProfileReader::preprocessProfile(BinaryContext &BC) {
 }
 
 bool YAMLProfileReader::mayHaveProfileData(const BinaryFunction &BF) {
-  if (!opts::IgnoreHash) {
-    return true;
-  }
   for (StringRef Name : BF.getNames())
     if (ProfileFunctionNames.contains(Name))
       return true;
@@ -366,10 +364,26 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
     return Profile.Hash == static_cast<uint64_t>(BF.getHash());
   };
 
+  uint64_t MatchedWithExactName = 0;
+  uint64_t MatchedWithHash = 0;
+  uint64_t MatchedWithLTOCommonName = 0;
+
   // Computes hash for binary functions.
-  if (!opts::IgnoreHash)
+  if (opts::MatchingFunctionsWithHash) {
     for (auto &[_, BF] : BC.getBinaryFunctions())
       BF.computeHash(YamlBP.Header.IsDFSOrder, YamlBP.Header.HashFunction);
+  }
+  else {
+    for (auto [YamlBF, BF] : llvm::zip_equal(YamlBP.Functions, ProfileBFs)) {
+      if (!BF)
+        continue;
+      BinaryFunction &Function = *BF;
+
+      if (!opts::IgnoreHash)
+        Function.computeHash(YamlBP.Header.IsDFSOrder,
+                             YamlBP.Header.HashFunction);
+    }
+  }
 
   // This first pass assigns profiles that match 100% by name and by hash.
   for (auto [YamlBF, BF] : llvm::zip_equal(YamlBP.Functions, ProfileBFs)) {
@@ -380,8 +394,10 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
     // the profile.
     Function.setExecutionCount(BinaryFunction::COUNT_NO_PROFILE);
 
-    if (profileMatches(YamlBF, Function))
+    if (profileMatches(YamlBF, Function)) {
       matchProfileToFunction(YamlBF, Function);
+      ++MatchedWithExactName;
+    }
   }
 
   // Uses the strict hash of profiled and binary functions to match functions
@@ -402,6 +418,7 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
           !ProfiledFunctions.count(It->second)) {
         auto *BF = It->second;
         matchProfileToFunction(YamlBF, *BF);
+        ++MatchedWithHash;
       }
     }
   }
@@ -420,6 +437,7 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
       for (BinaryFunction *BF : Functions) {
         if (!ProfiledFunctions.count(BF) && profileMatches(*YamlBF, *BF)) {
           matchProfileToFunction(*YamlBF, *BF);
+          ++MatchedWithLTOCommonName;
           return true;
         }
       }
@@ -431,8 +449,10 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
     // partially.
     if (!ProfileMatched && LTOProfiles.size() == 1 && Functions.size() == 1 &&
         !LTOProfiles.front()->Used &&
-        !ProfiledFunctions.count(*Functions.begin()))
+        !ProfiledFunctions.count(*Functions.begin())) {
       matchProfileToFunction(*LTOProfiles.front(), **Functions.begin());
+      ++MatchedWithLTOCommonName;
+    }
   }
 
   for (auto [YamlBF, BF] : llvm::zip_equal(YamlBP.Functions, ProfileBFs))
@@ -444,6 +464,15 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
       errs() << "BOLT-WARNING: profile ignored for function " << YamlBF.Name
              << '\n';
 
+  if (opts::Verbosity >= 2) {
+    outs() << "BOLT-INFO: matched " << MatchedWithExactName
+      << " functions with identical names\n";
+    outs() << "BOLT-INFO: matched " << MatchedWithHash
+      << " functions with hash\n";
+    outs() << "BOLT-INFO: matched " << MatchedWithLTOCommonName
+      << " functions with matching LTO common names\n";
+  }
+
   // Set for parseFunctionProfile().
   NormalizeByInsnCount = usesEvent("cycles") || usesEvent("instructions");
   NormalizeByCalls = usesEvent("branches");
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 1a3a8af21d81b..c157e45e1d586 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -82,6 +82,7 @@ extern cl::opt<bool> Hugify;
 extern cl::opt<bool> Instrument;
 extern cl::opt<JumpTableSupportLevel> JumpTables;
 extern cl::opt<bool> KeepNops;
+extern cl::opt<bool> MatchingFunctionsWithHash;
 extern cl::list<std::string> ReorderData;
 extern cl::opt<bolt::ReorderFunctions::ReorderType> ReorderFunctions;
 extern cl::opt<bool> TerminalTrap;
@@ -2982,6 +2983,9 @@ void RewriteInstance::selectFunctionsToProcess() {
     if (mustSkip(Function))
       return false;
 
+    if (opts::MatchingFunctionsWithHash)
+      return true;
+
     // If the list is not empty, only process functions from the list.
     if (!opts::ForceFunctionNames.empty() || !ForceFunctionsNR.empty()) {
       // Regex check (-funcs and -funcs-file options).
@@ -2998,6 +3002,7 @@ void RewriteInstance::selectFunctionsToProcess() {
     }
 
     if (opts::Lite) {
+
       // Forcibly include functions specified in the -function-order file.
       if (opts::ReorderFunctions == ReorderFunctions::RT_USER) {
         for (const StringRef Name : Function.getNames())
@@ -3008,7 +3013,6 @@ void RewriteInstance::selectFunctionsToProcess() {
             if (ReorderFunctionsLTOCommonSet.contains(*LTOCommonName))
               return true;
       }
-
       if (ProfileReader && !ProfileReader->mayHaveProfileData(Function))
         return false;
 
diff --git a/bolt/lib/Utils/CommandLineOpts.cpp b/bolt/lib/Utils/CommandLineOpts.cpp
index 41c89bc8aeba4..58d44a98b6218 100644
--- a/bolt/lib/Utils/CommandLineOpts.cpp
+++ b/bolt/lib/Utils/CommandLineOpts.cpp
@@ -128,6 +128,11 @@ cl::opt<bool>
                cl::desc("instrument code to generate accurate profile data"),
                cl::cat(BoltOptCategory));
 
+cl::opt<bool> MatchingFunctionsWithHash("stale-matching-matching-functions-with-hash",
+  cl::desc("Matching functions using hash"),
+  cl::Hidden,
+  cl::cat(BoltCategory));
+
 cl::opt<std::string>
 OutputFilename("o",
   cl::desc("<output file>"),
diff --git a/bolt/test/X86/hashing-based-function-matching.test b/bolt/test/X86/hashing-based-function-matching.test
index 833450047284a..83819f4c539d3 100644
--- a/bolt/test/X86/hashing-based-function-matching.test
+++ b/bolt/test/X86/hashing-based-function-matching.test
@@ -6,11 +6,9 @@
 # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %t/main.s -o %t.o
 # RUN: %clang %cflags %t.o -o %t.exe -Wl,-q -nostdlib
 # RUN: llvm-bolt %t.exe -o %t.out --data %t/yaml -v=2 \
-# RUN:   --print-cfg 2>&1 | FileCheck %s
+# RUN:   --print-cfg --stale-matching-matching-functions-with-hash 2>&1 --profile-ignore-hash=0 | FileCheck %s
 
-# CHECK: Binary Function "main" after building cfg
-# CHECK: Profile Acc : 100.0%
-# CHECK-NOT: BOLT-WARNING: no successor for block .LFT0 that matches index 3 or block .Ltmp0
+# CHECK: BOLT-INFO: matched 1 functions with hash
 
 #--- main.s
 .globl main

>From baec71c1a91b3ac7be09ee9774c8542430320ad0 Mon Sep 17 00:00:00 2001
From: shawbyoung <shawbyoung at gmail.com>
Date: Thu, 20 Jun 2024 14:37:10 -0700
Subject: [PATCH 10/13] spr amend

Created using spr 1.3.4
---
 bolt/lib/Profile/YAMLProfileReader.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/bolt/lib/Profile/YAMLProfileReader.cpp b/bolt/lib/Profile/YAMLProfileReader.cpp
index 603620aa483d7..dcc5d23745cb2 100644
--- a/bolt/lib/Profile/YAMLProfileReader.cpp
+++ b/bolt/lib/Profile/YAMLProfileReader.cpp
@@ -406,11 +406,10 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
     std::unordered_map<size_t, BinaryFunction *> StrictHashToBF;
     StrictHashToBF.reserve(BC.getBinaryFunctions().size());
 
-    for (auto &[_, BF] : BC.getBinaryFunctions()) {
+    for (auto &[_, BF] : BC.getBinaryFunctions())
       StrictHashToBF[BF.getHash()] = &BF;
-    }
 
-    for (auto YamlBF : YamlBP.Functions) {
+    for (yaml::bolt::BinaryFunctionProfile& YamlBF : YamlBP.Functions) {
       if (YamlBF.Used)
         continue;
       auto It = StrictHashToBF.find(YamlBF.Hash);

>From ff68ace13b1ece9c93322a3f1833f574b493c13b Mon Sep 17 00:00:00 2001
From: shawbyoung <shawbyoung at gmail.com>
Date: Thu, 20 Jun 2024 14:47:04 -0700
Subject: [PATCH 11/13] spr amend

Created using spr 1.3.4
---
 bolt/lib/Profile/YAMLProfileReader.cpp | 2 +-
 bolt/lib/Rewrite/RewriteInstance.cpp   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/bolt/lib/Profile/YAMLProfileReader.cpp b/bolt/lib/Profile/YAMLProfileReader.cpp
index dcc5d23745cb2..d04d54e1a9170 100644
--- a/bolt/lib/Profile/YAMLProfileReader.cpp
+++ b/bolt/lib/Profile/YAMLProfileReader.cpp
@@ -402,7 +402,7 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
 
   // Uses the strict hash of profiled and binary functions to match functions
   // that are not matched by name or common name.
-  if (!opts::IgnoreHash) {
+  if (opts::MatchingFunctionsWithHash) {
     std::unordered_map<size_t, BinaryFunction *> StrictHashToBF;
     StrictHashToBF.reserve(BC.getBinaryFunctions().size());
 
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index c157e45e1d586..7afc7c920318c 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -3002,7 +3002,6 @@ void RewriteInstance::selectFunctionsToProcess() {
     }
 
     if (opts::Lite) {
-
       // Forcibly include functions specified in the -function-order file.
       if (opts::ReorderFunctions == ReorderFunctions::RT_USER) {
         for (const StringRef Name : Function.getNames())
@@ -3013,6 +3012,7 @@ void RewriteInstance::selectFunctionsToProcess() {
             if (ReorderFunctionsLTOCommonSet.contains(*LTOCommonName))
               return true;
       }
+
       if (ProfileReader && !ProfileReader->mayHaveProfileData(Function))
         return false;
 

>From ef2eaaa3810e26f97088981450dee5b623ca1143 Mon Sep 17 00:00:00 2001
From: shawbyoung <shawbyoung at gmail.com>
Date: Thu, 20 Jun 2024 14:48:11 -0700
Subject: [PATCH 12/13] spr amend

Created using spr 1.3.4
---
 bolt/lib/Profile/YAMLProfileReader.cpp | 14 ++++++--------
 bolt/lib/Utils/CommandLineOpts.cpp     |  8 ++++----
 2 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/bolt/lib/Profile/YAMLProfileReader.cpp b/bolt/lib/Profile/YAMLProfileReader.cpp
index d04d54e1a9170..fd1a02ff63a3b 100644
--- a/bolt/lib/Profile/YAMLProfileReader.cpp
+++ b/bolt/lib/Profile/YAMLProfileReader.cpp
@@ -372,8 +372,7 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
   if (opts::MatchingFunctionsWithHash) {
     for (auto &[_, BF] : BC.getBinaryFunctions())
       BF.computeHash(YamlBP.Header.IsDFSOrder, YamlBP.Header.HashFunction);
-  }
-  else {
+  } else {
     for (auto [YamlBF, BF] : llvm::zip_equal(YamlBP.Functions, ProfileBFs)) {
       if (!BF)
         continue;
@@ -409,12 +408,11 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
     for (auto &[_, BF] : BC.getBinaryFunctions())
       StrictHashToBF[BF.getHash()] = &BF;
 
-    for (yaml::bolt::BinaryFunctionProfile& YamlBF : YamlBP.Functions) {
+    for (yaml::bolt::BinaryFunctionProfile &YamlBF : YamlBP.Functions) {
       if (YamlBF.Used)
         continue;
       auto It = StrictHashToBF.find(YamlBF.Hash);
-      if (It != StrictHashToBF.end() &&
-          !ProfiledFunctions.count(It->second)) {
+      if (It != StrictHashToBF.end() && !ProfiledFunctions.count(It->second)) {
         auto *BF = It->second;
         matchProfileToFunction(YamlBF, *BF);
         ++MatchedWithHash;
@@ -465,11 +463,11 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
 
   if (opts::Verbosity >= 2) {
     outs() << "BOLT-INFO: matched " << MatchedWithExactName
-      << " functions with identical names\n";
+           << " functions with identical names\n";
     outs() << "BOLT-INFO: matched " << MatchedWithHash
-      << " functions with hash\n";
+           << " functions with hash\n";
     outs() << "BOLT-INFO: matched " << MatchedWithLTOCommonName
-      << " functions with matching LTO common names\n";
+           << " functions with matching LTO common names\n";
   }
 
   // Set for parseFunctionProfile().
diff --git a/bolt/lib/Utils/CommandLineOpts.cpp b/bolt/lib/Utils/CommandLineOpts.cpp
index 58d44a98b6218..8144af29cba4e 100644
--- a/bolt/lib/Utils/CommandLineOpts.cpp
+++ b/bolt/lib/Utils/CommandLineOpts.cpp
@@ -128,10 +128,10 @@ cl::opt<bool>
                cl::desc("instrument code to generate accurate profile data"),
                cl::cat(BoltOptCategory));
 
-cl::opt<bool> MatchingFunctionsWithHash("stale-matching-matching-functions-with-hash",
-  cl::desc("Matching functions using hash"),
-  cl::Hidden,
-  cl::cat(BoltCategory));
+cl::opt<bool>
+    MatchingFunctionsWithHash("stale-matching-matching-functions-with-hash",
+                              cl::desc("Matching functions using hash"),
+                              cl::Hidden, cl::cat(BoltCategory));
 
 cl::opt<std::string>
 OutputFilename("o",

>From 3ed600c2f22356177f46e36b88eecc7ebd6e03ff Mon Sep 17 00:00:00 2001
From: shawbyoung <shawbyoung at gmail.com>
Date: Thu, 20 Jun 2024 15:05:10 -0700
Subject: [PATCH 13/13] spr amend

Created using spr 1.3.4
---
 bolt/docs/CommandLineArgumentReference.md | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/bolt/docs/CommandLineArgumentReference.md b/bolt/docs/CommandLineArgumentReference.md
index 8887d1f5d5bd4..0a5af3933b453 100644
--- a/bolt/docs/CommandLineArgumentReference.md
+++ b/bolt/docs/CommandLineArgumentReference.md
@@ -798,6 +798,10 @@
   bytes. Default value: 0, i.e. split iff the size is reduced. Note that on some
   architectures the size can increase after splitting.
 
+- `--stale-matching-matching-functions-with-hash`
+
+  Turns on matching functions with exact hash
+
 - `--stale-matching-max-func-size=<uint>`
 
   The maximum size of a function to consider for inference.
@@ -1161,4 +1165,4 @@
 
 - `--print-options`
 
-  Print non-default options after command line parsing
\ No newline at end of file
+  Print non-default options after command line parsing



More information about the llvm-branch-commits mailing list