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"
20+ #include " llvm/Support/Allocator.h"
1921#include < cassert>
2022#include < cstddef>
2123#include < cstdint>
2224#include < iterator>
23- #include < set>
2425
2526namespace llvm {
2627
@@ -32,8 +33,7 @@ namespace llvm {
3233// /
3334// / This implementation is an efficient implementation that only stores one copy
3435// / of the element being indexed per entry in the set, and allows any arbitrary
35- // / type to be indexed (as long as it can be ordered with operator< or a
36- // / comparator is provided).
36+ // / type to be indexed (as long as it can be implements DenseMapInfo).
3737// /
3838// / Here is a simple example using integers:
3939// /
@@ -57,18 +57,17 @@ namespace llvm {
5757// / 4
5858// / 5 1 2
5959// /
60- template <class ElemTy , class Compare = std::less<ElemTy>>
61- class EquivalenceClasses {
60+ template <class ElemTy > class EquivalenceClasses {
6261 // / ECValue - The EquivalenceClasses data structure is just a set of these.
6362 // / Each of these represents a relation for a value. First it stores the
64- // / value itself, which provides the ordering that the set queries. Next, it
65- // / provides a "next pointer", which is used to enumerate all of the elements
66- // / in the unioned set. Finally, it defines either a "end of list pointer" or
67- // / "leader pointer" depending on whether the value itself is a leader. A
68- // / " leader pointer" points to the node that is the leader for this element,
69- // / if the node is not a leader. A "end of list pointer" points to the last
70- // / node in the list of members of this list. Whether or not a node is a
71- // / leader is determined by a bit stolen from one of the pointers.
63+ // / value itself. Next, it provides a "next pointer", which is used to
64+ // / enumerate all of the elements in the unioned set. Finally, it defines
65+ // / either a "end of list pointer" or "leader pointer" depending on whether
66+ // / the value itself is a leader. A "leader pointer" points to the node that
67+ // / is the leader for this element, if the node is not a leader. A "end of
68+ // / list pointer" points to the last node in the list of members of this list.
69+ // / Whether or not a node is a leader is determined by a bit stolen from one
70+ // / of the pointers.
7271 class ECValue {
7372 friend class EquivalenceClasses ;
7473
@@ -112,36 +111,15 @@ class EquivalenceClasses {
112111 }
113112 };
114113
115- // / A wrapper of the comparator, to be passed to the set.
116- struct ECValueComparator {
117- using is_transparent = void ;
118-
119- ECValueComparator () : compare(Compare()) {}
120-
121- bool operator ()(const ECValue &lhs, const ECValue &rhs) const {
122- return compare (lhs.Data , rhs.Data );
123- }
124-
125- template <typename T>
126- bool operator ()(const T &lhs, const ECValue &rhs) const {
127- return compare (lhs, rhs.Data );
128- }
129-
130- template <typename T>
131- bool operator ()(const ECValue &lhs, const T &rhs) const {
132- return compare (lhs.Data , rhs);
133- }
134-
135- const Compare compare;
136- };
137-
138114 // / TheMapping - This implicitly provides a mapping from ElemTy values to the
139115 // / ECValues, it just keeps the key as part of the value.
140- std::set<ECValue, ECValueComparator > TheMapping;
116+ DenseMap<ElemTy, ECValue * > TheMapping;
141117
142118 // / List of all members, used to provide a determinstic iteration order.
143119 SmallVector<const ECValue *> Members;
144120
121+ mutable BumpPtrAllocator ECValueAllocator;
122+
145123public:
146124 EquivalenceClasses () = default;
147125 EquivalenceClasses (const EquivalenceClasses &RHS) {
@@ -223,10 +201,14 @@ class EquivalenceClasses {
223201 // / insert - Insert a new value into the union/find set, ignoring the request
224202 // / if the value already exists.
225203 const ECValue &insert (const ElemTy &Data) {
226- auto I = TheMapping.insert (ECValue (Data));
227- if (I.second )
228- Members.push_back (&*I.first );
229- return *I.first ;
204+ auto I = TheMapping.insert ({Data, nullptr });
205+ if (!I.second )
206+ return *I.first ->second ;
207+
208+ auto *ECV = new (ECValueAllocator) ECValue (Data);
209+ I.first ->second = ECV;
210+ Members.push_back (ECV);
211+ return *ECV;
230212 }
231213
232214 // / findLeader - Given a value in the set, return a member iterator for the
@@ -237,7 +219,7 @@ class EquivalenceClasses {
237219 auto I = TheMapping.find (V);
238220 if (I == TheMapping.end ())
239221 return member_iterator (nullptr );
240- return findLeader (*I);
222+ return findLeader (*I-> second );
241223 }
242224 member_iterator findLeader (const ECValue &ECV) const {
243225 return member_iterator (ECV.getLeader ());
0 commit comments