[llvm] [IPO] NFC: avoid recalculating FunctionId hashes during ProfiledCallGraph construction (PR #109014)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 26 11:46:13 PDT 2024


https://github.com/itrofimow updated https://github.com/llvm/llvm-project/pull/109014

>From f4d6006516cd2a7f21af2d384bb894177dca648d Mon Sep 17 00:00:00 2001
From: Ivan Trofimov <i.trofimow at yandex.ru>
Date: Tue, 17 Sep 2024 19:28:41 +0300
Subject: [PATCH 1/4] [IPO] Avoid recalculating FunctionId hashes

---
 .../llvm/Transforms/IPO/ProfiledCallGraph.h   | 36 ++++++++++++++-----
 1 file changed, 28 insertions(+), 8 deletions(-)

diff --git a/llvm/include/llvm/Transforms/IPO/ProfiledCallGraph.h b/llvm/include/llvm/Transforms/IPO/ProfiledCallGraph.h
index 3e7cc74fcf23b6..a09a35f804d78e 100644
--- a/llvm/include/llvm/Transforms/IPO/ProfiledCallGraph.h
+++ b/llvm/include/llvm/Transforms/IPO/ProfiledCallGraph.h
@@ -58,6 +58,20 @@ struct ProfiledCallGraphNode {
   edges Edges;
 };
 
+struct PrehashedFunctionId {
+
+  PrehashedFunctionId() = default;
+
+  /* implicit */ PrehashedFunctionId(FunctionId FId) : Id(FId), Hash(hash_value(Id)) {}
+
+  FunctionId Id;
+  uint64_t Hash;
+};
+
+inline uint64_t hash_value(const PrehashedFunctionId& Obj) {
+  return Obj.Hash;
+}
+
 class ProfiledCallGraph {
 public:
   using iterator = ProfiledCallGraphNode::iterator;
@@ -135,19 +149,23 @@ class ProfiledCallGraph {
   ProfiledCallGraphNode *getEntryNode() { return &Root; }
   
   void addProfiledFunction(FunctionId Name) {
+    addProfiledFunction(PrehashedFunctionId{Name});
+  }
+
+private:
+  void addProfiledFunction(PrehashedFunctionId Name) {
     if (!ProfiledFunctions.count(Name)) {
       // Link to synthetic root to make sure every node is reachable
       // from root. This does not affect SCC order.
       // Store the pointer of the node because the map can be rehashed.
       auto &Node =
-          ProfiledCallGraphNodeList.emplace_back(ProfiledCallGraphNode(Name));
+          ProfiledCallGraphNodeList.emplace_back(ProfiledCallGraphNode(Name.Id));
       ProfiledFunctions[Name] = &Node;
       Root.Edges.emplace(&Root, ProfiledFunctions[Name], 0);
     }
   }
 
-private:
-  void addProfiledCall(FunctionId CallerName, FunctionId CalleeName,
+  void addProfiledCall(PrehashedFunctionId CallerName, PrehashedFunctionId CalleeName,
                        uint64_t Weight = 0) {
     assert(ProfiledFunctions.count(CallerName));
     auto CalleeIt = ProfiledFunctions.find(CalleeName);
@@ -155,7 +173,7 @@ class ProfiledCallGraph {
       return;
     ProfiledCallGraphEdge Edge(ProfiledFunctions[CallerName],
                                CalleeIt->second, Weight);
-    auto &Edges = ProfiledFunctions[CallerName]->Edges;
+    auto &Edges = Edge.Source->Edges;
     auto [EdgeIt, Inserted] = Edges.insert(Edge);
     if (!Inserted) {
       // Accumulate weight to the existing edge.
@@ -166,19 +184,21 @@ class ProfiledCallGraph {
   }
 
   void addProfiledCalls(const FunctionSamples &Samples) {
-    addProfiledFunction(Samples.getFunction());
+    const PrehashedFunctionId SamplesFunction{Samples.getFunction()};
+
+    addProfiledFunction(SamplesFunction);
 
     for (const auto &Sample : Samples.getBodySamples()) {
       for (const auto &[Target, Frequency] : Sample.second.getCallTargets()) {
         addProfiledFunction(Target);
-        addProfiledCall(Samples.getFunction(), Target, Frequency);
+        addProfiledCall(SamplesFunction, Target, Frequency);
       }
     }
 
     for (const auto &CallsiteSamples : Samples.getCallsiteSamples()) {
       for (const auto &InlinedSamples : CallsiteSamples.second) {
         addProfiledFunction(InlinedSamples.first);
-        addProfiledCall(Samples.getFunction(), InlinedSamples.first,
+        addProfiledCall(SamplesFunction, InlinedSamples.first,
                         InlinedSamples.second.getHeadSamplesEstimate());
         addProfiledCalls(InlinedSamples.second);
       }
@@ -206,7 +226,7 @@ class ProfiledCallGraph {
   ProfiledCallGraphNode Root;
   // backing buffer for ProfiledCallGraphNodes.
   std::list<ProfiledCallGraphNode> ProfiledCallGraphNodeList;
-  HashKeyMap<llvm::DenseMap, FunctionId, ProfiledCallGraphNode*>
+  HashKeyMap<llvm::DenseMap, PrehashedFunctionId, ProfiledCallGraphNode*>
       ProfiledFunctions;
 };
 

>From 624902df9c2eb2c2fbfb82513dbb90f8c919fe3d Mon Sep 17 00:00:00 2001
From: Ivan Trofimov <i.trofimow at yandex.ru>
Date: Tue, 17 Sep 2024 20:13:16 +0300
Subject: [PATCH 2/4] clang-format

---
 .../llvm/Transforms/IPO/ProfiledCallGraph.h     | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/llvm/include/llvm/Transforms/IPO/ProfiledCallGraph.h b/llvm/include/llvm/Transforms/IPO/ProfiledCallGraph.h
index a09a35f804d78e..4d6223a2a0b6b7 100644
--- a/llvm/include/llvm/Transforms/IPO/ProfiledCallGraph.h
+++ b/llvm/include/llvm/Transforms/IPO/ProfiledCallGraph.h
@@ -62,15 +62,14 @@ struct PrehashedFunctionId {
 
   PrehashedFunctionId() = default;
 
-  /* implicit */ PrehashedFunctionId(FunctionId FId) : Id(FId), Hash(hash_value(Id)) {}
+  /* implicit */ PrehashedFunctionId(FunctionId FId)
+      : Id(FId), Hash(hash_value(Id)) {}
 
   FunctionId Id;
   uint64_t Hash;
 };
 
-inline uint64_t hash_value(const PrehashedFunctionId& Obj) {
-  return Obj.Hash;
-}
+inline uint64_t hash_value(const PrehashedFunctionId &Obj) { return Obj.Hash; }
 
 class ProfiledCallGraph {
 public:
@@ -158,15 +157,15 @@ class ProfiledCallGraph {
       // Link to synthetic root to make sure every node is reachable
       // from root. This does not affect SCC order.
       // Store the pointer of the node because the map can be rehashed.
-      auto &Node =
-          ProfiledCallGraphNodeList.emplace_back(ProfiledCallGraphNode(Name.Id));
+      auto &Node = ProfiledCallGraphNodeList.emplace_back(
+          ProfiledCallGraphNode(Name.Id));
       ProfiledFunctions[Name] = &Node;
       Root.Edges.emplace(&Root, ProfiledFunctions[Name], 0);
     }
   }
 
-  void addProfiledCall(PrehashedFunctionId CallerName, PrehashedFunctionId CalleeName,
-                       uint64_t Weight = 0) {
+  void addProfiledCall(PrehashedFunctionId CallerName,
+                       PrehashedFunctionId CalleeName, uint64_t Weight = 0) {
     assert(ProfiledFunctions.count(CallerName));
     auto CalleeIt = ProfiledFunctions.find(CalleeName);
     if (CalleeIt == ProfiledFunctions.end())
@@ -226,7 +225,7 @@ class ProfiledCallGraph {
   ProfiledCallGraphNode Root;
   // backing buffer for ProfiledCallGraphNodes.
   std::list<ProfiledCallGraphNode> ProfiledCallGraphNodeList;
-  HashKeyMap<llvm::DenseMap, PrehashedFunctionId, ProfiledCallGraphNode*>
+  HashKeyMap<llvm::DenseMap, PrehashedFunctionId, ProfiledCallGraphNode *>
       ProfiledFunctions;
 };
 

>From 61b255be847369e04c08c2cb3de9417c68f6ff34 Mon Sep 17 00:00:00 2001
From: Ivan Trofimov <i.trofimow at yandex.ru>
Date: Thu, 26 Sep 2024 21:44:32 +0300
Subject: [PATCH 3/4] make PrehashedFunctionId immutable, pass by const&

---
 .../llvm/Transforms/IPO/ProfiledCallGraph.h   | 25 +++++++++++++------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/llvm/include/llvm/Transforms/IPO/ProfiledCallGraph.h b/llvm/include/llvm/Transforms/IPO/ProfiledCallGraph.h
index 4d6223a2a0b6b7..91953cd7a9d81e 100644
--- a/llvm/include/llvm/Transforms/IPO/ProfiledCallGraph.h
+++ b/llvm/include/llvm/Transforms/IPO/ProfiledCallGraph.h
@@ -58,18 +58,27 @@ struct ProfiledCallGraphNode {
   edges Edges;
 };
 
-struct PrehashedFunctionId {
-
+class PrehashedFunctionId {
+public:
   PrehashedFunctionId() = default;
 
-  /* implicit */ PrehashedFunctionId(FunctionId FId)
+  PrehashedFunctionId(FunctionId FId)
       : Id(FId), Hash(hash_value(Id)) {}
 
+  uint64_t GetHash() const {
+    return Hash;
+  }
+
+  const FunctionId& GetId() const {
+    return Id;
+  }
+
+private:
   FunctionId Id;
   uint64_t Hash;
 };
 
-inline uint64_t hash_value(const PrehashedFunctionId &Obj) { return Obj.Hash; }
+inline uint64_t hash_value(const PrehashedFunctionId &Obj) { return Obj.GetHash(); }
 
 class ProfiledCallGraph {
 public:
@@ -152,20 +161,20 @@ class ProfiledCallGraph {
   }
 
 private:
-  void addProfiledFunction(PrehashedFunctionId Name) {
+  void addProfiledFunction(const PrehashedFunctionId& Name) {
     if (!ProfiledFunctions.count(Name)) {
       // Link to synthetic root to make sure every node is reachable
       // from root. This does not affect SCC order.
       // Store the pointer of the node because the map can be rehashed.
       auto &Node = ProfiledCallGraphNodeList.emplace_back(
-          ProfiledCallGraphNode(Name.Id));
+          ProfiledCallGraphNode(Name.GetId()));
       ProfiledFunctions[Name] = &Node;
       Root.Edges.emplace(&Root, ProfiledFunctions[Name], 0);
     }
   }
 
-  void addProfiledCall(PrehashedFunctionId CallerName,
-                       PrehashedFunctionId CalleeName, uint64_t Weight = 0) {
+  void addProfiledCall(const PrehashedFunctionId& CallerName,
+                       const PrehashedFunctionId& CalleeName, uint64_t Weight = 0) {
     assert(ProfiledFunctions.count(CallerName));
     auto CalleeIt = ProfiledFunctions.find(CalleeName);
     if (CalleeIt == ProfiledFunctions.end())

>From 14e64f463efaf9c9c8dff8e9b69e44e5c9674a11 Mon Sep 17 00:00:00 2001
From: Ivan Trofimov <i.trofimow at yandex.ru>
Date: Thu, 26 Sep 2024 21:45:56 +0300
Subject: [PATCH 4/4] + clang-format

---
 .../llvm/Transforms/IPO/ProfiledCallGraph.h   | 35 +++++++++----------
 1 file changed, 16 insertions(+), 19 deletions(-)

diff --git a/llvm/include/llvm/Transforms/IPO/ProfiledCallGraph.h b/llvm/include/llvm/Transforms/IPO/ProfiledCallGraph.h
index 91953cd7a9d81e..eaef73e9f3258e 100644
--- a/llvm/include/llvm/Transforms/IPO/ProfiledCallGraph.h
+++ b/llvm/include/llvm/Transforms/IPO/ProfiledCallGraph.h
@@ -50,10 +50,9 @@ struct ProfiledCallGraphNode {
   using edges = std::set<edge, ProfiledCallGraphEdgeComparer>;
   using iterator = edges::iterator;
   using const_iterator = edges::const_iterator;
-  
-  ProfiledCallGraphNode(FunctionId FName = FunctionId()) : Name(FName)
-  {}
-  
+
+  ProfiledCallGraphNode(FunctionId FName = FunctionId()) : Name(FName) {}
+
   FunctionId Name;
   edges Edges;
 };
@@ -62,23 +61,20 @@ class PrehashedFunctionId {
 public:
   PrehashedFunctionId() = default;
 
-  PrehashedFunctionId(FunctionId FId)
-      : Id(FId), Hash(hash_value(Id)) {}
+  PrehashedFunctionId(FunctionId FId) : Id(FId), Hash(hash_value(Id)) {}
 
-  uint64_t GetHash() const {
-    return Hash;
-  }
+  uint64_t GetHash() const { return Hash; }
 
-  const FunctionId& GetId() const {
-    return Id;
-  }
+  const FunctionId &GetId() const { return Id; }
 
 private:
   FunctionId Id;
   uint64_t Hash;
 };
 
-inline uint64_t hash_value(const PrehashedFunctionId &Obj) { return Obj.GetHash(); }
+inline uint64_t hash_value(const PrehashedFunctionId &Obj) {
+  return Obj.GetHash();
+}
 
 class ProfiledCallGraph {
 public:
@@ -155,13 +151,13 @@ class ProfiledCallGraph {
   iterator begin() { return Root.Edges.begin(); }
   iterator end() { return Root.Edges.end(); }
   ProfiledCallGraphNode *getEntryNode() { return &Root; }
-  
+
   void addProfiledFunction(FunctionId Name) {
     addProfiledFunction(PrehashedFunctionId{Name});
   }
 
 private:
-  void addProfiledFunction(const PrehashedFunctionId& Name) {
+  void addProfiledFunction(const PrehashedFunctionId &Name) {
     if (!ProfiledFunctions.count(Name)) {
       // Link to synthetic root to make sure every node is reachable
       // from root. This does not affect SCC order.
@@ -173,14 +169,15 @@ class ProfiledCallGraph {
     }
   }
 
-  void addProfiledCall(const PrehashedFunctionId& CallerName,
-                       const PrehashedFunctionId& CalleeName, uint64_t Weight = 0) {
+  void addProfiledCall(const PrehashedFunctionId &CallerName,
+                       const PrehashedFunctionId &CalleeName,
+                       uint64_t Weight = 0) {
     assert(ProfiledFunctions.count(CallerName));
     auto CalleeIt = ProfiledFunctions.find(CalleeName);
     if (CalleeIt == ProfiledFunctions.end())
       return;
-    ProfiledCallGraphEdge Edge(ProfiledFunctions[CallerName],
-                               CalleeIt->second, Weight);
+    ProfiledCallGraphEdge Edge(ProfiledFunctions[CallerName], CalleeIt->second,
+                               Weight);
     auto &Edges = Edge.Source->Edges;
     auto [EdgeIt, Inserted] = Edges.insert(Edge);
     if (!Inserted) {



More information about the llvm-commits mailing list