Reorder methods alphabetically. No functionality change.
[oota-llvm.git] / lib / Support / FoldingSet.cpp
index 059b780565b703786f803253a270dd98c6aca728..5f1de4a657fa4530da76857c7de902f00cab2011 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by James M. Laskey and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/APFloat.h"
 #include "llvm/Support/MathExtras.h"
 #include <cassert>
+#include <cstring>
 using namespace llvm;
 
 //===----------------------------------------------------------------------===//
-// FoldingSetImpl::NodeID Implementation
+// FoldingSetNodeID Implementation
 
 /// Add* - Add various data types to Bit data.
 ///
-void FoldingSetImpl::NodeID::AddPointer(const void *Ptr) {
+void FoldingSetNodeID::AddPointer(const void *Ptr) {
   // Note: this adds pointers to the hash using sizes and endianness that
   // depend on the host.  It doesn't matter however, because hashing on
   // pointer values in inherently unstable.  Nothing  should depend on the 
@@ -35,36 +35,68 @@ void FoldingSetImpl::NodeID::AddPointer(const void *Ptr) {
   if (sizeof(intptr_t) > sizeof(unsigned))
     Bits.push_back(unsigned(uint64_t(PtrI) >> 32));
 }
-void FoldingSetImpl::NodeID::AddInteger(signed I) {
+void FoldingSetNodeID::AddInteger(signed I) {
   Bits.push_back(I);
 }
-void FoldingSetImpl::NodeID::AddInteger(unsigned I) {
+void FoldingSetNodeID::AddInteger(unsigned I) {
   Bits.push_back(I);
 }
-void FoldingSetImpl::NodeID::AddInteger(int64_t I) {
+void FoldingSetNodeID::AddInteger(int64_t I) {
   AddInteger((uint64_t)I);
 }
-void FoldingSetImpl::NodeID::AddInteger(uint64_t I) {
+void FoldingSetNodeID::AddInteger(uint64_t I) {
   Bits.push_back(unsigned(I));
   
   // 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) {
+void FoldingSetNodeID::AddFloat(float F) {
   Bits.push_back(FloatToBits(F));
 }
-void FoldingSetImpl::NodeID::AddDouble(double D) {
+void FoldingSetNodeID::AddDouble(double D) {
  AddInteger(DoubleToBits(D));
 }
-void FoldingSetImpl::NodeID::AddAPFloat(const APFloat& apf) {
-  APInt api = apf.convertToAPInt();
-  const uint64_t *p = api.getRawData();
-  for (unsigned i=0; i<api.getNumWords(); i++)
-    AddInteger(*p++);
+
+void FoldingSetNodeID::AddString(const char *String) {
+  unsigned Size = static_cast<unsigned>(strlen(String));
+  Bits.push_back(Size);
+  if (!Size) return;
+
+  unsigned Units = Size / 4;
+  unsigned Pos = 0;
+  const unsigned *Base = (const unsigned *)String;
+  
+  // If the string is aligned do a bulk transfer.
+  if (!((intptr_t)Base & 3)) {
+    Bits.append(Base, Base + Units);
+    Pos = (Units + 1) * 4;
+  } else {
+    // Otherwise do it the hard way.
+    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) |
+                    (unsigned char)String[Pos - 1];
+      Bits.push_back(V);
+    }
+  }
+  
+  // With the leftover bits.
+  unsigned V = 0;
+  // Pos will have overshot size by 4 - #bytes left over. 
+  switch (Pos - Size) {
+  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;
+  default: return; // Nothing left.
+  }
+
+  Bits.push_back(V);
 }
-void FoldingSetImpl::NodeID::AddString(const std::string &String) {
-  unsigned Size = String.size();
+
+void FoldingSetNodeID::AddString(const std::string &String) {
+  unsigned Size = static_cast<unsigned>(String.size());
   Bits.push_back(Size);
   if (!Size) return;
 
@@ -100,11 +132,11 @@ void FoldingSetImpl::NodeID::AddString(const std::string &String) {
   Bits.push_back(V);
 }
 
-/// ComputeHash - Compute a strong hash value for this NodeID, used to 
+/// ComputeHash - Compute a strong hash value for this FoldingSetNodeID, used to 
 /// lookup the node in the FoldingSetImpl.
-unsigned FoldingSetImpl::NodeID::ComputeHash() const {
+unsigned FoldingSetNodeID::ComputeHash() const {
   // This is adapted from SuperFastHash by Paul Hsieh.
-  unsigned Hash = Bits.size();
+  unsigned Hash = static_cast<unsigned>(Bits.size());
   for (const unsigned *BP = &Bits[0], *E = BP+Bits.size(); BP != E; ++BP) {
     unsigned Data = *BP;
     Hash         += Data & 0xFFFF;
@@ -125,7 +157,7 @@ unsigned FoldingSetImpl::NodeID::ComputeHash() const {
 
 /// operator== - Used to compare two nodes to each other.
 ///
-bool FoldingSetImpl::NodeID::operator==(const FoldingSetImpl::NodeID &RHS)const{
+bool FoldingSetNodeID::operator==(const FoldingSetNodeID &RHS)const{
   if (Bits.size() != RHS.Bits.size()) return false;
   return memcmp(&Bits[0], &RHS.Bits[0], Bits.size()*sizeof(Bits[0])) == 0;
 }
@@ -148,7 +180,7 @@ static FoldingSetImpl::Node *GetNextPtr(void *NextInBucketPtr) {
   return static_cast<FoldingSetImpl::Node*>(NextInBucketPtr);
 }
 
-/// GetBucketPtr - Provides a casting of a bucket pointer for isNode
+
 /// testing.
 static void **GetBucketPtr(void *NextInBucketPtr) {
   intptr_t Ptr = reinterpret_cast<intptr_t>(NextInBucketPtr);
@@ -158,7 +190,7 @@ static void **GetBucketPtr(void *NextInBucketPtr) {
 
 /// GetBucketFor - Hash the specified node ID and return the hash bucket for
 /// the specified ID.
-static void **GetBucketFor(const FoldingSetImpl::NodeID &ID,
+static void **GetBucketFor(const FoldingSetNodeID &ID,
                            void **Buckets, unsigned NumBuckets) {
   // NumBuckets is always a power of 2.
   unsigned BucketNum = ID.ComputeHash() & (NumBuckets-1);
@@ -176,7 +208,7 @@ FoldingSetImpl::FoldingSetImpl(unsigned Log2InitSize) : NumNodes(0) {
   memset(Buckets, 0, NumBuckets*sizeof(void*));
   
   // Set the very last bucket to be a non-null "pointer".
-  Buckets[NumBuckets] = reinterpret_cast<void*>(-2);
+  Buckets[NumBuckets] = reinterpret_cast<void*>(-1);
 }
 FoldingSetImpl::~FoldingSetImpl() {
   delete [] Buckets;
@@ -209,7 +241,7 @@ void FoldingSetImpl::GrowHashTable() {
       NodeInBucket->SetNextInBucket(0);
 
       // Insert the node into the new bucket, after recomputing the hash.
-      NodeID ID;
+      FoldingSetNodeID ID;
       GetNodeProfile(ID, NodeInBucket);
       InsertNode(NodeInBucket, GetBucketFor(ID, Buckets, NumBuckets));
     }
@@ -221,15 +253,17 @@ void FoldingSetImpl::GrowHashTable() {
 /// FindNodeOrInsertPos - Look up the node specified by ID.  If it exists,
 /// return it.  If not, return the insertion token that will make insertion
 /// faster.
-FoldingSetImpl::Node *FoldingSetImpl::FindNodeOrInsertPos(const NodeID &ID,
-                                                          void *&InsertPos) {
+FoldingSetImpl::Node
+*FoldingSetImpl::FindNodeOrInsertPos(const FoldingSetNodeID &ID,
+                                     void *&InsertPos) {
+  
   void **Bucket = GetBucketFor(ID, Buckets, NumBuckets);
   void *Probe = *Bucket;
   
   InsertPos = 0;
   
   while (Node *NodeInBucket = GetNextPtr(Probe)) {
-    NodeID OtherID;
+    FoldingSetNodeID OtherID;
     GetNodeProfile(OtherID, NodeInBucket);
     if (OtherID == ID)
       return NodeInBucket;
@@ -250,7 +284,7 @@ void FoldingSetImpl::InsertNode(Node *N, void *InsertPos) {
   // Do we need to grow the hashtable?
   if (NumNodes+1 > NumBuckets*2) {
     GrowHashTable();
-    NodeID ID;
+    FoldingSetNodeID ID;
     GetNodeProfile(ID, N);
     InsertPos = GetBucketFor(ID, Buckets, NumBuckets);
   }
@@ -317,7 +351,7 @@ bool FoldingSetImpl::RemoveNode(Node *N) {
 /// equal to the specified node, return it.  Otherwise, insert 'N' and it
 /// instead.
 FoldingSetImpl::Node *FoldingSetImpl::GetOrInsertNode(FoldingSetImpl::Node *N) {
-  NodeID ID;
+  FoldingSetNodeID ID;
   GetNodeProfile(ID, N);
   void *IP;
   if (Node *E = FindNodeOrInsertPos(ID, IP))
@@ -331,7 +365,8 @@ FoldingSetImpl::Node *FoldingSetImpl::GetOrInsertNode(FoldingSetImpl::Node *N) {
 
 FoldingSetIteratorImpl::FoldingSetIteratorImpl(void **Bucket) {
   // Skip to the first non-null non-self-cycle bucket.
-  while (*Bucket == 0 || GetNextPtr(*Bucket) == 0)
+  while (*Bucket != reinterpret_cast<void*>(-1) &&
+         (*Bucket == 0 || GetNextPtr(*Bucket) == 0))
     ++Bucket;
   
   NodePtr = static_cast<FoldingSetNode*>(*Bucket);
@@ -350,9 +385,16 @@ void FoldingSetIteratorImpl::advance() {
     // Skip to the next non-null non-self-cycle bucket.
     do {
       ++Bucket;
-    } while (*Bucket == 0 || GetNextPtr(*Bucket) == 0);
+    } while (*Bucket != reinterpret_cast<void*>(-1) &&
+             (*Bucket == 0 || GetNextPtr(*Bucket) == 0));
     
     NodePtr = static_cast<FoldingSetNode*>(*Bucket);
   }
 }
 
+//===----------------------------------------------------------------------===//
+// FoldingSetBucketIteratorImpl Implementation
+
+FoldingSetBucketIteratorImpl::FoldingSetBucketIteratorImpl(void **Bucket) {
+  Ptr = (*Bucket == 0 || GetNextPtr(*Bucket) == 0) ? (void*) Bucket : *Bucket;
+}