aboutsummaryrefslogtreecommitdiff
path: root/llvm/include/llvm/ADT/ImmutableSet.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/include/llvm/ADT/ImmutableSet.h')
-rw-r--r--llvm/include/llvm/ADT/ImmutableSet.h104
1 files changed, 33 insertions, 71 deletions
diff --git a/llvm/include/llvm/ADT/ImmutableSet.h b/llvm/include/llvm/ADT/ImmutableSet.h
index a6a6abfd9600..f19913f8dcdd 100644
--- a/llvm/include/llvm/ADT/ImmutableSet.h
+++ b/llvm/include/llvm/ADT/ImmutableSet.h
@@ -15,6 +15,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator.h"
#include "llvm/Support/Allocator.h"
@@ -169,7 +170,7 @@ public:
bool contains(key_type_ref K) { return (bool) find(K); }
/// foreach - A member template the accepts invokes operator() on a functor
- /// object (specifed by Callback) for every node/subtree in the tree.
+ /// object (specified by Callback) for every node/subtree in the tree.
/// Nodes are visited using an inorder traversal.
template <typename Callback>
void foreach(Callback& C) {
@@ -183,7 +184,7 @@ public:
}
/// validateTree - A utility method that checks that the balancing and
- /// ordering invariants of the tree are satisifed. It is a recursive
+ /// ordering invariants of the tree are satisfied. It is a recursive
/// method that returns the height of the tree, which is then consumed
/// by the enclosing validateTree call. External callers should ignore the
/// return value. An invalid tree will cause an assertion to fire in
@@ -357,6 +358,12 @@ public:
}
};
+template <typename ImutInfo>
+struct IntrusiveRefCntPtrInfo<ImutAVLTree<ImutInfo>> {
+ static void retain(ImutAVLTree<ImutInfo> *Tree) { Tree->retain(); }
+ static void release(ImutAVLTree<ImutInfo> *Tree) { Tree->release(); }
+};
+
//===----------------------------------------------------------------------===//
// Immutable AVL-Tree Factory class.
//===----------------------------------------------------------------------===//
@@ -450,7 +457,7 @@ protected:
//===--------------------------------------------------===//
// "createNode" is used to generate new tree roots that link
- // to other trees. The functon may also simply move links
+ // to other trees. The function may also simply move links
// in an existing root if that root is still marked mutable.
// This is necessary because otherwise our balancing code
// would leak memory as it would create nodes that are
@@ -961,33 +968,14 @@ public:
using TreeTy = ImutAVLTree<ValInfo>;
private:
- TreeTy *Root;
+ IntrusiveRefCntPtr<TreeTy> Root;
public:
/// Constructs a set from a pointer to a tree root. In general one
/// should use a Factory object to create sets instead of directly
/// invoking the constructor, but there are cases where make this
/// constructor public is useful.
- explicit ImmutableSet(TreeTy* R) : Root(R) {
- if (Root) { Root->retain(); }
- }
-
- ImmutableSet(const ImmutableSet &X) : Root(X.Root) {
- if (Root) { Root->retain(); }
- }
-
- ~ImmutableSet() {
- if (Root) { Root->release(); }
- }
-
- ImmutableSet &operator=(const ImmutableSet &X) {
- if (Root != X.Root) {
- if (X.Root) { X.Root->retain(); }
- if (Root) { Root->release(); }
- Root = X.Root;
- }
- return *this;
- }
+ explicit ImmutableSet(TreeTy *R) : Root(R) {}
class Factory {
typename TreeTy::Factory F;
@@ -1016,7 +1004,7 @@ public:
/// The memory allocated to represent the set is released when the
/// factory object that created the set is destroyed.
LLVM_NODISCARD ImmutableSet add(ImmutableSet Old, value_type_ref V) {
- TreeTy *NewT = F.add(Old.Root, V);
+ TreeTy *NewT = F.add(Old.Root.get(), V);
return ImmutableSet(Canonicalize ? F.getCanonicalTree(NewT) : NewT);
}
@@ -1028,7 +1016,7 @@ public:
/// The memory allocated to represent the set is released when the
/// factory object that created the set is destroyed.
LLVM_NODISCARD ImmutableSet remove(ImmutableSet Old, value_type_ref V) {
- TreeTy *NewT = F.remove(Old.Root, V);
+ TreeTy *NewT = F.remove(Old.Root.get(), V);
return ImmutableSet(Canonicalize ? F.getCanonicalTree(NewT) : NewT);
}
@@ -1047,21 +1035,20 @@ public:
}
bool operator==(const ImmutableSet &RHS) const {
- return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
+ return Root && RHS.Root ? Root->isEqual(*RHS.Root.get()) : Root == RHS.Root;
}
bool operator!=(const ImmutableSet &RHS) const {
- return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
+ return Root && RHS.Root ? Root->isNotEqual(*RHS.Root.get())
+ : Root != RHS.Root;
}
TreeTy *getRoot() {
if (Root) { Root->retain(); }
- return Root;
+ return Root.get();
}
- TreeTy *getRootWithoutRetain() const {
- return Root;
- }
+ TreeTy *getRootWithoutRetain() const { return Root.get(); }
/// isEmpty - Return true if the set contains no elements.
bool isEmpty() const { return !Root; }
@@ -1082,7 +1069,7 @@ public:
using iterator = ImutAVLValueIterator<ImmutableSet>;
- iterator begin() const { return iterator(Root); }
+ iterator begin() const { return iterator(Root.get()); }
iterator end() const { return iterator(); }
//===--------------------------------------------------===//
@@ -1092,7 +1079,7 @@ public:
unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
static void Profile(FoldingSetNodeID &ID, const ImmutableSet &S) {
- ID.AddPointer(S.Root);
+ ID.AddPointer(S.Root.get());
}
void Profile(FoldingSetNodeID &ID) const { return Profile(ID, *this); }
@@ -1114,7 +1101,7 @@ public:
using FactoryTy = typename TreeTy::Factory;
private:
- TreeTy *Root;
+ IntrusiveRefCntPtr<TreeTy> Root;
FactoryTy *Factory;
public:
@@ -1122,42 +1109,18 @@ public:
/// should use a Factory object to create sets instead of directly
/// invoking the constructor, but there are cases where make this
/// constructor public is useful.
- explicit ImmutableSetRef(TreeTy* R, FactoryTy *F)
- : Root(R),
- Factory(F) {
- if (Root) { Root->retain(); }
- }
-
- ImmutableSetRef(const ImmutableSetRef &X)
- : Root(X.Root),
- Factory(X.Factory) {
- if (Root) { Root->retain(); }
- }
-
- ~ImmutableSetRef() {
- if (Root) { Root->release(); }
- }
-
- ImmutableSetRef &operator=(const ImmutableSetRef &X) {
- if (Root != X.Root) {
- if (X.Root) { X.Root->retain(); }
- if (Root) { Root->release(); }
- Root = X.Root;
- Factory = X.Factory;
- }
- return *this;
- }
+ ImmutableSetRef(TreeTy *R, FactoryTy *F) : Root(R), Factory(F) {}
static ImmutableSetRef getEmptySet(FactoryTy *F) {
return ImmutableSetRef(0, F);
}
ImmutableSetRef add(value_type_ref V) {
- return ImmutableSetRef(Factory->add(Root, V), Factory);
+ return ImmutableSetRef(Factory->add(Root.get(), V), Factory);
}
ImmutableSetRef remove(value_type_ref V) {
- return ImmutableSetRef(Factory->remove(Root, V), Factory);
+ return ImmutableSetRef(Factory->remove(Root.get(), V), Factory);
}
/// Returns true if the set contains the specified value.
@@ -1166,20 +1129,19 @@ public:
}
ImmutableSet<ValT> asImmutableSet(bool canonicalize = true) const {
- return ImmutableSet<ValT>(canonicalize ?
- Factory->getCanonicalTree(Root) : Root);
+ return ImmutableSet<ValT>(
+ canonicalize ? Factory->getCanonicalTree(Root.get()) : Root.get());
}
- TreeTy *getRootWithoutRetain() const {
- return Root;
- }
+ TreeTy *getRootWithoutRetain() const { return Root.get(); }
bool operator==(const ImmutableSetRef &RHS) const {
- return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
+ return Root && RHS.Root ? Root->isEqual(*RHS.Root.get()) : Root == RHS.Root;
}
bool operator!=(const ImmutableSetRef &RHS) const {
- return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
+ return Root && RHS.Root ? Root->isNotEqual(*RHS.Root.get())
+ : Root != RHS.Root;
}
/// isEmpty - Return true if the set contains no elements.
@@ -1195,7 +1157,7 @@ public:
using iterator = ImutAVLValueIterator<ImmutableSetRef>;
- iterator begin() const { return iterator(Root); }
+ iterator begin() const { return iterator(Root.get()); }
iterator end() const { return iterator(); }
//===--------------------------------------------------===//
@@ -1205,7 +1167,7 @@ public:
unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
static void Profile(FoldingSetNodeID &ID, const ImmutableSetRef &S) {
- ID.AddPointer(S.Root);
+ ID.AddPointer(S.Root.get());
}
void Profile(FoldingSetNodeID &ID) const { return Profile(ID, *this); }