@@ -112,91 +112,6 @@ struct ScopedWriterLock {
112
112
};
113
113
} // end anonymous namespace.
114
114
115
- // ===----------------------------------------------------------------------===//
116
- // AffineMap and IntegerSet hashing
117
- // ===----------------------------------------------------------------------===//
118
-
119
- // / A utility function to safely get or create a uniqued instance within the
120
- // / given set container.
121
- template <typename ValueT, typename DenseInfoT, typename KeyT,
122
- typename ConstructorFn>
123
- static ValueT safeGetOrCreate (DenseSet<ValueT, DenseInfoT> &container,
124
- KeyT &&key, llvm::sys::SmartRWMutex<true > &mutex,
125
- bool threadingIsEnabled,
126
- ConstructorFn &&constructorFn) {
127
- // Check for an existing instance in read-only mode.
128
- if (threadingIsEnabled) {
129
- llvm::sys::SmartScopedReader<true > instanceLock (mutex);
130
- auto it = container.find_as (key);
131
- if (it != container.end ())
132
- return *it;
133
- }
134
-
135
- // Acquire a writer-lock so that we can safely create the new instance.
136
- ScopedWriterLock instanceLock (mutex, threadingIsEnabled);
137
-
138
- // Check for an existing instance again here, because another writer thread
139
- // may have already created one. Otherwise, construct a new instance.
140
- auto existing = container.insert_as (ValueT (), key);
141
- if (existing.second )
142
- return *existing.first = constructorFn ();
143
- return *existing.first ;
144
- }
145
-
146
- namespace {
147
- struct AffineMapKeyInfo : DenseMapInfo<AffineMap> {
148
- // Affine maps are uniqued based on their dim/symbol counts and affine
149
- // expressions.
150
- using KeyTy = std::tuple<unsigned , unsigned , ArrayRef<AffineExpr>>;
151
- using DenseMapInfo<AffineMap>::isEqual;
152
-
153
- static unsigned getHashValue (const AffineMap &key) {
154
- return getHashValue (
155
- KeyTy (key.getNumDims (), key.getNumSymbols (), key.getResults ()));
156
- }
157
-
158
- static unsigned getHashValue (KeyTy key) {
159
- return hash_combine (
160
- std::get<0 >(key), std::get<1 >(key),
161
- hash_combine_range (std::get<2 >(key).begin (), std::get<2 >(key).end ()));
162
- }
163
-
164
- static bool isEqual (const KeyTy &lhs, AffineMap rhs) {
165
- if (rhs == getEmptyKey () || rhs == getTombstoneKey ())
166
- return false ;
167
- return lhs == std::make_tuple (rhs.getNumDims (), rhs.getNumSymbols (),
168
- rhs.getResults ());
169
- }
170
- };
171
-
172
- struct IntegerSetKeyInfo : DenseMapInfo<IntegerSet> {
173
- // Integer sets are uniqued based on their dim/symbol counts, affine
174
- // expressions appearing in the LHS of constraints, and eqFlags.
175
- using KeyTy =
176
- std::tuple<unsigned , unsigned , ArrayRef<AffineExpr>, ArrayRef<bool >>;
177
- using DenseMapInfo<IntegerSet>::isEqual;
178
-
179
- static unsigned getHashValue (const IntegerSet &key) {
180
- return getHashValue (KeyTy (key.getNumDims (), key.getNumSymbols (),
181
- key.getConstraints (), key.getEqFlags ()));
182
- }
183
-
184
- static unsigned getHashValue (KeyTy key) {
185
- return hash_combine (
186
- std::get<0 >(key), std::get<1 >(key),
187
- hash_combine_range (std::get<2 >(key).begin (), std::get<2 >(key).end ()),
188
- hash_combine_range (std::get<3 >(key).begin (), std::get<3 >(key).end ()));
189
- }
190
-
191
- static bool isEqual (const KeyTy &lhs, IntegerSet rhs) {
192
- if (rhs == getEmptyKey () || rhs == getTombstoneKey ())
193
- return false ;
194
- return lhs == std::make_tuple (rhs.getNumDims (), rhs.getNumSymbols (),
195
- rhs.getConstraints (), rhs.getEqFlags ());
196
- }
197
- };
198
- } // end anonymous namespace.
199
-
200
115
// ===----------------------------------------------------------------------===//
201
116
// MLIRContextImpl
202
117
// ===----------------------------------------------------------------------===//
@@ -279,19 +194,7 @@ class MLIRContextImpl {
279
194
// Affine uniquing
280
195
// ===--------------------------------------------------------------------===//
281
196
282
- // Affine allocator and mutex for thread safety.
283
- llvm::BumpPtrAllocator affineAllocator;
284
- llvm::sys::SmartRWMutex<true > affineMutex;
285
-
286
- // Affine map uniquing.
287
- using AffineMapSet = DenseSet<AffineMap, AffineMapKeyInfo>;
288
- AffineMapSet affineMaps;
289
-
290
- // Integer set uniquing.
291
- using IntegerSets = DenseSet<IntegerSet, IntegerSetKeyInfo>;
292
- IntegerSets integerSets;
293
-
294
- // Affine expression uniquing.
197
+ // Affine expression, map and integer set uniquing.
295
198
StorageUniquer affineUniquer;
296
199
297
200
// ===--------------------------------------------------------------------===//
@@ -415,6 +318,8 @@ MLIRContext::MLIRContext(const DialectRegistry ®istry, Threading setting)
415
318
impl->affineUniquer
416
319
.registerParametricStorageType <AffineConstantExprStorage>();
417
320
impl->affineUniquer .registerParametricStorageType <AffineDimExprStorage>();
321
+ impl->affineUniquer .registerParametricStorageType <AffineMapStorage>();
322
+ impl->affineUniquer .registerParametricStorageType <IntegerSetStorage>();
418
323
}
419
324
420
325
MLIRContext::~MLIRContext () {}
@@ -995,21 +900,10 @@ AffineMap AffineMap::getImpl(unsigned dimCount, unsigned symbolCount,
995
900
ArrayRef<AffineExpr> results,
996
901
MLIRContext *context) {
997
902
auto &impl = context->getImpl ();
998
- auto key = std::make_tuple (dimCount, symbolCount, results);
999
-
1000
- // Safely get or create an AffineMap instance.
1001
- return safeGetOrCreate (
1002
- impl.affineMaps , key, impl.affineMutex , impl.threadingIsEnabled , [&] {
1003
- auto *res = impl.affineAllocator .Allocate <detail::AffineMapStorage>();
1004
-
1005
- // Copy the results into the bump pointer.
1006
- results = copyArrayRefInto (impl.affineAllocator , results);
1007
-
1008
- // Initialize the memory using placement new.
1009
- new (res)
1010
- detail::AffineMapStorage{dimCount, symbolCount, results, context};
1011
- return AffineMap (res);
1012
- });
903
+ auto *storage = impl.affineUniquer .get <AffineMapStorage>(
904
+ [&](AffineMapStorage *storage) { storage->context = context; }, dimCount,
905
+ symbolCount, results);
906
+ return AffineMap (storage);
1013
907
}
1014
908
1015
909
// / Check whether the arguments passed to the AffineMap::get() are consistent.
@@ -1069,33 +963,9 @@ IntegerSet IntegerSet::get(unsigned dimCount, unsigned symbolCount,
1069
963
assert (constraints.size () == eqFlags.size ());
1070
964
1071
965
auto &impl = constraints[0 ].getContext ()->getImpl ();
1072
-
1073
- // A utility function to construct a new IntegerSetStorage instance.
1074
- auto constructorFn = [&] {
1075
- auto *res = impl.affineAllocator .Allocate <detail::IntegerSetStorage>();
1076
-
1077
- // Copy the results and equality flags into the bump pointer.
1078
- constraints = copyArrayRefInto (impl.affineAllocator , constraints);
1079
- eqFlags = copyArrayRefInto (impl.affineAllocator , eqFlags);
1080
-
1081
- // Initialize the memory using placement new.
1082
- new (res)
1083
- detail::IntegerSetStorage{dimCount, symbolCount, constraints, eqFlags};
1084
- return IntegerSet (res);
1085
- };
1086
-
1087
- // If this instance is uniqued, then we handle it separately so that multiple
1088
- // threads may simultaneously access existing instances.
1089
- if (constraints.size () < IntegerSet::kUniquingThreshold ) {
1090
- auto key = std::make_tuple (dimCount, symbolCount, constraints, eqFlags);
1091
- return safeGetOrCreate (impl.integerSets , key, impl.affineMutex ,
1092
- impl.threadingIsEnabled , constructorFn);
1093
- }
1094
-
1095
- // Otherwise, acquire a writer-lock so that we can safely create the new
1096
- // instance.
1097
- ScopedWriterLock affineLock (impl.affineMutex , impl.threadingIsEnabled );
1098
- return constructorFn ();
966
+ auto *storage = impl.affineUniquer .get <IntegerSetStorage>(
967
+ [](IntegerSetStorage *) {}, dimCount, symbolCount, constraints, eqFlags);
968
+ return IntegerSet (storage);
1099
969
}
1100
970
1101
971
// ===----------------------------------------------------------------------===//
0 commit comments