3737#include " support/insert_ordered.h"
3838#endif
3939
40+ #if UNSUBTYPING_DEBUG
41+ #define DBG (x ) x
42+ #else
43+ #define DBG (x )
44+ #endif
45+
4046// Compute and use the minimal subtype relation required to maintain module
4147// validity and behavior. This minimal relation will be a subset of the original
4248// subtype relation. Start by walking the IR and collecting pairs of types that
@@ -122,6 +128,16 @@ template<typename T> using Set = InsertOrderedSet<T>;
122128template <typename K, typename V> using Map = std::unordered_map<K, V>;
123129template <typename T> using Set = std::unordered_set<T>;
124130#endif
131+
132+ #if UNSUBTYPING_DEBUG
133+ Name getTypeName (Module& wasm, HeapType type) {
134+ if (auto it = wasm.typeNames .find (type); it != wasm.typeNames .end ()) {
135+ return it->second .name ;
136+ }
137+ return Name (" (unnamed)" );
138+ }
139+ #endif
140+
125141// A tree (or rather a forest) of types with the ability to query and set
126142// supertypes in constant time and efficiently iterate over supertypes and
127143// subtypes.
@@ -272,6 +288,22 @@ struct TypeTree {
272288
273289 Subtypes subtypes (HeapType type) { return {this , getIndex (type)}; }
274290
291+ #if UNSUBTYPING_DEBUG
292+ void dump (Module& wasm) {
293+ for (auto & node : nodes) {
294+ std::cerr << getTypeName (wasm, node.type );
295+ if (auto super = getSupertype (node.type )) {
296+ std::cerr << " <: " << getTypeName (wasm, *super);
297+ }
298+ std::cerr << " , children:" ;
299+ for (auto child : node.children ) {
300+ std::cerr << " " << getTypeName (wasm, nodes[child].type );
301+ }
302+ std::cerr << ' \n ' ;
303+ }
304+ }
305+ #endif
306+
275307private:
276308 Index getIndex (HeapType type) {
277309 auto [it, inserted] = indices.insert ({type, nodes.size ()});
@@ -293,7 +325,10 @@ struct Unsubtyping : Pass {
293325 // Map from cast source types to their destinations.
294326 Map<HeapType, std::vector<HeapType>> casts;
295327
328+ DBG (Module* wasm = nullptr );
329+
296330 void run (Module* wasm) override {
331+ DBG (this ->wasm = wasm);
297332 if (!wasm->features .hasGC ()) {
298333 return ;
299334 }
@@ -310,6 +345,7 @@ struct Unsubtyping : Pass {
310345 process (sub, super);
311346 }
312347
348+ DBG (types.dump (*wasm));
313349 rewriteTypes (*wasm);
314350
315351 // Cast types may be refinable if their source and target types are no
@@ -324,6 +360,8 @@ struct Unsubtyping : Pass {
324360 if (sub == super || sub.isBottom ()) {
325361 return ;
326362 }
363+ DBG (std::cerr << " noting " << getTypeName (*wasm, sub)
364+ << " <: " << getTypeName (*wasm, super) << ' \n ' );
327365 work.push_back ({sub, super});
328366 }
329367
@@ -482,6 +520,8 @@ struct Unsubtyping : Pass {
482520 }
483521
484522 void process (HeapType sub, HeapType super) {
523+ DBG (std::cerr << " processing " << getTypeName (*wasm, sub)
524+ << " <: " << getTypeName (*wasm, super) << ' \n ' );
485525 assert (HeapType::isSubType (sub, super));
486526 auto oldSuper = types.getSupertype (sub);
487527 if (oldSuper) {
0 commit comments