14 #ifndef LLVM_ADT_IMMUTABLESET_H
15 #define LLVM_ADT_IMMUTABLESET_H
20 #include "llvm/Support/DataTypes.h"
37 template <
typename ImutInfo >
77 if (ImutInfo::isEqual(K,CurrentKey))
79 else if (ImutInfo::isLess(K,CurrentKey))
92 while (Right) { T = Right; Right = T->
getRight(); }
118 if (!ImutInfo::isEqual(ImutInfo::KeyOfValue(
getValue()),
119 ImutInfo::KeyOfValue(V)))
123 if (!ImutInfo::isDataEqual(ImutInfo::DataOfValue(
getValue()),
124 ImutInfo::DataOfValue(V)))
144 while (LItr != LEnd && RItr != REnd) {
145 if (*LItr == *RItr) {
158 return LItr == LEnd && RItr == REnd;
173 template <
typename Callback>
174 void foreach(Callback&
C) {
196 assert(
getHeight() == ( HL > HR ? HL : HR ) + 1
197 &&
"Height calculation wrong");
199 assert((HL > HR ? HL-HR : HR-HL) <= 2
200 &&
"Balancing invariant violated");
204 ImutInfo::KeyOfValue(
getValue()))) &&
205 "Value in left child is not less that current value");
209 ImutInfo::isLess(ImutInfo::KeyOfValue(
getValue()),
211 "Current value is not less that value of right child");
227 unsigned height : 28;
228 unsigned IsMutable : 1;
229 unsigned IsDigestCached : 1;
230 unsigned IsCanonicalized : 1;
245 : factory(f), left(l), right(r), prev(0),
next(0), height(height),
246 IsMutable(
true), IsDigestCached(
false), IsCanonicalized(0),
247 value(v), digest(0), refCount(0)
250 if (right) right->
retain();
259 bool isMutable()
const {
return IsMutable; }
263 bool hasCachedDigest()
const {
return IsDigestCached; }
278 void markImmutable() {
279 assert(isMutable() &&
"Mutable flag already removed.");
284 void markedCachedDigest() {
285 assert(!hasCachedDigest() &&
"NoCachedDigest flag already removed.");
286 IsDigestCached =
true;
291 void setHeight(
unsigned h) {
292 assert(isMutable() &&
"Only a mutable tree can have its height changed.");
297 uint32_t computeDigest(ImutAVLTree* L, ImutAVLTree* R,
value_type_ref V) {
301 digest += L->computeDigest();
305 ImutInfo::Profile(ID,V);
306 digest += ID.ComputeHash();
309 digest += R->computeDigest();
314 inline uint32_t computeDigest() {
317 if (hasCachedDigest())
322 markedCachedDigest();
333 assert(refCount > 0);
342 if (IsCanonicalized) {
355 factory->freeNodes.push_back(
this);
363 template <
typename ImutInfo >
364 class ImutAVLFactory {
374 std::vector<TreeTy*> createdNodes;
375 std::vector<TreeTy*> freeNodes;
377 bool ownsAllocator()
const {
378 return Allocator & 0x1 ?
false :
true;
394 : Allocator(reinterpret_cast<uintptr_t>(&Alloc) | 0x1) {}
397 if (ownsAllocator())
delete &getAllocator();
439 return (hl > hr ? hl : hr) + 1;
446 for ( ; I!=E ; ++
I, ++TI) {
466 if (!freeNodes.empty()) {
467 T = freeNodes.back();
468 freeNodes.pop_back();
475 createdNodes.push_back(T);
484 for (
unsigned i = 0, n = createdNodes.size(); i < n; ++i) {
486 if (N->isMutable() && N->refCount == 0)
489 createdNodes.clear();
499 assert(!
isEmpty(L) &&
"Left tree cannot be empty to have a height >= 2");
507 assert(!
isEmpty(LR) &&
"LR cannot be empty because it has a height >= 1");
516 assert(!
isEmpty(R) &&
"Right tree cannot be empty to have a height >= 2");
524 assert(!
isEmpty(RL) &&
"RL cannot be empty because it has a height >= 1");
541 assert(!T->isMutable());
543 key_type_ref K = ImutInfo::KeyOfValue(V);
544 key_type_ref KCurrent = ImutInfo::KeyOfValue(
getValue(T));
546 if (ImutInfo::isEqual(K,KCurrent))
548 else if (ImutInfo::isLess(K,KCurrent))
562 assert(!T->isMutable());
564 key_type_ref KCurrent = ImutInfo::KeyOfValue(
getValue(T));
566 if (ImutInfo::isEqual(K,KCurrent)) {
568 }
else if (ImutInfo::isLess(K,KCurrent)) {
600 if (!T || !T->isMutable())
612 if (TNew->IsCanonicalized)
617 unsigned digest = TNew->computeDigest();
622 for (
TreeTy *
T = entry ;
T != 0;
T =
T->next) {
630 if (TNew->refCount == 0)
640 TNew->IsCanonicalized =
true;
649 template <
typename ImutInfo>
650 class ImutAVLTreeGenericIterator {
651 SmallVector<uintptr_t,20> stack;
661 if (Root) stack.
push_back(reinterpret_cast<uintptr_t>(Root));
665 assert(!stack.
empty());
670 assert(!stack.
empty());
682 assert(!stack.
empty());
699 if (stack.
size() != x.stack.size())
701 for (
unsigned i = 0 ; i < stack.
size(); i++)
702 if (stack[i] != x.stack[i])
710 assert(!stack.
empty());
716 stack.
push_back(reinterpret_cast<uintptr_t>(L));
722 stack.
push_back(reinterpret_cast<uintptr_t>(R));
736 assert(!stack.
empty());
761 template <
typename ImutInfo>
762 class ImutAVLTreeInOrderIterator {
763 typedef ImutAVLTreeGenericIterator<ImutInfo> InternalIteratorTy;
764 InternalIteratorTy InternalItr;
777 return InternalItr == x.InternalItr;
787 while (!InternalItr.atEnd() &&
788 InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
795 while (!InternalItr.atBeginning() &&
796 InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
802 InternalItr.skipToParent();
804 while (!InternalItr.atEnd() &&
805 InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft)
817 template <
typename T>
828 template <
typename T>
838 #define PROFILE_INTEGER_INFO(X)\
839 template<> struct ImutProfileInfo<X> : ImutProfileInteger<X> {};
852 #undef PROFILE_INTEGER_INFO
868 template <
typename T>
889 template <
typename T>
902 return std::equal_to<key_type>()(LHS,RHS);
906 return std::less<key_type>()(LHS,RHS);
915 template <
typename T>
924 static inline key_type_ref
KeyOfValue(value_type_ref D) {
return D; }
925 static inline data_type_ref
DataOfValue(value_type_ref) {
return true; }
927 static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) {
931 static inline bool isLess(key_type_ref LHS, key_type_ref RHS) {
935 static inline bool isDataEqual(data_type_ref,data_type_ref) {
return true; }
942 template <
typename ValT,
typename ValInfo = ImutContainerInfo<ValT> >
958 if (Root) { Root->
retain(); }
961 if (Root) { Root->
retain(); }
964 if (Root != X.Root) {
965 if (X.Root) { X.Root->
retain(); }
977 const bool Canonicalize;
981 : Canonicalize(canonicalize) {}
984 : F(Alloc), Canonicalize(canonicalize) {}
1030 return Root ? Root->
contains(V) :
false;
1034 return Root && RHS.Root ? Root->
isEqual(*RHS.Root) : Root == RHS.Root;
1038 return Root && RHS.Root ? Root->
isNotEqual(*RHS.Root) : Root != RHS.Root;
1042 if (Root) { Root->
retain(); }
1057 template <
typename Callback>
1058 void foreach(Callback& C) {
if (Root) Root->
foreach(C); }
1060 template <
typename Callback>
1061 void foreach() {
if (Root) { Callback
C; Root->
foreach(C); } }
1118 template <
typename ValT,
typename ValInfo = ImutContainerInfo<ValT> >
1138 if (Root) { Root->
retain(); }
1142 Factory(X.Factory) {
1143 if (Root) { Root->
retain(); }
1146 if (Root != X.Root) {
1147 if (X.Root) { X.Root->
retain(); }
1148 if (Root) { Root->
release(); }
1150 Factory = X.Factory;
1155 if (Root) { Root->
release(); }
1172 return Root ? Root->
contains(V) :
false;
1185 return Root && RHS.Root ? Root->
isEqual(*RHS.Root) : Root == RHS.Root;
1189 return Root && RHS.Root ? Root->
isNotEqual(*RHS.Root) : Root != RHS.Root;
unsigned getHeight() const
ImutAVLTree< ValInfo > TreeTy
void validateTree() const
ImmutableSet add(ImmutableSet Old, value_type_ref V)
void AddPointer(const void *Ptr)
ImmutableSetRef(const ImmutableSetRef &X)
void push_back(const T &Elt)
static void Profile(FoldingSetNodeID &ID, value_type_ref X)
ImmutableSet< ValT, ValInfo >::value_type_ref reference
unsigned validateTree() const
static void Profile(FoldingSetNodeID &ID, value_type_ref X)
static bool isDataEqual(data_type_ref, data_type_ref)
ValInfo::value_type value_type
TreeTy * balanceTree(TreeTy *L, value_type_ref V, TreeTy *R)
ImutAVLTree * getLeft() const
ValInfo::value_type_ref value_type_ref
static data_type_ref DataOfValue(value_type_ref)
bool operator==(const ImmutableSetRef &RHS) const
TreeTy * add(TreeTy *T, value_type_ref V)
bool operator==(const _Self &x) const
ImutInfo::key_type_ref key_type_ref
bool operator!=(const _Self &x) const
ImutProfileInfo< T * >::value_type value_type
bool contains(value_type_ref V) const
Returns true if the set contains the specified value.
ImutAVLTree< ValInfo > TreeTy
BumpPtrAllocator & getAllocator()
TreeTy * remove_internal(key_type_ref K, TreeTy *T)
bool contains(value_type_ref V) const
Returns true if the set contains the specified value.
void Profile(FoldingSetNodeID &ID) const
TreeTy * getRootWithoutRetain() const
ptrdiff_t difference_type
bool operator!=(const iterator &RHS) const
TreeTy * createNode(TreeTy *newLeft, TreeTy *oldTree, TreeTy *newRight)
iterator::pointer operator->() const
ImutAVLTreeGenericIterator(const TreeTy *Root)
bool isNotEqual(const ImutAVLTree &RHS) const
static void Profile(const T &X, FoldingSetNodeID &ID)
ImmutableSet & operator=(const ImmutableSet &X)
TreeTy::Factory * getTreeFactory() const
bool operator==(const iterator &RHS) const
bool isElementEqual(const ImutAVLTree *RHS) const
ImutAVLTree * getMaxElement()
static ImmutableSetRef getEmptySet(FactoryTy *F)
TreeTy * createNode(TreeTy *L, value_type_ref V, TreeTy *R)
bool operator!=(const _Self &x) const
#define llvm_unreachable(msg)
void AddInteger(signed I)
static bool isEqual(key_type_ref LHS, key_type_ref RHS)
TreeTy * operator->() const
ID
LLVM Calling Convention Representation.
static void Profile(FoldingSetNodeID &ID, const ImmutableSet &S)
static bool compareTreeWithSection(TreeTy *T, typename TreeTy::iterator &TI, typename TreeTy::iterator &TE)
static data_type_ref DataOfValue(value_type_ref)
ImmutableSetRef add(value_type_ref V)
unsigned getHeight() const
bool operator==(const iterator &RHS) const
ImutInfo::value_type_ref value_type_ref
#define PROFILE_INTEGER_INFO(X)
ImmutableSet getEmptySet()
getEmptySet - Returns an immutable set that contains no elements.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
ImutAVLFactory< ImutInfo > Factory
ImmutableSetRef(TreeTy *R, FactoryTy *F)
value_type_ref key_type_ref
Profile traits for integers.
ImutAVLTree< ImutInfo > TreeTy
void foreach(Callback &C)
ImutAVLTreeGenericIterator()
static void Profile(FoldingSetNodeID &ID, const ImmutableSetRef &S)
ImutAVLTreeInOrderIterator()
Factory(bool canonicalize=true)
const bool & value_type_ref
TreeTy * add_internal(value_type_ref V, TreeTy *T)
bool operator!=(const ImmutableSetRef &RHS) const
TreeTy * getEmptyTree() const
TreeTy * remove(TreeTy *T, key_type_ref V)
TreeTy * operator*() const
ImutAVLTree * find(key_type_ref K)
ImutAVLTree * getRight() const
void markImmutable(TreeTy *T)
ItTy next(ItTy it, Dist n)
static void Profile(FoldingSetNodeID &ID, value_type_ref X)
bool isElementEqual(value_type_ref V) const
ImutAVLTreeInOrderIterator(const TreeTy *Root)
bool isEmpty() const
isEmpty - Return true if the set contains no elements.
static bool isEqual(key_type_ref LHS, key_type_ref RHS)
TreeTy * getRight(TreeTy *T) const
value_type_ref getValue(TreeTy *T) const
bool contains(key_type_ref K)
bool operator!=(const ImmutableSet &RHS) const
ImutAVLTreeGenericIterator< ImutInfo > _Self
ImutAVLTreeInOrderIterator< ImutInfo > iterator
iterator::reference operator*() const
TreeTy * getRootWithoutRetain() const
unsigned getHeight() const
ImutProfileInfo< T >::value_type value_type
Factory(BumpPtrAllocator &Alloc, bool canonicalize=true)
ImutProfileInfo< T * >::value_type_ref value_type_ref
ImutInfo::value_type value_type
value_type_ref operator*() const
bool isEmpty() const
isEmpty - Return true if the set contains no elements.
bool operator!=(const iterator &RHS) const
ImmutableSetRef & operator=(const ImmutableSetRef &X)
static key_type_ref KeyOfValue(value_type_ref D)
#define LLVM_DELETED_FUNCTION
void validateTree() const
unsigned incrementHeight(TreeTy *L, TreeTy *R) const
void * Allocate(size_t Size, size_t Alignment)
TreeTy * getCanonicalTree(TreeTy *TNew)
TreeTy::Factory FactoryTy
ImutProfileInfo< T >::value_type_ref value_type_ref
static bool isDataEqual(data_type_ref, data_type_ref)
TreeTy * combineTrees(TreeTy *L, TreeTy *R)
TreeTy * removeMinBinding(TreeTy *T, TreeTy *&Noderemoved)
ImutAVLFactory(BumpPtrAllocator &Alloc)
ImutAVLTree< ImutInfo > TreeTy
TreeTy * operator*() const
static key_type_ref KeyOfValue(value_type_ref D)
uintptr_t getVisitState() const
const value_type & getValue() const
getValue - Returns the data value associated with the tree node.
static bool isLess(key_type_ref LHS, key_type_ref RHS)
ImmutableSet(const ImmutableSet &X)
ValInfo::value_type_ref value_type_ref
bool isEmpty(TreeTy *T) const
void Profile(FoldingSetNodeID &ID) const
ImmutableSet< ValT, ValInfo >::value_type value_type
std::bidirectional_iterator_tag iterator_category
value_type * operator->() const
iterator::value_type * pointer
static bool isLess(key_type_ref LHS, key_type_ref RHS)
bool operator==(const ImmutableSet &RHS) const
ValInfo::value_type value_type
static void Profile(FoldingSetNodeID &ID, value_type_ref X)
value_type value_type_ref
bool operator==(const _Self &x) const
bool isEqual(const ImutAVLTree &RHS) const
value_type_ref key_type_ref
TreeTy * getLeft(TreeTy *T) const
ImmutableSet< ValT > asImmutableSet(bool canonicalize=true) const
static RegisterPass< NVPTXAllocaHoisting > X("alloca-hoisting","Hoisting alloca instructions in non-entry ""blocks to the entry block")
unsigned getHeight(TreeTy *T) const
static unsigned maskCacheIndex(unsigned I)
ImutAVLTreeInOrderIterator< ImutInfo > _Self