15
15
#ifndef LLVM_ADT_EQUIVALENCECLASSES_H
16
16
#define LLVM_ADT_EQUIVALENCECLASSES_H
17
17
18
+ #include " llvm/ADT/DenseMap.h"
18
19
#include " llvm/ADT/SmallVector.h"
20
+ #include " llvm/Support/Allocator.h"
19
21
#include < cassert>
20
22
#include < cstddef>
21
23
#include < cstdint>
22
24
#include < iterator>
23
- #include < set>
24
25
25
26
namespace llvm {
26
27
@@ -32,8 +33,7 @@ namespace llvm {
32
33
// /
33
34
// / This implementation is an efficient implementation that only stores one copy
34
35
// / 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).
37
37
// /
38
38
// / Here is a simple example using integers:
39
39
// /
@@ -57,18 +57,17 @@ namespace llvm {
57
57
// / 4
58
58
// / 5 1 2
59
59
// /
60
- template <class ElemTy , class Compare = std::less<ElemTy>>
61
- class EquivalenceClasses {
60
+ template <class ElemTy > class EquivalenceClasses {
62
61
// / ECValue - The EquivalenceClasses data structure is just a set of these.
63
62
// / 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.
72
71
class ECValue {
73
72
friend class EquivalenceClasses ;
74
73
@@ -112,36 +111,15 @@ class EquivalenceClasses {
112
111
}
113
112
};
114
113
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
-
138
114
// / TheMapping - This implicitly provides a mapping from ElemTy values to the
139
115
// / ECValues, it just keeps the key as part of the value.
140
- std::set<ECValue, ECValueComparator > TheMapping;
116
+ DenseMap<ElemTy, ECValue * > TheMapping;
141
117
142
118
// / List of all members, used to provide a determinstic iteration order.
143
119
SmallVector<const ECValue *> Members;
144
120
121
+ mutable BumpPtrAllocator ECValueAllocator;
122
+
145
123
public:
146
124
EquivalenceClasses () = default;
147
125
EquivalenceClasses (const EquivalenceClasses &RHS) {
@@ -223,10 +201,14 @@ class EquivalenceClasses {
223
201
// / insert - Insert a new value into the union/find set, ignoring the request
224
202
// / if the value already exists.
225
203
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;
230
212
}
231
213
232
214
// / findLeader - Given a value in the set, return a member iterator for the
@@ -237,7 +219,7 @@ class EquivalenceClasses {
237
219
auto I = TheMapping.find (V);
238
220
if (I == TheMapping.end ())
239
221
return member_iterator (nullptr );
240
- return findLeader (*I);
222
+ return findLeader (*I-> second );
241
223
}
242
224
member_iterator findLeader (const ECValue &ECV) const {
243
225
return member_iterator (ECV.getLeader ());
0 commit comments