[llvm-branch-commits] [llvm] [BOLT] Function matching with function calls as anchors (PR #96596)

shaw young via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Jun 25 11:19:57 PDT 2024


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

>From 05d59574d6260b98a469921eb2fccf5398bfafb6 Mon Sep 17 00:00:00 2001
From: shawbyoung <shawbyoung at gmail.com>
Date: Mon, 24 Jun 2024 23:00:59 -0700
Subject: [PATCH 1/4] Added call to matchWithCallsAsAnchors

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 aafffac3d4b1c..1a0e5d239d252 100644
--- a/bolt/lib/Profile/YAMLProfileReader.cpp
+++ b/bolt/lib/Profile/YAMLProfileReader.cpp
@@ -479,6 +479,9 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
     if (!YamlBF.Used && BF && !ProfiledFunctions.count(BF))
       matchProfileToFunction(YamlBF, *BF);
 
+  uint64_t MatchedWithCallsAsAnchors = 0;
+  matchWithCallsAsAnchors(BC,  MatchedWithCallsAsAnchors);
+
   for (yaml::bolt::BinaryFunctionProfile &YamlBF : YamlBP.Functions)
     if (!YamlBF.Used && opts::Verbosity >= 1)
       errs() << "BOLT-WARNING: profile ignored for function " << YamlBF.Name

>From 77ef0008f4f5987719555e6cc3e32da812ae0f31 Mon Sep 17 00:00:00 2001
From: shawbyoung <shawbyoung at gmail.com>
Date: Mon, 24 Jun 2024 23:11:43 -0700
Subject: [PATCH 2/4] Changed CallHashToBF representation

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

diff --git a/bolt/lib/Profile/YAMLProfileReader.cpp b/bolt/lib/Profile/YAMLProfileReader.cpp
index 1a0e5d239d252..91b01a99c7485 100644
--- a/bolt/lib/Profile/YAMLProfileReader.cpp
+++ b/bolt/lib/Profile/YAMLProfileReader.cpp
@@ -29,6 +29,10 @@ static llvm::cl::opt<bool>
                cl::desc("ignore hash while reading function profile"),
                cl::Hidden, cl::cat(BoltOptCategory));
 
+llvm::cl::opt<bool> MatchWithCallsAsAnchors("match-with-calls-as-anchors",
+                                  cl::desc("Matches with calls as anchors"),
+                                  cl::Hidden, cl::cat(BoltOptCategory));
+
 llvm::cl::opt<bool> ProfileUseDFS("profile-use-dfs",
                                   cl::desc("use DFS order for YAML profile"),
                                   cl::Hidden, cl::cat(BoltOptCategory));
@@ -353,7 +357,7 @@ void YAMLProfileReader::matchWithCallsAsAnchors(
     llvm_unreachable("Unhandled HashFunction");
   };
 
-  std::unordered_map<uint64_t, BinaryFunction &> CallHashToBF;
+  std::unordered_map<uint64_t, BinaryFunction *> CallHashToBF;
 
   for (BinaryFunction *BF : BC.getAllBinaryFunctions()) {
     if (ProfiledFunctions.count(BF))
@@ -375,12 +379,12 @@ void YAMLProfileReader::matchWithCallsAsAnchors(
       for (const std::string &FunctionName : FunctionNames)
         HashString.append(FunctionName);
     }
-    CallHashToBF.emplace(ComputeCallHash(HashString), BF);
+    CallHashToBF[ComputeCallHash(HashString)] = BF;
   }
 
   std::unordered_map<uint32_t, std::string> ProfiledFunctionIdToName;
 
-  for (const yaml::bolt::BinaryFunctionProfile YamlBF : YamlBP.Functions)
+  for (const yaml::bolt::BinaryFunctionProfile &YamlBF : YamlBP.Functions)
     ProfiledFunctionIdToName[YamlBF.Id] = YamlBF.Name;
 
   for (yaml::bolt::BinaryFunctionProfile &YamlBF : YamlBP.Functions) {
@@ -401,7 +405,7 @@ void YAMLProfileReader::matchWithCallsAsAnchors(
     auto It = CallHashToBF.find(Hash);
     if (It == CallHashToBF.end())
       continue;
-    matchProfileToFunction(YamlBF, It->second);
+    matchProfileToFunction(YamlBF, *It->second);
     ++MatchedWithCallsAsAnchors;
   }
 }
@@ -480,7 +484,8 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
       matchProfileToFunction(YamlBF, *BF);
 
   uint64_t MatchedWithCallsAsAnchors = 0;
-  matchWithCallsAsAnchors(BC,  MatchedWithCallsAsAnchors);
+  if (opts::MatchWithCallsAsAnchors)
+    matchWithCallsAsAnchors(BC,  MatchedWithCallsAsAnchors);
 
   for (yaml::bolt::BinaryFunctionProfile &YamlBF : YamlBP.Functions)
     if (!YamlBF.Used && opts::Verbosity >= 1)

