X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FFoldingSet.cpp;h=6f7f5ea4cbf3cc09d910579ba03b1191f8d2e445;hb=ada530b4f552da1d122be0c6dbc936e689fc16fd;hp=7d0dca2cb13aa1dd2f3c024174808b9aeb557ef7;hpb=788a0c6a181ddb8f10b0f4b83af43b4469e9c73b;p=oota-llvm.git diff --git a/lib/Support/FoldingSet.cpp b/lib/Support/FoldingSet.cpp index 7d0dca2cb13..6f7f5ea4cbf 100644 --- a/lib/Support/FoldingSet.cpp +++ b/lib/Support/FoldingSet.cpp @@ -16,6 +16,7 @@ #include "llvm/ADT/FoldingSet.h" #include "llvm/Support/MathExtras.h" +#include using namespace llvm; //===----------------------------------------------------------------------===// @@ -41,7 +42,10 @@ void FoldingSetImpl::NodeID::AddInteger(unsigned I) { } void FoldingSetImpl::NodeID::AddInteger(uint64_t I) { Bits.push_back(unsigned(I)); - Bits.push_back(unsigned(I >> 32)); + + // If the integer is small, encode it just as 32-bits. + if ((uint64_t)(int)I != I) + Bits.push_back(unsigned(I >> 32)); } void FoldingSetImpl::NodeID::AddFloat(float F) { Bits.push_back(FloatToBits(F)); @@ -51,21 +55,20 @@ void FoldingSetImpl::NodeID::AddDouble(double D) { } void FoldingSetImpl::NodeID::AddString(const std::string &String) { unsigned Size = String.size(); + Bits.push_back(Size); + if (!Size) return; + unsigned Units = Size / 4; unsigned Pos = 0; const unsigned *Base = (const unsigned *)String.data(); // If the string is aligned do a bulk transfer. -#if 0 // FIXME - Add insert to SmallVector (tested with vector) if (!((intptr_t)Base & 3)) { - Bits.insert(Bits.end(), Base, Base + Units); - Pos = Units * sizeof(unsigned); + Bits.append(Base, Base + Units); + Pos = (Units + 1) * 4; } else { -#else - } -#endif // Otherwise do it the hard way. - for ( Pos += 4; Pos < Size; Pos += 4) { + for ( Pos += 4; Pos <= Size; Pos += 4) { unsigned V = ((unsigned char)String[Pos - 4] << 24) | ((unsigned char)String[Pos - 3] << 16) | ((unsigned char)String[Pos - 2] << 8) | @@ -81,7 +84,7 @@ void FoldingSetImpl::NodeID::AddString(const std::string &String) { case 1: V = (V << 8) | (unsigned char)String[Size - 3]; // Fall thru. case 2: V = (V << 8) | (unsigned char)String[Size - 2]; // Fall thru. case 3: V = (V << 8) | (unsigned char)String[Size - 1]; break; - case 0: return; // Nothing left. + default: return; // Nothing left. } Bits.push_back(V); @@ -125,8 +128,8 @@ bool FoldingSetImpl::NodeID::operator==(const FoldingSetImpl::NodeID &RHS)const{ /// singly-linked-list. In order to make deletion more efficient, we make /// the list circular, so we can delete a node without computing its hash. /// The problem with this is that the start of the hash buckets are not -/// Nodes. If NextInBucketPtr is a bucket pointer, this method returns null -/// : use GetBucketPtr when this happens. +/// Nodes. If NextInBucketPtr is a bucket pointer, this method returns null: +/// use GetBucketPtr when this happens. static FoldingSetImpl::Node *GetNextPtr(void *NextInBucketPtr, void **Buckets, unsigned NumBuckets) { if (NextInBucketPtr >= Buckets && NextInBucketPtr < Buckets + NumBuckets) @@ -152,8 +155,10 @@ static void **GetBucketFor(const FoldingSetImpl::NodeID &ID, //===----------------------------------------------------------------------===// // FoldingSetImpl Implementation -FoldingSetImpl::FoldingSetImpl() : NumNodes(0) { - NumBuckets = 64; +FoldingSetImpl::FoldingSetImpl(unsigned Log2InitSize) : NumNodes(0) { + assert(5 < Log2InitSize && Log2InitSize < 32 && + "Initial hash table size out of range"); + NumBuckets = 1 << Log2InitSize; Buckets = new void*[NumBuckets]; memset(Buckets, 0, NumBuckets*sizeof(void*)); } @@ -179,7 +184,7 @@ void FoldingSetImpl::GrowHashTable() { for (unsigned i = 0; i != OldNumBuckets; ++i) { void *Probe = OldBuckets[i]; if (!Probe) continue; - while (Node *NodeInBucket = GetNextPtr(Probe, OldBuckets, OldNumBuckets)){ + while (Node *NodeInBucket = GetNextPtr(Probe, OldBuckets, OldNumBuckets)) { // Figure out the next link, remove NodeInBucket from the old link. Probe = NodeInBucket->getNextInBucket(); NodeInBucket->SetNextInBucket(0); @@ -222,14 +227,16 @@ FoldingSetImpl::Node *FoldingSetImpl::FindNodeOrInsertPos(const NodeID &ID, /// is not already in the map. InsertPos must be obtained from /// FindNodeOrInsertPos. void FoldingSetImpl::InsertNode(Node *N, void *InsertPos) { - ++NumNodes; + assert(N->getNextInBucket() == 0); // Do we need to grow the hashtable? - if (NumNodes > NumBuckets*2) { + if (NumNodes+1 > NumBuckets*2) { GrowHashTable(); NodeID ID; GetNodeProfile(ID, N); InsertPos = GetBucketFor(ID, Buckets, NumBuckets); } + + ++NumNodes; /// The insert position is actually a bucket pointer. void **Bucket = static_cast(InsertPos); @@ -241,7 +248,7 @@ void FoldingSetImpl::InsertNode(Node *N, void *InsertPos) { if (Next == 0) Next = Bucket; - // Set the nodes next pointer, and make the bucket point to the node. + // Set the node's next pointer, and make the bucket point to the node. N->SetNextInBucket(Next); *Bucket = N; } @@ -250,15 +257,17 @@ void FoldingSetImpl::InsertNode(Node *N, void *InsertPos) { /// removed or false if the node was not in the folding set. bool FoldingSetImpl::RemoveNode(Node *N) { // Because each bucket is a circular list, we don't need to compute N's hash - // to remove it. Chase around the list until we find the node (or bucket) - // which points to N. + // to remove it. void *Ptr = N->getNextInBucket(); if (Ptr == 0) return false; // Not in folding set. --NumNodes; + N->SetNextInBucket(0); + // Remember what N originally pointed to, either a bucket or another node. void *NodeNextPtr = Ptr; - N->SetNextInBucket(0); + + // Chase around the list until we find the node (or bucket) which points to N. while (true) { if (Node *NodeInBucket = GetNextPtr(Ptr, Buckets, NumBuckets)) { // Advance pointer.