LLVM API Documentation
00001 //===--- ImmutableSet.h - Immutable (functional) set interface --*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the ImutAVLTree and ImmutableSet classes. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_ADT_IMMUTABLESET_H 00015 #define LLVM_ADT_IMMUTABLESET_H 00016 00017 #include "llvm/ADT/DenseMap.h" 00018 #include "llvm/ADT/FoldingSet.h" 00019 #include "llvm/Support/Allocator.h" 00020 #include "llvm/Support/DataTypes.h" 00021 #include "llvm/Support/ErrorHandling.h" 00022 #include <cassert> 00023 #include <functional> 00024 #include <vector> 00025 00026 namespace llvm { 00027 00028 //===----------------------------------------------------------------------===// 00029 // Immutable AVL-Tree Definition. 00030 //===----------------------------------------------------------------------===// 00031 00032 template <typename ImutInfo> class ImutAVLFactory; 00033 template <typename ImutInfo> class ImutIntervalAVLFactory; 00034 template <typename ImutInfo> class ImutAVLTreeInOrderIterator; 00035 template <typename ImutInfo> class ImutAVLTreeGenericIterator; 00036 00037 template <typename ImutInfo > 00038 class ImutAVLTree { 00039 public: 00040 typedef typename ImutInfo::key_type_ref key_type_ref; 00041 typedef typename ImutInfo::value_type value_type; 00042 typedef typename ImutInfo::value_type_ref value_type_ref; 00043 00044 typedef ImutAVLFactory<ImutInfo> Factory; 00045 friend class ImutAVLFactory<ImutInfo>; 00046 friend class ImutIntervalAVLFactory<ImutInfo>; 00047 00048 friend class ImutAVLTreeGenericIterator<ImutInfo>; 00049 00050 typedef ImutAVLTreeInOrderIterator<ImutInfo> iterator; 00051 00052 //===----------------------------------------------------===// 00053 // Public Interface. 00054 //===----------------------------------------------------===// 00055 00056 /// Return a pointer to the left subtree. This value 00057 /// is NULL if there is no left subtree. 00058 ImutAVLTree *getLeft() const { return left; } 00059 00060 /// Return a pointer to the right subtree. This value is 00061 /// NULL if there is no right subtree. 00062 ImutAVLTree *getRight() const { return right; } 00063 00064 /// getHeight - Returns the height of the tree. A tree with no subtrees 00065 /// has a height of 1. 00066 unsigned getHeight() const { return height; } 00067 00068 /// getValue - Returns the data value associated with the tree node. 00069 const value_type& getValue() const { return value; } 00070 00071 /// find - Finds the subtree associated with the specified key value. 00072 /// This method returns NULL if no matching subtree is found. 00073 ImutAVLTree* find(key_type_ref K) { 00074 ImutAVLTree *T = this; 00075 while (T) { 00076 key_type_ref CurrentKey = ImutInfo::KeyOfValue(T->getValue()); 00077 if (ImutInfo::isEqual(K,CurrentKey)) 00078 return T; 00079 else if (ImutInfo::isLess(K,CurrentKey)) 00080 T = T->getLeft(); 00081 else 00082 T = T->getRight(); 00083 } 00084 return NULL; 00085 } 00086 00087 /// getMaxElement - Find the subtree associated with the highest ranged 00088 /// key value. 00089 ImutAVLTree* getMaxElement() { 00090 ImutAVLTree *T = this; 00091 ImutAVLTree *Right = T->getRight(); 00092 while (Right) { T = Right; Right = T->getRight(); } 00093 return T; 00094 } 00095 00096 /// size - Returns the number of nodes in the tree, which includes 00097 /// both leaves and non-leaf nodes. 00098 unsigned size() const { 00099 unsigned n = 1; 00100 if (const ImutAVLTree* L = getLeft()) 00101 n += L->size(); 00102 if (const ImutAVLTree* R = getRight()) 00103 n += R->size(); 00104 return n; 00105 } 00106 00107 /// begin - Returns an iterator that iterates over the nodes of the tree 00108 /// in an inorder traversal. The returned iterator thus refers to the 00109 /// the tree node with the minimum data element. 00110 iterator begin() const { return iterator(this); } 00111 00112 /// end - Returns an iterator for the tree that denotes the end of an 00113 /// inorder traversal. 00114 iterator end() const { return iterator(); } 00115 00116 bool isElementEqual(value_type_ref V) const { 00117 // Compare the keys. 00118 if (!ImutInfo::isEqual(ImutInfo::KeyOfValue(getValue()), 00119 ImutInfo::KeyOfValue(V))) 00120 return false; 00121 00122 // Also compare the data values. 00123 if (!ImutInfo::isDataEqual(ImutInfo::DataOfValue(getValue()), 00124 ImutInfo::DataOfValue(V))) 00125 return false; 00126 00127 return true; 00128 } 00129 00130 bool isElementEqual(const ImutAVLTree* RHS) const { 00131 return isElementEqual(RHS->getValue()); 00132 } 00133 00134 /// isEqual - Compares two trees for structural equality and returns true 00135 /// if they are equal. This worst case performance of this operation is 00136 // linear in the sizes of the trees. 00137 bool isEqual(const ImutAVLTree& RHS) const { 00138 if (&RHS == this) 00139 return true; 00140 00141 iterator LItr = begin(), LEnd = end(); 00142 iterator RItr = RHS.begin(), REnd = RHS.end(); 00143 00144 while (LItr != LEnd && RItr != REnd) { 00145 if (*LItr == *RItr) { 00146 LItr.skipSubTree(); 00147 RItr.skipSubTree(); 00148 continue; 00149 } 00150 00151 if (!LItr->isElementEqual(*RItr)) 00152 return false; 00153 00154 ++LItr; 00155 ++RItr; 00156 } 00157 00158 return LItr == LEnd && RItr == REnd; 00159 } 00160 00161 /// isNotEqual - Compares two trees for structural inequality. Performance 00162 /// is the same is isEqual. 00163 bool isNotEqual(const ImutAVLTree& RHS) const { return !isEqual(RHS); } 00164 00165 /// contains - Returns true if this tree contains a subtree (node) that 00166 /// has an data element that matches the specified key. Complexity 00167 /// is logarithmic in the size of the tree. 00168 bool contains(key_type_ref K) { return (bool) find(K); } 00169 00170 /// foreach - A member template the accepts invokes operator() on a functor 00171 /// object (specifed by Callback) for every node/subtree in the tree. 00172 /// Nodes are visited using an inorder traversal. 00173 template <typename Callback> 00174 void foreach(Callback& C) { 00175 if (ImutAVLTree* L = getLeft()) 00176 L->foreach(C); 00177 00178 C(value); 00179 00180 if (ImutAVLTree* R = getRight()) 00181 R->foreach(C); 00182 } 00183 00184 /// validateTree - A utility method that checks that the balancing and 00185 /// ordering invariants of the tree are satisifed. It is a recursive 00186 /// method that returns the height of the tree, which is then consumed 00187 /// by the enclosing validateTree call. External callers should ignore the 00188 /// return value. An invalid tree will cause an assertion to fire in 00189 /// a debug build. 00190 unsigned validateTree() const { 00191 unsigned HL = getLeft() ? getLeft()->validateTree() : 0; 00192 unsigned HR = getRight() ? getRight()->validateTree() : 0; 00193 (void) HL; 00194 (void) HR; 00195 00196 assert(getHeight() == ( HL > HR ? HL : HR ) + 1 00197 && "Height calculation wrong"); 00198 00199 assert((HL > HR ? HL-HR : HR-HL) <= 2 00200 && "Balancing invariant violated"); 00201 00202 assert((!getLeft() || 00203 ImutInfo::isLess(ImutInfo::KeyOfValue(getLeft()->getValue()), 00204 ImutInfo::KeyOfValue(getValue()))) && 00205 "Value in left child is not less that current value"); 00206 00207 00208 assert(!(getRight() || 00209 ImutInfo::isLess(ImutInfo::KeyOfValue(getValue()), 00210 ImutInfo::KeyOfValue(getRight()->getValue()))) && 00211 "Current value is not less that value of right child"); 00212 00213 return getHeight(); 00214 } 00215 00216 //===----------------------------------------------------===// 00217 // Internal values. 00218 //===----------------------------------------------------===// 00219 00220 private: 00221 Factory *factory; 00222 ImutAVLTree *left; 00223 ImutAVLTree *right; 00224 ImutAVLTree *prev; 00225 ImutAVLTree *next; 00226 00227 unsigned height : 28; 00228 unsigned IsMutable : 1; 00229 unsigned IsDigestCached : 1; 00230 unsigned IsCanonicalized : 1; 00231 00232 value_type value; 00233 uint32_t digest; 00234 uint32_t refCount; 00235 00236 //===----------------------------------------------------===// 00237 // Internal methods (node manipulation; used by Factory). 00238 //===----------------------------------------------------===// 00239 00240 private: 00241 /// ImutAVLTree - Internal constructor that is only called by 00242 /// ImutAVLFactory. 00243 ImutAVLTree(Factory *f, ImutAVLTree* l, ImutAVLTree* r, value_type_ref v, 00244 unsigned height) 00245 : factory(f), left(l), right(r), prev(0), next(0), height(height), 00246 IsMutable(true), IsDigestCached(false), IsCanonicalized(0), 00247 value(v), digest(0), refCount(0) 00248 { 00249 if (left) left->retain(); 00250 if (right) right->retain(); 00251 } 00252 00253 /// isMutable - Returns true if the left and right subtree references 00254 /// (as well as height) can be changed. If this method returns false, 00255 /// the tree is truly immutable. Trees returned from an ImutAVLFactory 00256 /// object should always have this method return true. Further, if this 00257 /// method returns false for an instance of ImutAVLTree, all subtrees 00258 /// will also have this method return false. The converse is not true. 00259 bool isMutable() const { return IsMutable; } 00260 00261 /// hasCachedDigest - Returns true if the digest for this tree is cached. 00262 /// This can only be true if the tree is immutable. 00263 bool hasCachedDigest() const { return IsDigestCached; } 00264 00265 //===----------------------------------------------------===// 00266 // Mutating operations. A tree root can be manipulated as 00267 // long as its reference has not "escaped" from internal 00268 // methods of a factory object (see below). When a tree 00269 // pointer is externally viewable by client code, the 00270 // internal "mutable bit" is cleared to mark the tree 00271 // immutable. Note that a tree that still has its mutable 00272 // bit set may have children (subtrees) that are themselves 00273 // immutable. 00274 //===----------------------------------------------------===// 00275 00276 /// markImmutable - Clears the mutable flag for a tree. After this happens, 00277 /// it is an error to call setLeft(), setRight(), and setHeight(). 00278 void markImmutable() { 00279 assert(isMutable() && "Mutable flag already removed."); 00280 IsMutable = false; 00281 } 00282 00283 /// markedCachedDigest - Clears the NoCachedDigest flag for a tree. 00284 void markedCachedDigest() { 00285 assert(!hasCachedDigest() && "NoCachedDigest flag already removed."); 00286 IsDigestCached = true; 00287 } 00288 00289 /// setHeight - Changes the height of the tree. Used internally by 00290 /// ImutAVLFactory. 00291 void setHeight(unsigned h) { 00292 assert(isMutable() && "Only a mutable tree can have its height changed."); 00293 height = h; 00294 } 00295 00296 static inline 00297 uint32_t computeDigest(ImutAVLTree* L, ImutAVLTree* R, value_type_ref V) { 00298 uint32_t digest = 0; 00299 00300 if (L) 00301 digest += L->computeDigest(); 00302 00303 // Compute digest of stored data. 00304 FoldingSetNodeID ID; 00305 ImutInfo::Profile(ID,V); 00306 digest += ID.ComputeHash(); 00307 00308 if (R) 00309 digest += R->computeDigest(); 00310 00311 return digest; 00312 } 00313 00314 inline uint32_t computeDigest() { 00315 // Check the lowest bit to determine if digest has actually been 00316 // pre-computed. 00317 if (hasCachedDigest()) 00318 return digest; 00319 00320 uint32_t X = computeDigest(getLeft(), getRight(), getValue()); 00321 digest = X; 00322 markedCachedDigest(); 00323 return X; 00324 } 00325 00326 //===----------------------------------------------------===// 00327 // Reference count operations. 00328 //===----------------------------------------------------===// 00329 00330 public: 00331 void retain() { ++refCount; } 00332 void release() { 00333 assert(refCount > 0); 00334 if (--refCount == 0) 00335 destroy(); 00336 } 00337 void destroy() { 00338 if (left) 00339 left->release(); 00340 if (right) 00341 right->release(); 00342 if (IsCanonicalized) { 00343 if (next) 00344 next->prev = prev; 00345 00346 if (prev) 00347 prev->next = next; 00348 else 00349 factory->Cache[factory->maskCacheIndex(computeDigest())] = next; 00350 } 00351 00352 // We need to clear the mutability bit in case we are 00353 // destroying the node as part of a sweep in ImutAVLFactory::recoverNodes(). 00354 IsMutable = false; 00355 factory->freeNodes.push_back(this); 00356 } 00357 }; 00358 00359 //===----------------------------------------------------------------------===// 00360 // Immutable AVL-Tree Factory class. 00361 //===----------------------------------------------------------------------===// 00362 00363 template <typename ImutInfo > 00364 class ImutAVLFactory { 00365 friend class ImutAVLTree<ImutInfo>; 00366 typedef ImutAVLTree<ImutInfo> TreeTy; 00367 typedef typename TreeTy::value_type_ref value_type_ref; 00368 typedef typename TreeTy::key_type_ref key_type_ref; 00369 00370 typedef DenseMap<unsigned, TreeTy*> CacheTy; 00371 00372 CacheTy Cache; 00373 uintptr_t Allocator; 00374 std::vector<TreeTy*> createdNodes; 00375 std::vector<TreeTy*> freeNodes; 00376 00377 bool ownsAllocator() const { 00378 return Allocator & 0x1 ? false : true; 00379 } 00380 00381 BumpPtrAllocator& getAllocator() const { 00382 return *reinterpret_cast<BumpPtrAllocator*>(Allocator & ~0x1); 00383 } 00384 00385 //===--------------------------------------------------===// 00386 // Public interface. 00387 //===--------------------------------------------------===// 00388 00389 public: 00390 ImutAVLFactory() 00391 : Allocator(reinterpret_cast<uintptr_t>(new BumpPtrAllocator())) {} 00392 00393 ImutAVLFactory(BumpPtrAllocator& Alloc) 00394 : Allocator(reinterpret_cast<uintptr_t>(&Alloc) | 0x1) {} 00395 00396 ~ImutAVLFactory() { 00397 if (ownsAllocator()) delete &getAllocator(); 00398 } 00399 00400 TreeTy* add(TreeTy* T, value_type_ref V) { 00401 T = add_internal(V,T); 00402 markImmutable(T); 00403 recoverNodes(); 00404 return T; 00405 } 00406 00407 TreeTy* remove(TreeTy* T, key_type_ref V) { 00408 T = remove_internal(V,T); 00409 markImmutable(T); 00410 recoverNodes(); 00411 return T; 00412 } 00413 00414 TreeTy* getEmptyTree() const { return NULL; } 00415 00416 protected: 00417 00418 //===--------------------------------------------------===// 00419 // A bunch of quick helper functions used for reasoning 00420 // about the properties of trees and their children. 00421 // These have succinct names so that the balancing code 00422 // is as terse (and readable) as possible. 00423 //===--------------------------------------------------===// 00424 00425 bool isEmpty(TreeTy* T) const { return !T; } 00426 unsigned getHeight(TreeTy* T) const { return T ? T->getHeight() : 0; } 00427 TreeTy* getLeft(TreeTy* T) const { return T->getLeft(); } 00428 TreeTy* getRight(TreeTy* T) const { return T->getRight(); } 00429 value_type_ref getValue(TreeTy* T) const { return T->value; } 00430 00431 // Make sure the index is not the Tombstone or Entry key of the DenseMap. 00432 static inline unsigned maskCacheIndex(unsigned I) { 00433 return (I & ~0x02); 00434 } 00435 00436 unsigned incrementHeight(TreeTy* L, TreeTy* R) const { 00437 unsigned hl = getHeight(L); 00438 unsigned hr = getHeight(R); 00439 return (hl > hr ? hl : hr) + 1; 00440 } 00441 00442 static bool compareTreeWithSection(TreeTy* T, 00443 typename TreeTy::iterator& TI, 00444 typename TreeTy::iterator& TE) { 00445 typename TreeTy::iterator I = T->begin(), E = T->end(); 00446 for ( ; I!=E ; ++I, ++TI) { 00447 if (TI == TE || !I->isElementEqual(*TI)) 00448 return false; 00449 } 00450 return true; 00451 } 00452 00453 //===--------------------------------------------------===// 00454 // "createNode" is used to generate new tree roots that link 00455 // to other trees. The functon may also simply move links 00456 // in an existing root if that root is still marked mutable. 00457 // This is necessary because otherwise our balancing code 00458 // would leak memory as it would create nodes that are 00459 // then discarded later before the finished tree is 00460 // returned to the caller. 00461 //===--------------------------------------------------===// 00462 00463 TreeTy* createNode(TreeTy* L, value_type_ref V, TreeTy* R) { 00464 BumpPtrAllocator& A = getAllocator(); 00465 TreeTy* T; 00466 if (!freeNodes.empty()) { 00467 T = freeNodes.back(); 00468 freeNodes.pop_back(); 00469 assert(T != L); 00470 assert(T != R); 00471 } else { 00472 T = (TreeTy*) A.Allocate<TreeTy>(); 00473 } 00474 new (T) TreeTy(this, L, R, V, incrementHeight(L,R)); 00475 createdNodes.push_back(T); 00476 return T; 00477 } 00478 00479 TreeTy* createNode(TreeTy* newLeft, TreeTy* oldTree, TreeTy* newRight) { 00480 return createNode(newLeft, getValue(oldTree), newRight); 00481 } 00482 00483 void recoverNodes() { 00484 for (unsigned i = 0, n = createdNodes.size(); i < n; ++i) { 00485 TreeTy *N = createdNodes[i]; 00486 if (N->isMutable() && N->refCount == 0) 00487 N->destroy(); 00488 } 00489 createdNodes.clear(); 00490 } 00491 00492 /// balanceTree - Used by add_internal and remove_internal to 00493 /// balance a newly created tree. 00494 TreeTy* balanceTree(TreeTy* L, value_type_ref V, TreeTy* R) { 00495 unsigned hl = getHeight(L); 00496 unsigned hr = getHeight(R); 00497 00498 if (hl > hr + 2) { 00499 assert(!isEmpty(L) && "Left tree cannot be empty to have a height >= 2"); 00500 00501 TreeTy *LL = getLeft(L); 00502 TreeTy *LR = getRight(L); 00503 00504 if (getHeight(LL) >= getHeight(LR)) 00505 return createNode(LL, L, createNode(LR,V,R)); 00506 00507 assert(!isEmpty(LR) && "LR cannot be empty because it has a height >= 1"); 00508 00509 TreeTy *LRL = getLeft(LR); 00510 TreeTy *LRR = getRight(LR); 00511 00512 return createNode(createNode(LL,L,LRL), LR, createNode(LRR,V,R)); 00513 } 00514 00515 if (hr > hl + 2) { 00516 assert(!isEmpty(R) && "Right tree cannot be empty to have a height >= 2"); 00517 00518 TreeTy *RL = getLeft(R); 00519 TreeTy *RR = getRight(R); 00520 00521 if (getHeight(RR) >= getHeight(RL)) 00522 return createNode(createNode(L,V,RL), R, RR); 00523 00524 assert(!isEmpty(RL) && "RL cannot be empty because it has a height >= 1"); 00525 00526 TreeTy *RLL = getLeft(RL); 00527 TreeTy *RLR = getRight(RL); 00528 00529 return createNode(createNode(L,V,RLL), RL, createNode(RLR,R,RR)); 00530 } 00531 00532 return createNode(L,V,R); 00533 } 00534 00535 /// add_internal - Creates a new tree that includes the specified 00536 /// data and the data from the original tree. If the original tree 00537 /// already contained the data item, the original tree is returned. 00538 TreeTy* add_internal(value_type_ref V, TreeTy* T) { 00539 if (isEmpty(T)) 00540 return createNode(T, V, T); 00541 assert(!T->isMutable()); 00542 00543 key_type_ref K = ImutInfo::KeyOfValue(V); 00544 key_type_ref KCurrent = ImutInfo::KeyOfValue(getValue(T)); 00545 00546 if (ImutInfo::isEqual(K,KCurrent)) 00547 return createNode(getLeft(T), V, getRight(T)); 00548 else if (ImutInfo::isLess(K,KCurrent)) 00549 return balanceTree(add_internal(V, getLeft(T)), getValue(T), getRight(T)); 00550 else 00551 return balanceTree(getLeft(T), getValue(T), add_internal(V, getRight(T))); 00552 } 00553 00554 /// remove_internal - Creates a new tree that includes all the data 00555 /// from the original tree except the specified data. If the 00556 /// specified data did not exist in the original tree, the original 00557 /// tree is returned. 00558 TreeTy* remove_internal(key_type_ref K, TreeTy* T) { 00559 if (isEmpty(T)) 00560 return T; 00561 00562 assert(!T->isMutable()); 00563 00564 key_type_ref KCurrent = ImutInfo::KeyOfValue(getValue(T)); 00565 00566 if (ImutInfo::isEqual(K,KCurrent)) { 00567 return combineTrees(getLeft(T), getRight(T)); 00568 } else if (ImutInfo::isLess(K,KCurrent)) { 00569 return balanceTree(remove_internal(K, getLeft(T)), 00570 getValue(T), getRight(T)); 00571 } else { 00572 return balanceTree(getLeft(T), getValue(T), 00573 remove_internal(K, getRight(T))); 00574 } 00575 } 00576 00577 TreeTy* combineTrees(TreeTy* L, TreeTy* R) { 00578 if (isEmpty(L)) 00579 return R; 00580 if (isEmpty(R)) 00581 return L; 00582 TreeTy* OldNode; 00583 TreeTy* newRight = removeMinBinding(R,OldNode); 00584 return balanceTree(L, getValue(OldNode), newRight); 00585 } 00586 00587 TreeTy* removeMinBinding(TreeTy* T, TreeTy*& Noderemoved) { 00588 assert(!isEmpty(T)); 00589 if (isEmpty(getLeft(T))) { 00590 Noderemoved = T; 00591 return getRight(T); 00592 } 00593 return balanceTree(removeMinBinding(getLeft(T), Noderemoved), 00594 getValue(T), getRight(T)); 00595 } 00596 00597 /// markImmutable - Clears the mutable bits of a root and all of its 00598 /// descendants. 00599 void markImmutable(TreeTy* T) { 00600 if (!T || !T->isMutable()) 00601 return; 00602 T->markImmutable(); 00603 markImmutable(getLeft(T)); 00604 markImmutable(getRight(T)); 00605 } 00606 00607 public: 00608 TreeTy *getCanonicalTree(TreeTy *TNew) { 00609 if (!TNew) 00610 return 0; 00611 00612 if (TNew->IsCanonicalized) 00613 return TNew; 00614 00615 // Search the hashtable for another tree with the same digest, and 00616 // if find a collision compare those trees by their contents. 00617 unsigned digest = TNew->computeDigest(); 00618 TreeTy *&entry = Cache[maskCacheIndex(digest)]; 00619 do { 00620 if (!entry) 00621 break; 00622 for (TreeTy *T = entry ; T != 0; T = T->next) { 00623 // Compare the Contents('T') with Contents('TNew') 00624 typename TreeTy::iterator TI = T->begin(), TE = T->end(); 00625 if (!compareTreeWithSection(TNew, TI, TE)) 00626 continue; 00627 if (TI != TE) 00628 continue; // T has more contents than TNew. 00629 // Trees did match! Return 'T'. 00630 if (TNew->refCount == 0) 00631 TNew->destroy(); 00632 return T; 00633 } 00634 entry->prev = TNew; 00635 TNew->next = entry; 00636 } 00637 while (false); 00638 00639 entry = TNew; 00640 TNew->IsCanonicalized = true; 00641 return TNew; 00642 } 00643 }; 00644 00645 //===----------------------------------------------------------------------===// 00646 // Immutable AVL-Tree Iterators. 00647 //===----------------------------------------------------------------------===// 00648 00649 template <typename ImutInfo> 00650 class ImutAVLTreeGenericIterator { 00651 SmallVector<uintptr_t,20> stack; 00652 public: 00653 enum VisitFlag { VisitedNone=0x0, VisitedLeft=0x1, VisitedRight=0x3, 00654 Flags=0x3 }; 00655 00656 typedef ImutAVLTree<ImutInfo> TreeTy; 00657 typedef ImutAVLTreeGenericIterator<ImutInfo> _Self; 00658 00659 inline ImutAVLTreeGenericIterator() {} 00660 inline ImutAVLTreeGenericIterator(const TreeTy* Root) { 00661 if (Root) stack.push_back(reinterpret_cast<uintptr_t>(Root)); 00662 } 00663 00664 TreeTy* operator*() const { 00665 assert(!stack.empty()); 00666 return reinterpret_cast<TreeTy*>(stack.back() & ~Flags); 00667 } 00668 00669 uintptr_t getVisitState() const { 00670 assert(!stack.empty()); 00671 return stack.back() & Flags; 00672 } 00673 00674 00675 bool atEnd() const { return stack.empty(); } 00676 00677 bool atBeginning() const { 00678 return stack.size() == 1 && getVisitState() == VisitedNone; 00679 } 00680 00681 void skipToParent() { 00682 assert(!stack.empty()); 00683 stack.pop_back(); 00684 if (stack.empty()) 00685 return; 00686 switch (getVisitState()) { 00687 case VisitedNone: 00688 stack.back() |= VisitedLeft; 00689 break; 00690 case VisitedLeft: 00691 stack.back() |= VisitedRight; 00692 break; 00693 default: 00694 llvm_unreachable("Unreachable."); 00695 } 00696 } 00697 00698 inline bool operator==(const _Self& x) const { 00699 if (stack.size() != x.stack.size()) 00700 return false; 00701 for (unsigned i = 0 ; i < stack.size(); i++) 00702 if (stack[i] != x.stack[i]) 00703 return false; 00704 return true; 00705 } 00706 00707 inline bool operator!=(const _Self& x) const { return !operator==(x); } 00708 00709 _Self& operator++() { 00710 assert(!stack.empty()); 00711 TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags); 00712 assert(Current); 00713 switch (getVisitState()) { 00714 case VisitedNone: 00715 if (TreeTy* L = Current->getLeft()) 00716 stack.push_back(reinterpret_cast<uintptr_t>(L)); 00717 else 00718 stack.back() |= VisitedLeft; 00719 break; 00720 case VisitedLeft: 00721 if (TreeTy* R = Current->getRight()) 00722 stack.push_back(reinterpret_cast<uintptr_t>(R)); 00723 else 00724 stack.back() |= VisitedRight; 00725 break; 00726 case VisitedRight: 00727 skipToParent(); 00728 break; 00729 default: 00730 llvm_unreachable("Unreachable."); 00731 } 00732 return *this; 00733 } 00734 00735 _Self& operator--() { 00736 assert(!stack.empty()); 00737 TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags); 00738 assert(Current); 00739 switch (getVisitState()) { 00740 case VisitedNone: 00741 stack.pop_back(); 00742 break; 00743 case VisitedLeft: 00744 stack.back() &= ~Flags; // Set state to "VisitedNone." 00745 if (TreeTy* L = Current->getLeft()) 00746 stack.push_back(reinterpret_cast<uintptr_t>(L) | VisitedRight); 00747 break; 00748 case VisitedRight: 00749 stack.back() &= ~Flags; 00750 stack.back() |= VisitedLeft; 00751 if (TreeTy* R = Current->getRight()) 00752 stack.push_back(reinterpret_cast<uintptr_t>(R) | VisitedRight); 00753 break; 00754 default: 00755 llvm_unreachable("Unreachable."); 00756 } 00757 return *this; 00758 } 00759 }; 00760 00761 template <typename ImutInfo> 00762 class ImutAVLTreeInOrderIterator { 00763 typedef ImutAVLTreeGenericIterator<ImutInfo> InternalIteratorTy; 00764 InternalIteratorTy InternalItr; 00765 00766 public: 00767 typedef ImutAVLTree<ImutInfo> TreeTy; 00768 typedef ImutAVLTreeInOrderIterator<ImutInfo> _Self; 00769 00770 ImutAVLTreeInOrderIterator(const TreeTy* Root) : InternalItr(Root) { 00771 if (Root) operator++(); // Advance to first element. 00772 } 00773 00774 ImutAVLTreeInOrderIterator() : InternalItr() {} 00775 00776 inline bool operator==(const _Self& x) const { 00777 return InternalItr == x.InternalItr; 00778 } 00779 00780 inline bool operator!=(const _Self& x) const { return !operator==(x); } 00781 00782 inline TreeTy* operator*() const { return *InternalItr; } 00783 inline TreeTy* operator->() const { return *InternalItr; } 00784 00785 inline _Self& operator++() { 00786 do ++InternalItr; 00787 while (!InternalItr.atEnd() && 00788 InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft); 00789 00790 return *this; 00791 } 00792 00793 inline _Self& operator--() { 00794 do --InternalItr; 00795 while (!InternalItr.atBeginning() && 00796 InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft); 00797 00798 return *this; 00799 } 00800 00801 inline void skipSubTree() { 00802 InternalItr.skipToParent(); 00803 00804 while (!InternalItr.atEnd() && 00805 InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft) 00806 ++InternalItr; 00807 } 00808 }; 00809 00810 //===----------------------------------------------------------------------===// 00811 // Trait classes for Profile information. 00812 //===----------------------------------------------------------------------===// 00813 00814 /// Generic profile template. The default behavior is to invoke the 00815 /// profile method of an object. Specializations for primitive integers 00816 /// and generic handling of pointers is done below. 00817 template <typename T> 00818 struct ImutProfileInfo { 00819 typedef const T value_type; 00820 typedef const T& value_type_ref; 00821 00822 static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) { 00823 FoldingSetTrait<T>::Profile(X,ID); 00824 } 00825 }; 00826 00827 /// Profile traits for integers. 00828 template <typename T> 00829 struct ImutProfileInteger { 00830 typedef const T value_type; 00831 typedef const T& value_type_ref; 00832 00833 static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) { 00834 ID.AddInteger(X); 00835 } 00836 }; 00837 00838 #define PROFILE_INTEGER_INFO(X)\ 00839 template<> struct ImutProfileInfo<X> : ImutProfileInteger<X> {}; 00840 00841 PROFILE_INTEGER_INFO(char) 00842 PROFILE_INTEGER_INFO(unsigned char) 00843 PROFILE_INTEGER_INFO(short) 00844 PROFILE_INTEGER_INFO(unsigned short) 00845 PROFILE_INTEGER_INFO(unsigned) 00846 PROFILE_INTEGER_INFO(signed) 00847 PROFILE_INTEGER_INFO(long) 00848 PROFILE_INTEGER_INFO(unsigned long) 00849 PROFILE_INTEGER_INFO(long long) 00850 PROFILE_INTEGER_INFO(unsigned long long) 00851 00852 #undef PROFILE_INTEGER_INFO 00853 00854 /// Generic profile trait for pointer types. We treat pointers as 00855 /// references to unique objects. 00856 template <typename T> 00857 struct ImutProfileInfo<T*> { 00858 typedef const T* value_type; 00859 typedef value_type value_type_ref; 00860 00861 static inline void Profile(FoldingSetNodeID &ID, value_type_ref X) { 00862 ID.AddPointer(X); 00863 } 00864 }; 00865 00866 //===----------------------------------------------------------------------===// 00867 // Trait classes that contain element comparison operators and type 00868 // definitions used by ImutAVLTree, ImmutableSet, and ImmutableMap. These 00869 // inherit from the profile traits (ImutProfileInfo) to include operations 00870 // for element profiling. 00871 //===----------------------------------------------------------------------===// 00872 00873 00874 /// ImutContainerInfo - Generic definition of comparison operations for 00875 /// elements of immutable containers that defaults to using 00876 /// std::equal_to<> and std::less<> to perform comparison of elements. 00877 template <typename T> 00878 struct ImutContainerInfo : public ImutProfileInfo<T> { 00879 typedef typename ImutProfileInfo<T>::value_type value_type; 00880 typedef typename ImutProfileInfo<T>::value_type_ref value_type_ref; 00881 typedef value_type key_type; 00882 typedef value_type_ref key_type_ref; 00883 typedef bool data_type; 00884 typedef bool data_type_ref; 00885 00886 static inline key_type_ref KeyOfValue(value_type_ref D) { return D; } 00887 static inline data_type_ref DataOfValue(value_type_ref) { return true; } 00888 00889 static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) { 00890 return std::equal_to<key_type>()(LHS,RHS); 00891 } 00892 00893 static inline bool isLess(key_type_ref LHS, key_type_ref RHS) { 00894 return std::less<key_type>()(LHS,RHS); 00895 } 00896 00897 static inline bool isDataEqual(data_type_ref,data_type_ref) { return true; } 00898 }; 00899 00900 /// ImutContainerInfo - Specialization for pointer values to treat pointers 00901 /// as references to unique objects. Pointers are thus compared by 00902 /// their addresses. 00903 template <typename T> 00904 struct ImutContainerInfo<T*> : public ImutProfileInfo<T*> { 00905 typedef typename ImutProfileInfo<T*>::value_type value_type; 00906 typedef typename ImutProfileInfo<T*>::value_type_ref value_type_ref; 00907 typedef value_type key_type; 00908 typedef value_type_ref key_type_ref; 00909 typedef bool data_type; 00910 typedef bool data_type_ref; 00911 00912 static inline key_type_ref KeyOfValue(value_type_ref D) { return D; } 00913 static inline data_type_ref DataOfValue(value_type_ref) { return true; } 00914 00915 static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) { 00916 return LHS == RHS; 00917 } 00918 00919 static inline bool isLess(key_type_ref LHS, key_type_ref RHS) { 00920 return LHS < RHS; 00921 } 00922 00923 static inline bool isDataEqual(data_type_ref,data_type_ref) { return true; } 00924 }; 00925 00926 //===----------------------------------------------------------------------===// 00927 // Immutable Set 00928 //===----------------------------------------------------------------------===// 00929 00930 template <typename ValT, typename ValInfo = ImutContainerInfo<ValT> > 00931 class ImmutableSet { 00932 public: 00933 typedef typename ValInfo::value_type value_type; 00934 typedef typename ValInfo::value_type_ref value_type_ref; 00935 typedef ImutAVLTree<ValInfo> TreeTy; 00936 00937 private: 00938 TreeTy *Root; 00939 00940 public: 00941 /// Constructs a set from a pointer to a tree root. In general one 00942 /// should use a Factory object to create sets instead of directly 00943 /// invoking the constructor, but there are cases where make this 00944 /// constructor public is useful. 00945 explicit ImmutableSet(TreeTy* R) : Root(R) { 00946 if (Root) { Root->retain(); } 00947 } 00948 ImmutableSet(const ImmutableSet &X) : Root(X.Root) { 00949 if (Root) { Root->retain(); } 00950 } 00951 ImmutableSet &operator=(const ImmutableSet &X) { 00952 if (Root != X.Root) { 00953 if (X.Root) { X.Root->retain(); } 00954 if (Root) { Root->release(); } 00955 Root = X.Root; 00956 } 00957 return *this; 00958 } 00959 ~ImmutableSet() { 00960 if (Root) { Root->release(); } 00961 } 00962 00963 class Factory { 00964 typename TreeTy::Factory F; 00965 const bool Canonicalize; 00966 00967 public: 00968 Factory(bool canonicalize = true) 00969 : Canonicalize(canonicalize) {} 00970 00971 Factory(BumpPtrAllocator& Alloc, bool canonicalize = true) 00972 : F(Alloc), Canonicalize(canonicalize) {} 00973 00974 /// getEmptySet - Returns an immutable set that contains no elements. 00975 ImmutableSet getEmptySet() { 00976 return ImmutableSet(F.getEmptyTree()); 00977 } 00978 00979 /// add - Creates a new immutable set that contains all of the values 00980 /// of the original set with the addition of the specified value. If 00981 /// the original set already included the value, then the original set is 00982 /// returned and no memory is allocated. The time and space complexity 00983 /// of this operation is logarithmic in the size of the original set. 00984 /// The memory allocated to represent the set is released when the 00985 /// factory object that created the set is destroyed. 00986 ImmutableSet add(ImmutableSet Old, value_type_ref V) { 00987 TreeTy *NewT = F.add(Old.Root, V); 00988 return ImmutableSet(Canonicalize ? F.getCanonicalTree(NewT) : NewT); 00989 } 00990 00991 /// remove - Creates a new immutable set that contains all of the values 00992 /// of the original set with the exception of the specified value. If 00993 /// the original set did not contain the value, the original set is 00994 /// returned and no memory is allocated. The time and space complexity 00995 /// of this operation is logarithmic in the size of the original set. 00996 /// The memory allocated to represent the set is released when the 00997 /// factory object that created the set is destroyed. 00998 ImmutableSet remove(ImmutableSet Old, value_type_ref V) { 00999 TreeTy *NewT = F.remove(Old.Root, V); 01000 return ImmutableSet(Canonicalize ? F.getCanonicalTree(NewT) : NewT); 01001 } 01002 01003 BumpPtrAllocator& getAllocator() { return F.getAllocator(); } 01004 01005 typename TreeTy::Factory *getTreeFactory() const { 01006 return const_cast<typename TreeTy::Factory *>(&F); 01007 } 01008 01009 private: 01010 Factory(const Factory& RHS) LLVM_DELETED_FUNCTION; 01011 void operator=(const Factory& RHS) LLVM_DELETED_FUNCTION; 01012 }; 01013 01014 friend class Factory; 01015 01016 /// Returns true if the set contains the specified value. 01017 bool contains(value_type_ref V) const { 01018 return Root ? Root->contains(V) : false; 01019 } 01020 01021 bool operator==(const ImmutableSet &RHS) const { 01022 return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root; 01023 } 01024 01025 bool operator!=(const ImmutableSet &RHS) const { 01026 return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root; 01027 } 01028 01029 TreeTy *getRoot() { 01030 if (Root) { Root->retain(); } 01031 return Root; 01032 } 01033 01034 TreeTy *getRootWithoutRetain() const { 01035 return Root; 01036 } 01037 01038 /// isEmpty - Return true if the set contains no elements. 01039 bool isEmpty() const { return !Root; } 01040 01041 /// isSingleton - Return true if the set contains exactly one element. 01042 /// This method runs in constant time. 01043 bool isSingleton() const { return getHeight() == 1; } 01044 01045 template <typename Callback> 01046 void foreach(Callback& C) { if (Root) Root->foreach(C); } 01047 01048 template <typename Callback> 01049 void foreach() { if (Root) { Callback C; Root->foreach(C); } } 01050 01051 //===--------------------------------------------------===// 01052 // Iterators. 01053 //===--------------------------------------------------===// 01054 01055 class iterator { 01056 typename TreeTy::iterator itr; 01057 01058 iterator() {} 01059 iterator(TreeTy* t) : itr(t) {} 01060 friend class ImmutableSet<ValT,ValInfo>; 01061 01062 public: 01063 typedef typename ImmutableSet<ValT,ValInfo>::value_type value_type; 01064 typedef typename ImmutableSet<ValT,ValInfo>::value_type_ref reference; 01065 typedef typename iterator::value_type *pointer; 01066 typedef std::bidirectional_iterator_tag iterator_category; 01067 01068 typename iterator::reference operator*() const { return itr->getValue(); } 01069 typename iterator::pointer operator->() const { return &(operator*()); } 01070 01071 iterator& operator++() { ++itr; return *this; } 01072 iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; } 01073 iterator& operator--() { --itr; return *this; } 01074 iterator operator--(int) { iterator tmp(*this); --itr; return tmp; } 01075 01076 bool operator==(const iterator& RHS) const { return RHS.itr == itr; } 01077 bool operator!=(const iterator& RHS) const { return RHS.itr != itr; } 01078 }; 01079 01080 iterator begin() const { return iterator(Root); } 01081 iterator end() const { return iterator(); } 01082 01083 //===--------------------------------------------------===// 01084 // Utility methods. 01085 //===--------------------------------------------------===// 01086 01087 unsigned getHeight() const { return Root ? Root->getHeight() : 0; } 01088 01089 static inline void Profile(FoldingSetNodeID& ID, const ImmutableSet& S) { 01090 ID.AddPointer(S.Root); 01091 } 01092 01093 inline void Profile(FoldingSetNodeID& ID) const { 01094 return Profile(ID,*this); 01095 } 01096 01097 //===--------------------------------------------------===// 01098 // For testing. 01099 //===--------------------------------------------------===// 01100 01101 void validateTree() const { if (Root) Root->validateTree(); } 01102 }; 01103 01104 // NOTE: This may some day replace the current ImmutableSet. 01105 template <typename ValT, typename ValInfo = ImutContainerInfo<ValT> > 01106 class ImmutableSetRef { 01107 public: 01108 typedef typename ValInfo::value_type value_type; 01109 typedef typename ValInfo::value_type_ref value_type_ref; 01110 typedef ImutAVLTree<ValInfo> TreeTy; 01111 typedef typename TreeTy::Factory FactoryTy; 01112 01113 private: 01114 TreeTy *Root; 01115 FactoryTy *Factory; 01116 01117 public: 01118 /// Constructs a set from a pointer to a tree root. In general one 01119 /// should use a Factory object to create sets instead of directly 01120 /// invoking the constructor, but there are cases where make this 01121 /// constructor public is useful. 01122 explicit ImmutableSetRef(TreeTy* R, FactoryTy *F) 01123 : Root(R), 01124 Factory(F) { 01125 if (Root) { Root->retain(); } 01126 } 01127 ImmutableSetRef(const ImmutableSetRef &X) 01128 : Root(X.Root), 01129 Factory(X.Factory) { 01130 if (Root) { Root->retain(); } 01131 } 01132 ImmutableSetRef &operator=(const ImmutableSetRef &X) { 01133 if (Root != X.Root) { 01134 if (X.Root) { X.Root->retain(); } 01135 if (Root) { Root->release(); } 01136 Root = X.Root; 01137 Factory = X.Factory; 01138 } 01139 return *this; 01140 } 01141 ~ImmutableSetRef() { 01142 if (Root) { Root->release(); } 01143 } 01144 01145 static inline ImmutableSetRef getEmptySet(FactoryTy *F) { 01146 return ImmutableSetRef(0, F); 01147 } 01148 01149 ImmutableSetRef add(value_type_ref V) { 01150 return ImmutableSetRef(Factory->add(Root, V), Factory); 01151 } 01152 01153 ImmutableSetRef remove(value_type_ref V) { 01154 return ImmutableSetRef(Factory->remove(Root, V), Factory); 01155 } 01156 01157 /// Returns true if the set contains the specified value. 01158 bool contains(value_type_ref V) const { 01159 return Root ? Root->contains(V) : false; 01160 } 01161 01162 ImmutableSet<ValT> asImmutableSet(bool canonicalize = true) const { 01163 return ImmutableSet<ValT>(canonicalize ? 01164 Factory->getCanonicalTree(Root) : Root); 01165 } 01166 01167 TreeTy *getRootWithoutRetain() const { 01168 return Root; 01169 } 01170 01171 bool operator==(const ImmutableSetRef &RHS) const { 01172 return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root; 01173 } 01174 01175 bool operator!=(const ImmutableSetRef &RHS) const { 01176 return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root; 01177 } 01178 01179 /// isEmpty - Return true if the set contains no elements. 01180 bool isEmpty() const { return !Root; } 01181 01182 /// isSingleton - Return true if the set contains exactly one element. 01183 /// This method runs in constant time. 01184 bool isSingleton() const { return getHeight() == 1; } 01185 01186 //===--------------------------------------------------===// 01187 // Iterators. 01188 //===--------------------------------------------------===// 01189 01190 class iterator { 01191 typename TreeTy::iterator itr; 01192 iterator(TreeTy* t) : itr(t) {} 01193 friend class ImmutableSetRef<ValT,ValInfo>; 01194 public: 01195 iterator() {} 01196 inline value_type_ref operator*() const { return itr->getValue(); } 01197 inline iterator& operator++() { ++itr; return *this; } 01198 inline iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; } 01199 inline iterator& operator--() { --itr; return *this; } 01200 inline iterator operator--(int) { iterator tmp(*this); --itr; return tmp; } 01201 inline bool operator==(const iterator& RHS) const { return RHS.itr == itr; } 01202 inline bool operator!=(const iterator& RHS) const { return RHS.itr != itr; } 01203 inline value_type *operator->() const { return &(operator*()); } 01204 }; 01205 01206 iterator begin() const { return iterator(Root); } 01207 iterator end() const { return iterator(); } 01208 01209 //===--------------------------------------------------===// 01210 // Utility methods. 01211 //===--------------------------------------------------===// 01212 01213 unsigned getHeight() const { return Root ? Root->getHeight() : 0; } 01214 01215 static inline void Profile(FoldingSetNodeID& ID, const ImmutableSetRef& S) { 01216 ID.AddPointer(S.Root); 01217 } 01218 01219 inline void Profile(FoldingSetNodeID& ID) const { 01220 return Profile(ID,*this); 01221 } 01222 01223 //===--------------------------------------------------===// 01224 // For testing. 01225 //===--------------------------------------------------===// 01226 01227 void validateTree() const { if (Root) Root->validateTree(); } 01228 }; 01229 01230 } // end namespace llvm 01231 01232 #endif