aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2011-01-03 01:29:37 +0000
committerChris Lattner <sabre@nondot.org>2011-01-03 01:29:37 +0000
commit61a10a0dc91863b70002cc412a1277357d6a4b45 (patch)
tree5815722dc1c694d1665b9943afefa5c5c5766161
parentd957c717918c412402157b85fc51b4c6d2631381 (diff)
Enhance ScopedHashTable to allow it to take an allocator argument.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122721 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/ADT/ScopedHashTable.h56
-rw-r--r--include/llvm/ADT/StringMap.h3
-rw-r--r--include/llvm/Support/Allocator.h2
3 files changed, 43 insertions, 18 deletions
diff --git a/include/llvm/ADT/ScopedHashTable.h b/include/llvm/ADT/ScopedHashTable.h
index c96ad19707..0df2484ccc 100644
--- a/include/llvm/ADT/ScopedHashTable.h
+++ b/include/llvm/ADT/ScopedHashTable.h
@@ -31,12 +31,13 @@
#ifndef LLVM_ADT_SCOPEDHASHTABLE_H
#define LLVM_ADT_SCOPEDHASHTABLE_H
-#include <cassert>
#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Allocator.h"
namespace llvm {
-template <typename K, typename V, typename KInfo = DenseMapInfo<K> >
+template <typename K, typename V, typename KInfo = DenseMapInfo<K>,
+ typename AllocatorTy = MallocAllocator>
class ScopedHashTable;
template <typename K, typename V, typename KInfo = DenseMapInfo<K> >
@@ -45,11 +46,8 @@ class ScopedHashTableVal {
ScopedHashTableVal *NextForKey;
K Key;
V Val;
+ ScopedHashTableVal(const K &key, const V &val) : Key(key), Val(val) {}
public:
- ScopedHashTableVal(ScopedHashTableVal *nextInScope,
- ScopedHashTableVal *nextForKey, const K &key, const V &val)
- : NextInScope(nextInScope), NextForKey(nextForKey), Key(key), Val(val) {
- }
const K &getKey() const { return Key; }
const V &getValue() const { return Val; }
@@ -57,8 +55,27 @@ public:
ScopedHashTableVal *getNextForKey() { return NextForKey; }
const ScopedHashTableVal *getNextForKey() const { return NextForKey; }
-public:
ScopedHashTableVal *getNextInScope() { return NextInScope; }
+
+ template <typename AllocatorTy>
+ static ScopedHashTableVal *Create(ScopedHashTableVal *nextInScope,
+ ScopedHashTableVal *nextForKey,
+ const K &key, const V &val,
+ AllocatorTy &Allocator) {
+ ScopedHashTableVal *New = Allocator.template Allocate<ScopedHashTableVal>();
+ // Set up the value.
+ new (New) ScopedHashTableVal(key, val);
+ New->NextInScope = nextInScope;
+ New->NextForKey = nextForKey;
+ return New;
+ }
+
+ template <typename AllocatorTy>
+ void Destroy(AllocatorTy &Allocator) {
+ // Free memory referenced by the item.
+ this->~ScopedHashTableVal();
+ Allocator.Deallocate(this);
+ }
};
template <typename K, typename V, typename KInfo = DenseMapInfo<K> >
@@ -121,26 +138,35 @@ public:
};
-template <typename K, typename V, typename KInfo>
+template <typename K, typename V, typename KInfo, typename AllocatorTy>
class ScopedHashTable {
- DenseMap<K, ScopedHashTableVal<K, V, KInfo>*, KInfo> TopLevelMap;
+ typedef ScopedHashTableVal<K, V, KInfo> ValTy;
+ DenseMap<K, ValTy*, KInfo> TopLevelMap;
ScopedHashTableScope<K, V, KInfo> *CurScope;
+
+ AllocatorTy Allocator;
+
ScopedHashTable(const ScopedHashTable&); // NOT YET IMPLEMENTED
void operator=(const ScopedHashTable&); // NOT YET IMPLEMENTED
friend class ScopedHashTableScope<K, V, KInfo>;
public:
ScopedHashTable() : CurScope(0) {}
+ ScopedHashTable(AllocatorTy A) : CurScope(0), Allocator(A) {}
~ScopedHashTable() {
assert(CurScope == 0 && TopLevelMap.empty() && "Scope imbalance!");
}
+
+ typedef typename ReferenceAdder<AllocatorTy>::result AllocatorRefTy;
+ typedef typename ReferenceAdder<const AllocatorTy>::result AllocatorCRefTy;
+ AllocatorRefTy getAllocator() { return Allocator; }
+ AllocatorCRefTy getAllocator() const { return Allocator; }
bool count(const K &Key) const {
return TopLevelMap.count(Key);
}
V lookup(const K &Key) {
- typename DenseMap<K, ScopedHashTableVal<K, V, KInfo>*, KInfo>::iterator
- I = TopLevelMap.find(Key);
+ typename DenseMap<K, ValTy*, KInfo>::iterator I = TopLevelMap.find(Key);
if (I != TopLevelMap.end())
return I->second->getValue();
@@ -152,8 +178,8 @@ public:
ScopedHashTableVal<K, V, KInfo> *&KeyEntry = TopLevelMap[Key];
- KeyEntry= new ScopedHashTableVal<K, V, KInfo>(CurScope->getLastValInScope(),
- KeyEntry, Key, Val);
+ KeyEntry = ValTy::Create(CurScope->getLastValInScope(), KeyEntry, Key, Val,
+ Allocator);
CurScope->setLastValInScope(KeyEntry);
}
@@ -162,7 +188,7 @@ public:
iterator end() { return iterator(0); }
iterator begin(const K &Key) {
- typename DenseMap<K, ScopedHashTableVal<K, V, KInfo>*, KInfo>::iterator I =
+ typename DenseMap<K, ValTy*, KInfo>::iterator I =
TopLevelMap.find(Key);
if (I == TopLevelMap.end()) return end();
return iterator(I->second);
@@ -202,7 +228,7 @@ ScopedHashTableScope<K, V, KInfo>::~ScopedHashTableScope() {
LastValInScope = ThisEntry->getNextInScope();
// Delete this entry.
- delete ThisEntry;
+ ThisEntry->Destroy(HT.getAllocator());
}
}
diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h
index 752f55c226..bad0e6f513 100644
--- a/include/llvm/ADT/StringMap.h
+++ b/include/llvm/ADT/StringMap.h
@@ -242,9 +242,6 @@ public:
};
-template <typename T> struct ReferenceAdder { typedef T& result; };
-template <typename T> struct ReferenceAdder<T&> { typedef T result; };
-
/// StringMap - This is an unconventional map that is specialized for handling
/// keys that are "strings", which are basically ranges of bytes. This does some
/// funky memory allocation and hashing things to make it extremely efficient,
diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h
index b080e222a1..c6807099f8 100644
--- a/include/llvm/Support/Allocator.h
+++ b/include/llvm/Support/Allocator.h
@@ -23,6 +23,8 @@
#include <cstddef>
namespace llvm {
+template <typename T> struct ReferenceAdder { typedef T& result; };
+template <typename T> struct ReferenceAdder<T&> { typedef T result; };
class MallocAllocator {
public: