summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tools/wasm-split/split-options.cpp36
-rw-r--r--src/tools/wasm-split/wasm-split.cpp45
-rw-r--r--test/lit/help/wasm-split.test23
-rw-r--r--test/lit/wasm-split/basic.wast6
-rw-r--r--test/lit/wasm-split/invalid-options.wast18
-rw-r--r--test/lit/wasm-split/verbose.wast2
6 files changed, 75 insertions, 55 deletions
diff --git a/src/tools/wasm-split/split-options.cpp b/src/tools/wasm-split/split-options.cpp
index 8de08d5a1..163e987de 100644
--- a/src/tools/wasm-split/split-options.cpp
+++ b/src/tools/wasm-split/split-options.cpp
@@ -109,11 +109,10 @@ WasmSplitOptions::WasmSplitOptions()
[&](Options* o, const std::string& argument) { profileFile = argument; })
.add("--keep-funcs",
"",
- "Comma-separated list of functions to keep in the primary module, "
- "regardless of any profile. "
- "You can also pass a file with a list of functions separated by new "
- "lines. "
- "To do this, prepend @ before filename (--keep-funcs @myfile)",
+ "Comma-separated list of functions to keep in the primary module. The "
+ "rest will be split out. Cannot be used with --profile or "
+ "--split-funcs. You can also pass a file with one function per line "
+ "by passing @filename.",
{Mode::Split},
Options::Arguments::One,
[&](Options* o, const std::string& argument) {
@@ -121,12 +120,10 @@ WasmSplitOptions::WasmSplitOptions()
})
.add("--split-funcs",
"",
- "Comma-separated list of functions to split into the secondary "
- "module, regardless of any profile. If there is no profile, then "
- "this defaults to all functions defined in the module. "
- "You can also pass a file with a list of functions separated by new "
- "lines. "
- "To do this, prepend @ before filename (--split-funcs @myfile)",
+ "Comma-separated list of functions to split out to the secondary "
+ "module. The rest will be kept. Cannot be used with --profile or "
+ "--keep-funcs. You can also pass a file with one function per line "
+ "by passing @filename.",
{Mode::Split},
Options::Arguments::One,
[&](Options* o, const std::string& argument) {
@@ -342,15 +339,14 @@ bool WasmSplitOptions::validate() {
}
if (mode == Mode::Split) {
- std::vector<Name> impossible;
- std::set_intersection(keepFuncs.begin(),
- keepFuncs.end(),
- splitFuncs.begin(),
- splitFuncs.end(),
- std::inserter(impossible, impossible.end()));
- for (auto& func : impossible) {
- fail(std::string("Cannot both keep and split out function ") +
- func.c_str());
+ if (profileFile.size() && keepFuncs.size()) {
+ fail("Cannot use both --profile and --keep-funcs.");
+ }
+ if (profileFile.size() && splitFuncs.size()) {
+ fail("Cannot use both --profile and --split-funcs.");
+ }
+ if (keepFuncs.size() && splitFuncs.size()) {
+ fail("Cannot use both --keep-funcs and --split-funcs.");
}
}
diff --git a/src/tools/wasm-split/wasm-split.cpp b/src/tools/wasm-split/wasm-split.cpp
index b1ae153c9..2be368994 100644
--- a/src/tools/wasm-split/wasm-split.cpp
+++ b/src/tools/wasm-split/wasm-split.cpp
@@ -173,7 +173,7 @@ void splitModule(const WasmSplitOptions& options) {
std::set<Name> keepFuncs;
if (options.profileFile.size()) {
- // Use the profile to initialize `keepFuncs`.
+ // Use the profile to set `keepFuncs`.
uint64_t hash = hashFile(options.inputFiles[0]);
ProfileData profile = readProfile(options.profileFile);
if (profile.hash != hash) {
@@ -193,29 +193,32 @@ void splitModule(const WasmSplitOptions& options) {
if (i != profile.timestamps.size()) {
Fatal() << "Unexpected extra profile data";
}
- }
-
- // Add in the functions specified with --keep-funcs
- for (auto& func : options.keepFuncs) {
- if (!options.quiet && wasm.getFunctionOrNull(func) == nullptr) {
- std::cerr << "warning: function " << func << " does not exist\n";
+ } else if (options.keepFuncs.size()) {
+ // Use the explicitly provided `keepFuncs`.
+ for (auto& func : options.keepFuncs) {
+ if (!options.quiet && wasm.getFunctionOrNull(func) == nullptr) {
+ std::cerr << "warning: function " << func << " does not exist\n";
+ }
+ keepFuncs.insert(func);
}
- keepFuncs.insert(func);
- }
-
- // Remove the functions specified with --remove-funcs
- for (auto& func : options.splitFuncs) {
- auto* function = wasm.getFunctionOrNull(func);
- if (!options.quiet && function == nullptr) {
- std::cerr << "warning: function " << func << " does not exist\n";
+ } else if (options.splitFuncs.size()) {
+ // Use the explicitly provided `splitFuncs`.
+ for (auto& func : wasm.functions) {
+ keepFuncs.insert(func->name);
}
- if (function && function->imported()) {
- if (!options.quiet) {
- std::cerr << "warning: cannot split out imported function " << func
- << "\n";
+ for (auto& func : options.splitFuncs) {
+ auto* function = wasm.getFunctionOrNull(func);
+ if (!options.quiet && function == nullptr) {
+ std::cerr << "warning: function " << func << " does not exist\n";
+ }
+ if (function && function->imported()) {
+ if (!options.quiet) {
+ std::cerr << "warning: cannot split out imported function " << func
+ << "\n";
+ }
+ } else {
+ keepFuncs.erase(func);
}
- } else {
- keepFuncs.erase(func);
}
}
diff --git a/test/lit/help/wasm-split.test b/test/lit/help/wasm-split.test
index dd2b5f7e1..fe48e5e25 100644
--- a/test/lit/help/wasm-split.test
+++ b/test/lit/help/wasm-split.test
@@ -35,21 +35,18 @@
;; CHECK-NEXT: splitting.
;; CHECK-NEXT:
;; CHECK-NEXT: --keep-funcs [split] Comma-separated list of functions
-;; CHECK-NEXT: to keep in the primary module, regardless
-;; CHECK-NEXT: of any profile. You can also pass a file
-;; CHECK-NEXT: with a list of functions separated by new
-;; CHECK-NEXT: lines. To do this, prepend @ before
-;; CHECK-NEXT: filename (--keep-funcs @myfile)
+;; CHECK-NEXT: to keep in the primary module. The rest
+;; CHECK-NEXT: will be split out. Cannot be used with
+;; CHECK-NEXT: --profile or --split-funcs. You can also
+;; CHECK-NEXT: pass a file with one function per line by
+;; CHECK-NEXT: passing @filename.
;; CHECK-NEXT:
;; CHECK-NEXT: --split-funcs [split] Comma-separated list of functions
-;; CHECK-NEXT: to split into the secondary module,
-;; CHECK-NEXT: regardless of any profile. If there is no
-;; CHECK-NEXT: profile, then this defaults to all
-;; CHECK-NEXT: functions defined in the module. You can
-;; CHECK-NEXT: also pass a file with a list of functions
-;; CHECK-NEXT: separated by new lines. To do this,
-;; CHECK-NEXT: prepend @ before filename (--split-funcs
-;; CHECK-NEXT: @myfile)
+;; CHECK-NEXT: to split out to the secondary module. The
+;; CHECK-NEXT: rest will be kept. Cannot be used with
+;; CHECK-NEXT: --profile or --keep-funcs. You can also
+;; CHECK-NEXT: pass a file with one function per line by
+;; CHECK-NEXT: passing @filename.
;; CHECK-NEXT:
;; CHECK-NEXT: --primary-output,-o1 [split] Output file for the primary
;; CHECK-NEXT: module.
diff --git a/test/lit/wasm-split/basic.wast b/test/lit/wasm-split/basic.wast
index 6d5e6c870..c0f4db8d0 100644
--- a/test/lit/wasm-split/basic.wast
+++ b/test/lit/wasm-split/basic.wast
@@ -41,6 +41,12 @@
;; 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
+;; Also check the inverse workflow using --keep-all and --split-funcs
+;; RUN: wasm-split %s --export-prefix='%' -g -o1 %t.split-bar.1.wasm -o2 %t.split-bar.2.wasm --split-funcs=bar -v 2>&1 \
+;; RUN: | filecheck %s --check-prefix KEEP-FOO
+;; RUN: wasm-dis %t.split-bar.1.wasm | filecheck %s --check-prefix KEEP-FOO-PRIMARY
+;; RUN: wasm-dis %t.split-bar.2.wasm | filecheck %s --check-prefix KEEP-FOO-SECONDARY
+
(module
(table $table 1 1 funcref)
(elem (i32.const 0) $foo)
diff --git a/test/lit/wasm-split/invalid-options.wast b/test/lit/wasm-split/invalid-options.wast
index c77691ecc..2f9c0a148 100644
--- a/test/lit/wasm-split/invalid-options.wast
+++ b/test/lit/wasm-split/invalid-options.wast
@@ -53,6 +53,18 @@
;; RUN: not wasm-split %s --merge-profiles -g 2>&1 \
;; RUN: | filecheck %s --check-prefix MERGE-DEBUGINFO
+;; --profile cannot be used with --keep-funcs
+;; RUN: not wasm-split %s --profile=foo --keep-funcs=foo 2>&1 \
+;; RUN: | filecheck %s --check-prefix PROFILE-KEEP
+
+;; --profile cannot be used with --split-funcs
+;; RUN: not wasm-split %s --profile=foo --split-funcs=foo 2>&1 \
+;; RUN: | filecheck %s --check-prefix PROFILE-SPLIT
+
+;; --keep-funcs cannot be used with --split-funcs
+;; RUN: not wasm-split %s --keep-funcs=foo --split-funcs=foo 2>&1 \
+;; RUN: | filecheck %s --check-prefix KEEP-SPLIT
+
;; INSTRUMENT-PROFILE: error: Option --profile cannot be used in instrument mode.
;; INSTRUMENT-OUT1: error: Option --primary-output cannot be used in instrument mode.
@@ -79,4 +91,10 @@
;; MERGE-DEBUGINFO: error: Option --debuginfo cannot be used in merge-profiles mode.
+;; PROFILE-KEEP: error: Cannot use both --profile and --keep-funcs.
+
+;; PROFILE-SPLIT: error: Cannot use both --profile and --split-funcs.
+
+;; KEEP-SPLIT: error: Cannot use both --keep-funcs and --split-funcs.
+
(module)
diff --git a/test/lit/wasm-split/verbose.wast b/test/lit/wasm-split/verbose.wast
index cdedbfae6..0518a03a6 100644
--- a/test/lit/wasm-split/verbose.wast
+++ b/test/lit/wasm-split/verbose.wast
@@ -1,6 +1,6 @@
;; Test that --verbose mode correctly prints the kept and split funcs
-;; RUN: wasm-split %s --keep-funcs=foo,bar --split-funcs=baz --verbose \
+;; RUN: wasm-split %s --keep-funcs=foo,bar --verbose \
;; RUN: -o1 %t1.wasm -o2 %t2.wasm | filecheck %s
;; CHECK: Keeping functions: bar, foo{{$}}