>From ea7cb68ab9e8e158412c2e752986968968a60d93 Mon Sep 17 00:00:00 2001
From: shawbyoung <shawbyoung at gmail.com>
Date: Tue, 25 Jun 2024 09:28:39 -0700
Subject: [PATCH 3/4] Changed BF called FunctionNames to multiset

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 91b01a99c7485..3b3d73f7af023 100644
--- a/bolt/lib/Profile/YAMLProfileReader.cpp
+++ b/bolt/lib/Profile/YAMLProfileReader.cpp
@@ -365,7 +365,7 @@ void YAMLProfileReader::matchWithCallsAsAnchors(
 
     std::string HashString;
     for (const auto &BB : BF->blocks()) {
-      std::set<std::string> FunctionNames;
+      std::multiset<std::string> FunctionNames;
       for (const MCInst &Instr : BB) {
         // Skip non-call instructions.
         if (!BC.MIB->isCall(Instr))
@@ -397,9 +397,8 @@ void YAMLProfileReader::matchWithCallsAsAnchors(
         std::string &FunctionName = ProfiledFunctionIdToName[CallSite.DestId];
         FunctionNames.insert(FunctionName);
       }
-      for (const std::string &FunctionName : FunctionNames) {
+      for (const std::string &FunctionName : FunctionNames)
         HashString.append(FunctionName);
-      }
     }
     size_t Hash = ComputeCallHash(HashString);
     auto It = CallHashToBF.find(Hash);

>From c435034970c831c75ab718a9cb82c77d3004e091 Mon Sep 17 00:00:00 2001
From: shawbyoung <shawbyoung at gmail.com>
Date: Tue, 25 Jun 2024 11:19:47 -0700
Subject: [PATCH 4/4] GetOneName for YamlBF

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

diff --git a/bolt/lib/Profile/YAMLProfileReader.cpp b/bolt/lib/Profile/YAMLProfileReader.cpp
index 3b3d73f7af023..2ea1a051d314c 100644
--- a/bolt/lib/Profile/YAMLProfileReader.cpp
+++ b/bolt/lib/Profile/YAMLProfileReader.cpp
@@ -29,9 +29,10 @@ static llvm::cl::opt<bool>
                cl::desc("ignore hash while reading function profile"),
                cl::Hidden, cl::cat(BoltOptCategory));
 
-llvm::cl::opt<bool> MatchWithCallsAsAnchors("match-with-calls-as-anchors",
-                                  cl::desc("Matches with calls as anchors"),
-                                  cl::Hidden, cl::cat(BoltOptCategory));
+llvm::cl::opt<bool>
+    MatchWithCallsAsAnchors("match-with-calls-as-anchors",
+                            cl::desc("Matches with calls as anchors"),
+                            cl::Hidden, cl::cat(BoltOptCategory));
 
 llvm::cl::opt<bool> ProfileUseDFS("profile-use-dfs",
                                   cl::desc("use DFS order for YAML profile"),
@@ -358,12 +359,11 @@ void YAMLProfileReader::matchWithCallsAsAnchors(
   };
 
   std::unordered_map<uint64_t, BinaryFunction *> CallHashToBF;
-
   for (BinaryFunction *BF : BC.getAllBinaryFunctions()) {
     if (ProfiledFunctions.count(BF))
       continue;
 
-    std::string HashString;
+    std::string HashString{""};
     for (const auto &BB : BF->blocks()) {
       std::multiset<std::string> FunctionNames;
       for (const MCInst &Instr : BB) {
@@ -379,14 +379,23 @@ void YAMLProfileReader::matchWithCallsAsAnchors(
       for (const std::string &FunctionName : FunctionNames)
         HashString.append(FunctionName);
     }
+    // its possible we have some collisions.. our options to solve include
+    // cmp block ct, or potentially fname edit distance. although, thats p exp
+    if (HashString == "")
+      continue;
     CallHashToBF[ComputeCallHash(HashString)] = BF;
   }
 
   std::unordered_map<uint32_t, std::string> ProfiledFunctionIdToName;
-
-  for (const yaml::bolt::BinaryFunctionProfile &YamlBF : YamlBP.Functions)
-    ProfiledFunctionIdToName[YamlBF.Id] = YamlBF.Name;
-
+  for (const yaml::bolt::BinaryFunctionProfile &YamlBF : YamlBP.Functions) {
+    // How do we handle functions with multiple names? LTO specifically,
+    // right now the scope of this is to identical names wo lto i think
+    StringRef Name = YamlBF.Name;
+    const size_t Pos = Name.find("(*");
+    if (Pos != StringRef::npos)
+      Name = Name.substr(0, Pos);
+    ProfiledFunctionIdToName[YamlBF.Id] = Name;
+  }
   for (yaml::bolt::BinaryFunctionProfile &YamlBF : YamlBP.Functions) {
     if (YamlBF.Used)
       continue;
@@ -400,10 +409,14 @@ void YAMLProfileReader::matchWithCallsAsAnchors(
       for (const std::string &FunctionName : FunctionNames)
         HashString.append(FunctionName);
     }
+    if (HashString == "")
+      continue;
     size_t Hash = ComputeCallHash(HashString);
     auto It = CallHashToBF.find(Hash);
     if (It == CallHashToBF.end())
       continue;
+    if (ProfiledFunctions.count(It->second))
+      continue;
     matchProfileToFunction(YamlBF, *It->second);
     ++MatchedWithCallsAsAnchors;
   }
@@ -484,13 +497,18 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
 
   uint64_t MatchedWithCallsAsAnchors = 0;
   if (opts::MatchWithCallsAsAnchors)
-    matchWithCallsAsAnchors(BC,  MatchedWithCallsAsAnchors);
+    matchWithCallsAsAnchors(BC, MatchedWithCallsAsAnchors);
 
   for (yaml::bolt::BinaryFunctionProfile &YamlBF : YamlBP.Functions)
     if (!YamlBF.Used && opts::Verbosity >= 1)
       errs() << "BOLT-WARNING: profile ignored for function " << YamlBF.Name
              << '\n';
 
+  if (opts::Verbosity >= 2) {
+    outs() << "BOLT-INFO: matched " << MatchedWithCallsAsAnchors
+           << " functions with calls as anchors\n";
+  }
+
   // Set for parseFunctionProfile().
   NormalizeByInsnCount = usesEvent("cycles") || usesEvent("instructions");
   NormalizeByCalls = usesEvent("branches");



More information about the llvm-branch-commits mailing list