Modified node creation of ImutAVLTree to do a hash lookup for an existing
[oota-llvm.git] / include / llvm / ADT / ImmutableSet.h
1 //===--- ImmutableSet.h - Immutable (functional) set interface --*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the ImutAVLTree and ImmutableSet classes.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_ADT_IMSET_H
15 #define LLVM_ADT_IMSET_H
16
17 #include "llvm/Support/Allocator.h"
18 #include "llvm/ADT/FoldingSet.h"
19 #include <cassert>
20
21 namespace llvm {
22   
23 //===----------------------------------------------------------------------===//    
24 // Immutable AVL-Tree Definition.
25 //===----------------------------------------------------------------------===//
26
27 template <typename ImutInfo> class ImutAVLFactory;
28 template <typename ImutInfo> class ImutAVLTreeInOrderIterator;
29 template <typename ImutInfo> class ImutAVLTreeGenericIterator;
30   
31 template <typename ImutInfo >
32 class ImutAVLTree : public FoldingSetNode {
33 public:
34   typedef typename ImutInfo::key_type_ref   key_type_ref;
35   typedef typename ImutInfo::value_type     value_type;
36   typedef typename ImutInfo::value_type_ref value_type_ref;
37
38   typedef ImutAVLFactory<ImutInfo>          Factory;
39   friend class ImutAVLFactory<ImutInfo>;
40   
41   friend class ImutAVLTreeGenericIterator<ImutInfo>;
42   friend class FoldingSet<ImutAVLTree>;
43   
44   typedef ImutAVLTreeInOrderIterator<ImutInfo>  iterator;
45   
46   //===----------------------------------------------------===//  
47   // Public Interface.
48   //===----------------------------------------------------===//  
49   
50   /// getLeft - Returns a pointer to the left subtree.  This value
51   ///  is NULL if there is no left subtree.
52   ImutAVLTree* getLeft() const { 
53     assert (!isMutable() && "Node is incorrectly marked mutable.");
54     
55     return reinterpret_cast<ImutAVLTree*>(Left);
56   }
57   
58   /// getRight - Returns a pointer to the right subtree.  This value is
59   ///  NULL if there is no right subtree.
60   ImutAVLTree* getRight() const { return Right; }  
61   
62   
63   /// getHeight - Returns the height of the tree.  A tree with no subtrees
64   ///  has a height of 1.
65   unsigned getHeight() const { return Height; }  
66   
67   /// getValue - Returns the data value associated with the tree node.
68   const value_type& getValue() const { return Value; }
69   
70   /// find - Finds the subtree associated with the specified key value.
71   ///  This method returns NULL if no matching subtree is found.
72   ImutAVLTree* find(key_type_ref K) {
73     ImutAVLTree *T = this;
74     
75     while (T) {
76       key_type_ref CurrentKey = ImutInfo::KeyOfValue(T->getValue());
77       
78       if (ImutInfo::isEqual(K,CurrentKey))
79         return T;
80       else if (ImutInfo::isLess(K,CurrentKey))
81         T = T->getLeft();
82       else
83         T = T->getRight();
84     }
85     
86     return NULL;
87   }
88   
89   /// size - Returns the number of nodes in the tree, which includes
90   ///  both leaves and non-leaf nodes.
91   unsigned size() const {
92     unsigned n = 1;
93     
94     if (const ImutAVLTree* L = getLeft())  n += L->size();
95     if (const ImutAVLTree* R = getRight()) n += R->size();
96     
97     return n;
98   }
99   
100   /// begin - Returns an iterator that iterates over the nodes of the tree
101   ///  in an inorder traversal.  The returned iterator thus refers to the
102   ///  the tree node with the minimum data element.
103   iterator begin() const { return iterator(this); }
104   
105   /// end - Returns an iterator for the tree that denotes the end of an
106   ///  inorder traversal.
107   iterator end() const { return iterator(); }
108     
109   bool ElementEqual(value_type_ref V) const {
110     // Compare the keys.
111     if (!ImutInfo::isEqual(ImutInfo::KeyOfValue(getValue()),
112                            ImutInfo::KeyOfValue(V)))
113       return false;
114     
115     // Also compare the data values.
116     if (!ImutInfo::isDataEqual(ImutInfo::DataOfValue(getValue()),
117                                ImutInfo::DataOfValue(V)))
118       return false;
119     
120     return true;
121   }
122   
123   bool ElementEqual(const ImutAVLTree* RHS) const {
124     return ElementEqual(RHS->getValue());
125   }
126   
127   /// isEqual - Compares two trees for structural equality and returns true
128   ///   if they are equal.  This worst case performance of this operation is
129   //    linear in the sizes of the trees.
130   bool isEqual(const ImutAVLTree& RHS) const {
131     if (&RHS == this)
132       return true;
133     
134     iterator LItr = begin(), LEnd = end();
135     iterator RItr = RHS.begin(), REnd = RHS.end();
136     
137     while (LItr != LEnd && RItr != REnd) {
138       if (*LItr == *RItr) {
139         LItr.SkipSubTree();
140         RItr.SkipSubTree();
141         continue;
142       }
143       
144       if (!LItr->ElementEqual(*RItr))
145         return false;
146       
147       ++LItr;
148       ++RItr;
149     }
150     
151     return LItr == LEnd && RItr == REnd;
152   }
153
154   /// isNotEqual - Compares two trees for structural inequality.  Performance
155   ///  is the same is isEqual.
156   bool isNotEqual(const ImutAVLTree& RHS) const { return !isEqual(RHS); }
157   
158   /// contains - Returns true if this tree contains a subtree (node) that
159   ///  has an data element that matches the specified key.  Complexity
160   ///  is logarithmic in the size of the tree.
161   bool contains(const key_type_ref K) { return (bool) find(K); }
162   
163   /// foreach - A member template the accepts invokes operator() on a functor
164   ///  object (specifed by Callback) for every node/subtree in the tree.
165   ///  Nodes are visited using an inorder traversal.
166   template <typename Callback>
167   void foreach(Callback& C) {
168     if (ImutAVLTree* L = getLeft()) L->foreach(C);
169     
170     C(Value);    
171     
172     if (ImutAVLTree* R = getRight()) R->foreach(C);
173   }
174   
175   /// verify - A utility method that checks that the balancing and
176   ///  ordering invariants of the tree are satisifed.  It is a recursive
177   ///  method that returns the height of the tree, which is then consumed
178   ///  by the enclosing verify call.  External callers should ignore the
179   ///  return value.  An invalid tree will cause an assertion to fire in
180   ///  a debug build.
181   unsigned verify() const {
182     unsigned HL = getLeft() ? getLeft()->verify() : 0;
183     unsigned HR = getRight() ? getRight()->verify() : 0;
184     
185     assert (getHeight() == ( HL > HR ? HL : HR ) + 1 
186             && "Height calculation wrong.");
187     
188     assert ((HL > HR ? HL-HR : HR-HL) <= 2
189             && "Balancing invariant violated.");
190     
191     
192     assert (!getLeft()
193             || ImutInfo::isLess(ImutInfo::KeyOfValue(getLeft()->getValue()),
194                                 ImutInfo::KeyOfValue(getValue()))
195             && "Value in left child is not less that current value.");
196     
197     
198     assert (!getRight()
199             || ImutInfo::isLess(ImutInfo::KeyOfValue(getValue()),
200                                 ImutInfo::KeyOfValue(getRight()->getValue()))
201             && "Current value is not less that value of right child.");
202     
203     return getHeight();
204   }
205   
206   /// Profile - Profiling for ImutAVLTree.  This is not used by the
207   //    Factory object (which internally uses a FoldingSet), but can
208   //    be used by external clients that wish to insert an ImutAVLTree
209   //    object into a FoldingSet.
210   void Profile(llvm::FoldingSetNodeID& ID) const {
211     ID.AddPointer(this);
212   }   
213   
214   //===----------------------------------------------------===//  
215   // Internal Values.
216   //===----------------------------------------------------===//
217   
218 private:
219   uintptr_t        Left;
220   ImutAVLTree*     Right;
221   unsigned         Height;
222   value_type       Value;
223   unsigned         Hash;
224   
225   //===----------------------------------------------------===//    
226   // Internal methods (node manipulation; used by Factory).
227   //===----------------------------------------------------===//
228
229 private:
230   
231   enum { Mutable = 0x1 };
232
233   /// ImutAVLTree - Internal constructor that is only called by
234   ///   ImutAVLFactory.
235   ImutAVLTree(ImutAVLTree* l, ImutAVLTree* r, value_type_ref v, unsigned height)
236   : Left(reinterpret_cast<uintptr_t>(l) | Mutable),
237     Right(r), Height(height), Value(v), Hash(0) {}
238   
239   
240   /// isMutable - Returns true if the left and right subtree references
241   ///  (as well as height) can be changed.  If this method returns false,
242   ///  the tree is truly immutable.  Trees returned from an ImutAVLFactory
243   ///  object should always have this method return true.  Further, if this
244   ///  method returns false for an instance of ImutAVLTree, all subtrees
245   ///  will also have this method return false.  The converse is not true.
246   bool isMutable() const { return Left & Mutable; }
247   
248   /// getSafeLeft - Returns the pointer to the left tree by always masking
249   ///  out the mutable bit.  This is used internally by ImutAVLFactory,
250   ///  as no trees returned to the client should have the mutable flag set.
251   ImutAVLTree* getSafeLeft() const { 
252     return reinterpret_cast<ImutAVLTree*>(Left & ~Mutable);
253   }
254   
255   //===----------------------------------------------------===//    
256   // Mutating operations.  A tree root can be manipulated as
257   // long as its reference has not "escaped" from internal 
258   // methods of a factory object (see below).  When a tree
259   // pointer is externally viewable by client code, the 
260   // internal "mutable bit" is cleared to mark the tree 
261   // immutable.  Note that a tree that still has its mutable
262   // bit set may have children (subtrees) that are themselves
263   // immutable.
264   //===----------------------------------------------------===//
265   
266   
267   /// MarkImmutable - Clears the mutable flag for a tree.  After this happens,
268   ///   it is an error to call setLeft(), setRight(), and setHeight().  It
269   ///   is also then safe to call getLeft() instead of getSafeLeft().  
270   void MarkImmutable() {
271     assert (isMutable() && "Mutable flag already removed.");
272     Left &= ~Mutable;
273   }
274   
275   /// setLeft - Changes the reference of the left subtree.  Used internally
276   ///   by ImutAVLFactory.
277   void setLeft(ImutAVLTree* NewLeft) {
278     assert (isMutable() && 
279             "Only a mutable tree can have its left subtree changed.");
280     
281     Left = reinterpret_cast<uintptr_t>(NewLeft) | Mutable;
282   }
283   
284   /// setRight - Changes the reference of the right subtree.  Used internally
285   ///  by ImutAVLFactory.
286   void setRight(ImutAVLTree* NewRight) {
287     assert (isMutable() &&
288             "Only a mutable tree can have its right subtree changed.");
289     
290     Right = NewRight;
291   }
292   
293   /// setHeight - Changes the height of the tree.  Used internally by
294   ///  ImutAVLFactory.
295   void setHeight(unsigned h) {
296     assert (isMutable() && "Only a mutable tree can have its height changed.");
297     Height = h;
298   }
299   
300   
301   static inline
302   unsigned ComputeHash(ImutAVLTree* L, ImutAVLTree* R, value_type_ref V) {
303     unsigned hash = 0;
304     
305     if (L) hash += L->ComputeHash();
306     
307     { // Compute hash of stored data.
308       FoldingSetNodeID ID;
309       ImutInfo::Profile(ID,V);
310       hash += ID.ComputeHash();
311     }
312     
313     if (R) hash += R->ComputeHash();
314     
315     return hash;
316   }
317   
318   inline unsigned ComputeHash() {
319     if (Hash) return Hash;
320     
321     unsigned X = ComputeHash(getSafeLeft(), getRight(), getValue());
322     if (!isMutable()) Hash = X;
323     
324     return X;
325   }
326 };
327
328 //===----------------------------------------------------------------------===//    
329 // Immutable AVL-Tree Factory class.
330 //===----------------------------------------------------------------------===//
331
332 template <typename ImutInfo >  
333 class ImutAVLFactory {
334   typedef ImutAVLTree<ImutInfo> TreeTy;
335   typedef typename TreeTy::value_type_ref value_type_ref;
336   typedef typename TreeTy::key_type_ref   key_type_ref;
337   
338   typedef FoldingSet<TreeTy> CacheTy;
339   
340   CacheTy Cache;  
341   BumpPtrAllocator Allocator;    
342   
343   //===--------------------------------------------------===//    
344   // Public interface.
345   //===--------------------------------------------------===//
346   
347 public:
348   ImutAVLFactory() {}
349   
350   TreeTy* Add(TreeTy* T, value_type_ref V) {
351     T = Add_internal(V,T);
352     MarkImmutable(T);
353     return T;
354   }
355   
356   TreeTy* Remove(TreeTy* T, key_type_ref V) {
357     T = Remove_internal(V,T);
358     MarkImmutable(T);
359     return T;
360   }
361   
362   TreeTy* GetEmptyTree() const { return NULL; }
363   
364   BumpPtrAllocator& getAllocator() { return Allocator; }
365   
366   //===--------------------------------------------------===//    
367   // A bunch of quick helper functions used for reasoning
368   // about the properties of trees and their children.
369   // These have succinct names so that the balancing code
370   // is as terse (and readable) as possible.
371   //===--------------------------------------------------===//
372 private:
373   
374   bool           isEmpty(TreeTy* T) const { return !T; }
375   unsigned        Height(TreeTy* T) const { return T ? T->getHeight() : 0; }  
376   TreeTy*           Left(TreeTy* T) const { return T->getSafeLeft(); }
377   TreeTy*          Right(TreeTy* T) const { return T->getRight(); }  
378   value_type_ref   Value(TreeTy* T) const { return T->Value; }
379   
380   unsigned IncrementHeight(TreeTy* L, TreeTy* R) const {
381     unsigned hl = Height(L);
382     unsigned hr = Height(R);
383     return ( hl > hr ? hl : hr ) + 1;
384   }
385   
386   
387   static bool CompareTreeWithSection(TreeTy* T,
388                                      typename TreeTy::iterator& TI,
389                                      typename TreeTy::iterator& TE) {
390     
391     typename TreeTy::iterator I = T->begin(), E = T->end();
392     
393     for ( ; I!=E ; ++I, ++TI)
394       if (TI == TE || !I->ElementEqual(*TI))
395         return false;
396
397     return true;
398   }                     
399   
400   //===--------------------------------------------------===//    
401   // "CreateNode" is used to generate new tree roots that link
402   // to other trees.  The functon may also simply move links
403   // in an existing root if that root is still marked mutable.
404   // This is necessary because otherwise our balancing code
405   // would leak memory as it would create nodes that are
406   // then discarded later before the finished tree is
407   // returned to the caller.
408   //===--------------------------------------------------===//
409   
410   TreeTy* CreateNode(TreeTy* L, value_type_ref V, TreeTy* R) {
411     // Search the FoldingSet bucket for a Tree with the same hash.
412     unsigned hash = TreeTy::ComputeHash(L, R, V);
413     typename CacheTy::bucket_iterator I = Cache.bucket_begin(hash);
414     typename CacheTy::bucket_iterator E = Cache.bucket_end(hash);
415     
416     for (; I != E; ++I) {
417       TreeTy* T = &*I;
418
419       if (T->ComputeHash() != hash)
420         continue;
421       
422       // We found a collision.  Perform a comparison of Contents('T')
423       // with Contents('L')+'V'+Contents('R').
424       
425       typename TreeTy::iterator TI = T->begin(), TE = T->end();
426       
427       // First compare Contents('L') with the (initial) contents of T.
428       if (!CompareTreeWithSection(L, TI, TE))
429         continue;
430       
431       // Now compare the new data element.
432       if (TI == TE || !TI->ElementEqual(V))
433         continue;
434       
435       ++TI;
436
437       // Now compare the remainder of 'T' with 'R'.
438       if (!CompareTreeWithSection(R, TI, TE))
439         continue;
440       
441       if (TI != TE) // Contents('R') did not match suffix of 'T'.
442         continue;
443       
444       // Trees did match!  Return 'T'.
445       return T;
446     }
447     
448     // No tree with the contents: Contents('L')+'V'+Contents('R').
449     // Create it.
450
451     // Allocate the new tree node and insert it into the cache.
452     TreeTy* T = (TreeTy*) Allocator.Allocate<TreeTy>();    
453     new (T) TreeTy(L,R,V,IncrementHeight(L,R));
454
455     // We do not insert 'T' into the FoldingSet here.  This is because
456     // this tree is still mutable and things may get rebalanced.
457     // Because our hash is associative and based on the contents of
458     // the set, this should hopefully not cause any strange bugs.
459     // 'T' is inserted by 'MarkImmutable'.
460
461     return T;
462   }
463   
464   TreeTy* CreateNode(TreeTy* L, TreeTy* OldTree, TreeTy* R) {      
465     assert (!isEmpty(OldTree));
466     
467     if (OldTree->isMutable()) {
468       OldTree->setLeft(L);
469       OldTree->setRight(R);
470       OldTree->setHeight(IncrementHeight(L,R));
471       return OldTree;
472     }
473     else return CreateNode(L, Value(OldTree), R);
474   }
475   
476   /// Balance - Used by Add_internal and Remove_internal to
477   ///  balance a newly created tree.
478   TreeTy* Balance(TreeTy* L, value_type_ref V, TreeTy* R) {
479     
480     unsigned hl = Height(L);
481     unsigned hr = Height(R);
482     
483     if (hl > hr + 2) {
484       assert (!isEmpty(L) &&
485               "Left tree cannot be empty to have a height >= 2.");
486       
487       TreeTy* LL = Left(L);
488       TreeTy* LR = Right(L);
489       
490       if (Height(LL) >= Height(LR))
491         return CreateNode(LL, L, CreateNode(LR,V,R));
492       
493       assert (!isEmpty(LR) &&
494               "LR cannot be empty because it has a height >= 1.");
495       
496       TreeTy* LRL = Left(LR);
497       TreeTy* LRR = Right(LR);
498       
499       return CreateNode(CreateNode(LL,L,LRL), LR, CreateNode(LRR,V,R));                              
500     }
501     else if (hr > hl + 2) {
502       assert (!isEmpty(R) &&
503               "Right tree cannot be empty to have a height >= 2.");
504       
505       TreeTy* RL = Left(R);
506       TreeTy* RR = Right(R);
507       
508       if (Height(RR) >= Height(RL))
509         return CreateNode(CreateNode(L,V,RL), R, RR);
510       
511       assert (!isEmpty(RL) &&
512               "RL cannot be empty because it has a height >= 1.");
513       
514       TreeTy* RLL = Left(RL);
515       TreeTy* RLR = Right(RL);
516       
517       return CreateNode(CreateNode(L,V,RLL), RL, CreateNode(RLR,R,RR));
518     }
519     else
520       return CreateNode(L,V,R);
521   }
522   
523   /// Add_internal - Creates a new tree that includes the specified
524   ///  data and the data from the original tree.  If the original tree
525   ///  already contained the data item, the original tree is returned.
526   TreeTy* Add_internal(value_type_ref V, TreeTy* T) {
527     if (isEmpty(T))
528       return CreateNode(T, V, T);
529     
530     assert (!T->isMutable());
531     
532     key_type_ref K = ImutInfo::KeyOfValue(V);
533     key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T));
534     
535     if (ImutInfo::isEqual(K,KCurrent))
536       return CreateNode(Left(T), V, Right(T));
537     else if (ImutInfo::isLess(K,KCurrent))
538       return Balance(Add_internal(V,Left(T)), Value(T), Right(T));
539     else
540       return Balance(Left(T), Value(T), Add_internal(V,Right(T)));
541   }
542   
543   /// Remove_interal - Creates a new tree that includes all the data
544   ///  from the original tree except the specified data.  If the
545   ///  specified data did not exist in the original tree, the original
546   ///  tree is returned.
547   TreeTy* Remove_internal(key_type_ref K, TreeTy* T) {
548     if (isEmpty(T))
549       return T;
550     
551     assert (!T->isMutable());
552     
553     key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T));
554     
555     if (ImutInfo::isEqual(K,KCurrent))
556       return CombineLeftRightTrees(Left(T),Right(T));
557     else if (ImutInfo::isLess(K,KCurrent))
558       return Balance(Remove_internal(K,Left(T)), Value(T), Right(T));
559     else
560       return Balance(Left(T), Value(T), Remove_internal(K,Right(T)));
561   }
562   
563   TreeTy* CombineLeftRightTrees(TreeTy* L, TreeTy* R) {
564     if (isEmpty(L)) return R;      
565     if (isEmpty(R)) return L;
566     
567     TreeTy* OldNode;          
568     TreeTy* NewRight = RemoveMinBinding(R,OldNode);
569     return Balance(L,Value(OldNode),NewRight);
570   }
571   
572   TreeTy* RemoveMinBinding(TreeTy* T, TreeTy*& NodeRemoved) {
573     assert (!isEmpty(T));
574     
575     if (isEmpty(Left(T))) {
576       NodeRemoved = T;
577       return Right(T);
578     }
579     
580     return Balance(RemoveMinBinding(Left(T),NodeRemoved),Value(T),Right(T));
581   }    
582   
583   /// MarkImmutable - Clears the mutable bits of a root and all of its
584   ///  descendants.
585   void MarkImmutable(TreeTy* T) {
586     if (!T || !T->isMutable())
587       return;
588     
589     T->MarkImmutable();
590     MarkImmutable(Left(T));
591     MarkImmutable(Right(T));
592         
593     // Now that the node is immutable it can safely be inserted
594     // into the node cache.
595     Cache.InsertNode(T, (void*) &*Cache.bucket_end(T->ComputeHash()));
596   }
597 };
598   
599   
600 //===----------------------------------------------------------------------===//    
601 // Immutable AVL-Tree Iterators.
602 //===----------------------------------------------------------------------===//  
603
604 template <typename ImutInfo>
605 class ImutAVLTreeGenericIterator {
606   SmallVector<uintptr_t,20> stack;
607 public:
608   enum VisitFlag { VisitedNone=0x0, VisitedLeft=0x1, VisitedRight=0x3, 
609                    Flags=0x3 };
610   
611   typedef ImutAVLTree<ImutInfo> TreeTy;      
612   typedef ImutAVLTreeGenericIterator<ImutInfo> _Self;
613
614   inline ImutAVLTreeGenericIterator() {}
615   inline ImutAVLTreeGenericIterator(const TreeTy* Root) {
616     if (Root) stack.push_back(reinterpret_cast<uintptr_t>(Root));
617   }  
618   
619   TreeTy* operator*() const {
620     assert (!stack.empty());    
621     return reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
622   }
623   
624   uintptr_t getVisitState() {
625     assert (!stack.empty());
626     return stack.back() & Flags;
627   }
628   
629   
630   bool AtEnd() const { return stack.empty(); }
631
632   bool AtBeginning() const { 
633     return stack.size() == 1 && getVisitState() == VisitedNone;
634   }
635   
636   void SkipToParent() {
637     assert (!stack.empty());
638     stack.pop_back();
639     
640     if (stack.empty())
641       return;
642     
643     switch (getVisitState()) {
644       case VisitedNone:
645         stack.back() |= VisitedLeft;
646         break;
647       case VisitedLeft:
648         stack.back() |= VisitedRight;
649         break;
650       default:
651         assert (false && "Unreachable.");            
652     }
653   }
654   
655   inline bool operator==(const _Self& x) const {
656     if (stack.size() != x.stack.size())
657       return false;
658     
659     for (unsigned i = 0 ; i < stack.size(); i++)
660       if (stack[i] != x.stack[i])
661         return false;
662     
663     return true;
664   }
665   
666   inline bool operator!=(const _Self& x) const { return !operator==(x); }  
667   
668   _Self& operator++() {
669     assert (!stack.empty());
670     
671     TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
672     assert (Current);
673     
674     switch (getVisitState()) {
675       case VisitedNone:
676         if (TreeTy* L = Current->getSafeLeft())
677           stack.push_back(reinterpret_cast<uintptr_t>(L));
678         else
679           stack.back() |= VisitedLeft;
680         
681         break;
682         
683       case VisitedLeft:
684         if (TreeTy* R = Current->getRight())
685           stack.push_back(reinterpret_cast<uintptr_t>(R));
686         else
687           stack.back() |= VisitedRight;
688         
689         break;
690         
691       case VisitedRight:
692         SkipToParent();        
693         break;
694         
695       default:
696         assert (false && "Unreachable.");
697     }
698     
699     return *this;
700   }
701   
702   _Self& operator--() {
703     assert (!stack.empty());
704     
705     TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
706     assert (Current);
707     
708     switch (getVisitState()) {
709       case VisitedNone:
710         stack.pop_back();
711         break;
712         
713       case VisitedLeft:                
714         stack.back() &= ~Flags; // Set state to "VisitedNone."
715         
716         if (TreeTy* L = Current->getLeft())
717           stack.push_back(reinterpret_cast<uintptr_t>(L) | VisitedRight);
718           
719         break;
720         
721       case VisitedRight:        
722         stack.back() &= ~Flags;
723         stack.back() |= VisitedLeft;
724         
725         if (TreeTy* R = Current->getRight())
726           stack.push_back(reinterpret_cast<uintptr_t>(R) | VisitedRight);
727           
728         break;
729         
730       default:
731         assert (false && "Unreachable.");
732     }
733     
734     return *this;
735   }
736 };
737   
738 template <typename ImutInfo>
739 class ImutAVLTreeInOrderIterator {
740   typedef ImutAVLTreeGenericIterator<ImutInfo> InternalIteratorTy;
741   InternalIteratorTy InternalItr;
742
743 public:
744   typedef ImutAVLTree<ImutInfo> TreeTy;
745   typedef ImutAVLTreeInOrderIterator<ImutInfo> _Self;
746
747   ImutAVLTreeInOrderIterator(const TreeTy* Root) : InternalItr(Root) { 
748     if (Root) operator++(); // Advance to first element.
749   }
750   
751   ImutAVLTreeInOrderIterator() : InternalItr() {}
752
753   inline bool operator==(const _Self& x) const {
754     return InternalItr == x.InternalItr;
755   }
756   
757   inline bool operator!=(const _Self& x) const { return !operator==(x); }  
758   
759   inline TreeTy* operator*() const { return *InternalItr; }
760   inline TreeTy* operator->() const { return *InternalItr; }
761   
762   inline _Self& operator++() { 
763     do ++InternalItr;
764     while (!InternalItr.AtEnd() && 
765            InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
766
767     return *this;
768   }
769   
770   inline _Self& operator--() { 
771     do --InternalItr;
772     while (!InternalItr.AtBeginning() && 
773            InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
774     
775     return *this;
776   }
777   
778   inline void SkipSubTree() {
779     InternalItr.SkipToParent();
780     
781     while (!InternalItr.AtEnd() &&
782            InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft)
783       ++InternalItr;        
784   }
785 };
786     
787 //===----------------------------------------------------------------------===//    
788 // Trait classes for Profile information.
789 //===----------------------------------------------------------------------===//
790
791 /// Generic profile template.  The default behavior is to invoke the
792 /// profile method of an object.  Specializations for primitive integers
793 /// and generic handling of pointers is done below.
794 template <typename T>
795 struct ImutProfileInfo {
796   typedef const T  value_type;
797   typedef const T& value_type_ref;
798   
799   static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) {
800     FoldingSetTrait<T>::Profile(X,ID);
801   }
802 };
803
804 /// Profile traits for integers.
805 template <typename T>
806 struct ImutProfileInteger {    
807   typedef const T  value_type;
808   typedef const T& value_type_ref;
809   
810   static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) {
811     ID.AddInteger(X);
812   }  
813 };
814
815 #define PROFILE_INTEGER_INFO(X)\
816 template<> struct ImutProfileInfo<X> : ImutProfileInteger<X> {};
817
818 PROFILE_INTEGER_INFO(char)
819 PROFILE_INTEGER_INFO(unsigned char)
820 PROFILE_INTEGER_INFO(short)
821 PROFILE_INTEGER_INFO(unsigned short)
822 PROFILE_INTEGER_INFO(unsigned)
823 PROFILE_INTEGER_INFO(signed)
824 PROFILE_INTEGER_INFO(long)
825 PROFILE_INTEGER_INFO(unsigned long)
826 PROFILE_INTEGER_INFO(long long)
827 PROFILE_INTEGER_INFO(unsigned long long)
828
829 #undef PROFILE_INTEGER_INFO
830
831 /// Generic profile trait for pointer types.  We treat pointers as
832 /// references to unique objects.
833 template <typename T>
834 struct ImutProfileInfo<T*> {
835   typedef const T*   value_type;
836   typedef value_type value_type_ref;
837   
838   static inline void Profile(FoldingSetNodeID &ID, value_type_ref X) {
839     ID.AddPointer(X);
840   }
841 };
842
843 //===----------------------------------------------------------------------===//    
844 // Trait classes that contain element comparison operators and type
845 //  definitions used by ImutAVLTree, ImmutableSet, and ImmutableMap.  These
846 //  inherit from the profile traits (ImutProfileInfo) to include operations
847 //  for element profiling.
848 //===----------------------------------------------------------------------===//
849
850
851 /// ImutContainerInfo - Generic definition of comparison operations for
852 ///   elements of immutable containers that defaults to using
853 ///   std::equal_to<> and std::less<> to perform comparison of elements.
854 template <typename T>
855 struct ImutContainerInfo : public ImutProfileInfo<T> {
856   typedef typename ImutProfileInfo<T>::value_type      value_type;
857   typedef typename ImutProfileInfo<T>::value_type_ref  value_type_ref;
858   typedef value_type      key_type;
859   typedef value_type_ref  key_type_ref;
860   typedef bool            data_type;
861   typedef bool            data_type_ref;
862   
863   static inline key_type_ref KeyOfValue(value_type_ref D) { return D; }
864   static inline data_type_ref DataOfValue(value_type_ref) { return true; }
865   
866   static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) { 
867     return std::equal_to<key_type>()(LHS,RHS);
868   }
869   
870   static inline bool isLess(key_type_ref LHS, key_type_ref RHS) {
871     return std::less<key_type>()(LHS,RHS);
872   }
873   
874   static inline bool isDataEqual(data_type_ref,data_type_ref) { return true; }
875 };
876
877 /// ImutContainerInfo - Specialization for pointer values to treat pointers
878 ///  as references to unique objects.  Pointers are thus compared by
879 ///  their addresses.
880 template <typename T>
881 struct ImutContainerInfo<T*> : public ImutProfileInfo<T*> {
882   typedef typename ImutProfileInfo<T*>::value_type      value_type;
883   typedef typename ImutProfileInfo<T*>::value_type_ref  value_type_ref;
884   typedef value_type      key_type;
885   typedef value_type_ref  key_type_ref;
886   typedef bool            data_type;
887   typedef bool            data_type_ref;
888   
889   static inline key_type_ref KeyOfValue(value_type_ref D) { return D; }
890   static inline data_type_ref DataOfValue(value_type_ref) { return true; }
891   
892   static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) {
893     return LHS == RHS;
894   }
895   
896   static inline bool isLess(key_type_ref LHS, key_type_ref RHS) {
897     return LHS < RHS;
898   }
899   
900   static inline bool isDataEqual(data_type_ref,data_type_ref) { return true; }
901 };
902
903 //===----------------------------------------------------------------------===//    
904 // Immutable Set
905 //===----------------------------------------------------------------------===//
906
907 template <typename ValT, typename ValInfo = ImutContainerInfo<ValT> >
908 class ImmutableSet {
909 public:
910   typedef typename ValInfo::value_type      value_type;
911   typedef typename ValInfo::value_type_ref  value_type_ref;
912   typedef ImutAVLTree<ValInfo> TreeTy;
913
914 private:  
915   TreeTy* Root;
916
917 public:
918   /// Constructs a set from a pointer to a tree root.  In general one
919   /// should use a Factory object to create sets instead of directly
920   /// invoking the constructor, but there are cases where make this
921   /// constructor public is useful.
922   explicit ImmutableSet(TreeTy* R) : Root(R) {}
923   
924   class Factory {
925     typename TreeTy::Factory F;
926     
927   public:
928     Factory() {}
929     
930     /// GetEmptySet - Returns an immutable set that contains no elements.
931     ImmutableSet GetEmptySet() { return ImmutableSet(F.GetEmptyTree()); }
932     
933     /// Add - Creates a new immutable set that contains all of the values
934     ///  of the original set with the addition of the specified value.  If
935     ///  the original set already included the value, then the original set is
936     ///  returned and no memory is allocated.  The time and space complexity
937     ///  of this operation is logarithmic in the size of the original set.
938     ///  The memory allocated to represent the set is released when the
939     ///  factory object that created the set is destroyed.
940     ImmutableSet Add(ImmutableSet Old, value_type_ref V) {
941       return ImmutableSet(F.Add(Old.Root,V));
942     }
943     
944     /// Remove - Creates a new immutable set that contains all of the values
945     ///  of the original set with the exception of the specified value.  If
946     ///  the original set did not contain the value, the original set is
947     ///  returned and no memory is allocated.  The time and space complexity
948     ///  of this operation is logarithmic in the size of the original set.
949     ///  The memory allocated to represent the set is released when the
950     ///  factory object that created the set is destroyed.
951     ImmutableSet Remove(ImmutableSet Old, value_type_ref V) {
952       return ImmutableSet(F.Remove(Old.Root,V));
953     }
954     
955     BumpPtrAllocator& getAllocator() { return F.getAllocator(); }
956
957   private:
958     Factory(const Factory& RHS) {};
959     void operator=(const Factory& RHS) {};    
960   };
961   
962   friend class Factory;  
963
964   /// contains - Returns true if the set contains the specified value.
965   bool contains(const value_type_ref V) const {
966     return Root ? Root->contains(V) : false;
967   }
968   
969   bool operator==(ImmutableSet RHS) const {
970     return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
971   }
972   
973   bool operator!=(ImmutableSet RHS) const {
974     return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
975   }
976   
977   TreeTy* getRoot() const { return Root; }
978   
979   /// isEmpty - Return true if the set contains no elements.
980   bool isEmpty() const { return !Root; }
981   
982   template <typename Callback>
983   void foreach(Callback& C) { if (Root) Root->foreach(C); }
984   
985   template <typename Callback>
986   void foreach() { if (Root) { Callback C; Root->foreach(C); } }
987     
988   //===--------------------------------------------------===//    
989   // Iterators.
990   //===--------------------------------------------------===//  
991
992   class iterator {
993     typename TreeTy::iterator itr;
994     
995     iterator() {}
996     iterator(TreeTy* t) : itr(t) {}
997     friend class ImmutableSet<ValT,ValInfo>;
998   public:
999     inline value_type_ref operator*() const { return itr->getValue(); }
1000     inline iterator& operator++() { ++itr; return *this; }
1001     inline iterator  operator++(int) { iterator tmp(*this); ++itr; return tmp; }
1002     inline iterator& operator--() { --itr; return *this; }
1003     inline iterator  operator--(int) { iterator tmp(*this); --itr; return tmp; }
1004     inline bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
1005     inline bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }        
1006   };
1007   
1008   iterator begin() const { return iterator(Root); }
1009   iterator end() const { return iterator(); }  
1010   
1011   //===--------------------------------------------------===//    
1012   // For testing.
1013   //===--------------------------------------------------===//  
1014   
1015   void verify() const { if (Root) Root->verify(); }
1016   unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
1017 };
1018
1019 } // end namespace llvm
1020
1021 #endif