[PBQP] Use DenseSet rather than std::set for PBQP's PoolCostAllocator
authorLang Hames <lhames@gmail.com>
Mon, 20 Oct 2014 04:26:23 +0000 (04:26 +0000)
committerLang Hames <lhames@gmail.com>
Mon, 20 Oct 2014 04:26:23 +0000 (04:26 +0000)
implementation.

This is good for a ~6% reduction in total compile time on the nightly test suite
when running with -regalloc=pbqp.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220183 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/PBQP/CostAllocator.h
include/llvm/CodeGen/PBQP/Math.h
include/llvm/CodeGen/RegAllocPBQP.h

index 281ddfc..8c86a70 100644 (file)
 #ifndef LLVM_CODEGEN_PBQP_COSTALLOCATOR_H
 #define LLVM_CODEGEN_PBQP_COSTALLOCATOR_H
 
+#include "llvm/ADT/DenseSet.h"
 #include <memory>
-#include <set>
 #include <type_traits>
 
 namespace llvm {
 namespace PBQP {
 
-template <typename CostT,
-          typename CostKeyTComparator>
+template <typename CostT>
 class CostPool {
 public:
+  typedef std::shared_ptr<CostT> PoolRef;
+
+private:
+
   class PoolEntry : public std::enable_shared_from_this<PoolEntry> {
   public:
     template <typename CostKeyT>
@@ -42,27 +45,49 @@ public:
     CostT cost;
   };
 
-  typedef std::shared_ptr<CostT> PoolRef;
-
-private:
-  class EntryComparator {
+  class PoolEntryDSInfo {
   public:
+    static inline PoolEntry* getEmptyKey() { return nullptr; }
+
+    static inline PoolEntry* getTombstoneKey() {
+      return reinterpret_cast<PoolEntry*>(static_cast<uintptr_t>(1));
+    }
+
+    template <typename CostKeyT>
+    static unsigned getHashValue(const CostKeyT &C) {
+      return hash_value(C);
+    }
+
+    static unsigned getHashValue(PoolEntry *P) {
+      return getHashValue(P->getCost());
+    }
+
+    static unsigned getHashValue(const PoolEntry *P) {
+      return getHashValue(P->getCost());
+    }
+
+    template <typename CostKeyT1, typename CostKeyT2>
+    static
+    bool isEqual(const CostKeyT1 &C1, const CostKeyT2 &C2) {
+      return C1 == C2;
+    }
+
     template <typename CostKeyT>
-    typename std::enable_if<
-               !std::is_same<PoolEntry*,
-                             typename std::remove_const<CostKeyT>::type>::value,
-               bool>::type
-    operator()(const PoolEntry* a, const CostKeyT &b) {
-      return compare(a->getCost(), b);
+    static bool isEqual(const CostKeyT &C, PoolEntry *P) {
+      if (P == getEmptyKey() || P == getTombstoneKey())
+        return false;
+      return isEqual(C, P->getCost());
     }
-    bool operator()(const PoolEntry* a, const PoolEntry* b) {
-      return compare(a->getCost(), b->getCost());
+
+    static bool isEqual(PoolEntry *P1, PoolEntry *P2) {
+      if (P1 == getEmptyKey() || P1 == getTombstoneKey())
+        return P1 == P2;
+      return isEqual(P1->getCost(), P2);
     }
-  private:
-    CostKeyTComparator compare;
+
   };
 
-  typedef std::set<PoolEntry*, EntryComparator> EntrySet;
+  typedef DenseSet<PoolEntry*, PoolEntryDSInfo> EntrySet;
 
   EntrySet entrySet;
 
@@ -70,25 +95,22 @@ private:
 
 public:
   template <typename CostKeyT> PoolRef getCost(CostKeyT costKey) {
-    typename EntrySet::iterator itr =
-      std::lower_bound(entrySet.begin(), entrySet.end(), costKey,
-                       EntryComparator());
+    typename EntrySet::iterator itr = entrySet.find_as(costKey);
 
-    if (itr != entrySet.end() && costKey == (*itr)->getCost())
+    if (itr != entrySet.end())
       return PoolRef((*itr)->shared_from_this(), &(*itr)->getCost());
 
     auto p = std::make_shared<PoolEntry>(*this, std::move(costKey));
-    entrySet.insert(itr, p.get());
+    entrySet.insert(p.get());
     return PoolRef(std::move(p), &p->getCost());
   }
 };
 
-template <typename VectorT, typename VectorTComparator,
-          typename MatrixT, typename MatrixTComparator>
+template <typename VectorT, typename MatrixT>
 class PoolCostAllocator {
 private:
-  typedef CostPool<VectorT, VectorTComparator> VectorCostPool;
-  typedef CostPool<MatrixT, MatrixTComparator> MatrixCostPool;
+  typedef CostPool<VectorT> VectorCostPool;
+  typedef CostPool<MatrixT> MatrixCostPool;
 public:
   typedef VectorT Vector;
   typedef MatrixT Matrix;
index 60ad19b..2792608 100644 (file)
@@ -10,6 +10,7 @@
 #ifndef LLVM_CODEGEN_PBQP_MATH_H
 #define LLVM_CODEGEN_PBQP_MATH_H
 
+#include "llvm/ADT/Hashing.h"
 #include <algorithm>
 #include <cassert>
 #include <functional>
@@ -21,7 +22,7 @@ typedef float PBQPNum;
 
 /// \brief PBQP Vector class.
 class Vector {
-  friend class VectorComparator;
+  friend hash_code hash_value(const Vector &);
 public:
 
   /// \brief Construct a PBQP vector of the given size.
@@ -137,21 +138,12 @@ private:
   PBQPNum *Data;
 };
 
-class VectorComparator {
-public:
-  bool operator()(const Vector &A, const Vector &B) {
-    if (A.Length < B.Length)
-      return true;
-    if (B.Length < A.Length)
-      return false;
-    char *AData = reinterpret_cast<char*>(A.Data);
-    char *BData = reinterpret_cast<char*>(B.Data);
-    return std::lexicographical_compare(AData,
-                                        AData + A.Length * sizeof(PBQPNum),
-                                        BData,
-                                        BData + A.Length * sizeof(PBQPNum));
-  }
-};
+/// \brief Return a hash_value for the given vector.
+inline hash_code hash_value(const Vector &V) {
+  unsigned *VBegin = reinterpret_cast<unsigned*>(V.Data);
+  unsigned *VEnd = reinterpret_cast<unsigned*>(V.Data + V.Length);
+  return hash_combine(V.Length, hash_combine_range(VBegin, VEnd));
+}
 
 /// \brief Output a textual representation of the given vector on the given
 ///        output stream.
@@ -167,11 +159,10 @@ OStream& operator<<(OStream &OS, const Vector &V) {
   return OS;
 }
 
-
 /// \brief PBQP Matrix class
 class Matrix {
 private:
-  friend class MatrixComparator;
+  friend hash_code hash_value(const Matrix &);
 public:
 
   /// \brief Construct a PBQP Matrix with the given dimensions.
@@ -385,24 +376,12 @@ private:
   PBQPNum *Data;
 };
 
-class MatrixComparator {
-public:
-  bool operator()(const Matrix &A, const Matrix &B) {
-    if (A.Rows < B.Rows)
-      return true;
-    if (B.Rows < A.Rows)
-      return false;
-    if (A.Cols < B.Cols)
-      return true;
-    if (B.Cols < A.Cols)
-      return false;
-    char *AData = reinterpret_cast<char*>(A.Data);
-    char *BData = reinterpret_cast<char*>(B.Data);
-    return std::lexicographical_compare(
-             AData, AData + (A.Rows * A.Cols * sizeof(PBQPNum)),
-             BData, BData + (A.Rows * A.Cols * sizeof(PBQPNum)));
-  }
-};
+/// \brief Return a hash_code for the given matrix.
+inline hash_code hash_value(const Matrix &M) {
+  unsigned *MBegin = reinterpret_cast<unsigned*>(M.Data);
+  unsigned *MEnd = reinterpret_cast<unsigned*>(M.Data + (M.Rows * M.Cols));
+  return hash_combine(M.Rows, M.Cols, hash_combine_range(MBegin, MEnd));
+}
 
 /// \brief Output a textual representation of the given matrix on the given
 ///        output stream.
@@ -410,7 +389,7 @@ template <typename OStream>
 OStream& operator<<(OStream &OS, const Matrix &M) {
   assert((M.getRows() != 0) && "Zero-row matrix badness.");
   for (unsigned i = 0; i < M.getRows(); ++i)
-    OS << M.getRowAsVector(i);
+    OS << M.getRowAsVector(i) << "\n";
   return OS;
 }
 
@@ -424,6 +403,11 @@ private:
   Metadata md;
 };
 
+template <typename Metadata>
+inline hash_code hash_value(const MDVector<Metadata> &V) {
+  return hash_value(static_cast<const Vector&>(V));
+}
+
 template <typename Metadata>
 class MDMatrix : public Matrix {
 public:
@@ -434,6 +418,11 @@ private:
   Metadata md;
 };
 
+template <typename Metadata>
+inline hash_code hash_value(const MDMatrix<Metadata> &M) {
+  return hash_value(static_cast<const Matrix&>(M));
+}
+
 } // namespace PBQP
 } // namespace llvm
 
index 6ab9bcc..3d242f1 100644 (file)
@@ -145,9 +145,7 @@ public:
   typedef PBQP::Matrix RawMatrix;
   typedef PBQP::Vector Vector;
   typedef RAMatrix     Matrix;
-  typedef PBQP::PoolCostAllocator<
-    Vector, PBQP::VectorComparator,
-    Matrix, PBQP::MatrixComparator> CostAllocator;
+  typedef PBQP::PoolCostAllocator<Vector, Matrix> CostAllocator;
 
   typedef GraphBase::NodeId NodeId;
   typedef GraphBase::EdgeId EdgeId;