[llvm] r218892 - InstrProf: Avoid linear search in a hot loop

Justin Bogner mail at justinbogner.com
Thu Oct 2 10:14:18 PDT 2014


Author: bogner
Date: Thu Oct  2 12:14:18 2014
New Revision: 218892

URL: http://llvm.org/viewvc/llvm-project?rev=218892&view=rev
Log:
InstrProf: Avoid linear search in a hot loop

Every time we were adding or removing an expression when generating a
coverage mapping we were doing a linear search to try and deduplicate
the list. The indices in the list are important, so we can't just
replace it by a DenseMap entirely, but an auxilliary DenseMap for fast
lookup massively improves the performance issues I was seeing here.

Modified:
    llvm/trunk/include/llvm/ProfileData/CoverageMapping.h
    llvm/trunk/lib/ProfileData/CoverageMapping.cpp

Modified: llvm/trunk/include/llvm/ProfileData/CoverageMapping.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/CoverageMapping.h?rev=218892&r1=218891&r2=218892&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ProfileData/CoverageMapping.h (original)
+++ llvm/trunk/include/llvm/ProfileData/CoverageMapping.h Thu Oct  2 12:14:18 2014
@@ -16,6 +16,8 @@
 #define LLVM_PROFILEDATA_COVERAGEMAPPING_H_
 
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Hashing.h"
 #include "llvm/Support/ErrorOr.h"
 #include "llvm/Support/raw_ostream.h"
 #include <system_error>
@@ -91,10 +93,6 @@ struct CounterExpression {
 
   CounterExpression(ExprKind Kind, Counter LHS, Counter RHS)
       : Kind(Kind), LHS(LHS), RHS(RHS) {}
-
-  bool operator==(const CounterExpression &Other) const {
-    return Kind == Other.Kind && LHS == Other.LHS && RHS == Other.RHS;
-  }
 };
 
 /// \brief A Counter expression builder is used to construct the
@@ -102,7 +100,9 @@ struct CounterExpression {
 /// and simplifies algebraic expressions.
 class CounterExpressionBuilder {
   /// \brief A list of all the counter expressions
-  llvm::SmallVector<CounterExpression, 16> Expressions;
+  std::vector<CounterExpression> Expressions;
+  /// \brief A lookup table for the index of a given expression.
+  llvm::DenseMap<CounterExpression, unsigned> ExpressionIndices;
 
   /// \brief Return the counter which corresponds to the given expression.
   ///
@@ -370,6 +370,36 @@ public:
 };
 
 } // end namespace coverage
+
+/// \brief Provide DenseMapInfo for CounterExpression
+template<> struct DenseMapInfo<coverage::CounterExpression> {
+  static inline coverage::CounterExpression getEmptyKey() {
+    using namespace coverage;
+    return CounterExpression(CounterExpression::ExprKind::Subtract,
+                             Counter::getCounter(~0U),
+                             Counter::getCounter(~0U));
+  }
+
+  static inline coverage::CounterExpression getTombstoneKey() {
+    using namespace coverage;
+    return CounterExpression(CounterExpression::ExprKind::Add,
+                             Counter::getCounter(~0U),
+                             Counter::getCounter(~0U));
+  }
+
+  static unsigned getHashValue(const coverage::CounterExpression &V) {
+    return static_cast<unsigned>(
+        hash_combine(V.Kind, V.LHS.getKind(), V.LHS.getCounterID(),
+                     V.RHS.getKind(), V.RHS.getCounterID()));
+  }
+
+  static bool isEqual(const coverage::CounterExpression &LHS,
+                      const coverage::CounterExpression &RHS) {
+    return LHS.Kind == RHS.Kind && LHS.LHS == RHS.LHS && LHS.RHS == RHS.RHS;
+  }
+};
+
+
 } // end namespace llvm
 
 #endif // LLVM_PROFILEDATA_COVERAGEMAPPING_H_

Modified: llvm/trunk/lib/ProfileData/CoverageMapping.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/CoverageMapping.cpp?rev=218892&r1=218891&r2=218892&view=diff
==============================================================================
--- llvm/trunk/lib/ProfileData/CoverageMapping.cpp (original)
+++ llvm/trunk/lib/ProfileData/CoverageMapping.cpp Thu Oct  2 12:14:18 2014
@@ -28,12 +28,13 @@ using namespace coverage;
 #define DEBUG_TYPE "coverage-mapping"
 
 Counter CounterExpressionBuilder::get(const CounterExpression &E) {
-  for (unsigned I = 0, S = Expressions.size(); I < S; ++I) {
-    if (Expressions[I] == E)
-      return Counter::getExpression(I);
-  }
+  auto It = ExpressionIndices.find(E);
+  if (It != ExpressionIndices.end())
+    return Counter::getExpression(It->second);
+  unsigned I = Expressions.size();
   Expressions.push_back(E);
-  return Counter::getExpression(Expressions.size() - 1);
+  ExpressionIndices[E] = I;
+  return Counter::getExpression(I);
 }
 
 void CounterExpressionBuilder::extractTerms(





More information about the llvm-commits mailing list