|
45 | 45 | #include "pass.h"
|
46 | 46 | #include "support/dfa_minimization.h"
|
47 | 47 | #include "support/small_set.h"
|
48 |
| -#include "wasm-builder.h" |
49 |
| -#include "wasm-type-ordering.h" |
| 48 | +#include "support/topological_sort.h" |
50 | 49 | #include "wasm-type.h"
|
51 | 50 | #include "wasm.h"
|
52 | 51 |
|
@@ -169,13 +168,31 @@ struct TypeMerging : public Pass {
|
169 | 168 |
|
170 | 169 | std::vector<HeapType>
|
171 | 170 | mergeableSupertypesFirst(const std::vector<HeapType>& types) {
|
172 |
| - return HeapTypeOrdering::supertypesFirst( |
173 |
| - types, [&](HeapType type) -> std::optional<HeapType> { |
| 171 | + // Topological sort so that supertypes come first. Since we treat descriptor |
| 172 | + // chains as units represented by their base described types, we must handle |
| 173 | + // the case where one chain has multiple unrelated chains as supertypes. |
| 174 | + InsertOrderedMap<HeapType, std::vector<HeapType>> subtypes; |
| 175 | + for (auto type : types) { |
| 176 | + // Skip descriptor types, since they will be considered as a unit with |
| 177 | + // their base described types. |
| 178 | + if (type.getDescribedType()) { |
| 179 | + continue; |
| 180 | + } |
| 181 | + subtypes.insert({type, {}}); |
| 182 | + } |
| 183 | + // Find the base described type (`superBase`) for each supertype in the |
| 184 | + // chain starting at `subBase`. |
| 185 | + for (auto [subBase, _] : subtypes) { |
| 186 | + for (auto type : subBase.getDescriptorChain()) { |
174 | 187 | if (auto super = type.getDeclaredSuperType()) {
|
175 |
| - return getMerged(*super); |
| 188 | + auto superBase = getMerged(getBaseDescribedType(*super)); |
| 189 | + if (auto it = subtypes.find(superBase); it != subtypes.end()) { |
| 190 | + it->second.push_back(subBase); |
| 191 | + } |
176 | 192 | }
|
177 |
| - return std::nullopt; |
178 |
| - }); |
| 193 | + } |
| 194 | + } |
| 195 | + return TopologicalSort::sortOf(subtypes.begin(), subtypes.end()); |
179 | 196 | }
|
180 | 197 |
|
181 | 198 | void run(Module* module_) override;
|
@@ -354,13 +371,7 @@ bool TypeMerging::merge(MergeKind kind) {
|
354 | 371 | // For each type, either create a new partition or add to its supertype's
|
355 | 372 | // partition.
|
356 | 373 | for (auto type : mergeableSupertypesFirst(mergeable)) {
|
357 |
| - // Skip descriptor types. Since types in descriptor chains all have to be |
358 |
| - // merged into matching descriptor chains together, only the base described |
359 |
| - // type in each chain is considered, and its DFA state will include the |
360 |
| - // shape of its entire descriptor chain. |
361 |
| - if (type.getDescribedType()) { |
362 |
| - continue; |
363 |
| - } |
| 374 | + assert(!type.getDescribedType()); |
364 | 375 | // We need partitions for any public children of this type since those
|
365 | 376 | // children will participate in the DFA we're creating. We use the base
|
366 | 377 | // described type of the child because that's the type that the DFA state
|
|
0 commit comments