diff options
-rw-r--r-- | src/tools/wasm-split/split-options.cpp | 36 | ||||
-rw-r--r-- | src/tools/wasm-split/wasm-split.cpp | 45 | ||||
-rw-r--r-- | test/lit/help/wasm-split.test | 23 | ||||
-rw-r--r-- | test/lit/wasm-split/basic.wast | 6 | ||||
-rw-r--r-- | test/lit/wasm-split/invalid-options.wast | 18 | ||||
-rw-r--r-- | test/lit/wasm-split/verbose.wast | 2 |
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{{$}} |