@@ -112,91 +112,6 @@ struct ScopedWriterLock {
112112};
113113} // end anonymous namespace.
114114
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-
200115// ===----------------------------------------------------------------------===//
201116// MLIRContextImpl
202117// ===----------------------------------------------------------------------===//
@@ -279,19 +194,7 @@ class MLIRContextImpl {
279194 // Affine uniquing
280195 // ===--------------------------------------------------------------------===//
281196
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.
295198 StorageUniquer affineUniquer;
296199
297200 // ===--------------------------------------------------------------------===//
@@ -415,6 +318,8 @@ MLIRContext::MLIRContext(const DialectRegistry ®istry, Threading setting)
415318 impl->affineUniquer
416319 .registerParametricStorageType <AffineConstantExprStorage>();
417320 impl->affineUniquer .registerParametricStorageType <AffineDimExprStorage>();
321+ impl->affineUniquer .registerParametricStorageType <AffineMapStorage>();
322+ impl->affineUniquer .registerParametricStorageType <IntegerSetStorage>();
418323}
419324
420325MLIRContext::~MLIRContext () {}
@@ -995,21 +900,10 @@ AffineMap AffineMap::getImpl(unsigned dimCount, unsigned symbolCount,
995900 ArrayRef<AffineExpr> results,
996901 MLIRContext *context) {
997902 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);
1013907}
1014908
1015909// / Check whether the arguments passed to the AffineMap::get() are consistent.
@@ -1069,33 +963,9 @@ IntegerSet IntegerSet::get(unsigned dimCount, unsigned symbolCount,
1069963 assert (constraints.size () == eqFlags.size ());
1070964
1071965 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);
1099969}
1100970
1101971// ===----------------------------------------------------------------------===//
0 commit comments