diff options
-rw-r--r-- | src/passes/RemoveUnusedModuleElements.cpp | 134 |
1 files changed, 41 insertions, 93 deletions
diff --git a/src/passes/RemoveUnusedModuleElements.cpp b/src/passes/RemoveUnusedModuleElements.cpp index 88e806768..e082f8e15 100644 --- a/src/passes/RemoveUnusedModuleElements.cpp +++ b/src/passes/RemoveUnusedModuleElements.cpp @@ -50,22 +50,17 @@ namespace wasm { -enum class ModuleElementKind { - Function, - Global, - Tag, - Memory, - Table, - DataSegment, - ElementSegment, -}; +// TODO: remove this alias +using ModuleElementKind = ModuleItemKind; // An element in the module that we track: a kind (function, global, etc.) + the // name of the particular element. using ModuleElement = std::pair<ModuleElementKind, Name>; // Visit or walk an expression to find what things are referenced. -struct ReferenceFinder : public PostWalker<ReferenceFinder> { +struct ReferenceFinder + : public PostWalker<ReferenceFinder, + UnifiedExpressionVisitor<ReferenceFinder>> { // Our findings are placed in these data structures, which the user of this // code can then process. std::vector<ModuleElement> elements; @@ -79,7 +74,38 @@ struct ReferenceFinder : public PostWalker<ReferenceFinder> { void noteRefFunc(Name refFunc) { refFuncs.push_back(refFunc); } void note(StructField structField) { structFields.push_back(structField); } - // Visitors + // Generic visitor + + void visitExpression(Expression* curr) { +#define DELEGATE_ID curr->_id + +#define DELEGATE_START(id) [[maybe_unused]] auto* cast = curr->cast<id>(); + +#define DELEGATE_GET_FIELD(id, field) cast->field + +#define DELEGATE_FIELD_TYPE(id, field) +#define DELEGATE_FIELD_HEAPTYPE(id, field) +#define DELEGATE_FIELD_CHILD(id, field) +#define DELEGATE_FIELD_OPTIONAL_CHILD(id, field) +#define DELEGATE_FIELD_INT(id, field) +#define DELEGATE_FIELD_INT_ARRAY(id, field) +#define DELEGATE_FIELD_LITERAL(id, field) +#define DELEGATE_FIELD_NAME(id, field) +#define DELEGATE_FIELD_NAME_VECTOR(id, field) +#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field) +#define DELEGATE_FIELD_SCOPE_NAME_USE(id, field) +#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field) +#define DELEGATE_FIELD_ADDRESS(id, field) + +#define DELEGATE_FIELD_NAME_KIND(id, field, kind) \ + if (cast->field.is()) { \ + note({kind, cast->field}); \ + } + +#include "wasm-delegations-fields.def" + } + + // Specific visitors void visitCall(Call* curr) { note({ModuleElementKind::Function, curr->target}); @@ -126,76 +152,8 @@ struct ReferenceFinder : public PostWalker<ReferenceFinder> { noteCallRef(curr->target->type.getHeapType()); } - void visitGlobalGet(GlobalGet* curr) { - note({ModuleElementKind::Global, curr->name}); - } - void visitGlobalSet(GlobalSet* curr) { - note({ModuleElementKind::Global, curr->name}); - } - - void visitLoad(Load* curr) { - note({ModuleElementKind::Memory, curr->memory}); - } - void visitStore(Store* curr) { - note({ModuleElementKind::Memory, curr->memory}); - } - void visitAtomicCmpxchg(AtomicCmpxchg* curr) { - note({ModuleElementKind::Memory, curr->memory}); - } - void visitAtomicRMW(AtomicRMW* curr) { - note({ModuleElementKind::Memory, curr->memory}); - } - void visitAtomicWait(AtomicWait* curr) { - note({ModuleElementKind::Memory, curr->memory}); - } - void visitAtomicNotify(AtomicNotify* curr) { - note({ModuleElementKind::Memory, curr->memory}); - } - void visitSIMDLoad(SIMDLoad* curr) { - note({ModuleElementKind::Memory, curr->memory}); - } - void visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) { - note({ModuleElementKind::Memory, curr->memory}); - } - void visitMemoryInit(MemoryInit* curr) { - note({ModuleElementKind::DataSegment, curr->segment}); - note({ModuleElementKind::Memory, curr->memory}); - } - void visitDataDrop(DataDrop* curr) { - note({ModuleElementKind::DataSegment, curr->segment}); - } - void visitMemoryCopy(MemoryCopy* curr) { - note({ModuleElementKind::Memory, curr->destMemory}); - note({ModuleElementKind::Memory, curr->sourceMemory}); - } - void visitMemoryFill(MemoryFill* curr) { - note({ModuleElementKind::Memory, curr->memory}); - } - void visitMemorySize(MemorySize* curr) { - note({ModuleElementKind::Memory, curr->memory}); - } - void visitMemoryGrow(MemoryGrow* curr) { - note({ModuleElementKind::Memory, curr->memory}); - } void visitRefFunc(RefFunc* curr) { noteRefFunc(curr->func); } - void visitTableGet(TableGet* curr) { - note({ModuleElementKind::Table, curr->table}); - } - void visitTableSet(TableSet* curr) { - note({ModuleElementKind::Table, curr->table}); - } - void visitTableSize(TableSize* curr) { - note({ModuleElementKind::Table, curr->table}); - } - void visitTableGrow(TableGrow* curr) { - note({ModuleElementKind::Table, curr->table}); - } - void visitThrow(Throw* curr) { note({ModuleElementKind::Tag, curr->tag}); } - void visitTry(Try* curr) { - for (auto tag : curr->catchTags) { - note({ModuleElementKind::Tag, tag}); - } - } + void visitStructGet(StructGet* curr) { if (curr->ref->type == Type::unreachable || curr->ref->type.isNull()) { return; @@ -203,19 +161,6 @@ struct ReferenceFinder : public PostWalker<ReferenceFinder> { auto type = curr->ref->type.getHeapType(); note(StructField{type, curr->index}); } - // TODO: use delegations-fields - void visitArrayNewData(ArrayNewData* curr) { - note({ModuleElementKind::DataSegment, curr->segment}); - } - void visitArrayNewElem(ArrayNewElem* curr) { - note({ModuleElementKind::ElementSegment, curr->segment}); - } - void visitArrayInitData(ArrayInitData* curr) { - note({ModuleElementKind::DataSegment, curr->segment}); - } - void visitArrayInitElem(ArrayInitElem* curr) { - note({ModuleElementKind::ElementSegment, curr->segment}); - } }; // Analyze a module to find what things are referenced and what things are used. @@ -493,6 +438,9 @@ struct Analyzer { } break; } + default: { + WASM_UNREACHABLE("invalid kind"); + } } } return worked; |