From 61a10a0dc91863b70002cc412a1277357d6a4b45 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 3 Jan 2011 01:29:37 +0000 Subject: [PATCH] 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 --- include/llvm/ADT/ScopedHashTable.h | 56 ++++++++++++++++++++++-------- include/llvm/ADT/StringMap.h | 3 -- include/llvm/Support/Allocator.h | 2 ++ 3 files changed, 43 insertions(+), 18 deletions(-) diff --git a/include/llvm/ADT/ScopedHashTable.h b/include/llvm/ADT/ScopedHashTable.h index c96ad19707f..0df2484ccc1 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 #include "llvm/ADT/DenseMap.h" +#include "llvm/Support/Allocator.h" namespace llvm { -template > +template , + typename AllocatorTy = MallocAllocator> class ScopedHashTable; template > @@ -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 + static ScopedHashTableVal *Create(ScopedHashTableVal *nextInScope, + ScopedHashTableVal *nextForKey, + const K &key, const V &val, + AllocatorTy &Allocator) { + ScopedHashTableVal *New = Allocator.template Allocate(); + // Set up the value. + new (New) ScopedHashTableVal(key, val); + New->NextInScope = nextInScope; + New->NextForKey = nextForKey; + return New; + } + + template + void Destroy(AllocatorTy &Allocator) { + // Free memory referenced by the item. + this->~ScopedHashTableVal(); + Allocator.Deallocate(this); + } }; template > @@ -121,26 +138,35 @@ public: }; -template +template class ScopedHashTable { - DenseMap*, KInfo> TopLevelMap; + typedef ScopedHashTableVal ValTy; + DenseMap TopLevelMap; ScopedHashTableScope *CurScope; + + AllocatorTy Allocator; + ScopedHashTable(const ScopedHashTable&); // NOT YET IMPLEMENTED void operator=(const ScopedHashTable&); // NOT YET IMPLEMENTED friend class ScopedHashTableScope; public: ScopedHashTable() : CurScope(0) {} + ScopedHashTable(AllocatorTy A) : CurScope(0), Allocator(A) {} ~ScopedHashTable() { assert(CurScope == 0 && TopLevelMap.empty() && "Scope imbalance!"); } + + typedef typename ReferenceAdder::result AllocatorRefTy; + typedef typename ReferenceAdder::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*, KInfo>::iterator - I = TopLevelMap.find(Key); + typename DenseMap::iterator I = TopLevelMap.find(Key); if (I != TopLevelMap.end()) return I->second->getValue(); @@ -152,8 +178,8 @@ public: ScopedHashTableVal *&KeyEntry = TopLevelMap[Key]; - KeyEntry= new ScopedHashTableVal(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*, KInfo>::iterator I = + typename DenseMap::iterator I = TopLevelMap.find(Key); if (I == TopLevelMap.end()) return end(); return iterator(I->second); @@ -202,7 +228,7 @@ ScopedHashTableScope::~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 752f55c2264..bad0e6f5136 100644 --- a/include/llvm/ADT/StringMap.h +++ b/include/llvm/ADT/StringMap.h @@ -242,9 +242,6 @@ public: }; -template struct ReferenceAdder { typedef T& result; }; -template struct ReferenceAdder { 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 b080e222a10..c6807099f85 100644 --- a/include/llvm/Support/Allocator.h +++ b/include/llvm/Support/Allocator.h @@ -23,6 +23,8 @@ #include namespace llvm { +template struct ReferenceAdder { typedef T& result; }; +template struct ReferenceAdder { typedef T result; }; class MallocAllocator { public: