summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2020-01-27 20:15:53 -0800
committerGitHub <noreply@github.com>2020-01-27 20:15:53 -0800
commitbfff812cdfe3caccbceee73cee168326d4b9dc63 (patch)
tree29febd3bb3b2da31116e7296b9855227a536989b /src
parent090a40518e21d36f31becc06f8f955945edb0fa1 (diff)
downloadbinaryen-bfff812cdfe3caccbceee73cee168326d4b9dc63.tar.gz
binaryen-bfff812cdfe3caccbceee73cee168326d4b9dc63.tar.bz2
binaryen-bfff812cdfe3caccbceee73cee168326d4b9dc63.zip
Optionally minify imported module names (#2620)
This replaces imports like env.foo with a.foo, which can save a bunch of bytes when there are many imported functions. Note that by changing all the import names to a it ends up requiring a single merged import module. Note also that when doing this we modify all the imports, minifying their modules and names (since it makes no sense to be careful about minifying only modules known to us - env/wasi - if we are minifyin the names of all modules). This will require an emscripten PR to benefit from it.
Diffstat (limited to 'src')
-rw-r--r--src/passes/MinifyImportsAndExports.cpp56
-rw-r--r--src/passes/pass.cpp4
-rw-r--r--src/passes/passes.h1
3 files changed, 53 insertions, 8 deletions
diff --git a/src/passes/MinifyImportsAndExports.cpp b/src/passes/MinifyImportsAndExports.cpp
index 60dd2cd80..3a4dd8f80 100644
--- a/src/passes/MinifyImportsAndExports.cpp
+++ b/src/passes/MinifyImportsAndExports.cpp
@@ -24,9 +24,12 @@
// (import "env" "longname" (func $internal))
// to
// (import "env" "a" (func $internal))
-// "a" is the minified name (note that we only minify the base,
-// not the module).
+// "a" is the minified name. If we also minify module names, then the
+// result could be
+// (import "a" "a" (func $internal))
//
+// TODO: check if we can minify names to the empty string "", which is even
+// shorter than one character.
#include <map>
#include <string>
@@ -42,11 +45,11 @@
namespace wasm {
struct MinifyImportsAndExports : public Pass {
- bool minifyExports;
+ bool minifyExports, minifyModules;
public:
- explicit MinifyImportsAndExports(bool minifyExports)
- : minifyExports(minifyExports) {}
+ explicit MinifyImportsAndExports(bool minifyExports, bool minifyModules)
+ : minifyExports(minifyExports), minifyModules(minifyModules) {}
private:
// Generates minified names that are valid in JS.
@@ -160,7 +163,12 @@ private:
}
};
auto processImport = [&](Importable* curr) {
- if (curr->module == ENV || curr->module.startsWith("wasi_")) {
+ // Minify all import base names if we are importing modules (which means
+ // we will minify all modules names, so we are not being careful).
+ // Otherwise, assume we just want to minify "normal" imports like env
+ // and wasi, but not special things like asm2wasm or custom user things.
+ if (minifyModules || curr->module == ENV ||
+ curr->module.startsWith("wasi_")) {
process(curr->base);
}
};
@@ -179,13 +187,45 @@ private:
for (auto& pair : newToOld) {
std::cout << pair.second.str << " => " << pair.first.str << '\n';
}
+
+ if (minifyModules) {
+ doMinifyModules(module);
+ }
+ }
+
+ const Name SINGLETON_MODULE_NAME = "a";
+
+ void doMinifyModules(Module* module) {
+ // Minify the module name itself, and also merge all the modules into
+ // one. Assert against overlapping names.
+#ifndef NDEBUG
+ std::set<Name> seenImports;
+#endif
+ auto processImport = [&](Importable* curr) {
+ curr->module = SINGLETON_MODULE_NAME;
+#ifndef NDEBUG
+ assert(seenImports.count(curr->base) == 0);
+ seenImports.insert(curr->base);
+#endif
+ };
+ ModuleUtils::iterImportedGlobals(*module, processImport);
+ ModuleUtils::iterImportedFunctions(*module, processImport);
+ ModuleUtils::iterImportedEvents(*module, processImport);
+ ModuleUtils::iterImportedMemories(*module, processImport);
+ ModuleUtils::iterImportedTables(*module, processImport);
}
};
-Pass* createMinifyImportsPass() { return new MinifyImportsAndExports(false); }
+Pass* createMinifyImportsPass() {
+ return new MinifyImportsAndExports(false, false);
+}
Pass* createMinifyImportsAndExportsPass() {
- return new MinifyImportsAndExports(true);
+ return new MinifyImportsAndExports(true, false);
+}
+
+Pass* createMinifyImportsAndExportsAndModulesPass() {
+ return new MinifyImportsAndExports(true, true);
}
} // namespace wasm
diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp
index 80cc0c1c9..9567d27b6 100644
--- a/src/passes/pass.cpp
+++ b/src/passes/pass.cpp
@@ -185,6 +185,10 @@ void PassRegistry::registerPasses() {
"minifies both import and export names, and emits a mapping to "
"the minified ones",
createMinifyImportsAndExportsPass);
+ registerPass("minify-imports-and-exports-and-modules",
+ "minifies both import and export names, and emits a mapping to "
+ "the minified ones, and minifies the modules as well",
+ createMinifyImportsAndExportsAndModulesPass);
registerPass("mod-asyncify-always-and-only-unwind",
"apply the assumption that asyncify imports always unwind, "
"and we never rewind",
diff --git a/src/passes/passes.h b/src/passes/passes.h
index df5601d2f..868c5b407 100644
--- a/src/passes/passes.h
+++ b/src/passes/passes.h
@@ -63,6 +63,7 @@ Pass* createMergeLocalsPass();
Pass* createMinifiedPrinterPass();
Pass* createMinifyImportsPass();
Pass* createMinifyImportsAndExportsPass();
+Pass* createMinifyImportsAndExportsAndModulesPass();
Pass* createMetricsPass();
Pass* createNameListPass();
Pass* createNoExitRuntimePass();