1515#ifndef LLVM_ADT_EQUIVALENCECLASSES_H
1616#define LLVM_ADT_EQUIVALENCECLASSES_H
1717
18+ #include " llvm/ADT/DenseMap.h"
1819#include " llvm/ADT/SmallVector.h"
1920#include " llvm/ADT/iterator_range.h"
21+ #include " llvm/Support/Allocator.h"
2022#include < cassert>
2123#include < cstddef>
2224#include < cstdint>
2325#include < iterator>
24- #include < set>
2526
2627namespace llvm {
2728
@@ -33,8 +34,7 @@ namespace llvm {
3334// /
3435// / This implementation is an efficient implementation that only stores one copy
3536// / of the element being indexed per entry in the set, and allows any arbitrary
36- // / type to be indexed (as long as it can be ordered with operator< or a
37- // / comparator is provided).
37+ // / type to be indexed (as long as it can be implements DenseMapInfo).
3838// /
3939// / Here is a simple example using integers:
4040// /
@@ -58,18 +58,17 @@ namespace llvm {
5858// / 4
5959// / 5 1 2
6060// /
61- template <class ElemTy , class Compare = std::less<ElemTy>>
62- class EquivalenceClasses {
61+ template <class ElemTy > class EquivalenceClasses {
6362 // / ECValue - The EquivalenceClasses data structure is just a set of these.
6463 // / Each of these represents a relation for a value. First it stores the
65- // / value itself, which provides the ordering that the set queries. Next, it
66- // / provides a "next pointer", which is used to enumerate all of the elements
67- // / in the unioned set. Finally, it defines either a "end of list pointer" or
68- // / "leader pointer" depending on whether the value itself is a leader. A
69- // / " leader pointer" points to the node that is the leader for this element,
70- // / if the node is not a leader. A "end of list pointer" points to the last
71- // / node in the list of members of this list. Whether or not a node is a
72- // / leader is determined by a bit stolen from one of the pointers.
64+ // / value itself. Next, it provides a "next pointer", which is used to
65+ // / enumerate all of the elements in the unioned set. Finally, it defines
66+ // / either a "end of list pointer" or "leader pointer" depending on whether
67+ // / the value itself is a leader. A "leader pointer" points to the node that
68+ // / is the leader for this element, if the node is not a leader. A "end of
69+ // / list pointer" points to the last node in the list of members of this list.
70+ // / Whether or not a node is a leader is determined by a bit stolen from one
71+ // / of the pointers.
7372 class ECValue {
7473 friend class EquivalenceClasses ;
7574
@@ -113,36 +112,15 @@ class EquivalenceClasses {
113112 }
114113 };
115114
116- // / A wrapper of the comparator, to be passed to the set.
117- struct ECValueComparator {
118- using is_transparent = void ;
119-
120- ECValueComparator () : compare(Compare()) {}
121-
122- bool operator ()(const ECValue &lhs, const ECValue &rhs) const {
123- return compare (lhs.Data , rhs.Data );
124- }
125-
126- template <typename T>
127- bool operator ()(const T &lhs, const ECValue &rhs) const {
128- return compare (lhs, rhs.Data );
129- }
130-
131- template <typename T>
132- bool operator ()(const ECValue &lhs, const T &rhs) const {
133- return compare (lhs.Data , rhs);
134- }
135-
136- const Compare compare;
137- };
138-
139115 // / TheMapping - This implicitly provides a mapping from ElemTy values to the
140116 // / ECValues, it just keeps the key as part of the value.
141- std::set<ECValue, ECValueComparator > TheMapping;
117+ DenseMap<ElemTy, ECValue * > TheMapping;
142118
143119 // / List of all members, used to provide a determinstic iteration order.
144120 SmallVector<const ECValue *> Members;
145121
122+ mutable BumpPtrAllocator ECValueAllocator;
123+
146124public:
147125 EquivalenceClasses () = default;
148126 EquivalenceClasses (const EquivalenceClasses &RHS) {
@@ -232,10 +210,14 @@ class EquivalenceClasses {
232210 // / insert - Insert a new value into the union/find set, ignoring the request
233211 // / if the value already exists.
234212 const ECValue &insert (const ElemTy &Data) {
235- auto I = TheMapping.insert (ECValue (Data));
236- if (I.second )
237- Members.push_back (&*I.first );
238- return *I.first ;
213+ auto I = TheMapping.insert ({Data, nullptr });
214+ if (!I.second )
215+ return *I.first ->second ;
216+
217+ auto *ECV = new (ECValueAllocator) ECValue (Data);
218+ I.first ->second = ECV;
219+ Members.push_back (ECV);
220+ return *ECV;
239221 }
240222
241223 // / findLeader - Given a value in the set, return a member iterator for the
@@ -246,7 +228,7 @@ class EquivalenceClasses {
246228 auto I = TheMapping.find (V);
247229 if (I == TheMapping.end ())
248230 return member_iterator (nullptr );
249- return findLeader (*I);
231+ return findLeader (*I-> second );
250232 }
251233 member_iterator findLeader (const ECValue &ECV) const {
252234 return member_iterator (ECV.getLeader ());
0 commit comments