@@ -136,6 +136,10 @@ template<typename CompareTypes> struct RecGroupComparator {
136136 }
137137
138138 Comparison compare (Type a, Type b) {
139+ // Compare types as they will eventually be written out, not as they are in
140+ // the IR.
141+ a = a.asWrittenGivenFeatures (features);
142+ b = b.asWrittenGivenFeatures (features);
139143 if (a.isBasic () != b.isBasic ()) {
140144 return b.isBasic () < a.isBasic () ? LT : GT;
141145 }
@@ -152,14 +156,12 @@ template<typename CompareTypes> struct RecGroupComparator {
152156 return compare (a.getTuple (), b.getTuple ());
153157 }
154158 assert (a.isRef () && b.isRef ());
155- // Only consider exactness if custom descriptors are enabled. Otherwise, it
156- // will be erased when the types are written, so we ignore it here, too.
157- if (features.hasCustomDescriptors () && a.isExact () != b.isExact ()) {
158- return a.isExact () < b.isExact () ? LT : GT;
159- }
160159 if (a.isNullable () != b.isNullable ()) {
161160 return a.isNullable () < b.isNullable () ? LT : GT;
162161 }
162+ if (a.isExact () != b.isExact ()) {
163+ return a.isExact () < b.isExact () ? LT : GT;
164+ }
163165 return compare (a.getHeapType (), b.getHeapType ());
164166 }
165167
@@ -294,6 +296,9 @@ struct RecGroupHasher {
294296 }
295297
296298 size_t hash (Type type) {
299+ // Hash types as they will eventually be written out, not as they are in the
300+ // IR.
301+ type = type.asWrittenGivenFeatures (features);
297302 size_t digest = wasm::hash (type.isBasic ());
298303 if (type.isBasic ()) {
299304 wasm::rehash (digest, type.getBasic ());
@@ -305,10 +310,8 @@ struct RecGroupHasher {
305310 return digest;
306311 }
307312 assert (type.isRef ());
308- if (features.hasCustomDescriptors ()) {
309- wasm::rehash (digest, type.isExact ());
310- }
311313 wasm::rehash (digest, type.isNullable ());
314+ wasm::rehash (digest, type.isExact ());
312315 hash_combine (digest, hash (type.getHeapType ()));
313316 return digest;
314317 }
@@ -372,15 +375,16 @@ bool ComparableRecGroupShape::operator>(const RecGroupShape& other) const {
372375
373376const std::vector<HeapType>&
374377UniqueRecGroups::insert (std::vector<HeapType> types) {
375- auto & group = *groups.emplace (groups.end (), std::move (types));
376- if (shapes.emplace (RecGroupShape (group, features)).second ) {
378+ auto groupIt = groups.emplace (groups.end (), std::move (types));
379+ auto & group = *groupIt;
380+ if (shapes.emplace (RecGroupShape (group, features), groupIt).second ) {
377381 // The types are already unique.
378382 return group;
379383 }
380384 // There is a conflict. Find a brand that makes the group unique.
381385 BrandTypeIterator brand;
382386 group.push_back (*brand);
383- while (!shapes.emplace (RecGroupShape (group, features)).second ) {
387+ while (!shapes.emplace (RecGroupShape (group, features), groupIt ).second ) {
384388 group.back () = *++brand;
385389 }
386390 // Rebuild the rec group to include the brand. Map the old types (excluding
@@ -405,6 +409,17 @@ UniqueRecGroups::insert(std::vector<HeapType> types) {
405409 return group;
406410}
407411
412+ const std::vector<HeapType>&
413+ UniqueRecGroups::insertOrGet (std::vector<HeapType> types) {
414+ auto groupIt = groups.emplace (groups.end (), std::move (types));
415+ auto [it, inserted] =
416+ shapes.emplace (RecGroupShape (*groupIt, features), groupIt);
417+ if (!inserted) {
418+ groups.erase (groupIt);
419+ }
420+ return *it->second ;
421+ }
422+
408423} // namespace wasm
409424
410425namespace std {
0 commit comments