summaryrefslogtreecommitdiff
path: root/test/lit/wasm-split
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2020-11-24 21:16:30 -0800
committerGitHub <noreply@github.com>2020-11-24 21:16:30 -0800
commit2aa6aa62c6182317679596f7372dde6ee3665d15 (patch)
treed8e842321db3383aa263ec6226a74ca8741119a9 /test/lit/wasm-split
parent78ccc1976bac069ae65b2ec227e8c2c515a02801 (diff)
downloadbinaryen-2aa6aa62c6182317679596f7372dde6ee3665d15.tar.gz
binaryen-2aa6aa62c6182317679596f7372dde6ee3665d15.tar.bz2
binaryen-2aa6aa62c6182317679596f7372dde6ee3665d15.zip
[wasm-split] Read and use profiles (#3400)
Read the profiles produced by wasm-split's instrumentation to guide splitting. In this initial implementation, all functions that the profile shows to have been called are kept in the initial module. In the future, users may be able to tune this so that functions that are run later will still be split out.
Diffstat (limited to 'test/lit/wasm-split')
-rw-r--r--test/lit/wasm-split/call_exports.mjs25
-rw-r--r--test/lit/wasm-split/profile-guided.wast67
2 files changed, 92 insertions, 0 deletions
diff --git a/test/lit/wasm-split/call_exports.mjs b/test/lit/wasm-split/call_exports.mjs
new file mode 100644
index 000000000..546564d2e
--- /dev/null
+++ b/test/lit/wasm-split/call_exports.mjs
@@ -0,0 +1,25 @@
+// Instantiates an instrumented module, calls the given exports, then collects
+// its wasm-split profile and writes it to a given file.
+//
+// Usage:
+//
+// node call_exports.mjs <module> <profile> <export>*
+
+import * as fs from 'fs';
+
+let wasm = process.argv[2];
+let outFile = process.argv[3];
+
+// Create the Wasm instance
+let { _, instance } = await WebAssembly.instantiate(fs.readFileSync(wasm));
+
+// Call the specified exports
+for (let i = 4; i < process.argv.length; i++) {
+ console.log('calling', process.argv[i]);
+ instance.exports[process.argv[i]]();
+}
+
+// Create and read the profile
+let profileSize = instance.exports['__write_profile'](0, 2**32 - 1);
+let profileData = Buffer.from(instance.exports.memory.buffer, 0, profileSize);
+fs.writeFileSync(outFile, profileData);
diff --git a/test/lit/wasm-split/profile-guided.wast b/test/lit/wasm-split/profile-guided.wast
new file mode 100644
index 000000000..f2d79f99c
--- /dev/null
+++ b/test/lit/wasm-split/profile-guided.wast
@@ -0,0 +1,67 @@
+;; Instrument the binary
+
+;; RUN: wasm-split --instrument %s -o %t.instrumented.wasm
+
+;; Create profiles
+
+;; RUN: node %S/call_exports.mjs %t.instrumented.wasm %t.foo.prof foo
+;; RUN: node %S/call_exports.mjs %t.instrumented.wasm %t.bar.prof bar
+;; RUN: node %S/call_exports.mjs %t.instrumented.wasm %t.both.prof foo bar
+;; RUN: node %S/call_exports.mjs %t.instrumented.wasm %t.none.prof
+
+;; Create profile-guided splits
+
+;; RUN: wasm-split %s --profile=%t.foo.prof -v -o1 %t.foo.1.wasm -o2 %t.foo.2.wasm \
+;; RUN: | filecheck %s --check-prefix FOO
+
+;; FOO: Keeping functions: deep_foo_callee, foo, foo_callee, shared_callee
+;; FOO: Splitting out functions: bar, bar_callee, uncalled
+
+;; RUN: wasm-split %s --profile=%t.bar.prof -v -o1 %t.bar.1.wasm -o2 %t.bar.2.wasm \
+;; RUN: | filecheck %s --check-prefix BAR
+
+;; BAR: Keeping functions: bar, bar_callee, shared_callee
+;; BAR: Splitting out functions: deep_foo_callee, foo, foo_callee, uncalled
+
+;; RUN: wasm-split %s --profile=%t.both.prof -v -o1 %t.both.1.wasm -o2 %t.both.2.wasm \
+;; RUN: | filecheck %s --check-prefix BOTH
+
+;; BOTH: Keeping functions: bar, bar_callee, deep_foo_callee, foo, foo_callee, shared_callee
+;; BOTH: Splitting out functions: uncalled
+
+;; RUN: wasm-split %s --profile=%t.none.prof -v -o1 %t.none.1.wasm -o2 %t.none.2.wasm \
+;; RUN: | filecheck %s --check-prefix NONE
+
+;; NONE: Keeping functions:
+;; NONE: Splitting out functions: bar, bar_callee, deep_foo_callee, foo, foo_callee, shared_callee, uncalled
+
+
+(module
+ (memory $mem 1 1)
+ (export "memory" (memory $mem))
+ (export "foo" (func $foo))
+ (export "bar" (func $bar))
+ (export "uncalled" (func $uncalled))
+
+ (func $foo
+ (call $foo_callee)
+ (call $shared_callee)
+ )
+
+ (func $bar
+ (call $shared_callee)
+ (call $bar_callee)
+ )
+
+ (func $uncalled)
+
+ (func $foo_callee
+ (call $deep_foo_callee)
+ )
+
+ (func $bar_callee)
+
+ (func $shared_callee)
+
+ (func $deep_foo_callee)
+)