[llvm] r265577 - IR: Use DenseSet instead of DenseMap for ConstantUniqueMap; NFC

Duncan P. N. Exon Smith via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 6 10:56:09 PDT 2016


Author: dexonsmith
Date: Wed Apr  6 12:56:08 2016
New Revision: 265577

URL: http://llvm.org/viewvc/llvm-project?rev=265577&view=rev
Log:
IR: Use DenseSet instead of DenseMap for ConstantUniqueMap; NFC

Use a DenseSet instead of a DenseMap for constants in LLVMContextImpl.
Last time I looked at this was some time before r223588, when
DenseSet<V> had no advantage over DenseMap<V,char>.  After r223588,
there's a 50% memory savings.

This is all mechanical.  There were little bits of missing API from
DenseSet so I added the trivial implementations:

  - iterator::operator++(int)
  - template <class LookupKeyT> insert_as(ValueTy, LookupKeyT)

There should be no functionality change, just reduced memory consumption
(this wasn't on a profile or anything; just a cleanup I stumbled on).

Modified:
    llvm/trunk/include/llvm/ADT/DenseSet.h
    llvm/trunk/lib/IR/ConstantsContext.h
    llvm/trunk/lib/IR/LLVMContextImpl.cpp

Modified: llvm/trunk/include/llvm/ADT/DenseSet.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/DenseSet.h?rev=265577&r1=265576&r2=265577&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/DenseSet.h (original)
+++ llvm/trunk/include/llvm/ADT/DenseSet.h Wed Apr  6 12:56:08 2016
@@ -94,6 +94,7 @@ public:
     ValueT *operator->() { return &I->getFirst(); }
 
     Iterator& operator++() { ++I; return *this; }
+    Iterator operator++(int) { auto T = *this; ++I; return T; }
     bool operator==(const Iterator& X) const { return I == X.I; }
     bool operator!=(const Iterator& X) const { return I != X.I; }
   };
@@ -115,6 +116,7 @@ public:
     const ValueT *operator->() { return &I->getFirst(); }
 
     ConstIterator& operator++() { ++I; return *this; }
+    ConstIterator operator++(int) { auto T = *this; ++I; return T; }
     bool operator==(const ConstIterator& X) const { return I == X.I; }
     bool operator!=(const ConstIterator& X) const { return I != X.I; }
   };
@@ -152,6 +154,19 @@ public:
     return TheMap.insert(std::make_pair(V, Empty));
   }
 
+  /// Alternative version of insert that uses a different (and possibly less
+  /// expensive) key type.
+  template <typename LookupKeyT>
+  std::pair<iterator, bool> insert_as(const ValueT &V,
+                                      const LookupKeyT &LookupKey) {
+    return insert_as(ValueT(V), LookupKey);
+  }
+  template <typename LookupKeyT>
+  std::pair<iterator, bool> insert_as(ValueT &&V, const LookupKeyT &LookupKey) {
+    detail::DenseSetEmpty Empty;
+    return TheMap.insert_as(std::make_pair(std::move(V), Empty), LookupKey);
+  }
+
   // Range insertion of values.
   template<typename InputIt>
   void insert(InputIt I, InputIt E) {

Modified: llvm/trunk/lib/IR/ConstantsContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/ConstantsContext.h?rev=265577&r1=265576&r2=265577&view=diff
==============================================================================
--- llvm/trunk/lib/IR/ConstantsContext.h (original)
+++ llvm/trunk/lib/IR/ConstantsContext.h Wed Apr  6 12:56:08 2016
@@ -15,7 +15,7 @@
 #ifndef LLVM_LIB_IR_CONSTANTSCONTEXT_H
 #define LLVM_LIB_IR_CONSTANTSCONTEXT_H
 
-#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/Instructions.h"
@@ -584,26 +584,25 @@ private:
   };
 
 public:
-  typedef DenseMap<ConstantClass *, char, MapInfo> MapTy;
+  typedef DenseSet<ConstantClass *, MapInfo> MapTy;
 
 private:
   MapTy Map;
 
 public:
-  typename MapTy::iterator map_begin() { return Map.begin(); }
-  typename MapTy::iterator map_end() { return Map.end(); }
+  typename MapTy::iterator begin() { return Map.begin(); }
+  typename MapTy::iterator end() { return Map.end(); }
 
   void freeConstants() {
     for (auto &I : Map)
-      // Asserts that use_empty().
-      delete I.first;
+      delete I; // Asserts that use_empty().
   }
 private:
   ConstantClass *create(TypeClass *Ty, ValType V, LookupKeyHashed &HashKey) {
     ConstantClass *Result = V.create(Ty);
 
     assert(Result->getType() == Ty && "Type specified is not correct!");
-    Map.insert_as(std::make_pair(Result, '\0'), HashKey);
+    Map.insert_as(Result, HashKey);
 
     return Result;
   }
