summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ir/module-splitting.cpp2
-rw-r--r--src/ir/module-splitting.h6
-rw-r--r--src/tools/wasm-split/wasm-split.cpp11
-rw-r--r--test/example/module-splitting.cpp13
-rw-r--r--test/lit/wasm-split/multi-split.wast102
5 files changed, 65 insertions, 69 deletions
diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp
index 777818689..caa996b30 100644
--- a/src/ir/module-splitting.cpp
+++ b/src/ir/module-splitting.cpp
@@ -442,7 +442,7 @@ ModuleSplitter::classifyFunctions(Module& primary, const Config& config) {
// module since that would make them async when they may not have the JSPI
// wrapper. Exported JSPI functions can still benefit from splitting though
// since only the JSPI wrapper stub will remain in the primary module.
- if (func->imported() || config.primaryFuncs.count(func->name) ||
+ if (func->imported() || !config.secondaryFuncs.count(func->name) ||
(config.jspi && ExportUtils::isExported(primary, *func)) ||
segmentReferrers.count(func->name)) {
primaryFuncs.insert(func->name);
diff --git a/src/ir/module-splitting.h b/src/ir/module-splitting.h
index 620993d2d..89e4dd2bb 100644
--- a/src/ir/module-splitting.h
+++ b/src/ir/module-splitting.h
@@ -47,11 +47,11 @@ namespace wasm::ModuleSplitting {
static const Name LOAD_SECONDARY_MODULE("__load_secondary_module");
struct Config {
- // The set of functions to keep in the primary module. All others are split
- // out into the new secondary module. Must include the start function if it
+ // The set of functions to split into the secondary module. All others are
+ // kept in the primary module. Must not include the start function if it
// exists. May or may not include imported functions, which are always kept in
// the primary module regardless.
- std::set<Name> primaryFuncs;
+ std::set<Name> secondaryFuncs;
// Whether to import placeholder functions into the primary module that will
// be called when a secondary function is called before the secondary module
// has been loaded.
diff --git a/src/tools/wasm-split/wasm-split.cpp b/src/tools/wasm-split/wasm-split.cpp
index 1cfe5bad9..d26f6f1d6 100644
--- a/src/tools/wasm-split/wasm-split.cpp
+++ b/src/tools/wasm-split/wasm-split.cpp
@@ -221,7 +221,7 @@ void splitModule(const WasmSplitOptions& options) {
std::set<Name> splitFuncs;
if (options.profileFile.size()) {
- // Use the profile to set `keepFuncs`.
+ // Use the profile to set `keepFuncs` and `splitFuncs`.
uint64_t hash = hashFile(options.inputFiles[0]);
getFunctionsToKeepAndSplit(
wasm, hash, options.profileFile, keepFuncs, splitFuncs);
@@ -319,7 +319,7 @@ void splitModule(const WasmSplitOptions& options) {
// Actually perform the splitting
ModuleSplitting::Config config;
- config.primaryFuncs = std::move(keepFuncs);
+ config.secondaryFuncs = std::move(splitFuncs);
if (options.importNamespace.size()) {
config.importNamespace = options.importNamespace;
}
@@ -418,9 +418,6 @@ void multiSplitModule(const WasmSplitOptions& options) {
config.usePlaceholders = false;
config.importNamespace = "";
config.minimizeNewExportNames = true;
- for (auto& func : wasm.functions) {
- config.primaryFuncs.insert(func->name);
- }
for (auto& [mod, funcs] : moduleFuncs) {
if (options.verbose) {
std::cerr << "Splitting module " << mod << '\n';
@@ -428,9 +425,7 @@ void multiSplitModule(const WasmSplitOptions& options) {
if (!options.quiet && funcs.empty()) {
std::cerr << "warning: Module " << mod << " will be empty\n";
}
- for (auto& func : funcs) {
- config.primaryFuncs.erase(Name(func));
- }
+ config.secondaryFuncs = std::set<Name>(funcs.begin(), funcs.end());
auto splitResults = ModuleSplitting::splitFunctions(wasm, config);
// TODO: symbolMap, placeholderMap, emitModuleNames
// TODO: Support --emit-text and use .wast in that case.
diff --git a/test/example/module-splitting.cpp b/test/example/module-splitting.cpp
index 81f095f48..b55beb1d3 100644
--- a/test/example/module-splitting.cpp
+++ b/test/example/module-splitting.cpp
@@ -28,14 +28,21 @@ void do_test(const std::set<Name>& keptFuncs, std::string&& module) {
valid = validator.validate(*primary);
assert(valid && "before invalid!");
+ std::set<Name> splitFuncs;
+ for (auto& func : primary->functions) {
+ splitFuncs.insert(func->name);
+ }
+
std::cout << "Before:\n";
std::cout << *primary.get();
std::cout << "Keeping: ";
if (keptFuncs.size()) {
auto it = keptFuncs.begin();
+ splitFuncs.erase(*it);
std::cout << *it++;
while (it != keptFuncs.end()) {
+ splitFuncs.erase(*it);
std::cout << ", " << *it++;
}
} else {
@@ -44,7 +51,7 @@ void do_test(const std::set<Name>& keptFuncs, std::string&& module) {
std::cout << "\n";
ModuleSplitting::Config config;
- config.primaryFuncs = keptFuncs;
+ config.secondaryFuncs = std::move(splitFuncs);
config.newExportPrefix = "%";
auto secondary = splitFunctions(*primary, config).secondary;
@@ -443,7 +450,6 @@ void test_minimized_exports() {
Module primary;
primary.features = FeatureSet::All;
- std::set<Name> keep;
Expression* callBody = nullptr;
Builder builder(primary);
@@ -453,7 +459,6 @@ void test_minimized_exports() {
Name name = std::to_string(i);
primary.addFunction(
Builder::makeFunction(name, funcType, {}, builder.makeNop()));
- keep.insert(name);
callBody =
builder.blockify(callBody, builder.makeCall(name, {}, Type::none));
@@ -470,7 +475,7 @@ void test_minimized_exports() {
primary.addFunction(Builder::makeFunction("call", funcType, {}, callBody));
ModuleSplitting::Config config;
- config.primaryFuncs = std::move(keep);
+ config.secondaryFuncs = {"call"};
config.newExportPrefix = "%";
config.minimizeNewExportNames = true;
diff --git a/test/lit/wasm-split/multi-split.wast b/test/lit/wasm-split/multi-split.wast
index 9206e60ee..d7fb56c07 100644
--- a/test/lit/wasm-split/multi-split.wast
+++ b/test/lit/wasm-split/multi-split.wast
@@ -7,8 +7,10 @@
;; RUN: wasm-dis %t3.wasm | filecheck %s --check-prefix=CHECK-C
(module
- (type $ret-i32 (func (result i32)))
;; PRIMARY: (type $ret-i64 (func (result i64)))
+
+ ;; PRIMARY: (type $ret-i32 (func (result i32)))
+ (type $ret-i32 (func (result i32)))
(type $ret-i64 (func (result i64)))
;; PRIMARY: (type $ret-f32 (func (result f32)))
(type $ret-f32 (func (result f32)))
@@ -62,24 +64,24 @@
)
(i32.const 0)
)
- ;; CHECK-B: (type $0 (func (result i32)))
+ ;; CHECK-B: (type $0 (func (result f32)))
- ;; CHECK-B: (type $1 (func (result f32)))
+ ;; CHECK-B: (type $1 (func (result i32)))
;; CHECK-B: (type $2 (func (result i64)))
- ;; CHECK-B: (import "" "table_3" (table $timport$0 2 funcref))
-
- ;; CHECK-B: (import "" "table" (table $timport$1 1 funcref))
+ ;; CHECK-B: (import "" "table_4" (table $timport$0 1 funcref))
;; CHECK-B: (import "" "b" (func $C (result f32)))
- ;; CHECK-B: (elem $0 (table $timport$0) (i32.const 0) func $B $1)
+ ;; CHECK-B: (import "" "c" (func $fimport$1 (result i32)))
+
+ ;; CHECK-B: (elem $0 (i32.const 0) $B)
;; CHECK-B: (func $B (result i64)
;; CHECK-B-NEXT: (drop
- ;; CHECK-B-NEXT: (call_ref $0
- ;; CHECK-B-NEXT: (ref.func $1)
+ ;; CHECK-B-NEXT: (call_ref $1
+ ;; CHECK-B-NEXT: (ref.func $fimport$1)
;; CHECK-B-NEXT: )
;; CHECK-B-NEXT: )
;; CHECK-B-NEXT: (drop
@@ -88,7 +90,7 @@
;; CHECK-B-NEXT: )
;; CHECK-B-NEXT: )
;; CHECK-B-NEXT: (drop
- ;; CHECK-B-NEXT: (call_ref $1
+ ;; CHECK-B-NEXT: (call_ref $0
;; CHECK-B-NEXT: (ref.func $C)
;; CHECK-B-NEXT: )
;; CHECK-B-NEXT: )
@@ -112,33 +114,29 @@
)
(i64.const 0)
)
- ;; CHECK-C: (type $0 (func (result i64)))
+ ;; CHECK-C: (type $0 (func (result i32)))
- ;; CHECK-C: (type $1 (func (result i32)))
+ ;; CHECK-C: (type $1 (func (result i64)))
;; CHECK-C: (type $2 (func (result f32)))
- ;; CHECK-C: (import "" "table_4" (table $timport$0 2 funcref))
+ ;; CHECK-C: (import "" "table_6" (table $timport$0 1 funcref))
- ;; CHECK-C: (import "" "table_3" (table $timport$1 2 funcref))
+ ;; CHECK-C: (import "" "c" (func $fimport$0 (result i32)))
- ;; CHECK-C: (elem $0 (table $timport$0) (i32.const 0) func $0 $C)
+ ;; CHECK-C: (import "" "d" (func $fimport$1 (result i64)))
- ;; CHECK-C: (func $0 (result i64)
- ;; CHECK-C-NEXT: (call_indirect (type $0)
- ;; CHECK-C-NEXT: (i32.const 0)
- ;; CHECK-C-NEXT: )
- ;; CHECK-C-NEXT: )
+ ;; CHECK-C: (elem $0 (i32.const 0) $C)
;; CHECK-C: (func $C (result f32)
;; CHECK-C-NEXT: (drop
- ;; CHECK-C-NEXT: (call_ref $1
- ;; CHECK-C-NEXT: (ref.func $3)
+ ;; CHECK-C-NEXT: (call_ref $0
+ ;; CHECK-C-NEXT: (ref.func $fimport$0)
;; CHECK-C-NEXT: )
;; CHECK-C-NEXT: )
;; CHECK-C-NEXT: (drop
- ;; CHECK-C-NEXT: (call_ref $0
- ;; CHECK-C-NEXT: (ref.func $2)
+ ;; CHECK-C-NEXT: (call_ref $1
+ ;; CHECK-C-NEXT: (ref.func $fimport$1)
;; CHECK-C-NEXT: )
;; CHECK-C-NEXT: )
;; CHECK-C-NEXT: (drop
@@ -169,52 +167,50 @@
)
;; PRIMARY: (table $0 1 funcref)
-;; PRIMARY: (table $1 2 funcref)
+;; PRIMARY: (table $1 1 funcref)
-;; PRIMARY: (table $2 2 funcref)
+;; PRIMARY: (table $2 1 funcref)
;; PRIMARY: (elem $0 (table $0) (i32.const 0) funcref (item (ref.null nofunc)))
-;; PRIMARY: (elem $1 (table $1) (i32.const 0) funcref (item (ref.null nofunc)) (item (ref.null nofunc)))
+;; PRIMARY: (elem $1 (table $1) (i32.const 0) funcref (item (ref.null nofunc)))
-;; PRIMARY: (elem $2 (table $2) (i32.const 0) funcref (item (ref.null nofunc)) (item (ref.null nofunc)))
+;; PRIMARY: (elem $2 (table $2) (i32.const 0) funcref (item (ref.null nofunc)))
-;; PRIMARY: (export "a" (func $0))
+;; PRIMARY: (export "a" (func $1))
-;; PRIMARY: (export "b" (func $1))
+;; PRIMARY: (export "b" (func $3))
;; PRIMARY: (export "table" (table $0))
-;; PRIMARY: (export "table_3" (table $1))
+;; PRIMARY: (export "c" (func $0))
+
+;; PRIMARY: (export "table_4" (table $1))
+
+;; PRIMARY: (export "d" (func $2))
+
+;; PRIMARY: (export "table_6" (table $2))
+
+;; PRIMARY: (func $0 (result i32)
+;; PRIMARY-NEXT: (call_indirect (type $ret-i32)
+;; PRIMARY-NEXT: (i32.const 0)
+;; PRIMARY-NEXT: )
+;; PRIMARY-NEXT: )
-;; PRIMARY: (export "table_4" (table $2))
+;; PRIMARY: (func $1 (result i64)
+;; PRIMARY-NEXT: (call_indirect (type $ret-i64)
+;; PRIMARY-NEXT: (i32.const 0)
+;; PRIMARY-NEXT: )
+;; PRIMARY-NEXT: )
-;; PRIMARY: (func $0 (result i64)
+;; PRIMARY: (func $2 (result i64)
;; PRIMARY-NEXT: (call_indirect (type $ret-i64)
;; PRIMARY-NEXT: (i32.const 0)
;; PRIMARY-NEXT: )
;; PRIMARY-NEXT: )
-;; PRIMARY: (func $1 (result f32)
+;; PRIMARY: (func $3 (result f32)
;; PRIMARY-NEXT: (call_indirect (type $ret-f32)
-;; PRIMARY-NEXT: (i32.const 1)
+;; PRIMARY-NEXT: (i32.const 0)
;; PRIMARY-NEXT: )
;; PRIMARY-NEXT: )
-
-;; CHECK-B: (func $1 (result i32)
-;; CHECK-B-NEXT: (call_indirect (type $0)
-;; CHECK-B-NEXT: (i32.const 0)
-;; CHECK-B-NEXT: )
-;; CHECK-B-NEXT: )
-
-;; CHECK-C: (func $2 (result i64)
-;; CHECK-C-NEXT: (call_indirect (type $0)
-;; CHECK-C-NEXT: (i32.const 0)
-;; CHECK-C-NEXT: )
-;; CHECK-C-NEXT: )
-
-;; CHECK-C: (func $3 (result i32)
-;; CHECK-C-NEXT: (call_indirect (type $1)
-;; CHECK-C-NEXT: (i32.const 1)
-;; CHECK-C-NEXT: )
-;; CHECK-C-NEXT: )