Home | History | Annotate | Line # | Download | only in ADT
      1 //===--- ImmutableSet.h - Immutable (functional) set interface --*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // This file defines the ImutAVLTree and ImmutableSet classes.
     10 //
     11 //===----------------------------------------------------------------------===//
     12 
     13 #ifndef LLVM_ADT_IMMUTABLESET_H
     14 #define LLVM_ADT_IMMUTABLESET_H
     15 
     16 #include "llvm/ADT/DenseMap.h"
     17 #include "llvm/ADT/FoldingSet.h"
     18 #include "llvm/ADT/IntrusiveRefCntPtr.h"
     19 #include "llvm/ADT/SmallVector.h"
     20 #include "llvm/ADT/iterator.h"
     21 #include "llvm/Support/Allocator.h"
     22 #include "llvm/Support/ErrorHandling.h"
     23 #include <cassert>
     24 #include <cstdint>
     25 #include <functional>
     26 #include <iterator>
     27 #include <new>
     28 #include <vector>
     29 
     30 namespace llvm {
     31 
     32 //===----------------------------------------------------------------------===//
     33 // Immutable AVL-Tree Definition.
     34 //===----------------------------------------------------------------------===//
     35 
     36 template <typename ImutInfo> class ImutAVLFactory;
     37 template <typename ImutInfo> class ImutIntervalAVLFactory;
     38 template <typename ImutInfo> class ImutAVLTreeInOrderIterator;
     39 template <typename ImutInfo> class ImutAVLTreeGenericIterator;
     40 
     41 template <typename ImutInfo >
     42 class ImutAVLTree {
     43 public:
     44   using key_type_ref = typename ImutInfo::key_type_ref;
     45   using value_type = typename ImutInfo::value_type;
     46   using value_type_ref = typename ImutInfo::value_type_ref;
     47   using Factory = ImutAVLFactory<ImutInfo>;
     48   using iterator = ImutAVLTreeInOrderIterator<ImutInfo>;
     49 
     50   friend class ImutAVLFactory<ImutInfo>;
     51   friend class ImutIntervalAVLFactory<ImutInfo>;
     52   friend class ImutAVLTreeGenericIterator<ImutInfo>;
     53 
     54   //===----------------------------------------------------===//
     55   // Public Interface.
     56   //===----------------------------------------------------===//
     57 
     58   /// Return a pointer to the left subtree.  This value
     59   ///  is NULL if there is no left subtree.
     60   ImutAVLTree *getLeft() const { return left; }
     61 
     62   /// Return a pointer to the right subtree.  This value is
     63   ///  NULL if there is no right subtree.
     64   ImutAVLTree *getRight() const { return right; }
     65 
     66   /// getHeight - Returns the height of the tree.  A tree with no subtrees
     67   ///  has a height of 1.
     68   unsigned getHeight() const { return height; }
     69 
     70   /// getValue - Returns the data value associated with the tree node.
     71   const value_type& getValue() const { return value; }
     72 
     73   /// find - Finds the subtree associated with the specified key value.
     74   ///  This method returns NULL if no matching subtree is found.
     75   ImutAVLTree* find(key_type_ref K) {
     76     ImutAVLTree *T = this;
     77     while (T) {
     78       key_type_ref CurrentKey = ImutInfo::KeyOfValue(T->getValue());
     79       if (ImutInfo::isEqual(K,CurrentKey))
     80         return T;
     81       else if (ImutInfo::isLess(K,CurrentKey))
     82         T = T->getLeft();
     83       else
     84         T = T->getRight();
     85     }
     86     return nullptr;
     87   }
     88 
     89   /// getMaxElement - Find the subtree associated with the highest ranged
     90   ///  key value.
     91   ImutAVLTree* getMaxElement() {
     92     ImutAVLTree *T = this;
     93     ImutAVLTree *Right = T->getRight();
     94     while (Right) { T = Right; Right = T->getRight(); }
     95     return T;
     96   }
     97 
     98   /// size - Returns the number of nodes in the tree, which includes
     99   ///  both leaves and non-leaf nodes.
    100   unsigned size() const {
    101     unsigned n = 1;
    102     if (const ImutAVLTree* L = getLeft())
    103       n += L->size();
    104     if (const ImutAVLTree* R = getRight())
    105       n += R->size();
    106     return n;
    107   }
    108 
    109   /// begin - Returns an iterator that iterates over the nodes of the tree
    110   ///  in an inorder traversal.  The returned iterator thus refers to the
    111   ///  the tree node with the minimum data element.
    112   iterator begin() const { return iterator(this); }
    113 
    114   /// end - Returns an iterator for the tree that denotes the end of an
    115   ///  inorder traversal.
    116   iterator end() const { return iterator(); }
    117 
    118   bool isElementEqual(value_type_ref V) const {
    119     // Compare the keys.
    120     if (!ImutInfo::isEqual(ImutInfo::KeyOfValue(getValue()),
    121                            ImutInfo::KeyOfValue(V)))
    122       return false;
    123 
    124     // Also compare the data values.
    125     if (!ImutInfo::isDataEqual(ImutInfo::DataOfValue(getValue()),
    126                                ImutInfo::DataOfValue(V)))
    127       return false;
    128 
    129     return true;
    130   }
    131 
    132   bool isElementEqual(const ImutAVLTree* RHS) const {
    133     return isElementEqual(RHS->getValue());
    134   }
    135 
    136   /// isEqual - Compares two trees for structural equality and returns true
    137   ///   if they are equal.  This worst case performance of this operation is
    138   //    linear in the sizes of the trees.
    139   bool isEqual(const ImutAVLTree& RHS) const {
    140     if (&RHS == this)
    141       return true;
    142 
    143     iterator LItr = begin(), LEnd = end();
    144     iterator RItr = RHS.begin(), REnd = RHS.end();
    145 
    146     while (LItr != LEnd && RItr != REnd) {
    147       if (&*LItr == &*RItr) {
    148         LItr.skipSubTree();
    149         RItr.skipSubTree();
    150         continue;
    151       }
    152 
    153       if (!LItr->isElementEqual(&*RItr))
    154         return false;
    155 
    156       ++LItr;
    157       ++RItr;
    158     }
    159 
    160     return LItr == LEnd && RItr == REnd;
    161   }
    162 
    163   /// isNotEqual - Compares two trees for structural inequality.  Performance
    164   ///  is the same is isEqual.
    165   bool isNotEqual(const ImutAVLTree& RHS) const { return !isEqual(RHS); }
    166 
    167   /// contains - Returns true if this tree contains a subtree (node) that
    168   ///  has an data element that matches the specified key.  Complexity
    169   ///  is logarithmic in the size of the tree.
    170   bool contains(key_type_ref K) { return (bool) find(K); }
    171 
    172   /// foreach - A member template the accepts invokes operator() on a functor
    173   ///  object (specified by Callback) for every node/subtree in the tree.
    174   ///  Nodes are visited using an inorder traversal.
    175   template <typename Callback>
    176   void foreach(Callback& C) {
    177     if (ImutAVLTree* L = getLeft())
    178       L->foreach(C);
    179 
    180     C(value);
    181 
    182     if (ImutAVLTree* R = getRight())
    183       R->foreach(C);
    184   }
    185 
    186   /// validateTree - A utility method that checks that the balancing and
    187   ///  ordering invariants of the tree are satisfied.  It is a recursive
    188   ///  method that returns the height of the tree, which is then consumed
    189   ///  by the enclosing validateTree call.  External callers should ignore the
    190   ///  return value.  An invalid tree will cause an assertion to fire in
    191   ///  a debug build.
    192   unsigned validateTree() const {
    193     unsigned HL = getLeft() ? getLeft()->validateTree() : 0;
    194     unsigned HR = getRight() ? getRight()->validateTree() : 0;
    195     (void) HL;
    196     (void) HR;
    197 
    198     assert(getHeight() == ( HL > HR ? HL : HR ) + 1
    199             && "Height calculation wrong");
    200 
    201     assert((HL > HR ? HL-HR : HR-HL) <= 2
    202            && "Balancing invariant violated");
    203 
    204     assert((!getLeft() ||
    205             ImutInfo::isLess(ImutInfo::KeyOfValue(getLeft()->getValue()),
    206                              ImutInfo::KeyOfValue(getValue()))) &&
    207            "Value in left child is not less that current value");
    208 
    209     assert((!getRight() ||
    210              ImutInfo::isLess(ImutInfo::KeyOfValue(getValue()),
    211                               ImutInfo::KeyOfValue(getRight()->getValue()))) &&
    212            "Current value is not less that value of right child");
    213 
    214     return getHeight();
    215   }
    216 
    217   //===----------------------------------------------------===//
    218   // Internal values.
    219   //===----------------------------------------------------===//
    220 
    221 private:
    222   Factory *factory;
    223   ImutAVLTree *left;
    224   ImutAVLTree *right;
    225   ImutAVLTree *prev = nullptr;
    226   ImutAVLTree *next = nullptr;
    227 
    228   unsigned height : 28;
    229   bool IsMutable : 1;
    230   bool IsDigestCached : 1;
    231   bool IsCanonicalized : 1;
    232 
    233   value_type value;
    234   uint32_t digest = 0;
    235   uint32_t refCount = 0;
    236 
    237   //===----------------------------------------------------===//
    238   // Internal methods (node manipulation; used by Factory).
    239   //===----------------------------------------------------===//
    240 
    241 private:
    242   /// ImutAVLTree - Internal constructor that is only called by
    243   ///   ImutAVLFactory.
    244   ImutAVLTree(Factory *f, ImutAVLTree* l, ImutAVLTree* r, value_type_ref v,
    245               unsigned height)
    246     : factory(f), left(l), right(r), height(height), IsMutable(true),
    247       IsDigestCached(false), IsCanonicalized(false), value(v)
    248   {
    249     if (left) left->retain();
    250     if (right) right->retain();
    251   }
    252 
    253   /// isMutable - Returns true if the left and right subtree references
    254   ///  (as well as height) can be changed.  If this method returns false,
    255   ///  the tree is truly immutable.  Trees returned from an ImutAVLFactory
    256   ///  object should always have this method return true.  Further, if this
    257   ///  method returns false for an instance of ImutAVLTree, all subtrees
    258   ///  will also have this method return false.  The converse is not true.
    259   bool isMutable() const { return IsMutable; }
    260 
    261   /// hasCachedDigest - Returns true if the digest for this tree is cached.
    262   ///  This can only be true if the tree is immutable.
    263   bool hasCachedDigest() const { return IsDigestCached; }
    264 
    265   //===----------------------------------------------------===//
    266   // Mutating operations.  A tree root can be manipulated as
    267   // long as its reference has not "escaped" from internal
    268   // methods of a factory object (see below).  When a tree
    269   // pointer is externally viewable by client code, the
    270   // internal "mutable bit" is cleared to mark the tree
    271   // immutable.  Note that a tree that still has its mutable
    272   // bit set may have children (subtrees) that are themselves
    273   // immutable.
    274   //===----------------------------------------------------===//
    275 
    276   /// markImmutable - Clears the mutable flag for a tree.  After this happens,
    277   ///   it is an error to call setLeft(), setRight(), and setHeight().
    278   void markImmutable() {
    279     assert(isMutable() && "Mutable flag already removed.");
    280     IsMutable = false;
    281   }
    282 
    283   /// markedCachedDigest - Clears the NoCachedDigest flag for a tree.
    284   void markedCachedDigest() {
    285     assert(!hasCachedDigest() && "NoCachedDigest flag already removed.");
    286     IsDigestCached = true;
    287   }
    288 
    289   /// setHeight - Changes the height of the tree.  Used internally by
    290   ///  ImutAVLFactory.
    291   void setHeight(unsigned h) {
    292     assert(isMutable() && "Only a mutable tree can have its height changed.");
    293     height = h;
    294   }
    295 
    296   static uint32_t computeDigest(ImutAVLTree *L, ImutAVLTree *R,
    297                                 value_type_ref V) {
    298     uint32_t digest = 0;
    299 
    300     if (L)
    301       digest += L->computeDigest();
    302 
    303     // Compute digest of stored data.
    304     FoldingSetNodeID ID;
    305     ImutInfo::Profile(ID,V);
    306     digest += ID.ComputeHash();
    307 
    308     if (R)
    309       digest += R->computeDigest();
    310 
    311     return digest;
    312   }
    313 
    314   uint32_t computeDigest() {
    315     // Check the lowest bit to determine if digest has actually been
    316     // pre-computed.
    317     if (hasCachedDigest())
    318       return digest;
    319 
    320     uint32_t X = computeDigest(getLeft(), getRight(), getValue());
    321     digest = X;
    322     markedCachedDigest();
    323     return X;
    324   }
    325 
    326   //===----------------------------------------------------===//
    327   // Reference count operations.
    328   //===----------------------------------------------------===//
    329 
    330 public:
    331   void retain() { ++refCount; }
    332 
    333   void release() {
    334     assert(refCount > 0);
    335     if (--refCount == 0)
    336       destroy();
    337   }
    338 
    339   void destroy() {
    340     if (left)
    341       left->release();
    342     if (right)
    343       right->release();
    344     if (IsCanonicalized) {
    345       if (next)
    346         next->prev = prev;
    347 
    348       if (prev)
    349         prev->next = next;
    350       else
    351         factory->Cache[factory->maskCacheIndex(computeDigest())] = next;
    352     }
    353 
    354     // We need to clear the mutability bit in case we are
    355     // destroying the node as part of a sweep in ImutAVLFactory::recoverNodes().
    356     IsMutable = false;
    357     factory->freeNodes.push_back(this);
    358   }
    359 };
    360 
    361 template <typename ImutInfo>
    362 struct IntrusiveRefCntPtrInfo<ImutAVLTree<ImutInfo>> {
    363   static void retain(ImutAVLTree<ImutInfo> *Tree) { Tree->retain(); }
    364   static void release(ImutAVLTree<ImutInfo> *Tree) { Tree->release(); }
    365 };
    366 
    367 //===----------------------------------------------------------------------===//
    368 // Immutable AVL-Tree Factory class.
    369 //===----------------------------------------------------------------------===//
    370 
    371 template <typename ImutInfo >
    372 class ImutAVLFactory {
    373   friend class ImutAVLTree<ImutInfo>;
    374 
    375   using TreeTy = ImutAVLTree<ImutInfo>;
    376   using value_type_ref = typename TreeTy::value_type_ref;
    377   using key_type_ref = typename TreeTy::key_type_ref;
    378   using CacheTy = DenseMap<unsigned, TreeTy*>;
    379 
    380   CacheTy Cache;
    381   uintptr_t Allocator;
    382   std::vector<TreeTy*> createdNodes;
    383   std::vector<TreeTy*> freeNodes;
    384 
    385   bool ownsAllocator() const {
    386     return (Allocator & 0x1) == 0;
    387   }
    388 
    389   BumpPtrAllocator& getAllocator() const {
    390     return *reinterpret_cast<BumpPtrAllocator*>(Allocator & ~0x1);
    391   }
    392 
    393   //===--------------------------------------------------===//
    394   // Public interface.
    395   //===--------------------------------------------------===//
    396 
    397 public:
    398   ImutAVLFactory()
    399     : Allocator(reinterpret_cast<uintptr_t>(new BumpPtrAllocator())) {}
    400 
    401   ImutAVLFactory(BumpPtrAllocator& Alloc)
    402     : Allocator(reinterpret_cast<uintptr_t>(&Alloc) | 0x1) {}
    403 
    404   ~ImutAVLFactory() {
    405     if (ownsAllocator()) delete &getAllocator();
    406   }
    407 
    408   TreeTy* add(TreeTy* T, value_type_ref V) {
    409     T = add_internal(V,T);
    410     markImmutable(T);
    411     recoverNodes();
    412     return T;
    413   }
    414 
    415   TreeTy* remove(TreeTy* T, key_type_ref V) {
    416     T = remove_internal(V,T);
    417     markImmutable(T);
    418     recoverNodes();
    419     return T;
    420   }
    421 
    422   TreeTy* getEmptyTree() const { return nullptr; }
    423 
    424 protected:
    425   //===--------------------------------------------------===//
    426   // A bunch of quick helper functions used for reasoning
    427   // about the properties of trees and their children.
    428   // These have succinct names so that the balancing code
    429   // is as terse (and readable) as possible.
    430   //===--------------------------------------------------===//
    431 
    432   bool            isEmpty(TreeTy* T) const { return !T; }
    433   unsigned        getHeight(TreeTy* T) const { return T ? T->getHeight() : 0; }
    434   TreeTy*         getLeft(TreeTy* T) const { return T->getLeft(); }
    435   TreeTy*         getRight(TreeTy* T) const { return T->getRight(); }
    436   value_type_ref  getValue(TreeTy* T) const { return T->value; }
    437 
    438   // Make sure the index is not the Tombstone or Entry key of the DenseMap.
    439   static unsigned maskCacheIndex(unsigned I) { return (I & ~0x02); }
    440 
    441   unsigned incrementHeight(TreeTy* L, TreeTy* R) const {
    442     unsigned hl = getHeight(L);
    443     unsigned hr = getHeight(R);
    444     return (hl > hr ? hl : hr) + 1;
    445   }
    446 
    447   static bool compareTreeWithSection(TreeTy* T,
    448                                      typename TreeTy::iterator& TI,
    449                                      typename TreeTy::iterator& TE) {
    450     typename TreeTy::iterator I = T->begin(), E = T->end();
    451     for ( ; I!=E ; ++I, ++TI) {
    452       if (TI == TE || !I->isElementEqual(&*TI))
    453         return false;
    454     }
    455     return true;
    456   }
    457 
    458   //===--------------------------------------------------===//
    459   // "createNode" is used to generate new tree roots that link
    460   // to other trees.  The function may also simply move links
    461   // in an existing root if that root is still marked mutable.
    462   // This is necessary because otherwise our balancing code
    463   // would leak memory as it would create nodes that are
    464   // then discarded later before the finished tree is
    465   // returned to the caller.
    466   //===--------------------------------------------------===//
    467 
    468   TreeTy* createNode(TreeTy* L, value_type_ref V, TreeTy* R) {
    469     BumpPtrAllocator& A = getAllocator();
    470     TreeTy* T;
    471     if (!freeNodes.empty()) {
    472       T = freeNodes.back();
    473       freeNodes.pop_back();
    474       assert(T != L);
    475       assert(T != R);
    476     } else {
    477       T = (TreeTy*) A.Allocate<TreeTy>();
    478     }
    479     new (T) TreeTy(this, L, R, V, incrementHeight(L,R));
    480     createdNodes.push_back(T);
    481     return T;
    482   }
    483 
    484   TreeTy* createNode(TreeTy* newLeft, TreeTy* oldTree, TreeTy* newRight) {
    485     return createNode(newLeft, getValue(oldTree), newRight);
    486   }
    487 
    488   void recoverNodes() {
    489     for (unsigned i = 0, n = createdNodes.size(); i < n; ++i) {
    490       TreeTy *N = createdNodes[i];
    491       if (N->isMutable() && N->refCount == 0)
    492         N->destroy();
    493     }
    494     createdNodes.clear();
    495   }
    496 
    497   /// balanceTree - Used by add_internal and remove_internal to
    498   ///  balance a newly created tree.
    499   TreeTy* balanceTree(TreeTy* L, value_type_ref V, TreeTy* R) {
    500     unsigned hl = getHeight(L);
    501     unsigned hr = getHeight(R);
    502 
    503     if (hl > hr + 2) {
    504       assert(!isEmpty(L) && "Left tree cannot be empty to have a height >= 2");
    505 
    506       TreeTy *LL = getLeft(L);
    507       TreeTy *LR = getRight(L);
    508 
    509       if (getHeight(LL) >= getHeight(LR))
    510         return createNode(LL, L, createNode(LR,V,R));
    511 
    512       assert(!isEmpty(LR) && "LR cannot be empty because it has a height >= 1");
    513 
    514       TreeTy *LRL = getLeft(LR);
    515       TreeTy *LRR = getRight(LR);
    516 
    517       return createNode(createNode(LL,L,LRL), LR, createNode(LRR,V,R));
    518     }
    519 
    520     if (hr > hl + 2) {
    521       assert(!isEmpty(R) && "Right tree cannot be empty to have a height >= 2");
    522 
    523       TreeTy *RL = getLeft(R);
    524       TreeTy *RR = getRight(R);
    525 
    526       if (getHeight(RR) >= getHeight(RL))
    527         return createNode(createNode(L,V,RL), R, RR);
    528 
    529       assert(!isEmpty(RL) && "RL cannot be empty because it has a height >= 1");
    530 
    531       TreeTy *RLL = getLeft(RL);
    532       TreeTy *RLR = getRight(RL);
    533 
    534       return createNode(createNode(L,V,RLL), RL, createNode(RLR,R,RR));
    535     }
    536 
    537     return createNode(L,V,R);
    538   }
    539 
    540   /// add_internal - Creates a new tree that includes the specified
    541   ///  data and the data from the original tree.  If the original tree
    542   ///  already contained the data item, the original tree is returned.
    543   TreeTy* add_internal(value_type_ref V, TreeTy* T) {
    544     if (isEmpty(T))
    545       return createNode(T, V, T);
    546     assert(!T->isMutable());
    547 
    548     key_type_ref K = ImutInfo::KeyOfValue(V);
    549     key_type_ref KCurrent = ImutInfo::KeyOfValue(getValue(T));
    550 
    551     if (ImutInfo::isEqual(K,KCurrent))
    552       return createNode(getLeft(T), V, getRight(T));
    553     else if (ImutInfo::isLess(K,KCurrent))
    554       return balanceTree(add_internal(V, getLeft(T)), getValue(T), getRight(T));
    555     else
    556       return balanceTree(getLeft(T), getValue(T), add_internal(V, getRight(T)));
    557   }
    558 
    559   /// remove_internal - Creates a new tree that includes all the data
    560   ///  from the original tree except the specified data.  If the
    561   ///  specified data did not exist in the original tree, the original
    562   ///  tree is returned.
    563   TreeTy* remove_internal(key_type_ref K, TreeTy* T) {
    564     if (isEmpty(T))
    565       return T;
    566 
    567     assert(!T->isMutable());
    568 
    569     key_type_ref KCurrent = ImutInfo::KeyOfValue(getValue(T));
    570 
    571     if (ImutInfo::isEqual(K,KCurrent)) {
    572       return combineTrees(getLeft(T), getRight(T));
    573     } else if (ImutInfo::isLess(K,KCurrent)) {
    574       return balanceTree(remove_internal(K, getLeft(T)),
    575                                             getValue(T), getRight(T));
    576     } else {
    577       return balanceTree(getLeft(T), getValue(T),
    578                          remove_internal(K, getRight(T)));
    579     }
    580   }
    581 
    582   TreeTy* combineTrees(TreeTy* L, TreeTy* R) {
    583     if (isEmpty(L))
    584       return R;
    585     if (isEmpty(R))
    586       return L;
    587     TreeTy* OldNode;
    588     TreeTy* newRight = removeMinBinding(R,OldNode);
    589     return balanceTree(L, getValue(OldNode), newRight);
    590   }
    591 
    592   TreeTy* removeMinBinding(TreeTy* T, TreeTy*& Noderemoved) {
    593     assert(!isEmpty(T));
    594     if (isEmpty(getLeft(T))) {
    595       Noderemoved = T;
    596       return getRight(T);
    597     }
    598     return balanceTree(removeMinBinding(getLeft(T), Noderemoved),
    599                        getValue(T), getRight(T));
    600   }
    601 
    602   /// markImmutable - Clears the mutable bits of a root and all of its
    603   ///  descendants.
    604   void markImmutable(TreeTy* T) {
    605     if (!T || !T->isMutable())
    606       return;
    607     T->markImmutable();
    608     markImmutable(getLeft(T));
    609     markImmutable(getRight(T));
    610   }
    611 
    612 public:
    613   TreeTy *getCanonicalTree(TreeTy *TNew) {
    614     if (!TNew)
    615       return nullptr;
    616 
    617     if (TNew->IsCanonicalized)
    618       return TNew;
    619 
    620     // Search the hashtable for another tree with the same digest, and
    621     // if find a collision compare those trees by their contents.
    622     unsigned digest = TNew->computeDigest();
    623     TreeTy *&entry = Cache[maskCacheIndex(digest)];
    624     do {
    625       if (!entry)
    626         break;
    627       for (TreeTy *T = entry ; T != nullptr; T = T->next) {
    628         // Compare the Contents('T') with Contents('TNew')
    629         typename TreeTy::iterator TI = T->begin(), TE = T->end();
    630         if (!compareTreeWithSection(TNew, TI, TE))
    631           continue;
    632         if (TI != TE)
    633           continue; // T has more contents than TNew.
    634         // Trees did match!  Return 'T'.
    635         if (TNew->refCount == 0)
    636           TNew->destroy();
    637         return T;
    638       }
    639       entry->prev = TNew;
    640       TNew->next = entry;
    641     }
    642     while (false);
    643 
    644     entry = TNew;
    645     TNew->IsCanonicalized = true;
    646     return TNew;
    647   }
    648 };
    649 
    650 //===----------------------------------------------------------------------===//
    651 // Immutable AVL-Tree Iterators.
    652 //===----------------------------------------------------------------------===//
    653 
    654 template <typename ImutInfo> class ImutAVLTreeGenericIterator {
    655   SmallVector<uintptr_t,20> stack;
    656 
    657 public:
    658   using iterator_category = std::bidirectional_iterator_tag;
    659   using value_type = ImutAVLTree<ImutInfo>;
    660   using difference_type = std::ptrdiff_t;
    661   using pointer = value_type *;
    662   using reference = value_type &;
    663 
    664   enum VisitFlag { VisitedNone=0x0, VisitedLeft=0x1, VisitedRight=0x3,
    665                    Flags=0x3 };
    666 
    667   using TreeTy = ImutAVLTree<ImutInfo>;
    668 
    669   ImutAVLTreeGenericIterator() = default;
    670   ImutAVLTreeGenericIterator(const TreeTy *Root) {
    671     if (Root) stack.push_back(reinterpret_cast<uintptr_t>(Root));
    672   }
    673 
    674   TreeTy &operator*() const {
    675     assert(!stack.empty());
    676     return *reinterpret_cast<TreeTy *>(stack.back() & ~Flags);
    677   }
    678   TreeTy *operator->() const { return &*this; }
    679 
    680   uintptr_t getVisitState() const {
    681     assert(!stack.empty());
    682     return stack.back() & Flags;
    683   }
    684 
    685   bool atEnd() const { return stack.empty(); }
    686 
    687   bool atBeginning() const {
    688     return stack.size() == 1 && getVisitState() == VisitedNone;
    689   }
    690 
    691   void skipToParent() {
    692     assert(!stack.empty());
    693     stack.pop_back();
    694     if (stack.empty())
    695       return;
    696     switch (getVisitState()) {
    697       case VisitedNone:
    698         stack.back() |= VisitedLeft;
    699         break;
    700       case VisitedLeft:
    701         stack.back() |= VisitedRight;
    702         break;
    703       default:
    704         llvm_unreachable("Unreachable.");
    705     }
    706   }
    707 
    708   bool operator==(const ImutAVLTreeGenericIterator &x) const {
    709     return stack == x.stack;
    710   }
    711 
    712   bool operator!=(const ImutAVLTreeGenericIterator &x) const {
    713     return !(*this == x);
    714   }
    715 
    716   ImutAVLTreeGenericIterator &operator++() {
    717     assert(!stack.empty());
    718     TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
    719     assert(Current);
    720     switch (getVisitState()) {
    721       case VisitedNone:
    722         if (TreeTy* L = Current->getLeft())
    723           stack.push_back(reinterpret_cast<uintptr_t>(L));
    724         else
    725           stack.back() |= VisitedLeft;
    726         break;
    727       case VisitedLeft:
    728         if (TreeTy* R = Current->getRight())
    729           stack.push_back(reinterpret_cast<uintptr_t>(R));
    730         else
    731           stack.back() |= VisitedRight;
    732         break;
    733       case VisitedRight:
    734         skipToParent();
    735         break;
    736       default:
    737         llvm_unreachable("Unreachable.");
    738     }
    739     return *this;
    740   }
    741 
    742   ImutAVLTreeGenericIterator &operator--() {
    743     assert(!stack.empty());
    744     TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
    745     assert(Current);
    746     switch (getVisitState()) {
    747       case VisitedNone:
    748         stack.pop_back();
    749         break;
    750       case VisitedLeft:
    751         stack.back() &= ~Flags; // Set state to "VisitedNone."
    752         if (TreeTy* L = Current->getLeft())
    753           stack.push_back(reinterpret_cast<uintptr_t>(L) | VisitedRight);
    754         break;
    755       case VisitedRight:
    756         stack.back() &= ~Flags;
    757         stack.back() |= VisitedLeft;
    758         if (TreeTy* R = Current->getRight())
    759           stack.push_back(reinterpret_cast<uintptr_t>(R) | VisitedRight);
    760         break;
    761       default:
    762         llvm_unreachable("Unreachable.");
    763     }
    764     return *this;
    765   }
    766 };
    767 
    768 template <typename ImutInfo> class ImutAVLTreeInOrderIterator {
    769   using InternalIteratorTy = ImutAVLTreeGenericIterator<ImutInfo>;
    770 
    771   InternalIteratorTy InternalItr;
    772 
    773 public:
    774   using iterator_category = std::bidirectional_iterator_tag;
    775   using value_type = ImutAVLTree<ImutInfo>;
    776   using difference_type = std::ptrdiff_t;
    777   using pointer = value_type *;
    778   using reference = value_type &;
    779 
    780   using TreeTy = ImutAVLTree<ImutInfo>;
    781 
    782   ImutAVLTreeInOrderIterator(const TreeTy* Root) : InternalItr(Root) {
    783     if (Root)
    784       ++*this; // Advance to first element.
    785   }
    786 
    787   ImutAVLTreeInOrderIterator() : InternalItr() {}
    788 
    789   bool operator==(const ImutAVLTreeInOrderIterator &x) const {
    790     return InternalItr == x.InternalItr;
    791   }
    792 
    793   bool operator!=(const ImutAVLTreeInOrderIterator &x) const {
    794     return !(*this == x);
    795   }
    796 
    797   TreeTy &operator*() const { return *InternalItr; }
    798   TreeTy *operator->() const { return &*InternalItr; }
    799 
    800   ImutAVLTreeInOrderIterator &operator++() {
    801     do ++InternalItr;
    802     while (!InternalItr.atEnd() &&
    803            InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
    804 
    805     return *this;
    806   }
    807 
    808   ImutAVLTreeInOrderIterator &operator--() {
    809     do --InternalItr;
    810     while (!InternalItr.atBeginning() &&
    811            InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
    812 
    813     return *this;
    814   }
    815 
    816   void skipSubTree() {
    817     InternalItr.skipToParent();
    818 
    819     while (!InternalItr.atEnd() &&
    820            InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft)
    821       ++InternalItr;
    822   }
    823 };
    824 
    825 /// Generic iterator that wraps a T::TreeTy::iterator and exposes
    826 /// iterator::getValue() on dereference.
    827 template <typename T>
    828 struct ImutAVLValueIterator
    829     : iterator_adaptor_base<
    830           ImutAVLValueIterator<T>, typename T::TreeTy::iterator,
    831           typename std::iterator_traits<
    832               typename T::TreeTy::iterator>::iterator_category,
    833           const typename T::value_type> {
    834   ImutAVLValueIterator() = default;
    835   explicit ImutAVLValueIterator(typename T::TreeTy *Tree)
    836       : ImutAVLValueIterator::iterator_adaptor_base(Tree) {}
    837 
    838   typename ImutAVLValueIterator::reference operator*() const {
    839     return this->I->getValue();
    840   }
    841 };
    842 
    843 //===----------------------------------------------------------------------===//
    844 // Trait classes for Profile information.
    845 //===----------------------------------------------------------------------===//
    846 
    847 /// Generic profile template.  The default behavior is to invoke the
    848 /// profile method of an object.  Specializations for primitive integers
    849 /// and generic handling of pointers is done below.
    850 template <typename T>
    851 struct ImutProfileInfo {
    852   using value_type = const T;
    853   using value_type_ref = const T&;
    854 
    855   static void Profile(FoldingSetNodeID &ID, value_type_ref X) {
    856     FoldingSetTrait<T>::Profile(X,ID);
    857   }
    858 };
    859 
    860 /// Profile traits for integers.
    861 template <typename T>
    862 struct ImutProfileInteger {
    863   using value_type = const T;
    864   using value_type_ref = const T&;
    865 
    866   static void Profile(FoldingSetNodeID &ID, value_type_ref X) {
    867     ID.AddInteger(X);
    868   }
    869 };
    870 
    871 #define PROFILE_INTEGER_INFO(X)\
    872 template<> struct ImutProfileInfo<X> : ImutProfileInteger<X> {};
    873 
    874 PROFILE_INTEGER_INFO(char)
    875 PROFILE_INTEGER_INFO(unsigned char)
    876 PROFILE_INTEGER_INFO(short)
    877 PROFILE_INTEGER_INFO(unsigned short)
    878 PROFILE_INTEGER_INFO(unsigned)
    879 PROFILE_INTEGER_INFO(signed)
    880 PROFILE_INTEGER_INFO(long)
    881 PROFILE_INTEGER_INFO(unsigned long)
    882 PROFILE_INTEGER_INFO(long long)
    883 PROFILE_INTEGER_INFO(unsigned long long)
    884 
    885 #undef PROFILE_INTEGER_INFO
    886 
    887 /// Profile traits for booleans.
    888 template <>
    889 struct ImutProfileInfo<bool> {
    890   using value_type = const bool;
    891   using value_type_ref = const bool&;
    892 
    893   static void Profile(FoldingSetNodeID &ID, value_type_ref X) {
    894     ID.AddBoolean(X);
    895   }
    896 };
    897 
    898 /// Generic profile trait for pointer types.  We treat pointers as
    899 /// references to unique objects.
    900 template <typename T>
    901 struct ImutProfileInfo<T*> {
    902   using value_type = const T*;
    903   using value_type_ref = value_type;
    904 
    905   static void Profile(FoldingSetNodeID &ID, value_type_ref X) {
    906     ID.AddPointer(X);
    907   }
    908 };
    909 
    910 //===----------------------------------------------------------------------===//
    911 // Trait classes that contain element comparison operators and type
    912 //  definitions used by ImutAVLTree, ImmutableSet, and ImmutableMap.  These
    913 //  inherit from the profile traits (ImutProfileInfo) to include operations
    914 //  for element profiling.
    915 //===----------------------------------------------------------------------===//
    916 
    917 /// ImutContainerInfo - Generic definition of comparison operations for
    918 ///   elements of immutable containers that defaults to using
    919 ///   std::equal_to<> and std::less<> to perform comparison of elements.
    920 template <typename T>
    921 struct ImutContainerInfo : public ImutProfileInfo<T> {
    922   using value_type = typename ImutProfileInfo<T>::value_type;
    923   using value_type_ref = typename ImutProfileInfo<T>::value_type_ref;
    924   using key_type = value_type;
    925   using key_type_ref = value_type_ref;
    926   using data_type = bool;
    927   using data_type_ref = bool;
    928 
    929   static key_type_ref KeyOfValue(value_type_ref D) { return D; }
    930   static data_type_ref DataOfValue(value_type_ref) { return true; }
    931 
    932   static bool isEqual(key_type_ref LHS, key_type_ref RHS) {
    933     return std::equal_to<key_type>()(LHS,RHS);
    934   }
    935 
    936   static bool isLess(key_type_ref LHS, key_type_ref RHS) {
    937     return std::less<key_type>()(LHS,RHS);
    938   }
    939 
    940   static bool isDataEqual(data_type_ref, data_type_ref) { return true; }
    941 };
    942 
    943 /// ImutContainerInfo - Specialization for pointer values to treat pointers
    944 ///  as references to unique objects.  Pointers are thus compared by
    945 ///  their addresses.
    946 template <typename T>
    947 struct ImutContainerInfo<T*> : public ImutProfileInfo<T*> {
    948   using value_type = typename ImutProfileInfo<T*>::value_type;
    949   using value_type_ref = typename ImutProfileInfo<T*>::value_type_ref;
    950   using key_type = value_type;
    951   using key_type_ref = value_type_ref;
    952   using data_type = bool;
    953   using data_type_ref = bool;
    954 
    955   static key_type_ref KeyOfValue(value_type_ref D) { return D; }
    956   static data_type_ref DataOfValue(value_type_ref) { return true; }
    957 
    958   static bool isEqual(key_type_ref LHS, key_type_ref RHS) { return LHS == RHS; }
    959 
    960   static bool isLess(key_type_ref LHS, key_type_ref RHS) { return LHS < RHS; }
    961 
    962   static bool isDataEqual(data_type_ref, data_type_ref) { return true; }
    963 };
    964 
    965 //===----------------------------------------------------------------------===//
    966 // Immutable Set
    967 //===----------------------------------------------------------------------===//
    968 
    969 template <typename ValT, typename ValInfo = ImutContainerInfo<ValT>>
    970 class ImmutableSet {
    971 public:
    972   using value_type = typename ValInfo::value_type;
    973   using value_type_ref = typename ValInfo::value_type_ref;
    974   using TreeTy = ImutAVLTree<ValInfo>;
    975 
    976 private:
    977   IntrusiveRefCntPtr<TreeTy> Root;
    978 
    979 public:
    980   /// Constructs a set from a pointer to a tree root.  In general one
    981   /// should use a Factory object to create sets instead of directly
    982   /// invoking the constructor, but there are cases where make this
    983   /// constructor public is useful.
    984   explicit ImmutableSet(TreeTy *R) : Root(R) {}
    985 
    986   class Factory {
    987     typename TreeTy::Factory F;
    988     const bool Canonicalize;
    989 
    990   public:
    991     Factory(bool canonicalize = true)
    992       : Canonicalize(canonicalize) {}
    993 
    994     Factory(BumpPtrAllocator& Alloc, bool canonicalize = true)
    995       : F(Alloc), Canonicalize(canonicalize) {}
    996 
    997     Factory(const Factory& RHS) = delete;
    998     void operator=(const Factory& RHS) = delete;
    999 
   1000     /// getEmptySet - Returns an immutable set that contains no elements.
   1001     ImmutableSet getEmptySet() {
   1002       return ImmutableSet(F.getEmptyTree());
   1003     }
   1004 
   1005     /// add - Creates a new immutable set that contains all of the values
   1006     ///  of the original set with the addition of the specified value.  If
   1007     ///  the original set already included the value, then the original set is
   1008     ///  returned and no memory is allocated.  The time and space complexity
   1009     ///  of this operation is logarithmic in the size of the original set.
   1010     ///  The memory allocated to represent the set is released when the
   1011     ///  factory object that created the set is destroyed.
   1012     LLVM_NODISCARD ImmutableSet add(ImmutableSet Old, value_type_ref V) {
   1013       TreeTy *NewT = F.add(Old.Root.get(), V);
   1014       return ImmutableSet(Canonicalize ? F.getCanonicalTree(NewT) : NewT);
   1015     }
   1016 
   1017     /// remove - Creates a new immutable set that contains all of the values
   1018     ///  of the original set with the exception of the specified value.  If
   1019     ///  the original set did not contain the value, the original set is
   1020     ///  returned and no memory is allocated.  The time and space complexity
   1021     ///  of this operation is logarithmic in the size of the original set.
   1022     ///  The memory allocated to represent the set is released when the
   1023     ///  factory object that created the set is destroyed.
   1024     LLVM_NODISCARD ImmutableSet remove(ImmutableSet Old, value_type_ref V) {
   1025       TreeTy *NewT = F.remove(Old.Root.get(), V);
   1026       return ImmutableSet(Canonicalize ? F.getCanonicalTree(NewT) : NewT);
   1027     }
   1028 
   1029     BumpPtrAllocator& getAllocator() { return F.getAllocator(); }
   1030 
   1031     typename TreeTy::Factory *getTreeFactory() const {
   1032       return const_cast<typename TreeTy::Factory *>(&F);
   1033     }
   1034   };
   1035 
   1036   friend class Factory;
   1037 
   1038   /// Returns true if the set contains the specified value.
   1039   bool contains(value_type_ref V) const {
   1040     return Root ? Root->contains(V) : false;
   1041   }
   1042 
   1043   bool operator==(const ImmutableSet &RHS) const {
   1044     return Root && RHS.Root ? Root->isEqual(*RHS.Root.get()) : Root == RHS.Root;
   1045   }
   1046 
   1047   bool operator!=(const ImmutableSet &RHS) const {
   1048     return Root && RHS.Root ? Root->isNotEqual(*RHS.Root.get())
   1049                             : Root != RHS.Root;
   1050   }
   1051 
   1052   TreeTy *getRoot() {
   1053     if (Root) { Root->retain(); }
   1054     return Root.get();
   1055   }
   1056 
   1057   TreeTy *getRootWithoutRetain() const { return Root.get(); }
   1058 
   1059   /// isEmpty - Return true if the set contains no elements.
   1060   bool isEmpty() const { return !Root; }
   1061 
   1062   /// isSingleton - Return true if the set contains exactly one element.
   1063   ///   This method runs in constant time.
   1064   bool isSingleton() const { return getHeight() == 1; }
   1065 
   1066   template <typename Callback>
   1067   void foreach(Callback& C) { if (Root) Root->foreach(C); }
   1068 
   1069   template <typename Callback>
   1070   void foreach() { if (Root) { Callback C; Root->foreach(C); } }
   1071 
   1072   //===--------------------------------------------------===//
   1073   // Iterators.
   1074   //===--------------------------------------------------===//
   1075 
   1076   using iterator = ImutAVLValueIterator<ImmutableSet>;
   1077 
   1078   iterator begin() const { return iterator(Root.get()); }
   1079   iterator end() const { return iterator(); }
   1080 
   1081   //===--------------------------------------------------===//
   1082   // Utility methods.
   1083   //===--------------------------------------------------===//
   1084 
   1085   unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
   1086 
   1087   static void Profile(FoldingSetNodeID &ID, const ImmutableSet &S) {
   1088     ID.AddPointer(S.Root.get());
   1089   }
   1090 
   1091   void Profile(FoldingSetNodeID &ID) const { return Profile(ID, *this); }
   1092 
   1093   //===--------------------------------------------------===//
   1094   // For testing.
   1095   //===--------------------------------------------------===//
   1096 
   1097   void validateTree() const { if (Root) Root->validateTree(); }
   1098 };
   1099 
   1100 // NOTE: This may some day replace the current ImmutableSet.
   1101 template <typename ValT, typename ValInfo = ImutContainerInfo<ValT>>
   1102 class ImmutableSetRef {
   1103 public:
   1104   using value_type = typename ValInfo::value_type;
   1105   using value_type_ref = typename ValInfo::value_type_ref;
   1106   using TreeTy = ImutAVLTree<ValInfo>;
   1107   using FactoryTy = typename TreeTy::Factory;
   1108 
   1109 private:
   1110   IntrusiveRefCntPtr<TreeTy> Root;
   1111   FactoryTy *Factory;
   1112 
   1113 public:
   1114   /// Constructs a set from a pointer to a tree root.  In general one
   1115   /// should use a Factory object to create sets instead of directly
   1116   /// invoking the constructor, but there are cases where make this
   1117   /// constructor public is useful.
   1118   ImmutableSetRef(TreeTy *R, FactoryTy *F) : Root(R), Factory(F) {}
   1119 
   1120   static ImmutableSetRef getEmptySet(FactoryTy *F) {
   1121     return ImmutableSetRef(0, F);
   1122   }
   1123 
   1124   ImmutableSetRef add(value_type_ref V) {
   1125     return ImmutableSetRef(Factory->add(Root.get(), V), Factory);
   1126   }
   1127 
   1128   ImmutableSetRef remove(value_type_ref V) {
   1129     return ImmutableSetRef(Factory->remove(Root.get(), V), Factory);
   1130   }
   1131 
   1132   /// Returns true if the set contains the specified value.
   1133   bool contains(value_type_ref V) const {
   1134     return Root ? Root->contains(V) : false;
   1135   }
   1136 
   1137   ImmutableSet<ValT> asImmutableSet(bool canonicalize = true) const {
   1138     return ImmutableSet<ValT>(
   1139         canonicalize ? Factory->getCanonicalTree(Root.get()) : Root.get());
   1140   }
   1141 
   1142   TreeTy *getRootWithoutRetain() const { return Root.get(); }
   1143 
   1144   bool operator==(const ImmutableSetRef &RHS) const {
   1145     return Root && RHS.Root ? Root->isEqual(*RHS.Root.get()) : Root == RHS.Root;
   1146   }
   1147 
   1148   bool operator!=(const ImmutableSetRef &RHS) const {
   1149     return Root && RHS.Root ? Root->isNotEqual(*RHS.Root.get())
   1150                             : Root != RHS.Root;
   1151   }
   1152 
   1153   /// isEmpty - Return true if the set contains no elements.
   1154   bool isEmpty() const { return !Root; }
   1155 
   1156   /// isSingleton - Return true if the set contains exactly one element.
   1157   ///   This method runs in constant time.
   1158   bool isSingleton() const { return getHeight() == 1; }
   1159 
   1160   //===--------------------------------------------------===//
   1161   // Iterators.
   1162   //===--------------------------------------------------===//
   1163 
   1164   using iterator = ImutAVLValueIterator<ImmutableSetRef>;
   1165 
   1166   iterator begin() const { return iterator(Root.get()); }
   1167   iterator end() const { return iterator(); }
   1168 
   1169   //===--------------------------------------------------===//
   1170   // Utility methods.
   1171   //===--------------------------------------------------===//
   1172 
   1173   unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
   1174 
   1175   static void Profile(FoldingSetNodeID &ID, const ImmutableSetRef &S) {
   1176     ID.AddPointer(S.Root.get());
   1177   }
   1178 
   1179   void Profile(FoldingSetNodeID &ID) const { return Profile(ID, *this); }
   1180 
   1181   //===--------------------------------------------------===//
   1182   // For testing.
   1183   //===--------------------------------------------------===//
   1184 
   1185   void validateTree() const { if (Root) Root->validateTree(); }
   1186 };
   1187 
   1188 } // end namespace llvm
   1189 
   1190 #endif // LLVM_ADT_IMMUTABLESET_H
   1191