From ec039c65bc54b63f9b3ce7240b19817f9689dac9 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Tue, 20 Jan 2026 07:57:49 +0000 Subject: [PATCH 1/6] [wasm-split] Export/Import only necessary elements In `ModuleSplitter::shareImportableItems`, we now check if each module element is used by a secondary module and export & import it only when it is necessary. This removes the need to run RemoveUnusedModuleElements pass for secondary modules at the end, and also removes unnecessary exports from the primary module in case they are not used in any secondary modules. This reduces the running time on a 'acx_gallery' reproducer provided by @biggs0125 before from 78.3s to 16.4s in average on my machine, reducing it by around 79%. In that 'acx_gallery' program, this PR reduces the size of the primary module by 8% and reduces the all combined module size (primary + secondaries) by 3.7%. --- Detailed analysis for 'acx_gallery', a case where we split a module into 301 (1 primary + 300 secondary) modules: - Before this PR: Time: 78.3s Task breakdown: ``` Task Total Time (ms) Percentage --------------------------------------------------------------------------- shareImportableItems 34472.0000 49.90% removeUnusedSecondaryElements 24720.2000 35.78% moveSecondaryFunctions 4938.0500 7.15% writeModule_secondary 2892.7603 4.19% writeModule_primary 897.3630 1.30% exportImportCalledPrimaryFunctions 667.9780 0.97% indirectReferencesToSecondaryFunctions 201.9830 0.29% indirectCallsToSecondaryFunctions 133.2190 0.19% classifyFunctions 118.3200 0.17% setupTablePatching 42.6402 0.06% thunkExportedSecondaryFunctions 0.9307 0.00% initExportedPrimaryFuncs 0.8008 0.00% --------------------------------------------------------------------------- Overall Total ``` - After this PR: Time: 16.4s Task breakdown: ``` Task Total Time (ms) Percentage --------------------------------------------------------------------------- moveSecondaryFunctions 5341.1700 43.94% writeModule_secondary 2960.8319 24.36% shareImportableItems 1568.6400 12.91% writeModule_primary 765.7240 6.30% exportImportCalledPrimaryFunctions 762.9670 6.28% indirectReferencesToSecondaryFunctions 362.3300 2.98% classifyFunctions 204.4540 1.68% indirectCallsToSecondaryFunctions 139.2110 1.15% setupTablePatching 45.2461 0.37% thunkExportedSecondaryFunctions 3.0373 0.02% initExportedPrimaryFuncs 0.9982 0.01% --------------------------------------------------------------------------- Overall Total 12154.6095 100.00% ``` We can see that `shareImportableItems`, which took up the largest share, has been reduced significantly, and `removeUnusedSecondaryElements`, which was the second largest, is not necessary anymore. --- src/ir/module-splitting.cpp | 115 +++++++++++++++--- test/lit/wasm-split/basic.wast | 1 - test/lit/wasm-split/passive.wast | 6 +- test/lit/wasm-split/ref.func.wast | 10 +- test/lit/wasm-split/segments.wast | 2 - test/lit/wasm-split/selective-exports.wast | 57 +++++++++ test/lit/wasm-split/table64-const-offset.wast | 5 +- .../lit/wasm-split/table64-global-offset.wast | 6 +- test/lit/wasm-split/trampoline.wast | 6 +- 9 files changed, 164 insertions(+), 44 deletions(-) create mode 100644 test/lit/wasm-split/selective-exports.wast diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp index 797314e9f34..a6d624cf8ac 100644 --- a/src/ir/module-splitting.cpp +++ b/src/ir/module-splitting.cpp @@ -343,7 +343,6 @@ struct ModuleSplitter { void exportImportCalledPrimaryFunctions(); void setupTablePatching(); void shareImportableItems(); - void removeUnusedSecondaryElements(); ModuleSplitter(Module& primary, const Config& config) : config(config), primary(primary), tableManager(primary), @@ -359,7 +358,6 @@ struct ModuleSplitter { exportImportCalledPrimaryFunctions(); setupTablePatching(); shareImportableItems(); - removeUnusedSecondaryElements(); } }; @@ -911,12 +909,98 @@ void ModuleSplitter::shareImportableItems() { } }; - // TODO: Be more selective by only sharing global items that are actually used - // in the secondary module, just like we do for functions. + struct UsedNames { + std::unordered_set globals; + std::unordered_set memories; + std::unordered_set tables; + std::unordered_set tags; + }; + + struct NameCollector + : public PostWalker> { + UsedNames& used; + NameCollector(UsedNames& used) : used(used) {} + + void visitExpression(Expression* curr) { +#define DELEGATE_ID curr->_id +#define DELEGATE_START(id) [[maybe_unused]] auto* cast = curr->cast(); +#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_INT(id, field) +#define DELEGATE_FIELD_LITERAL(id, field) +#define DELEGATE_FIELD_NAME(id, field) +#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field) +#define DELEGATE_FIELD_SCOPE_NAME_USE(id, field) +#define DELEGATE_FIELD_ADDRESS(id, field) + +#define DELEGATE_FIELD_NAME_KIND(id, field, kind) \ + if (cast->field.is()) { \ + if (kind == ModuleItemKind::Global) { \ + used.globals.insert(cast->field); \ + } else if (kind == ModuleItemKind::Table) { \ + used.tables.insert(cast->field); \ + } else if (kind == ModuleItemKind::Memory) { \ + used.memories.insert(cast->field); \ + } else if (kind == ModuleItemKind::Tag) { \ + used.tags.insert(cast->field); \ + } \ + } + +#include "wasm-delegations-fields.def" + } + }; for (auto& secondaryPtr : secondaries) { Module& secondary = *secondaryPtr; + + // Collect names used in the secondary module + UsedNames used; + ModuleUtils::ParallelFunctionAnalysis nameCollector( + secondary, [&](Function* func, UsedNames& used) { + if (!func->imported()) { + NameCollector(used).walk(func->body); + } + }); + + for (auto& [_, funcUsed] : nameCollector.map) { + used.globals.insert(funcUsed.globals.begin(), funcUsed.globals.end()); + used.memories.insert(funcUsed.memories.begin(), funcUsed.memories.end()); + used.tables.insert(funcUsed.tables.begin(), funcUsed.tables.end()); + used.tags.insert(funcUsed.tags.begin(), funcUsed.tags.end()); + } + + NameCollector collector(used); + for (auto& global : secondary.globals) { + if (!global->imported()) { + collector.walk(global->init); + } + } + for (auto& segment : secondary.dataSegments) { + used.memories.insert(segment->memory); + if (segment->offset) { + collector.walk(segment->offset); + } + } + for (auto& segment : secondary.elementSegments) { + if (segment->table.is()) { + used.tables.insert(segment->table); + } + if (segment->offset) { + collector.walk(segment->offset); + } + for (auto* item : segment->data) { + collector.walk(item); + } + } + + // Export module items that are used in the secondary module for (auto& memory : primary.memories) { + if (!used.memories.count(memory->name)) { + continue; + } auto secondaryMemory = ModuleUtils::copyMemory(memory.get(), secondary); makeImportExport( *memory, *secondaryMemory, "memory", ExternalKind::Memory); @@ -924,14 +1008,19 @@ void ModuleSplitter::shareImportableItems() { for (auto& table : primary.tables) { auto secondaryTable = secondary.getTableOrNull(table->name); + if (!secondaryTable && !used.tables.count(table->name)) { + continue; + } if (!secondaryTable) { secondaryTable = ModuleUtils::copyTable(table.get(), secondary); } - makeImportExport(*table, *secondaryTable, "table", ExternalKind::Table); } for (auto& global : primary.globals) { + if (!used.globals.count(global->name)) { + continue; + } if (global->mutable_) { assert(primary.features.hasMutableGlobals() && "TODO: add wrapper functions for disallowed mutable globals"); @@ -949,6 +1038,9 @@ void ModuleSplitter::shareImportableItems() { } for (auto& tag : primary.tags) { + if (!used.tags.count(tag->name)) { + continue; + } auto secondaryTag = std::make_unique(); secondaryTag->type = tag->type; makeImportExport(*tag, *secondaryTag, "tag", ExternalKind::Tag); @@ -957,19 +1049,6 @@ void ModuleSplitter::shareImportableItems() { } } -void ModuleSplitter::removeUnusedSecondaryElements() { - // TODO: It would be better to be more selective about only exporting and - // importing those items that the secondary module needs. This would reduce - // code size in the primary module as well. - for (auto& secondaryPtr : secondaries) { - PassRunner runner(secondaryPtr.get()); - // Do not validate here in the middle, as the IR still needs updating later. - runner.options.validate = false; - runner.add("remove-unused-module-elements"); - runner.run(); - } -} - } // anonymous namespace Results splitFunctions(Module& primary, const Config& config) { diff --git a/test/lit/wasm-split/basic.wast b/test/lit/wasm-split/basic.wast index ef0ce332c1b..7813ac612f2 100644 --- a/test/lit/wasm-split/basic.wast +++ b/test/lit/wasm-split/basic.wast @@ -160,7 +160,6 @@ ;; KEEP-BOTH-PRIMARY-NEXT: (type $0 (func (param i32) (result i32))) ;; KEEP-BOTH-PRIMARY-NEXT: (table $table 1 1 funcref) ;; KEEP-BOTH-PRIMARY-NEXT: (elem $0 (i32.const 0) $foo) -;; KEEP-BOTH-PRIMARY-NEXT: (export "%table" (table $table)) ;; KEEP-BOTH-PRIMARY-NEXT: (func $foo (param $0 i32) (result i32) ;; KEEP-BOTH-PRIMARY-NEXT: (call $bar ;; KEEP-BOTH-PRIMARY-NEXT: (i32.const 0) diff --git a/test/lit/wasm-split/passive.wast b/test/lit/wasm-split/passive.wast index 57cdbc18af0..0b0fbfa7790 100644 --- a/test/lit/wasm-split/passive.wast +++ b/test/lit/wasm-split/passive.wast @@ -21,9 +21,7 @@ ;; PRIMARY: (elem $1 (table $1) (i32.const 0) func $placeholder_0) - ;; PRIMARY: (export "table" (table $table)) - - ;; PRIMARY: (export "table_1" (table $1)) + ;; PRIMARY: (export "table" (table $1)) ;; PRIMARY: (func $in-table (type $0) ;; PRIMARY-NEXT: ) @@ -34,7 +32,7 @@ ;; SECONDARY: (type $0 (func)) - ;; SECONDARY: (import "primary" "table_1" (table $timport$0 1 funcref)) + ;; SECONDARY: (import "primary" "table" (table $timport$0 1 funcref)) ;; SECONDARY: (elem $0 (i32.const 0) $second-in-table) diff --git a/test/lit/wasm-split/ref.func.wast b/test/lit/wasm-split/ref.func.wast index 561a63f03e9..63dc3080b16 100644 --- a/test/lit/wasm-split/ref.func.wast +++ b/test/lit/wasm-split/ref.func.wast @@ -36,13 +36,7 @@ ;; PRIMARY: (export "prime" (func $prime)) - ;; PRIMARY: (export "table" (table $table)) - - ;; PRIMARY: (export "table_2" (table $1)) - - ;; PRIMARY: (export "global" (global $glob1)) - - ;; PRIMARY: (export "global_4" (global $glob2)) + ;; PRIMARY: (export "table" (table $1)) ;; PRIMARY: (func $prime (type $0) ;; PRIMARY-NEXT: (drop @@ -63,7 +57,7 @@ ;; SECONDARY: (type $0 (func)) - ;; SECONDARY: (import "primary" "table_2" (table $timport$0 2 funcref)) + ;; SECONDARY: (import "primary" "table" (table $timport$0 2 funcref)) ;; SECONDARY: (import "primary" "prime" (func $prime (exact (type $0)))) diff --git a/test/lit/wasm-split/segments.wast b/test/lit/wasm-split/segments.wast index 0cf119a871f..123ecceae03 100644 --- a/test/lit/wasm-split/segments.wast +++ b/test/lit/wasm-split/segments.wast @@ -29,8 +29,6 @@ ;; PRIMARY: (elem $1 (i32.const 0) $placeholder_0) - ;; PRIMARY: (export "memory" (memory $mem)) - ;; PRIMARY: (export "table" (table $0)) ;; PRIMARY: (func $data.drop diff --git a/test/lit/wasm-split/selective-exports.wast b/test/lit/wasm-split/selective-exports.wast new file mode 100644 index 00000000000..4d2e0def020 --- /dev/null +++ b/test/lit/wasm-split/selective-exports.wast @@ -0,0 +1,57 @@ +;; RUN: wasm-split %s -g -o1 %t.1.wasm -o2 %t.2.wasm --keep-funcs=foo -all +;; RUN: wasm-dis %t.1.wasm | filecheck %s + +;; Check if only the module elements that are used in the secondary module are +;; exported from the primary module. + +;; CHECK: (export "memory" (memory $used-mem)) +;; CHECK-NOT: (export "{{.*}}" (memory $unused-mem)) +;; CHECK: (export "table" (table $used-table)) +;; CHECK-NOT: (export "{{.*}}" (table $unused-table)) +;; CHECK: (export "global" (global $used-global)) +;; CHECK-NOT: (export "{{.*}}" (global $unused-global)) +;; CHECK: (export "tag" (tag $used-tag)) +;; CHECK-NOT: (export "{{.*}}" (tag $unused-tag)) + +(module + (memory $used-mem 1 1) + (memory $unused-mem 1 1) + (global $used-global i32 (i32.const 10)) + (global $unused-global i32 (i32.const 20)) + (table $used-table 1 1 funcref) + (table $unused-table 1 1 funcref) + (tag $used-tag (param i32)) + (tag $unused-tag (param i32)) + + (elem (table $used-table) (i32.const 0) func $foo) + + (func $foo (param i32) (result i32) + (call $bar (i32.const 0)) + ;; call_indirect requires a table, ensuring at least one table exists + ) + + (func $bar (param i32) (result i32) + (call $foo (i32.const 1)) + ;; Uses $used-mem + (drop + (i32.load + (i32.const 24) + ) + ) + ;; Uses $used-table + (drop + (call_indirect (param i32) (result i32) + (i32.const 0) + (i32.const 0) + ) + ) + ;; Uses $used-global + (drop + (global.get $used-global) + ) + ;; Uses $used-tag + (throw $used-tag + (i32.const 0) + ) + ) +) diff --git a/test/lit/wasm-split/table64-const-offset.wast b/test/lit/wasm-split/table64-const-offset.wast index c3c584ad91a..cd396f6361f 100644 --- a/test/lit/wasm-split/table64-const-offset.wast +++ b/test/lit/wasm-split/table64-const-offset.wast @@ -52,8 +52,7 @@ ;; PRIMARY-REF-NEXT: (elem $0 (table $table) (i64.const 0) func $foo) ;; PRIMARY-REF-NEXT: (elem $1 (table $1) (i32.const 0) func $placeholder_0) ;; PRIMARY-REF-NEXT: (export "%foo" (func $foo)) -;; PRIMARY-REF-NEXT: (export "%table" (table $table)) -;; PRIMARY-REF-NEXT: (export "%table_2" (table $1)) +;; PRIMARY-REF-NEXT: (export "%table" (table $1)) ;; PRIMARY-REF-NEXT: (func $foo (param $0 i32) (result i32) ;; PRIMARY-REF-NEXT: (call_indirect $1 (type $0) ;; PRIMARY-REF-NEXT: (i32.const 0) @@ -64,7 +63,7 @@ ;; SECONDARY-REF: (module ;; SECONDARY-REF-NEXT: (type $0 (func (param i32) (result i32))) -;; SECONDARY-REF-NEXT: (import "primary" "%table_2" (table $timport$0 1 funcref)) +;; SECONDARY-REF-NEXT: (import "primary" "%table" (table $timport$0 1 funcref)) ;; SECONDARY-REF-NEXT: (import "primary" "%foo" (func $foo (param i32) (result i32))) ;; SECONDARY-REF-NEXT: (elem $0 (i32.const 0) $bar) ;; SECONDARY-REF-NEXT: (func $bar (param $0 i32) (result i32) diff --git a/test/lit/wasm-split/table64-global-offset.wast b/test/lit/wasm-split/table64-global-offset.wast index fb31e90e0ef..ebcc930903b 100644 --- a/test/lit/wasm-split/table64-global-offset.wast +++ b/test/lit/wasm-split/table64-global-offset.wast @@ -59,9 +59,7 @@ ;; PRIMARY-REF-NEXT: (elem $0 (table $table) (global.get $g) func $foo) ;; PRIMARY-REF-NEXT: (elem $1 (table $1) (i32.const 0) func $placeholder_0) ;; PRIMARY-REF-NEXT: (export "%foo" (func $foo)) -;; PRIMARY-REF-NEXT: (export "%table" (table $table)) -;; PRIMARY-REF-NEXT: (export "%table_2" (table $1)) -;; PRIMARY-REF-NEXT: (export "%global" (global $g)) +;; PRIMARY-REF-NEXT: (export "%table" (table $1)) ;; PRIMARY-REF-NEXT: (func $foo (param $0 i32) (result i32) ;; PRIMARY-REF-NEXT: (call_indirect $1 (type $0) ;; PRIMARY-REF-NEXT: (i32.const 0) @@ -72,7 +70,7 @@ ;; SECONDARY-REF: (module ;; SECONDARY-REF-NEXT: (type $0 (func (param i32) (result i32))) -;; SECONDARY-REF-NEXT: (import "primary" "%table_2" (table $timport$0 1 funcref)) +;; SECONDARY-REF-NEXT: (import "primary" "%table" (table $timport$0 1 funcref)) ;; SECONDARY-REF-NEXT: (import "primary" "%foo" (func $foo (param i32) (result i32))) ;; SECONDARY-REF-NEXT: (elem $0 (i32.const 0) $bar) ;; SECONDARY-REF-NEXT: (func $bar (param $0 i32) (result i32) diff --git a/test/lit/wasm-split/trampoline.wast b/test/lit/wasm-split/trampoline.wast index 2ba2a61b28a..8c1fb5d5167 100644 --- a/test/lit/wasm-split/trampoline.wast +++ b/test/lit/wasm-split/trampoline.wast @@ -22,9 +22,7 @@ ;; PRIMARY: (export "foo" (func $foo)) - ;; PRIMARY: (export "table" (table $table)) - - ;; PRIMARY: (export "table_3" (table $1)) + ;; PRIMARY: (export "table" (table $1)) ;; PRIMARY: (func $foo (param $0 i32) (result i32) ;; PRIMARY-NEXT: (call_indirect $1 (type $0) @@ -37,7 +35,7 @@ ) ;; SECONDARY: (type $0 (func (param i32) (result i32))) - ;; SECONDARY: (import "primary" "table_3" (table $timport$0 1 funcref)) + ;; SECONDARY: (import "primary" "table" (table $timport$0 1 funcref)) ;; SECONDARY: (import "primary" "foo" (func $foo (exact (param i32) (result i32)))) From 8642d46a4326c22e533e1286906e15f91c67087e Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Fri, 23 Jan 2026 05:30:59 +0000 Subject: [PATCH 2/6] Use switch-case --- src/ir/module-splitting.cpp | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp index a6d624cf8ac..d890cfba28c 100644 --- a/src/ir/module-splitting.cpp +++ b/src/ir/module-splitting.cpp @@ -938,14 +938,24 @@ void ModuleSplitter::shareImportableItems() { #define DELEGATE_FIELD_NAME_KIND(id, field, kind) \ if (cast->field.is()) { \ - if (kind == ModuleItemKind::Global) { \ - used.globals.insert(cast->field); \ - } else if (kind == ModuleItemKind::Table) { \ - used.tables.insert(cast->field); \ - } else if (kind == ModuleItemKind::Memory) { \ - used.memories.insert(cast->field); \ - } else if (kind == ModuleItemKind::Tag) { \ - used.tags.insert(cast->field); \ + switch (kind) { \ + case ModuleItemKind::Table: \ + used.tables.insert(cast->field); \ + break; \ + case ModuleItemKind::Memory: \ + used.memories.insert(cast->field); \ + break; \ + case ModuleItemKind::Global: \ + used.globals.insert(cast->field); \ + break; \ + case ModuleItemKind::Tag: \ + used.tags.insert(cast->field); \ + break; \ + case ModuleItemKind::Function: \ + case ModuleItemKind::DataSegment: \ + case ModuleItemKind::ElementSegment: \ + case ModuleItemKind::Invalid: \ + break; \ } \ } From 8b7850a81c70432f534ef6d07faba27c81f161fb Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Fri, 23 Jan 2026 06:05:41 +0000 Subject: [PATCH 3/6] Use walkModuleCode() --- src/ir/module-splitting.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp index d890cfba28c..69fed354aa8 100644 --- a/src/ir/module-splitting.cpp +++ b/src/ir/module-splitting.cpp @@ -983,27 +983,14 @@ void ModuleSplitter::shareImportableItems() { } NameCollector collector(used); - for (auto& global : secondary.globals) { - if (!global->imported()) { - collector.walk(global->init); - } - } + collector.walkModuleCode(&secondary); for (auto& segment : secondary.dataSegments) { used.memories.insert(segment->memory); - if (segment->offset) { - collector.walk(segment->offset); - } } for (auto& segment : secondary.elementSegments) { if (segment->table.is()) { used.tables.insert(segment->table); } - if (segment->offset) { - collector.walk(segment->offset); - } - for (auto* item : segment->data) { - collector.walk(item); - } } // Export module items that are used in the secondary module From e8592425904c07b8f2c49a5313da82d77299e552 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Fri, 23 Jan 2026 06:56:23 +0000 Subject: [PATCH 4/6] Add missing memory.is() check --- src/ir/module-splitting.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp index 69fed354aa8..d904d00feeb 100644 --- a/src/ir/module-splitting.cpp +++ b/src/ir/module-splitting.cpp @@ -985,7 +985,9 @@ void ModuleSplitter::shareImportableItems() { NameCollector collector(used); collector.walkModuleCode(&secondary); for (auto& segment : secondary.dataSegments) { - used.memories.insert(segment->memory); + if (segment->memory.is()) { + used.memories.insert(segment->memory); + } } for (auto& segment : secondary.elementSegments) { if (segment->table.is()) { From 5e7b3762da9e33ddc45eeb6ee0544e5f3d640ecf Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Sat, 24 Jan 2026 03:40:08 +0000 Subject: [PATCH 5/6] Table export comments --- src/ir/module-splitting.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp index d904d00feeb..9ffa4784da1 100644 --- a/src/ir/module-splitting.cpp +++ b/src/ir/module-splitting.cpp @@ -1006,6 +1006,11 @@ void ModuleSplitter::shareImportableItems() { } for (auto& table : primary.tables) { + // 1. In case we copied this table to this secondary module in + // setupTablePatching(), secondary.getTableOrNull(table->name) is not + // null, and we need to export it. + // 2. As in the case with other module elements, if the table is used in + // the secondary module's instructions, we need to export it. auto secondaryTable = secondary.getTableOrNull(table->name); if (!secondaryTable && !used.tables.count(table->name)) { continue; From 8f804640d2fbf434379a8fc8de8324f244736977 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Sat, 24 Jan 2026 04:04:13 +0000 Subject: [PATCH 6/6] Example test update --- test/example/module-splitting.txt | 122 +++++++++++++++--------------- 1 file changed, 63 insertions(+), 59 deletions(-) diff --git a/test/example/module-splitting.txt b/test/example/module-splitting.txt index 0db22c7855c..88de5da0a4e 100644 --- a/test/example/module-splitting.txt +++ b/test/example/module-splitting.txt @@ -26,10 +26,6 @@ After: (memory $mem 3 42 shared) (table $tab 3 42 funcref) (tag $e (type $0) (param i32)) - (export "%memory" (memory $mem)) - (export "%table" (table $tab)) - (export "%global" (global $glob)) - (export "%tag" (tag $e)) ) Secondary: (module @@ -52,10 +48,6 @@ After: (import "env" "tab" (table $tab 3 42 funcref)) (import "env" "glob" (global $glob (mut i32))) (import "env" "e" (tag $e (type $0) (param i32))) - (export "%memory" (memory $mem)) - (export "%table" (table $tab)) - (export "%global" (global $glob)) - (export "%tag" (tag $e)) ) Secondary: (module @@ -149,7 +141,6 @@ After: (type $0 (func (param i32) (result i32))) (table $table 1 funcref) (elem $0 (i32.const 0) $foo) - (export "%table" (table $table)) (func $foo (type $0) (param $0 i32) (result i32) (local.get $0) ) @@ -174,7 +165,6 @@ After: (type $0 (func (param i32) (result i32))) (table $table 2 funcref) (elem $0 (i32.const 0) $foo $foo) - (export "%table" (table $table)) (func $foo (type $0) (param $0 i32) (result i32) (local.get $0) ) @@ -201,8 +191,6 @@ After: (import "env" "base" (global $base i32)) (table $table 1 funcref) (elem $0 (global.get $base) $foo) - (export "%table" (table $table)) - (export "%global" (global $base)) (func $foo (type $0) (param $0 i32) (result i32) (local.get $0) ) @@ -229,8 +217,6 @@ After: (import "env" "base" (global $base i32)) (table $table 2 funcref) (elem $0 (global.get $base) $foo $foo) - (export "%table" (table $table)) - (export "%global" (global $base)) (func $foo (type $0) (param $0 i32) (result i32) (local.get $0) ) @@ -272,7 +258,6 @@ After: (table $table 1000 funcref) (elem $0 (i32.const 42) $foo) (export "foo" (func $foo)) - (export "%table" (table $table)) ) Secondary: (module @@ -297,8 +282,6 @@ After: (table $table 1000 funcref) (elem $0 (global.get $base) $foo) (export "foo" (func $foo)) - (export "%table" (table $table)) - (export "%global" (global $base)) ) Secondary: (module @@ -318,6 +301,10 @@ After: ) Secondary: (module + (type $0 (func (param i32) (result i32))) + (func $foo (type $0) (param $0 i32) (result i32) + (local.get $0) + ) ) @@ -374,8 +361,7 @@ After: (table $0 1 funcref) (elem $0 (table $table) (i32.const 0) func $trampoline_foo) (elem $0_1 (table $0) (i32.const 0) func $placeholder_0) - (export "%table" (table $table)) - (export "%table_1" (table $0)) + (export "%table" (table $0)) (func $trampoline_foo (type $0) (param $0 i32) (result i32) (call_indirect $0 (type $0) (local.get $0) @@ -386,7 +372,7 @@ After: Secondary: (module (type $0 (func (param i32) (result i32))) - (import "primary" "%table_1" (table $0 1 funcref)) + (import "primary" "%table" (table $0 1 funcref)) (elem $0 (i32.const 0) $foo) (func $foo (type $0) (param $0 i32) (result i32) (local.get $0) @@ -412,8 +398,7 @@ After: (table $0 1 funcref) (elem $0 (table $table) (i32.const 0) func $trampoline_foo $trampoline_foo) (elem $0_1 (table $0) (i32.const 0) func $placeholder_0) - (export "%table" (table $table)) - (export "%table_1" (table $0)) + (export "%table" (table $0)) (func $trampoline_foo (type $0) (param $0 i32) (result i32) (call_indirect $0 (type $0) (local.get $0) @@ -424,7 +409,7 @@ After: Secondary: (module (type $0 (func (param i32) (result i32))) - (import "primary" "%table_1" (table $0 1 funcref)) + (import "primary" "%table" (table $0 1 funcref)) (elem $0 (i32.const 0) $foo) (func $foo (type $0) (param $0 i32) (result i32) (local.get $0) @@ -452,8 +437,7 @@ After: (elem $0 (table $table) (i32.const 42) func $trampoline_foo) (elem $0_1 (table $0) (i32.const 0) func $placeholder_0) (export "foo" (func $trampoline_foo)) - (export "%table" (table $table)) - (export "%table_2" (table $0)) + (export "%table" (table $0)) (func $trampoline_foo (type $0) (param $0 i32) (result i32) (call_indirect $0 (type $0) (local.get $0) @@ -464,7 +448,7 @@ After: Secondary: (module (type $0 (func (param i32) (result i32))) - (import "primary" "%table_2" (table $0 1 funcref)) + (import "primary" "%table" (table $0 1 funcref)) (elem $0 (i32.const 0) $foo) (func $foo (type $0) (param $0 i32) (result i32) (local.get $0) @@ -494,9 +478,7 @@ After: (elem $0 (table $table) (global.get $base) func $trampoline_foo) (elem $0_1 (table $0) (i32.const 0) func $placeholder_0) (export "foo" (func $trampoline_foo)) - (export "%table" (table $table)) - (export "%table_2" (table $0)) - (export "%global" (global $base)) + (export "%table" (table $0)) (func $trampoline_foo (type $0) (param $0 i32) (result i32) (call_indirect $0 (type $0) (local.get $0) @@ -507,7 +489,7 @@ After: Secondary: (module (type $0 (func (param i32) (result i32))) - (import "primary" "%table_2" (table $0 1 funcref)) + (import "primary" "%table" (table $0 1 funcref)) (elem $0 (i32.const 0) $foo) (func $foo (type $0) (param $0 i32) (result i32) (local.get $0) @@ -537,9 +519,7 @@ After: (elem $0 (table $table) (global.get $base) func $trampoline_foo $trampoline_foo) (elem $0_1 (table $0) (i32.const 0) func $placeholder_0) (export "foo" (func $trampoline_foo)) - (export "%table" (table $table)) - (export "%table_2" (table $0)) - (export "%global" (global $base)) + (export "%table" (table $0)) (func $trampoline_foo (type $0) (param $0 i32) (result i32) (call_indirect $0 (type $0) (local.get $0) @@ -550,7 +530,7 @@ After: Secondary: (module (type $0 (func (param i32) (result i32))) - (import "primary" "%table_2" (table $0 1 funcref)) + (import "primary" "%table" (table $0 1 funcref)) (elem $0 (i32.const 0) $foo) (func $foo (type $0) (param $0 i32) (result i32) (local.get $0) @@ -584,9 +564,7 @@ After: (elem $0 (table $table) (global.get $base) func $null $trampoline_foo) (elem $0_1 (table $0) (i32.const 0) func $placeholder_0) (export "foo" (func $trampoline_foo)) - (export "%table" (table $table)) - (export "%table_2" (table $0)) - (export "%global" (global $base)) + (export "%table" (table $0)) (func $null (type $0) ) (func $trampoline_foo (type $1) (param $0 i32) (result i32) @@ -599,7 +577,7 @@ After: Secondary: (module (type $0 (func (param i32) (result i32))) - (import "primary" "%table_2" (table $0 1 funcref)) + (import "primary" "%table" (table $0 1 funcref)) (elem $0 (i32.const 0) $foo) (func $foo (type $0) (param $0 i32) (result i32) (local.get $0) @@ -654,6 +632,11 @@ After: ) Secondary: (module + (type $0 (func)) + (import "primary" "%bar" (func $bar (exact (type $0)))) + (func $foo (type $0) + (call $bar) + ) ) @@ -708,6 +691,13 @@ After: ) Secondary: (module + (type $0 (func)) + (func $bar (type $0) + (nop) + ) + (func $foo (type $0) + (call $bar) + ) ) @@ -781,8 +771,7 @@ After: (table $0 2 funcref) (elem $0 (table $table) (i32.const 0) func $trampoline_foo $bar $trampoline_baz $quux) (elem $0_1 (table $0) (i32.const 0) func $placeholder_0 $placeholder_1) - (export "%table" (table $table)) - (export "%table_1" (table $0)) + (export "%table" (table $0)) (func $bar (type $0) (nop) ) @@ -803,7 +792,7 @@ After: Secondary: (module (type $0 (func)) - (import "primary" "%table_1" (table $0 2 funcref)) + (import "primary" "%table" (table $0 2 funcref)) (elem $0 (i32.const 0) $foo $baz) (func $baz (type $0) (nop) @@ -844,9 +833,7 @@ After: (table $0 2 funcref) (elem $0 (table $table) (global.get $base) func $trampoline_foo $bar $trampoline_baz $quux) (elem $0_1 (table $0) (i32.const 0) func $placeholder_0 $placeholder_1) - (export "%table" (table $table)) - (export "%table_1" (table $0)) - (export "%global" (global $base)) + (export "%table" (table $0)) (func $bar (type $0) (nop) ) @@ -867,7 +854,7 @@ After: Secondary: (module (type $0 (func)) - (import "primary" "%table_1" (table $0 2 funcref)) + (import "primary" "%table" (table $0 2 funcref)) (elem $0 (i32.const 0) $foo $baz) (func $baz (type $0) (nop) @@ -907,8 +894,7 @@ After: (table $0 3 funcref) (elem $0 (table $table) (i32.const 0) func $trampoline_foo $trampoline_bar $baz $trampoline_quux) (elem $0_1 (table $0) (i32.const 0) func $placeholder_0 $placeholder_1 $placeholder_2) - (export "%table" (table $table)) - (export "%table_1" (table $0)) + (export "%table" (table $0)) (func $baz (type $0) (nop) ) @@ -931,7 +917,7 @@ After: Secondary: (module (type $0 (func)) - (import "primary" "%table_1" (table $0 3 funcref)) + (import "primary" "%table" (table $0 3 funcref)) (elem $0 (i32.const 0) $foo $bar $quux) (func $bar (type $0) (nop) @@ -976,9 +962,7 @@ After: (table $0 3 funcref) (elem $0 (table $table) (global.get $base) func $trampoline_foo $trampoline_bar $baz $trampoline_quux) (elem $0_1 (table $0) (i32.const 0) func $placeholder_0 $placeholder_1 $placeholder_2) - (export "%table" (table $table)) - (export "%table_1" (table $0)) - (export "%global" (global $base)) + (export "%table" (table $0)) (func $baz (type $0) (nop) ) @@ -1001,7 +985,7 @@ After: Secondary: (module (type $0 (func)) - (import "primary" "%table_1" (table $0 3 funcref)) + (import "primary" "%table" (table $0 3 funcref)) (elem $0 (i32.const 0) $foo $bar $quux) (func $bar (type $0) (nop) @@ -1039,9 +1023,7 @@ After: (elem $0 (table $table) (global.get $base) func $foo $trampoline_bar) (elem $0_1 (table $0) (i32.const 0) func $placeholder_0) (export "%foo" (func $foo)) - (export "%table" (table $table)) - (export "%table_2" (table $0)) - (export "%global" (global $base)) + (export "%table" (table $0)) (func $foo (type $0) (nop) ) @@ -1054,7 +1036,7 @@ After: Secondary: (module (type $0 (func)) - (import "primary" "%table_2" (table $0 1 funcref)) + (import "primary" "%table" (table $0 1 funcref)) (import "primary" "%foo" (func $foo (exact (type $0)))) (elem $0 (i32.const 0) $bar) (func $bar (type $0) @@ -1089,8 +1071,7 @@ After: (elem $0 (table $table) (i32.const 0) func $foo) (elem $0_1 (table $0) (i32.const 0) func $placeholder_0) (export "%foo" (func $foo)) - (export "%table" (table $table)) - (export "%table_2" (table $0)) + (export "%table" (table $0)) (func $foo (type $0) (param $0 i32) (result i32) (call_indirect $0 (type $0) (i32.const 0) @@ -1101,7 +1082,7 @@ After: Secondary: (module (type $0 (func (param i32) (result i32))) - (import "primary" "%table_2" (table $0 1 funcref)) + (import "primary" "%table" (table $0 1 funcref)) (import "primary" "%foo" (func $foo (exact (type $0) (param i32) (result i32)))) (elem $0 (i32.const 0) $bar) (func $bar (type $0) (param $0 i32) (result i32) @@ -1193,5 +1174,28 @@ Minimized names primary: Minimized names secondary: (module + (type $0 (func)) + (import "primary" "%a" (func $0 (exact (type $0)))) + (import "primary" "%c" (func $1 (exact (type $0)))) + (import "primary" "%d" (func $2 (exact (type $0)))) + (import "primary" "already_exported" (func $3 (exact (type $0)))) + (import "primary" "%e" (func $4 (exact (type $0)))) + (import "primary" "%f" (func $5 (exact (type $0)))) + (import "primary" "%g" (func $6 (exact (type $0)))) + (import "primary" "%b" (func $7 (exact (type $0)))) + (import "primary" "%h" (func $8 (exact (type $0)))) + (import "primary" "%i" (func $9 (exact (type $0)))) + (func $call (type $0) + (call $0) + (call $1) + (call $2) + (call $3) + (call $4) + (call $5) + (call $6) + (call $7) + (call $8) + (call $9) + ) )