@@ -621,7 +620,7 @@ public:
     if (I == Map.end())
       Result = create(Ty, V, Lookup);
     else
-      Result = I->first;
+      Result = *I;
     assert(Result && "Unexpected nullptr");
 
     return Result;
@@ -631,7 +630,7 @@ public:
   void remove(ConstantClass *CP) {
     typename MapTy::iterator I = Map.find(CP);
     assert(I != Map.end() && "Constant not found in constant table!");
-    assert(I->first == CP && "Didn't find correct element?");
+    assert(*I == CP && "Didn't find correct element?");
     Map.erase(I);
   }
 
@@ -645,7 +644,7 @@ public:
 
     auto I = Map.find_as(Lookup);
     if (I != Map.end())
-      return I->first;
+      return *I;
 
     // Update to the new value.  Optimize for the case when we have a single
     // operand that we're changing, but handle bulk updates efficiently.
@@ -659,7 +658,7 @@ public:
         if (CP->getOperand(I) == From)
           CP->setOperand(I, To);
     }
-    Map.insert_as(std::make_pair(CP, '\0'), Lookup);
+    Map.insert_as(CP, Lookup);
     return nullptr;
   }
 

Modified: llvm/trunk/lib/IR/LLVMContextImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.cpp?rev=265577&r1=265576&r2=265577&view=diff
==============================================================================
--- llvm/trunk/lib/IR/LLVMContextImpl.cpp (original)
+++ llvm/trunk/lib/IR/LLVMContextImpl.cpp Wed Apr  6 12:56:08 2016
@@ -48,26 +48,6 @@ LLVMContextImpl::LLVMContextImpl(LLVMCon
   NamedStructTypesUniqueID = 0;
 }
 
-namespace {
-struct DropReferences {
-  // Takes the value_type of a ConstantUniqueMap's internal map, whose 'second'
-  // is a Constant*.
-  template <typename PairT> void operator()(const PairT &P) {
-    P.second->dropAllReferences();
-  }
-};
-
-// Temporary - drops pair.first instead of second.
-struct DropFirst {
-  // Takes the value_type of a ConstantUniqueMap's internal map, whose 'second'
-  // is a Constant*.
-  template<typename PairT>
-  void operator()(const PairT &P) {
-    P.first->dropAllReferences();
-  }
-};
-}
-
 LLVMContextImpl::~LLVMContextImpl() {
   // NOTE: We need to delete the contents of OwnedModules, but Module's dtor
   // will call LLVMContextImpl::removeModule, thus invalidating iterators into
@@ -99,14 +79,14 @@ LLVMContextImpl::~LLVMContextImpl() {
 #include "llvm/IR/Metadata.def"
 
   // Free the constants.
-  std::for_each(ExprConstants.map_begin(), ExprConstants.map_end(),
-                DropFirst());
-  std::for_each(ArrayConstants.map_begin(), ArrayConstants.map_end(),
-                DropFirst());
-  std::for_each(StructConstants.map_begin(), StructConstants.map_end(),
-                DropFirst());
-  std::for_each(VectorConstants.map_begin(), VectorConstants.map_end(),
-                DropFirst());
+  for (auto *I : ExprConstants)
+    I->dropAllReferences();
+  for (auto *I : ArrayConstants)
+    I->dropAllReferences();
+  for (auto *I : StructConstants)
+    I->dropAllReferences();
+  for (auto *I : VectorConstants)
+    I->dropAllReferences();
   ExprConstants.freeConstants();
   ArrayConstants.freeConstants();
   StructConstants.freeConstants();
@@ -165,10 +145,8 @@ void LLVMContextImpl::dropTriviallyDeadC
   do {
     Changed = false;
 
-    for (auto I = ArrayConstants.map_begin(), E = ArrayConstants.map_end();
-         I != E; ) {
-      auto *C = I->first;
-      I++;
+    for (auto I = ArrayConstants.begin(), E = ArrayConstants.end(); I != E;) {
+      auto *C = *I++;
       if (C->use_empty()) {
         Changed = true;
         C->destroyConstant();




More information about the llvm-commits mailing list