diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h
new file mode 100644
index 0000000..c808d3b
--- /dev/null
+++ b/include/llvm/ADT/FoldingSet.h
@@ -0,0 +1,281 @@
+//===-- llvm/ADT/FoldingSet.h - Uniquing Hash Set ---------------*- C++ -*-===//
+//
+//                     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 defines a hash set that can be used to remove duplication of nodes
+// in a graph.  This code was originally created by Chris Lattner for use with
+// SelectionDAGCSEMap, but was isolated to provide use across the llvm code set. 
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_FOLDINGSET_H
+#define LLVM_ADT_FOLDINGSET_H
+
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+
+/// This folding set used for two purposes:
+///   1. Given information about a node we want to create, look up the unique
+///      instance of the node in the set.  If the node already exists, return
+///      it, otherwise return the bucket it should be inserted into.
+///   2. Given a node that has already been created, remove it from the set.
+/// 
+/// This class is implemented as a single-link chained hash table, where the
+/// "buckets" are actually the nodes themselves (the next pointer is in the
+/// node).  The last node points back to the bucket to simplified node removal.
+///
+/// Any node that is to be included in the folding set must be a subclass of
+/// FoldingSetNode.  The node class must also define a Profile method used to
+/// establish the unique bits of data for the node.  The Profile method is
+/// passed a FoldingSetNodeID object which is used to gather the bits.  Just 
+/// call one of the Add* functions defined in the FoldingSetImpl::NodeID class.
+///
+/// Eg.
+///    class MyNode : public FoldingSetNode {
+///    private:
+///      std::string Name;
+///      unsigned Value;
+///    public:
+///      MyNode(const char *N, unsigned V) : Name(N), Value(V) {}
+///       ...
+///      void Profile(FoldingSetNodeID &ID) {
+///        ID.AddString(Name);
+///        ID.AddInteger(Value);
+///       }
+///       ...
+///     };
+///
+/// To define the folding set itself use the FoldingSet template;
+///
+/// Eg.
+///    FoldingSet<MyNode> MyFoldingSet;
+///
+/// Four public methods are available to manipulate the folding set; 
+///
+/// 1) If you have an existing node that you want add to the set but unsure
+/// that the node might already exist then call;
+///
+///    MyNode *M = MyFoldingSet.GetOrInsertNode(N);
+///
+/// If The result is equal to the input then the node has been inserted.
+/// Otherwise, the result is the node existing in the folding set, and the
+/// input can be discarded (use the result instead.)
+///
+/// 2) If you are ready to construct a node but want to check if it already
+/// exists, then call FindNodeOrInsertPos with a FoldingSetNodeID of the bits to
+/// check;
+///
+///   FoldingSetNodeID ID;
+///   ID.AddString(Name);
+///   ID.AddInteger(Value);
+///   void *InsertPoint;
+///
+///    MyNode *M = MyFoldingSet.FindNodeOrInsertPos(ID, InsertPoint);
+///
+/// If found then M with be non-NULL, else InsertPoint will point to where it
+/// should be inserted using InsertNode.
+///
+/// 3) If you get a NULL result from FindNodeOrInsertPos then you can ass a new
+/// node with FindNodeOrInsertPos;
+///
+///    InsertNode(N, InsertPoint);
+///
+/// 4) Finally, if you want to remove a node from the folding set call;
+///
+///    bool WasRemoved = RemoveNode(N);
+///
+/// The result indicates whether the node did exist in the folding set.
+
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetImpl - Implements the folding set functionality.  The main
+/// structure is an array of buckets.  Each bucket is indexed by the hash of
+/// the nodes it contains.  The bucket itself points to the nodes contained
+/// in the bucket via a singly linked list.  The last node in the list points
+/// back to the bucket to facilitate node removal.
+/// 
+class FoldingSetImpl {
+private:
+  // Buckets - Array of bucket chains.
+  void **Buckets;
+  
+  // NumBuckets - Length of the Buckets array.  Always a power of 2.
+  unsigned NumBuckets;
+  
+  // NumNodes - Number of nodes in the folding set.  Growth occurs when NumNodes
+  // is greater than twice teh number of buckets.
+  unsigned NumNodes;
+  
+public:
+  FoldingSetImpl();
+  ~FoldingSetImpl();
+  
+  // Forward declaration.
+  class Node;
+
+  //===--------------------------------------------------------------------===//
+  /// NodeID - This class is used to gather all the unique data bits of a
+  /// node.  When all the bits are gathered this class is used to produce a
+  /// hash value for the node.  
+  ///
+  class NodeID {
+    /// Bits - Vector of all the data bits that make the node unique.
+    /// Use a SmallVector to avoid a heap allocation in the common case.
+    SmallVector<unsigned, 32> Bits;
+    
+  public:
+    NodeID() {}
+    
+    /// getRawData - Return the ith entry in the Bits data.
+    ///
+    unsigned getRawData(unsigned i) const {
+      return Bits[i];
+    }
+    
+    /// Add* - Add various data types to Bit data.
+    ///
+    void AddPointer(const void *Ptr);
+    void AddInteger(signed I);
+    void AddInteger(unsigned I);
+    void AddInteger(uint64_t I);
+    void AddFloat(float F);
+    void AddDouble(double D);
+    void AddString(const std::string &String);
+    
+    /// ComputeHash - Compute a strong hash value for this NodeID, used to 
+    /// lookup the node in the FoldingSetImpl.
+    unsigned ComputeHash() const;
+    
+    /// operator== - Used to compare two nodes to each other.
+    ///
+    bool operator==(const NodeID &RHS) const;
+  };
+
+  //===--------------------------------------------------------------------===//
+  /// Node - This class is used to maintain the singly linked bucket list in
+  /// a folding set.
+  ///
+  class Node {
+  private:
+    // nextInBucket - next linek in the bucket list.
+    void *nextInBucket;
+    
+  public:
+
+    Node() : nextInBucket(0) {}
+    
+    // Accessors
+    void *getNextInBucket() const { return nextInBucket; }
+    void SetNextInBucket(void *N) { nextInBucket = N; }
+  };
+
+  /// RemoveNode - Remove a node from the folding set, returning true if one
+  /// was removed or false if the node was not in the folding set.
+  bool RemoveNode(Node *N);
+  
+  /// GetOrInsertNode - If there is an existing simple Node exactly
+  /// equal to the specified node, return it.  Otherwise, insert 'N' and return
+  /// it instead.
+  Node *GetOrInsertNode(Node *N);
+  
+  /// FindNodeOrInsertPos - Look up the node specified by ID.  If it exists,
+  /// return it.  If not, return the insertion token that will make insertion
+  /// faster.
+  Node *FindNodeOrInsertPos(const NodeID &ID, void *&InsertPos);
+  
+  /// InsertNode - Insert the specified node into the folding set, knowing that
+  /// it is not already in the folding set.  InsertPos must be obtained from 
+  /// FindNodeOrInsertPos.
+  void InsertNode(Node *N, void *InsertPos);
+    
+  private:
+    /// GetNextPtr - In order to save space, each bucket is a
+    /// 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.
+    Node *GetNextPtr(void *NextInBucketPtr);
+    
+    /// GetNextPtr - This is just like the previous GetNextPtr implementation,
+    /// but allows a bucket array to be specified.
+    Node *GetNextPtr(void *NextInBucketPtr, void **Buckets, unsigned NumBuck);
+    
+    /// GetBucketPtr - Provides a casting of a bucket pointer for isNode
+    /// testing.
+    void **GetBucketPtr(void *NextInBucketPtr);
+    
+    /// GetBucketFor - Hash the specified node ID and return the hash bucket for
+    /// the specified ID.
+    void **GetBucketFor(const NodeID &ID) const;
+    
+    /// GrowHashTable - Double the size of the hash table and rehash everything.
+    ///
+    void GrowHashTable();
+    
+  protected:
+  
+    /// GetNodeProfile - Instantiations of the FoldingSet template implement
+    /// this function to gather data bits for teh given node.
+    virtual void GetNodeProfile(NodeID &ID, Node *N) = 0;
+  };
+
+  // Convenence types to hide the implementation of the folding set.
+  typedef FoldingSetImpl::Node FoldingSetNode;
+  typedef FoldingSetImpl::NodeID FoldingSetNodeID;
+
+  //===--------------------------------------------------------------------===//
+  /// FoldingSet - This template class is used to instantiate a specialized
+  /// implementation of the folding set to the node class T.  T must be a 
+  /// subclass of FoldingSetNode and implement a Profile function.
+  ///
+  template<class T> class FoldingSet : public FoldingSetImpl {
+  private:
+    /// GetNodeProfile - Each instantiatation of the FoldingSet 
+    virtual void GetNodeProfile(NodeID &ID, Node *N) {
+      T *TN = static_cast<T *>(N);
+      TN->Profile(ID);
+    }
+    
+  public:
+    /// RemoveNode - Remove a node from the folding set, returning true if one
+    /// was removed or false if the node was not in the folding set.
+    bool RemoveNode(T *N) {
+      return FoldingSetImpl::RemoveNode(static_cast<FoldingSetNode *>(N));
+    }
+    
+    /// GetOrInsertNode - If there is an existing simple Node exactly
+    /// equal to the specified node, return it.  Otherwise, insert 'N' and
+    /// return it instead.
+    T *GetOrInsertNode(Node *N) {
+      return static_cast<T *>(FoldingSetImpl::GetOrInsertNode(
+                                             static_cast<FoldingSetNode *>(N)));
+    }
+    
+    /// FindNodeOrInsertPos - Look up the node specified by ID.  If it exists,
+    /// return it.  If not, return the insertion token that will make insertion
+    /// faster.
+    T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
+      return static_cast<T *>(FoldingSetImpl::FindNodeOrInsertPos(ID,
+                                                                  InsertPos));
+    }
+    
+    /// InsertNode - Insert the specified node into the folding set, knowing
+    /// that it is not already in the folding set.  InsertPos must be obtained
+    /// from  FindNodeOrInsertPos.
+    void InsertNode(T *N, void *InsertPos) {
+      FoldingSetImpl::InsertNode(static_cast<FoldingSetNode *>(N), InsertPos);
+    }
+  };
+
+}; // End of namespace llvm.
+
+
+#endif
+
diff --git a/lib/Support/FoldingSet.cpp b/lib/Support/FoldingSet.cpp
new file mode 100644
index 0000000..6c1b13f
--- /dev/null
+++ b/lib/Support/FoldingSet.cpp
@@ -0,0 +1,282 @@
+//===-- Support/FoldingSet.cpp - Uniquing Hash Set --------------*- C++ -*-===//
+//
+//                     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 implements a hash set that can be used to remove duplication of
+// nodes in a graph.  This code was originally created by Chris Lattner for use
+// with SelectionDAGCSEMap, but was isolated to provide use across the llvm code
+// set. 
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/FoldingSet.h"
+
+#include "llvm/ADT/MathExtras.h"
+
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// FoldingSetImpl::NodeID Implementation
+
+/// Add* - Add various data types to Bit data.
+///
+void FoldingSetImpl::NodeID::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 
+  // ordering of nodes in the folding set.
+  intptr_t PtrI = (intptr_t)Ptr;
+  Bits.push_back(unsigned(PtrI));
+  if (sizeof(intptr_t) > sizeof(unsigned))
+    Bits.push_back(unsigned(uint64_t(PtrI) >> 32));
+}
+void FoldingSetImpl::NodeID::AddInteger(signed I) {
+  Bits.push_back(I);
+}
+void FoldingSetImpl::NodeID::AddInteger(unsigned I) {
+  Bits.push_back(I);
+}
+void FoldingSetImpl::NodeID::AddInteger(uint64_t I) {
+  Bits.push_back(unsigned(I));
+  Bits.push_back(unsigned(I >> 32));
+}
+void FoldingSetImpl::NodeID::AddFloat(float F) {
+  Bits.push_back(FloatToBits(F));
+}
+void FoldingSetImpl::NodeID::AddDouble(double D) {
+  Bits.push_back(DoubleToBits(D));
+}
+void FoldingSetImpl::NodeID::AddString(const std::string &String) {
+  // Note: An assumption is made here that strings are composed of one byte
+  // chars.
+  unsigned Size = String.size();
+  unsigned Units = Size / sizeof(unsigned);
+  const unsigned *Base = (const unsigned *)String.data();
+  Bits.insert(Bits.end(), Base, Base + Units);
+  if (Size & 3) {
+    unsigned V = 0;
+    for (unsigned i = Units * sizeof(unsigned); i < Size; ++i)
+      V = (V << 8) | String[i];
+    Bits.push_back(V);
+  }
+}
+
+/// ComputeHash - Compute a strong hash value for this NodeID, used to 
+/// lookup the node in the FoldingSetImpl.
+unsigned FoldingSetImpl::NodeID::ComputeHash() const {
+  // This is adapted from SuperFastHash by Paul Hsieh.
+  unsigned Hash = Bits.size();
+  for (const unsigned *BP = &Bits[0], *E = BP+Bits.size(); BP != E; ++BP) {
+    unsigned Data = *BP;
+    Hash         += Data & 0xFFFF;
+    unsigned Tmp  = ((Data >> 16) << 11) ^ Hash;
+    Hash          = (Hash << 16) ^ Tmp;
+    Hash         += Hash >> 11;
+  }
+  
+  // Force "avalanching" of final 127 bits.
+  Hash ^= Hash << 3;
+  Hash += Hash >> 5;
+  Hash ^= Hash << 4;
+  Hash += Hash >> 17;
+  Hash ^= Hash << 25;
+  Hash += Hash >> 6;
+  return Hash;
+}
+
+/// operator== - Used to compare two nodes to each other.
+///
+bool FoldingSetImpl::NodeID::operator==(const FoldingSetImpl::NodeID &RHS)const{
+  if (Bits.size() != RHS.Bits.size()) return false;
+  return memcmp(&Bits[0], &RHS.Bits[0], Bits.size()*sizeof(Bits[0])) == 0;
+}
+
+
+//===----------------------------------------------------------------------===//
+// FoldingSetImpl Implementation
+
+FoldingSetImpl::FoldingSetImpl() : NumNodes(0) {
+  NumBuckets = 64;
+  Buckets = new void*[NumBuckets];
+  memset(Buckets, 0, NumBuckets*sizeof(void*));
+}
+FoldingSetImpl::~FoldingSetImpl() {
+  delete [] Buckets;
+}
+
+/// GetNextPtr - In order to save space, each bucket is a
+/// 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.
+FoldingSetImpl::Node *FoldingSetImpl::GetNextPtr(void *NextInBucketPtr) {
+  if (NextInBucketPtr >= Buckets && NextInBucketPtr < Buckets+NumBuckets)
+    return 0;
+  return static_cast<Node*>(NextInBucketPtr);
+}
+
+/// GetNextPtr - This is just like the previous GetNextPtr implementation,
+/// but allows a bucket array to be specified.
+FoldingSetImpl::Node *FoldingSetImpl::GetNextPtr(void *NextInBucketPtr,
+                                                 void **Bucks,
+                                                 unsigned NumBuck) {
+  if (NextInBucketPtr >= Bucks && NextInBucketPtr < Bucks+NumBuck)
+    return 0;
+  return static_cast<Node*>(NextInBucketPtr);
+}
+
+/// GetBucketPtr - Provides a casting of a bucket pointer for isNode
+/// testing.
+void **FoldingSetImpl::GetBucketPtr(void *NextInBucketPtr) {
+  return static_cast<void**>(NextInBucketPtr);
+}
+
+/// GetBucketFor - Hash the specified node ID and return the hash bucket for
+/// the specified ID.
+void **FoldingSetImpl::GetBucketFor(const NodeID &ID) const {
+  // NumBuckets is always a power of 2.
+  unsigned BucketNum = ID.ComputeHash() & (NumBuckets-1);
+  return Buckets+BucketNum;
+}
+
+/// GrowHashTable - Double the size of the hash table and rehash everything.
+///
+void FoldingSetImpl::GrowHashTable() {
+  void **OldBuckets = Buckets;
+  unsigned OldNumBuckets = NumBuckets;
+  NumBuckets <<= 1;
+  
+  // Reset the node count to zero: we're going to reinsert everything.
+  NumNodes = 0;
+  
+  // Clear out new buckets.
+  Buckets = new void*[NumBuckets];
+  memset(Buckets, 0, NumBuckets*sizeof(void*));
+
+  // Walk the old buckets, rehashing nodes into their new place.
+  for (unsigned i = 0; i != OldNumBuckets; ++i) {
+    void *Probe = OldBuckets[i];
+    if (!Probe) continue;
+    while (Node *NodeInBucket = GetNextPtr(Probe, OldBuckets, OldNumBuckets)){
+      // Figure out the next link, remove NodeInBucket from the old link.
+      Probe = NodeInBucket->getNextInBucket();
+      NodeInBucket->SetNextInBucket(0);
+
+      // Insert the node into the new bucket, after recomputing the hash.
+      NodeID ID;
+      GetNodeProfile(ID, NodeInBucket);
+      InsertNode(NodeInBucket, GetBucketFor(ID));
+    }
+  }
+  
+  delete[] OldBuckets;
+}
+
+/// 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) {
+  void **Bucket = GetBucketFor(ID);
+  void *Probe = *Bucket;
+  
+  InsertPos = 0;
+  
+  while (Node *NodeInBucket = GetNextPtr(Probe)) {
+    NodeID OtherID;
+    GetNodeProfile(OtherID, NodeInBucket);
+    if (OtherID == ID)
+      return NodeInBucket;
+
+    Probe = NodeInBucket->getNextInBucket();
+  }
+  
+  // Didn't find the node, return null with the bucket as the InsertPos.
+  InsertPos = Bucket;
+  return 0;
+}
+
+/// InsertNode - Insert the specified node into the folding set, knowing that it
+/// is not already in the map.  InsertPos must be obtained from 
+/// FindNodeOrInsertPos.
+void FoldingSetImpl::InsertNode(Node *N, void *InsertPos) {
+  ++NumNodes;
+  // Do we need to grow the hashtable?
+  if (NumNodes > NumBuckets*2) {
+    GrowHashTable();
+    NodeID ID;
+    GetNodeProfile(ID, N);
+    InsertPos = GetBucketFor(ID);
+  }
+  
+  /// The insert position is actually a bucket pointer.
+  void **Bucket = static_cast<void**>(InsertPos);
+  
+  void *Next = *Bucket;
+  
+  // If this is the first insertion into this bucket, its next pointer will be
+  // null.  Pretend as if it pointed to itself.
+  if (Next == 0)
+    Next = Bucket;
+
+  // Set the nodes next pointer, and make the bucket point to the node.
+  N->SetNextInBucket(Next);
+  *Bucket = N;
+}
+
+/// RemoveNode - Remove a node from the folding set, returning true if one was
+/// 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.
+  void *Ptr = N->getNextInBucket();
+  if (Ptr == 0) return false;  // Not in folding set.
+
+  --NumNodes;
+
+  void *NodeNextPtr = Ptr;
+  N->SetNextInBucket(0);
+  while (true) {
+    if (Node *NodeInBucket = GetNextPtr(Ptr)) {
+      // Advance pointer.
+      Ptr = NodeInBucket->getNextInBucket();
+      
+      // We found a node that points to N, change it to point to N's next node,
+      // removing N from the list.
+      if (Ptr == N) {
+        NodeInBucket->SetNextInBucket(NodeNextPtr);
+        return true;
+      }
+    } else {
+      void **Bucket = GetBucketPtr(Ptr);
+      Ptr = *Bucket;
+      
+      // If we found that the bucket points to N, update the bucket to point to
+      // whatever is next.
+      if (Ptr == N) {
+        *Bucket = NodeNextPtr;
+        return true;
+      }
+    }
+  }
+}
+
+/// GetOrInsertNode - If there is an existing simple Node exactly
+/// equal to the specified node, return it.  Otherwise, insert 'N' and it
+/// instead.
+FoldingSetImpl::Node *FoldingSetImpl::GetOrInsertNode(FoldingSetImpl::Node *N) {
+  NodeID ID;
+  GetNodeProfile(ID, N);
+  void *IP;
+  if (Node *E = FindNodeOrInsertPos(ID, IP))
+    return E;
+  InsertNode(N, IP);
+  return N;
+}
