summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ir/module-splitting.cpp12
-rw-r--r--src/ir/module-splitting.h4
-rw-r--r--src/tools/wasm-split.cpp1
-rw-r--r--test/example/module-splitting.cpp44
-rw-r--r--test/example/module-splitting.txt72
-rw-r--r--test/lit/wasm-split/basic.wast88
-rw-r--r--test/lit/wasm-split/minimized-exports.wast38
7 files changed, 213 insertions, 46 deletions
diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp
index 5f9ba0aad..d6dca8994 100644
--- a/src/ir/module-splitting.cpp
+++ b/src/ir/module-splitting.cpp
@@ -266,6 +266,8 @@ struct ModuleSplitter {
TableSlotManager tableManager;
+ Names::MinifiedNameGenerator minified;
+
// Map from internal function names to (one of) their corresponding export
// names.
std::map<Name, Name> exportedPrimaryFuncs;
@@ -344,8 +346,14 @@ void ModuleSplitter::exportImportFunction(Name funcName) {
if (exportIt != exportedPrimaryFuncs.end()) {
exportName = exportIt->second;
} else {
- exportName = Names::getValidExportName(
- primary, config.newExportPrefix + funcName.c_str());
+ if (config.minimizeNewExportNames) {
+ do {
+ exportName = config.newExportPrefix + minified.getName();
+ } while (primary.getExportOrNull(exportName) != nullptr);
+ } else {
+ exportName = Names::getValidExportName(
+ primary, config.newExportPrefix + funcName.c_str());
+ }
primary.addExport(
Builder::makeExport(exportName, funcName, ExternalKind::Function));
exportedPrimaryFuncs[funcName] = exportName;
diff --git a/src/ir/module-splitting.h b/src/ir/module-splitting.h
index 9a2597067..479fba148 100644
--- a/src/ir/module-splitting.h
+++ b/src/ir/module-splitting.h
@@ -62,6 +62,10 @@ struct Config {
// used to differentiate between "real" exports of the module and exports that
// should only be consumed by the secondary module.
std::string newExportPrefix = "";
+ // Whether the export names of newly created exports should be minimized. If
+ // false, the original function names will be used (after `newExportPrefix`)
+ // as the new export names.
+ bool minimizeNewExportNames = false;
};
// Returns the new secondary module and modifies the `primary` module in place.
diff --git a/src/tools/wasm-split.cpp b/src/tools/wasm-split.cpp
index 3ac8b2c45..7f3fe65c4 100644
--- a/src/tools/wasm-split.cpp
+++ b/src/tools/wasm-split.cpp
@@ -676,6 +676,7 @@ void splitModule(Module& wasm, const WasmSplitOptions& options) {
if (options.exportPrefix.size()) {
config.newExportPrefix = options.exportPrefix;
}
+ config.minimizeNewExportNames = !options.passOptions.debugInfo;
std::unique_ptr<Module> secondary =
ModuleSplitting::splitFunctions(wasm, config);
diff --git a/test/example/module-splitting.cpp b/test/example/module-splitting.cpp
index 5391fe584..2aa67d6d5 100644
--- a/test/example/module-splitting.cpp
+++ b/test/example/module-splitting.cpp
@@ -64,6 +64,8 @@ void do_test(const std::set<Name>& keptFuncs, std::string&& module) {
assert(valid && "secondary invalid!");
}
+void test_minimized_exports();
+
int main() {
// Trivial module
do_test({}, "(module)");
@@ -437,4 +439,46 @@ int main() {
(export "foo2" (func $foo))
(func $foo)
))");
+
+ test_minimized_exports();
+}
+
+void test_minimized_exports() {
+ Module primary;
+ primary.features = FeatureSet::All;
+
+ std::set<Name> keep;
+ Expression* callBody = nullptr;
+
+ Builder builder(primary);
+
+ for (size_t i = 0; i < 10; ++i) {
+ Name name = std::to_string(i);
+ primary.addFunction(Builder::makeFunction(name, {}, {}, builder.makeNop()));
+ keep.insert(name);
+ callBody =
+ builder.blockify(callBody, builder.makeCall(name, {}, Type::none));
+
+ if (i == 3) {
+ primary.addExport(
+ Builder::makeExport("already_exported", name, ExternalKind::Function));
+ }
+ if (i == 7) {
+ primary.addExport(
+ Builder::makeExport("%b", name, ExternalKind::Function));
+ }
+ }
+
+ primary.addFunction(Builder::makeFunction("call", {}, {}, callBody));
+
+ ModuleSplitting::Config config;
+ config.primaryFuncs = std::move(keep);
+ config.newExportPrefix = "%";
+ config.minimizeNewExportNames = true;
+
+ auto secondary = splitFunctions(primary, config);
+ std::cout << "Minimized names primary:\n";
+ std::cout << primary << "\n";
+ std::cout << "Minimized names secondary:\n";
+ std::cout << *secondary << "\n";
}
diff --git a/test/example/module-splitting.txt b/test/example/module-splitting.txt
index 5c3728cde..2b92e9dd6 100644
--- a/test/example/module-splitting.txt
+++ b/test/example/module-splitting.txt
@@ -1107,3 +1107,75 @@ Secondary:
)
+Minimized names primary:
+(module
+ (type $none_=>_none (func))
+ (export "already_exported" (func $3))
+ (export "%b" (func $7))
+ (export "%a" (func $0))
+ (export "%c" (func $1))
+ (export "%d" (func $2))
+ (export "%e" (func $4))
+ (export "%f" (func $5))
+ (export "%g" (func $6))
+ (export "%h" (func $8))
+ (export "%i" (func $9))
+ (func $0
+ (nop)
+ )
+ (func $1
+ (nop)
+ )
+ (func $2
+ (nop)
+ )
+ (func $3
+ (nop)
+ )
+ (func $4
+ (nop)
+ )
+ (func $5
+ (nop)
+ )
+ (func $6
+ (nop)
+ )
+ (func $7
+ (nop)
+ )
+ (func $8
+ (nop)
+ )
+ (func $9
+ (nop)
+ )
+)
+
+Minimized names secondary:
+(module
+ (type $none_=>_none (func))
+ (import "primary" "%a" (func $0))
+ (import "primary" "%c" (func $1))
+ (import "primary" "%d" (func $2))
+ (import "primary" "already_exported" (func $3))
+ (import "primary" "%e" (func $4))
+ (import "primary" "%f" (func $5))
+ (import "primary" "%g" (func $6))
+ (import "primary" "%b" (func $7))
+ (import "primary" "%h" (func $8))
+ (import "primary" "%i" (func $9))
+ (func $call
+ (call $0)
+ (call $1)
+ (call $2)
+ (call $3)
+ (call $4)
+ (call $5)
+ (call $6)
+ (call $7)
+ (call $8)
+ (call $9)
+ )
+)
+
diff --git a/test/lit/wasm-split/basic.wast b/test/lit/wasm-split/basic.wast
index 98fe433f3..7bbc14b49 100644
--- a/test/lit/wasm-split/basic.wast
+++ b/test/lit/wasm-split/basic.wast
@@ -1,19 +1,19 @@
-;; RUN: wasm-split %s --export-prefix='%' -o1 %t.none.1.wasm -o2 %t.none.2.wasm -v 2>&1 \
+;; RUN: wasm-split %s --export-prefix='%' -g -o1 %t.none.1.wasm -o2 %t.none.2.wasm -v 2>&1 \
;; RUN: | filecheck %s --check-prefix KEEP-NONE
;; RUN: wasm-dis %t.none.1.wasm | filecheck %s --check-prefix KEEP-NONE-PRIMARY
;; RUN: wasm-dis %t.none.2.wasm | filecheck %s --check-prefix KEEP-NONE-SECONDARY
-;; RUN: wasm-split %s --export-prefix='%' -o1 %t.foo.1.wasm -o2 %t.foo.2.wasm --keep-funcs=foo -v 2>&1 \
+;; RUN: wasm-split %s --export-prefix='%' -g -o1 %t.foo.1.wasm -o2 %t.foo.2.wasm --keep-funcs=foo -v 2>&1 \
;; RUN: | filecheck %s --check-prefix KEEP-FOO
;; RUN: wasm-dis %t.foo.1.wasm | filecheck %s --check-prefix KEEP-FOO-PRIMARY
;; RUN: wasm-dis %t.foo.2.wasm | filecheck %s --check-prefix KEEP-FOO-SECONDARY
-;; RUN: wasm-split %s --export-prefix='%' -o1 %t.bar.1.wasm -o2 %t.bar.2.wasm --keep-funcs=bar -v 2>&1 \
+;; RUN: wasm-split %s --export-prefix='%' -g -o1 %t.bar.1.wasm -o2 %t.bar.2.wasm --keep-funcs=bar -v 2>&1 \
;; RUN: | filecheck %s --check-prefix KEEP-BAR
;; RUN: wasm-dis %t.bar.1.wasm | filecheck %s --check-prefix KEEP-BAR-PRIMARY
;; RUN: wasm-dis %t.bar.2.wasm | filecheck %s --check-prefix KEEP-BAR-SECONDARY
-;; RUN: wasm-split %s --export-prefix='%' -o1 %t.both.1.wasm -o2 %t.both.2.wasm --keep-funcs=foo,bar -v 2>&1 \
+;; RUN: wasm-split %s --export-prefix='%' -g -o1 %t.both.1.wasm -o2 %t.both.2.wasm --keep-funcs=foo,bar -v 2>&1 \
;; RUN: | filecheck %s --check-prefix KEEP-BOTH
;; RUN: wasm-dis %t.both.1.wasm | filecheck %s --check-prefix KEEP-BOTH-PRIMARY
;; RUN: wasm-dis %t.both.2.wasm | filecheck %s --check-prefix KEEP-BOTH-SECONDARY
@@ -33,23 +33,23 @@
;; KEEP-NONE-PRIMARY: (module
;; KEEP-NONE-PRIMARY-NEXT: (type $i32_=>_i32 (func (param i32) (result i32)))
-;; KEEP-NONE-PRIMARY-NEXT: (import "placeholder" "0" (func $fimport$0 (param i32) (result i32)))
-;; KEEP-NONE-PRIMARY-NEXT: (table $0 1 1 funcref)
-;; KEEP-NONE-PRIMARY-NEXT: (elem (i32.const 0) $fimport$0)
-;; KEEP-NONE-PRIMARY-NEXT: (export "%table" (table $0))
+;; KEEP-NONE-PRIMARY-NEXT: (import "placeholder" "0" (func $placeholder_0 (param i32) (result i32)))
+;; KEEP-NONE-PRIMARY-NEXT: (table $table 1 1 funcref)
+;; KEEP-NONE-PRIMARY-NEXT: (elem (i32.const 0) $placeholder_0)
+;; KEEP-NONE-PRIMARY-NEXT: (export "%table" (table $table))
;; KEEP-NONE-PRIMARY-NEXT: )
;; KEEP-NONE-SECONDARY: (module
;; KEEP-NONE-SECONDARY-NEXT: (type $i32_=>_i32 (func (param i32) (result i32)))
-;; KEEP-NONE-SECONDARY-NEXT: (import "primary" "%table" (table $timport$0 1 1 funcref))
-;; KEEP-NONE-SECONDARY-NEXT: (elem (i32.const 0) $1)
-;; KEEP-NONE-SECONDARY-NEXT: (func $0 (param $0 i32) (result i32)
-;; KEEP-NONE-SECONDARY-NEXT: (call $1
+;; KEEP-NONE-SECONDARY-NEXT: (import "primary" "%table" (table $table 1 1 funcref))
+;; KEEP-NONE-SECONDARY-NEXT: (elem (i32.const 0) $foo)
+;; KEEP-NONE-SECONDARY-NEXT: (func $bar (param $0 i32) (result i32)
+;; KEEP-NONE-SECONDARY-NEXT: (call $foo
;; KEEP-NONE-SECONDARY-NEXT: (i32.const 1)
;; KEEP-NONE-SECONDARY-NEXT: )
;; KEEP-NONE-SECONDARY-NEXT: )
-;; KEEP-NONE-SECONDARY-NEXT: (func $1 (param $0 i32) (result i32)
-;; KEEP-NONE-SECONDARY-NEXT: (call $0
+;; KEEP-NONE-SECONDARY-NEXT: (func $foo (param $0 i32) (result i32)
+;; KEEP-NONE-SECONDARY-NEXT: (call $bar
;; KEEP-NONE-SECONDARY-NEXT: (i32.const 0)
;; KEEP-NONE-SECONDARY-NEXT: )
;; KEEP-NONE-SECONDARY-NEXT: )
@@ -60,12 +60,12 @@
;; KEEP-FOO-PRIMARY: (module
;; KEEP-FOO-PRIMARY-NEXT: (type $i32_=>_i32 (func (param i32) (result i32)))
-;; KEEP-FOO-PRIMARY-NEXT: (import "placeholder" "1" (func $fimport$0 (param i32) (result i32)))
-;; KEEP-FOO-PRIMARY-NEXT: (table $0 2 2 funcref)
-;; KEEP-FOO-PRIMARY-NEXT: (elem (i32.const 0) $0 $fimport$0)
-;; KEEP-FOO-PRIMARY-NEXT: (export "%foo" (func $0))
-;; KEEP-FOO-PRIMARY-NEXT: (export "%table" (table $0))
-;; KEEP-FOO-PRIMARY-NEXT: (func $0 (param $0 i32) (result i32)
+;; KEEP-FOO-PRIMARY-NEXT: (import "placeholder" "1" (func $placeholder_1 (param i32) (result i32)))
+;; KEEP-FOO-PRIMARY-NEXT: (table $table 2 2 funcref)
+;; KEEP-FOO-PRIMARY-NEXT: (elem (i32.const 0) $foo $placeholder_1)
+;; KEEP-FOO-PRIMARY-NEXT: (export "%foo" (func $foo))
+;; KEEP-FOO-PRIMARY-NEXT: (export "%table" (table $table))
+;; KEEP-FOO-PRIMARY-NEXT: (func $foo (param $0 i32) (result i32)
;; KEEP-FOO-PRIMARY-NEXT: (call_indirect (type $i32_=>_i32)
;; KEEP-FOO-PRIMARY-NEXT: (i32.const 0)
;; KEEP-FOO-PRIMARY-NEXT: (i32.const 1)
@@ -75,11 +75,11 @@
;; KEEP-FOO-SECONDARY: (module
;; KEEP-FOO-SECONDARY-NEXT: (type $i32_=>_i32 (func (param i32) (result i32)))
-;; KEEP-FOO-SECONDARY-NEXT: (import "primary" "%table" (table $timport$0 2 2 funcref))
-;; KEEP-FOO-SECONDARY-NEXT: (import "primary" "%foo" (func $fimport$0 (param i32) (result i32)))
-;; KEEP-FOO-SECONDARY-NEXT: (elem (i32.const 1) $0)
-;; KEEP-FOO-SECONDARY-NEXT: (func $0 (param $0 i32) (result i32)
-;; KEEP-FOO-SECONDARY-NEXT: (call $fimport$0
+;; KEEP-FOO-SECONDARY-NEXT: (import "primary" "%table" (table $table 2 2 funcref))
+;; KEEP-FOO-SECONDARY-NEXT: (import "primary" "%foo" (func $foo (param i32) (result i32)))
+;; KEEP-FOO-SECONDARY-NEXT: (elem (i32.const 1) $bar)
+;; KEEP-FOO-SECONDARY-NEXT: (func $bar (param $0 i32) (result i32)
+;; KEEP-FOO-SECONDARY-NEXT: (call $foo
;; KEEP-FOO-SECONDARY-NEXT: (i32.const 1)
;; KEEP-FOO-SECONDARY-NEXT: )
;; KEEP-FOO-SECONDARY-NEXT: )
@@ -90,12 +90,12 @@
;; KEEP-BAR-PRIMARY: (module
;; KEEP-BAR-PRIMARY-NEXT: (type $i32_=>_i32 (func (param i32) (result i32)))
-;; KEEP-BAR-PRIMARY-NEXT: (import "placeholder" "0" (func $fimport$0 (param i32) (result i32)))
-;; KEEP-BAR-PRIMARY-NEXT: (table $0 1 1 funcref)
-;; KEEP-BAR-PRIMARY-NEXT: (elem (i32.const 0) $fimport$0)
-;; KEEP-BAR-PRIMARY-NEXT: (export "%bar" (func $0))
-;; KEEP-BAR-PRIMARY-NEXT: (export "%table" (table $0))
-;; KEEP-BAR-PRIMARY-NEXT: (func $0 (param $0 i32) (result i32)
+;; KEEP-BAR-PRIMARY-NEXT: (import "placeholder" "0" (func $placeholder_0 (param i32) (result i32)))
+;; KEEP-BAR-PRIMARY-NEXT: (table $table 1 1 funcref)
+;; KEEP-BAR-PRIMARY-NEXT: (elem (i32.const 0) $placeholder_0)
+;; KEEP-BAR-PRIMARY-NEXT: (export "%bar" (func $bar))
+;; KEEP-BAR-PRIMARY-NEXT: (export "%table" (table $table))
+;; KEEP-BAR-PRIMARY-NEXT: (func $bar (param $0 i32) (result i32)
;; KEEP-BAR-PRIMARY-NEXT: (call_indirect (type $i32_=>_i32)
;; KEEP-BAR-PRIMARY-NEXT: (i32.const 1)
;; KEEP-BAR-PRIMARY-NEXT: (i32.const 0)
@@ -105,11 +105,11 @@
;; KEEP-BAR-SECONDARY: (module
;; KEEP-BAR-SECONDARY-NEXT: (type $i32_=>_i32 (func (param i32) (result i32)))
-;; KEEP-BAR-SECONDARY-NEXT: (import "primary" "%table" (table $timport$0 1 1 funcref))
-;; KEEP-BAR-SECONDARY-NEXT: (import "primary" "%bar" (func $fimport$0 (param i32) (result i32)))
-;; KEEP-BAR-SECONDARY-NEXT: (elem (i32.const 0) $0)
-;; KEEP-BAR-SECONDARY-NEXT: (func $0 (param $0 i32) (result i32)
-;; KEEP-BAR-SECONDARY-NEXT: (call $fimport$0
+;; KEEP-BAR-SECONDARY-NEXT: (import "primary" "%table" (table $table 1 1 funcref))
+;; KEEP-BAR-SECONDARY-NEXT: (import "primary" "%bar" (func $bar (param i32) (result i32)))
+;; KEEP-BAR-SECONDARY-NEXT: (elem (i32.const 0) $foo)
+;; KEEP-BAR-SECONDARY-NEXT: (func $foo (param $0 i32) (result i32)
+;; KEEP-BAR-SECONDARY-NEXT: (call $bar
;; KEEP-BAR-SECONDARY-NEXT: (i32.const 0)
;; KEEP-BAR-SECONDARY-NEXT: )
;; KEEP-BAR-SECONDARY-NEXT: )
@@ -121,21 +121,21 @@
;; KEEP-BOTH-PRIMARY: (module
;; KEEP-BOTH-PRIMARY-NEXT: (type $i32_=>_i32 (func (param i32) (result i32)))
-;; KEEP-BOTH-PRIMARY-NEXT: (table $0 1 1 funcref)
-;; KEEP-BOTH-PRIMARY-NEXT: (elem (i32.const 0) $0)
-;; KEEP-BOTH-PRIMARY-NEXT: (export "%table" (table $0))
-;; KEEP-BOTH-PRIMARY-NEXT: (func $0 (param $0 i32) (result i32)
-;; KEEP-BOTH-PRIMARY-NEXT: (call $1
+;; KEEP-BOTH-PRIMARY-NEXT: (table $table 1 1 funcref)
+;; KEEP-BOTH-PRIMARY-NEXT: (elem (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)
;; KEEP-BOTH-PRIMARY-NEXT: )
;; KEEP-BOTH-PRIMARY-NEXT: )
-;; KEEP-BOTH-PRIMARY-NEXT: (func $1 (param $0 i32) (result i32)
-;; KEEP-BOTH-PRIMARY-NEXT: (call $0
+;; KEEP-BOTH-PRIMARY-NEXT: (func $bar (param $0 i32) (result i32)
+;; KEEP-BOTH-PRIMARY-NEXT: (call $foo
;; KEEP-BOTH-PRIMARY-NEXT: (i32.const 1)
;; KEEP-BOTH-PRIMARY-NEXT: )
;; KEEP-BOTH-PRIMARY-NEXT: )
;; KEEP-BOTH-PRIMARY-NEXT: )
;; KEEP-BOTH-SECONDARY: (module
-;; KEEP-BOTH-SECONDARY-NEXT: (import "primary" "%table" (table $timport$0 1 1 funcref))
+;; KEEP-BOTH-SECONDARY-NEXT: (import "primary" "%table" (table $table 1 1 funcref))
;; KEEP-BOTH-SECONDARY-NEXT: )
diff --git a/test/lit/wasm-split/minimized-exports.wast b/test/lit/wasm-split/minimized-exports.wast
new file mode 100644
index 000000000..a7c225550
--- /dev/null
+++ b/test/lit/wasm-split/minimized-exports.wast
@@ -0,0 +1,38 @@
+;; RUN: wasm-split %s --keep-funcs=foo,bar --export-prefix='%' -o1 %t.1.wasm -o2 %t.2.wasm
+;; RUN: wasm-dis %t.1.wasm | filecheck %s --check-prefix PRIMARY
+;; RUN: wasm-dis %t.2.wasm | filecheck %s --check-prefix SECONDARY
+
+;; PRIMARY: (module
+;; PRIMARY-NEXT: (type $none_=>_none (func))
+;; PRIMARY-NEXT: (export "%a" (func $1))
+;; PRIMARY-NEXT: (export "%b" (func $0))
+;; PRIMARY-NEXT: (func $0
+;; PRIMARY-NEXT: (nop)
+;; PRIMARY-NEXT: )
+;; PRIMARY-NEXT: (func $1
+;; PRIMARY-NEXT: (nop)
+;; PRIMARY-NEXT: )
+;; PRIMARY-NEXT: )
+
+;; SECONDARY: (module
+;; SECONDARY-NEXT: (type $none_=>_none (func))
+;; SECONDARY-NEXT: (import "primary" "%a" (func $fimport$0))
+;; SECONDARY-NEXT: (import "primary" "%b" (func $fimport$1))
+;; SECONDARY-NEXT: (func $0
+;; SECONDARY-NEXT: (call $fimport$1)
+;; SECONDARY-NEXT: (call $fimport$0)
+;; SECONDARY-NEXT: )
+;; SECONDARY-NEXT: )
+
+(module
+ (func $foo
+ (nop)
+ )
+ (func $bar
+ (nop)
+ )
+ (func $baz
+ (call $foo)
+ (call $bar)
+ )
+)