33
33
// permutations, fall back to keeping the types distinct by adding distinct
34
34
// brand types to the recursion groups to ensure they have different shapes.
35
35
//
36
- // There are several possible algorithmic design for detecting when to generate
36
+ // There are several possible algorithmic designs for detecting when to generate
37
37
// permutations and determining what permutations to generate. They trade off
38
38
// the amount of "wasted" work spent generating shapes that have already been
39
39
// used with the amount of work spent trying to avoid the wasted work and with
@@ -161,23 +161,30 @@ struct BrandTypeIterator {
161
161
}
162
162
};
163
163
164
- // Create an adjacency list with edges from supertype to subtypes.
164
+ // Create an adjacency list with edges from supertype to subtype and from
165
+ // described type to descriptor.
165
166
std::vector<std::vector<Index>>
166
- createSubtypeGraph (const std::vector<HeapType>& types) {
167
+ createTypeOrderGraph (const std::vector<HeapType>& types) {
167
168
std::unordered_map<HeapType, Index> indices;
168
169
for (auto type : types) {
169
170
indices.insert ({type, indices.size ()});
170
171
}
171
172
172
- std::vector<std::vector<Index>> subtypeGraph (types.size ());
173
+ std::vector<std::vector<Index>> typeOrderGraph (types.size ());
173
174
for (Index i = 0 ; i < types.size (); ++i) {
174
175
if (auto super = types[i].getDeclaredSuperType ()) {
175
176
if (auto it = indices.find (*super); it != indices.end ()) {
176
- subtypeGraph [it->second ].push_back (i);
177
+ typeOrderGraph [it->second ].push_back (i);
177
178
}
178
179
}
180
+ if (auto desc = types[i].getDescribedType ()) {
181
+ // Described types must be in the same SCC / rec group.
182
+ auto it = indices.find (*desc);
183
+ assert (it != indices.end ());
184
+ typeOrderGraph[it->second ].push_back (i);
185
+ }
179
186
}
180
- return subtypeGraph ;
187
+ return typeOrderGraph ;
181
188
}
182
189
183
190
struct RecGroupInfo ;
@@ -199,13 +206,13 @@ struct GroupClassInfo {
199
206
// group, offset by 1 iff there is a brand type. Used to ensure that we only
200
207
// find emit permutations that respect the constraint that supertypes must be
201
208
// ordered before subtypes.
202
- std::vector<std::vector<Index>> subtypeGraph ;
209
+ std::vector<std::vector<Index>> typeOrderGraph ;
203
210
// A generator of valid permutations of the components in this class.
204
211
TopologicalOrders orders;
205
212
206
- // Initialize `subtypeGraph ` and `orders` based on the canonical ordering
213
+ // Initialize `typeOrderGraph ` and `orders` based on the canonical ordering
207
214
// encoded by the group and permutation in `info`.
208
- static std::vector<std::vector<Index>> initSubtypeGraph (RecGroupInfo& info);
215
+ static std::vector<std::vector<Index>> initTypeOrderGraph (RecGroupInfo& info);
209
216
GroupClassInfo (RecGroupInfo& info);
210
217
211
218
void advance (FeatureSet features) {
@@ -222,10 +229,10 @@ struct GroupClassInfo {
222
229
brand.emplace ();
223
230
// Make room in the subtype graph for the brand type, which goes at the
224
231
// beginning of the canonical order.
225
- subtypeGraph .insert (subtypeGraph .begin (), {{}});
232
+ typeOrderGraph .insert (typeOrderGraph .begin (), {{}});
226
233
// Adjust indices.
227
- for (Index i = 1 ; i < subtypeGraph .size (); ++i) {
228
- for (auto & edge : subtypeGraph [i]) {
234
+ for (Index i = 1 ; i < typeOrderGraph .size (); ++i) {
235
+ for (auto & edge : typeOrderGraph [i]) {
229
236
++edge;
230
237
}
231
238
}
@@ -237,7 +244,7 @@ struct GroupClassInfo {
237
244
}
238
245
// Start back at the initial permutation with the new brand.
239
246
orders.~TopologicalOrders ();
240
- new (&orders) TopologicalOrders (subtypeGraph );
247
+ new (&orders) TopologicalOrders (typeOrderGraph );
241
248
}
242
249
243
250
// Permute the types in the given group to match the current configuration in
@@ -266,7 +273,7 @@ struct RecGroupInfo {
266
273
};
267
274
268
275
std::vector<std::vector<Index>>
269
- GroupClassInfo::initSubtypeGraph (RecGroupInfo& info) {
276
+ GroupClassInfo::initTypeOrderGraph (RecGroupInfo& info) {
270
277
assert (!info.classInfo );
271
278
assert (info.permutation .size () == info.group .size ());
272
279
@@ -275,19 +282,19 @@ GroupClassInfo::initSubtypeGraph(RecGroupInfo& info) {
275
282
canonical[info.permutation [i]] = info.group [i];
276
283
}
277
284
278
- return createSubtypeGraph (canonical);
285
+ return createTypeOrderGraph (canonical);
279
286
}
280
287
281
288
GroupClassInfo::GroupClassInfo (RecGroupInfo& info)
282
289
: singletonType(info.group.size() == 1
283
290
? std::optional<HeapType>(info.group[0 ])
284
291
: std::nullopt),
285
- brand(std::nullopt), subtypeGraph(initSubtypeGraph (info)),
286
- orders(subtypeGraph ) {}
292
+ brand(std::nullopt), typeOrderGraph(initTypeOrderGraph (info)),
293
+ orders(typeOrderGraph ) {}
287
294
288
295
void GroupClassInfo::permute (RecGroupInfo& info) {
289
296
assert (info.group .size () == info.permutation .size ());
290
- bool insertingBrand = info.group .size () < subtypeGraph .size ();
297
+ bool insertingBrand = info.group .size () < typeOrderGraph .size ();
291
298
// First, un-permute the group to get back to the canonical order, offset by 1
292
299
// if we are newly inserting a brand.
293
300
std::vector<HeapType> canonical (info.group .size () + insertingBrand);
@@ -422,9 +429,9 @@ struct MinimizeRecGroups : Pass {
422
429
groups.emplace_back ();
423
430
424
431
// The SCC is not necessarily topologically sorted to have the supertypes
425
- // come first. Fix that.
432
+ // and described types come first. Fix that.
426
433
std::vector<HeapType> sccTypes (scc.begin (), scc.end ());
427
- auto deps = createSubtypeGraph (sccTypes);
434
+ auto deps = createTypeOrderGraph (sccTypes);
428
435
auto permutation = *TopologicalOrders (deps).begin ();
429
436
groups.back ().group .resize (sccTypes.size ());
430
437
for (Index i = 0 ; i < sccTypes.size (); ++i) {
0 commit comments