Implement offline variable substitution in order to reduce memory

and time usage.
Fixup operator == to make this work, and add a resize method to DenseMap
so we can resize our hashtable once we know how big it should be.

llvm-svn: 42269
This commit is contained in:
Daniel Berlin 2007-09-24 19:45:49 +00:00
parent 071efe28bb
commit 5d7136a1df
3 changed files with 960 additions and 104 deletions

View File

@ -100,6 +100,9 @@ public:
bool empty() const { return NumEntries == 0; } bool empty() const { return NumEntries == 0; }
unsigned size() const { return NumEntries; } unsigned size() const { return NumEntries; }
/// Grow the densemap so that it has at least Size buckets. Does not shrink
void resize(size_t Size) { grow(Size); }
void clear() { void clear() {
// If the capacity of the array is huge, and the # elements used is small, // If the capacity of the array is huge, and the # elements used is small,
// shrink the array. // shrink the array.
@ -228,7 +231,7 @@ private:
// causing infinite loops in lookup. // causing infinite loops in lookup.
if (NumEntries*4 >= NumBuckets*3 || if (NumEntries*4 >= NumBuckets*3 ||
NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) { NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) {
this->grow(); this->grow(NumBuckets * 2);
LookupBucketFor(Key, TheBucket); LookupBucketFor(Key, TheBucket);
} }
++NumEntries; ++NumEntries;
@ -310,11 +313,12 @@ private:
new (&Buckets[i].first) KeyT(EmptyKey); new (&Buckets[i].first) KeyT(EmptyKey);
} }
void grow() { void grow(unsigned AtLeast) {
unsigned OldNumBuckets = NumBuckets; unsigned OldNumBuckets = NumBuckets;
BucketT *OldBuckets = Buckets; BucketT *OldBuckets = Buckets;
// Double the number of buckets. // Double the number of buckets.
while (NumBuckets <= AtLeast)
NumBuckets <<= 1; NumBuckets <<= 1;
NumTombstones = 0; NumTombstones = 0;
Buckets = reinterpret_cast<BucketT*>(new char[sizeof(BucketT)*NumBuckets]); Buckets = reinterpret_cast<BucketT*>(new char[sizeof(BucketT)*NumBuckets]);

View File

@ -75,7 +75,6 @@ private:
} }
friend struct ilist_traits<SparseBitVectorElement<ElementSize> >; friend struct ilist_traits<SparseBitVectorElement<ElementSize> >;
public: public:
explicit SparseBitVectorElement(unsigned Idx) { explicit SparseBitVectorElement(unsigned Idx) {
ElementIndex = Idx; ElementIndex = Idx;
@ -287,6 +286,14 @@ public:
} }
BecameZero = allzero; BecameZero = allzero;
} }
// Get a hash value for this element;
uint64_t getHashValue() const {
uint64_t HashVal = 0;
for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
HashVal ^= Bits[i];
}
return HashVal;
}
}; };
template <unsigned ElementSize = 128> template <unsigned ElementSize = 128>
@ -544,22 +551,20 @@ public:
return false; return false;
} }
bool operator!=(const SparseBitVector &RHS) { bool operator!=(const SparseBitVector &RHS) const {
return !(*this == RHS); return !(*this == RHS);
} }
bool operator==(const SparseBitVector &RHS) { bool operator==(const SparseBitVector &RHS) const {
ElementListConstIter Iter1 = Elements.begin(); ElementListConstIter Iter1 = Elements.begin();
ElementListConstIter Iter2 = RHS.Elements.begin(); ElementListConstIter Iter2 = RHS.Elements.begin();
while (Iter2 != RHS.Elements.end()) { for (; Iter1 != Elements.end() && Iter2 != RHS.Elements.end();
if (Iter1->index() != Iter2->index() ++Iter1, ++Iter2) {
|| *Iter1 != *Iter2) if (*Iter1 != *Iter2)
return false; return false;
++Iter1;
++Iter2;
} }
return Iter1 == Elements.end(); return Iter1 == Elements.end() && Iter2 == RHS.Elements.end();
} }
// Union our bitmap with the RHS and return true if we changed. // Union our bitmap with the RHS and return true if we changed.
@ -789,6 +794,17 @@ public:
return iterator(this, ~0); return iterator(this, ~0);
} }
// Get a hash value for this bitmap.
uint64_t getHashValue() const {
uint64_t HashVal = 0;
for (ElementListConstIter Iter = Elements.begin();
Iter != Elements.end();
++Iter) {
HashVal ^= Iter->index();
HashVal ^= Iter->getHashValue();
}
return HashVal;
}
}; };
// Convenience functions to allow Or and And without dereferencing in the user // Convenience functions to allow Or and And without dereferencing in the user
@ -828,9 +844,10 @@ void dump(const SparseBitVector<ElementSize> &LHS, llvm::OStream &out) {
for (bi = LHS.begin(); bi != LHS.end(); ++bi) { for (bi = LHS.begin(); bi != LHS.end(); ++bi) {
out << *bi << " "; out << *bi << " ";
} }
out << "\n"; out << " ]\n";
}
} }
}
#endif #endif

File diff suppressed because it is too large Load Diff