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