summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/tools/asm2wasm.cpp22
-rw-r--r--src/tools/optimization-options.h175
-rw-r--r--src/tools/wasm-opt.cpp30
3 files changed, 129 insertions, 98 deletions
diff --git a/src/tools/asm2wasm.cpp b/src/tools/asm2wasm.cpp
index 24cff6f09..cf0715198 100644
--- a/src/tools/asm2wasm.cpp
+++ b/src/tools/asm2wasm.cpp
@@ -25,6 +25,7 @@
#include "wasm-printing.h"
#include "wasm-io.h"
#include "wasm-validator.h"
+#include "optimization-options.h"
#include "asm2wasm.h"
@@ -32,15 +33,13 @@ using namespace cashew;
using namespace wasm;
int main(int argc, const char *argv[]) {
- PassOptions passOptions;
bool legalizeJavaScriptFFI = true;
- bool runOptimizationPasses = false;
Asm2WasmBuilder::TrapMode trapMode = Asm2WasmBuilder::TrapMode::JS;
bool wasmOnly = false;
std::string symbolMap;
bool emitBinary = true;
- Options options("asm2wasm", "Translate asm.js files to .wast files");
+ OptimizationOptions options("asm2wasm", "Translate asm.js files to .wast files");
options
.add("--output", "-o", "Output file (stdout if not specified)",
Options::Arguments::One,
@@ -72,7 +71,6 @@ int main(int argc, const char *argv[]) {
[](Options *o, const std::string &argument) {
o->extra["table max"] = argument;
})
- #include "optimization-options.h"
.add("--no-opts", "-n", "Disable optimization passes (deprecated)", Options::Arguments::Zero,
[](Options *o, const std::string &) {
std::cerr << "--no-opts is deprecated (use -O0, etc.)\n";
@@ -103,7 +101,7 @@ int main(int argc, const char *argv[]) {
})
.add("--debuginfo", "-g", "Emit names section and debug info (for debug info you must emit text, -S, for this to work)",
Options::Arguments::Zero,
- [&](Options *o, const std::string &arguments) { passOptions.debugInfo = true; })
+ [&](Options *o, const std::string &arguments) { options.passOptions.debugInfo = true; })
.add("--symbolmap", "-s", "Emit a symbol map (indexes => names)",
Options::Arguments::One,
[&](Options *o, const std::string &argument) { symbolMap = argument; })
@@ -122,6 +120,12 @@ int main(int argc, const char *argv[]) {
emitBinary = false;
}
+ if (options.runningDefaultOptimizationPasses()) {
+ if (options.passes.size() > 1) {
+ Fatal() << "asm2wasm can only run default optimization passes (-O, -Ox, etc.), and not specific additional passes";
+ }
+ }
+
const auto &tm_it = options.extra.find("total memory");
size_t totalMemory =
tm_it == options.extra.end() ? 16 * 1024 * 1024 : atoi(tm_it->second.c_str());
@@ -133,7 +137,7 @@ int main(int argc, const char *argv[]) {
Asm2WasmPreProcessor pre;
// wasm binaries can contain a names section, but not full debug info
- pre.debugInfo = passOptions.debugInfo && !emitBinary;
+ pre.debugInfo = options.passOptions.debugInfo && !emitBinary;
auto input(
read_file<std::vector<char>>(options.extra["infile"], Flags::Text, options.debug ? Flags::Debug : Flags::Release));
char *start = pre.process(input.data());
@@ -145,7 +149,7 @@ int main(int argc, const char *argv[]) {
if (options.debug) std::cerr << "wasming..." << std::endl;
Module wasm;
wasm.memory.initial = wasm.memory.max = totalMemory / Memory::kPageSize;
- Asm2WasmBuilder asm2wasm(wasm, pre, options.debug, trapMode, passOptions, legalizeJavaScriptFFI, runOptimizationPasses, wasmOnly);
+ Asm2WasmBuilder asm2wasm(wasm, pre, options.debug, trapMode, options.passOptions, legalizeJavaScriptFFI, options.runningDefaultOptimizationPasses(), wasmOnly);
asm2wasm.processAsm(asmjs);
// import mem init file, if provided
@@ -162,7 +166,7 @@ int main(int argc, const char *argv[]) {
init = Builder(wasm).makeConst(Literal(int32_t(atoi(memBase->second.c_str()))));
}
wasm.memory.segments.emplace_back(init, data);
- if (runOptimizationPasses) {
+ if (options.runningDefaultOptimizationPasses()) {
PassRunner runner(&wasm);
runner.add("memory-packing");
runner.run();
@@ -197,7 +201,7 @@ int main(int argc, const char *argv[]) {
if (options.debug) std::cerr << "emitting..." << std::endl;
ModuleWriter writer;
writer.setDebug(options.debug);
- writer.setDebugInfo(passOptions.debugInfo);
+ writer.setDebugInfo(options.passOptions.debugInfo);
writer.setSymbolMap(symbolMap);
writer.setBinary(emitBinary);
writer.write(wasm, options.extra["output"]);
diff --git a/src/tools/optimization-options.h b/src/tools/optimization-options.h
index 2af430723..b094f96ce 100644
--- a/src/tools/optimization-options.h
+++ b/src/tools/optimization-options.h
@@ -18,67 +18,116 @@
// Shared optimization options for commandline tools
//
- .add("", "-O", "execute default optimization passes",
- Options::Arguments::Zero,
- [&runOptimizationPasses, &passOptions](Options*, const std::string&) {
- passOptions.optimizeLevel = 2;
- passOptions.shrinkLevel = 1;
- runOptimizationPasses = true;
- })
- .add("", "-O0", "execute no optimization passes",
- Options::Arguments::Zero,
- [&passOptions](Options*, const std::string&) {
- passOptions.optimizeLevel = 0;
- passOptions.shrinkLevel = 0;
- })
- .add("", "-O1", "execute -O1 optimization passes",
- Options::Arguments::Zero,
- [&runOptimizationPasses, &passOptions](Options*, const std::string&) {
- passOptions.optimizeLevel = 1;
- passOptions.shrinkLevel = 0;
- runOptimizationPasses = true;
- })
- .add("", "-O2", "execute -O2 optimization passes",
- Options::Arguments::Zero,
- [&runOptimizationPasses, &passOptions](Options*, const std::string&) {
- passOptions.optimizeLevel = 2;
- passOptions.shrinkLevel = 0;
- runOptimizationPasses = true;
- })
- .add("", "-O3", "execute -O3 optimization passes",
- Options::Arguments::Zero,
- [&runOptimizationPasses, &passOptions](Options*, const std::string&) {
- passOptions.optimizeLevel = 3;
- passOptions.shrinkLevel = 0;
- runOptimizationPasses = true;
- })
- .add("", "-Os", "execute default optimization passes, focusing on code size",
- Options::Arguments::Zero,
- [&runOptimizationPasses, &passOptions](Options*, const std::string&) {
- passOptions.optimizeLevel = 2;
- passOptions.shrinkLevel = 1;
- runOptimizationPasses = true;
- })
- .add("", "-Oz", "execute default optimization passes, super-focusing on code size",
- Options::Arguments::Zero,
- [&runOptimizationPasses, &passOptions](Options*, const std::string&) {
- passOptions.optimizeLevel = 2;
- passOptions.shrinkLevel = 2;
- runOptimizationPasses = true;
- })
- .add("--optimize-level", "-ol", "How much to focus on optimizing code",
- Options::Arguments::One,
- [&passOptions](Options* o, const std::string& argument) {
- passOptions.optimizeLevel = atoi(argument.c_str());
- })
- .add("--shrink-level", "-s", "How much to focus on shrinking code size",
- Options::Arguments::One,
- [&passOptions](Options* o, const std::string& argument) {
- passOptions.shrinkLevel = atoi(argument.c_str());
- })
- .add("--ignore-implicit-traps", "-iit", "Optimize under the helpful assumption that no surprising traps occur (from load, div/mod, etc.)",
- Options::Arguments::Zero,
- [&passOptions](Options*, const std::string&) {
- passOptions.ignoreImplicitTraps = true;
- })
+namespace wasm {
+
+struct OptimizationOptions : public Options {
+ static constexpr const char* DEFAULT_OPT_PASSES = "O";
+
+ std::vector<std::string> passes;
+ PassOptions passOptions;
+
+ OptimizationOptions(const std::string &command, const std::string &description) : Options(command, description) {
+ (*this).add("", "-O", "execute default optimization passes",
+ Options::Arguments::Zero,
+ [this](Options*, const std::string&) {
+ passOptions.optimizeLevel = 2;
+ passOptions.shrinkLevel = 1;
+ passes.push_back(DEFAULT_OPT_PASSES);
+ })
+ .add("", "-O0", "execute no optimization passes",
+ Options::Arguments::Zero,
+ [this](Options*, const std::string&) {
+ passOptions.optimizeLevel = 0;
+ passOptions.shrinkLevel = 0;
+ })
+ .add("", "-O1", "execute -O1 optimization passes",
+ Options::Arguments::Zero,
+ [this](Options*, const std::string&) {
+ passOptions.optimizeLevel = 1;
+ passOptions.shrinkLevel = 0;
+ passes.push_back(DEFAULT_OPT_PASSES);
+ })
+ .add("", "-O2", "execute -O2 optimization passes",
+ Options::Arguments::Zero,
+ [this](Options*, const std::string&) {
+ passOptions.optimizeLevel = 2;
+ passOptions.shrinkLevel = 0;
+ passes.push_back(DEFAULT_OPT_PASSES);
+ })
+ .add("", "-O3", "execute -O3 optimization passes",
+ Options::Arguments::Zero,
+ [this](Options*, const std::string&) {
+ passOptions.optimizeLevel = 3;
+ passOptions.shrinkLevel = 0;
+ passes.push_back(DEFAULT_OPT_PASSES);
+ })
+ .add("", "-Os", "execute default optimization passes, focusing on code size",
+ Options::Arguments::Zero,
+ [this](Options*, const std::string&) {
+ passOptions.optimizeLevel = 2;
+ passOptions.shrinkLevel = 1;
+ passes.push_back(DEFAULT_OPT_PASSES);
+ })
+ .add("", "-Oz", "execute default optimization passes, super-focusing on code size",
+ Options::Arguments::Zero,
+ [this](Options*, const std::string&) {
+ passOptions.optimizeLevel = 2;
+ passOptions.shrinkLevel = 2;
+ passes.push_back(DEFAULT_OPT_PASSES);
+ })
+ .add("--optimize-level", "-ol", "How much to focus on optimizing code",
+ Options::Arguments::One,
+ [this](Options* o, const std::string& argument) {
+ passOptions.optimizeLevel = atoi(argument.c_str());
+ })
+ .add("--shrink-level", "-s", "How much to focus on shrinking code size",
+ Options::Arguments::One,
+ [this](Options* o, const std::string& argument) {
+ passOptions.shrinkLevel = atoi(argument.c_str());
+ })
+ .add("--ignore-implicit-traps", "-iit", "Optimize under the helpful assumption that no surprising traps occur (from load, div/mod, etc.)",
+ Options::Arguments::Zero,
+ [this](Options*, const std::string&) {
+ passOptions.ignoreImplicitTraps = true;
+ });
+ // add passes in registry
+ for (const auto& p : PassRegistry::get()->getRegisteredNames()) {
+ (*this).add(
+ std::string("--") + p, "", PassRegistry::get()->getPassDescription(p),
+ Options::Arguments::Zero,
+ [this, p](Options*, const std::string&) {
+ passes.push_back(p);
+ }
+ );
+ }
+ }
+
+ bool runningDefaultOptimizationPasses() {
+ for (auto& pass : passes) {
+ if (pass == DEFAULT_OPT_PASSES) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool runningPasses() {
+ return passes.size() > 0;
+ }
+
+ PassRunner getPassRunner(Module& wasm) {
+ PassRunner passRunner(&wasm, passOptions);
+ if (debug) passRunner.setDebug(true);
+ for (auto& pass : passes) {
+ if (pass == DEFAULT_OPT_PASSES) {
+ passRunner.addDefaultOptimizationPasses();
+ } else {
+ passRunner.add(pass);
+ }
+ }
+ return passRunner;
+ }
+};
+
+} // namespace wasm
diff --git a/src/tools/wasm-opt.cpp b/src/tools/wasm-opt.cpp
index 468f3ce93..0603ae93c 100644
--- a/src/tools/wasm-opt.cpp
+++ b/src/tools/wasm-opt.cpp
@@ -30,6 +30,7 @@
#include "wasm-io.h"
#include "wasm-interpreter.h"
#include "shell-interface.h"
+#include "optimization-options.h"
using namespace wasm;
@@ -93,13 +94,11 @@ struct ExecutionResults {
int main(int argc, const char* argv[]) {
Name entry;
std::vector<std::string> passes;
- bool runOptimizationPasses = false;
- PassOptions passOptions;
bool emitBinary = true;
bool debugInfo = false;
bool fuzzExec = false;
- Options options("wasm-opt", "Optimize .wast files");
+ OptimizationOptions options("wasm-opt", "Optimize .wast files");
options
.add("--output", "-o", "Output file (stdout if not specified)",
Options::Arguments::One,
@@ -107,7 +106,6 @@ int main(int argc, const char* argv[]) {
o->extra["output"] = argument;
Colors::disable();
})
- #include "optimization-options.h"
.add("--emit-text", "-S", "Emit text instead of binary for the output file",
Options::Arguments::Zero,
[&](Options *o, const std::string &argument) { emitBinary = false; })
@@ -121,20 +119,8 @@ int main(int argc, const char* argv[]) {
[](Options* o, const std::string& argument) {
o->extra["infile"] = argument;
});
- for (const auto& p : PassRegistry::get()->getRegisteredNames()) {
- options.add(
- std::string("--") + p, "", PassRegistry::get()->getPassDescription(p),
- Options::Arguments::Zero,
- [&passes, p](Options*, const std::string&) { passes.push_back(p); });
- }
options.parse(argc, argv);
- if (runOptimizationPasses) {
- passes.resize(passes.size() + 1);
- std::move_backward(passes.begin(), passes.begin() + passes.size() - 1, passes.end());
- passes[0] = "O";
- }
-
auto input(read_file<std::string>(options.extra["infile"], Flags::Text, options.debug ? Flags::Debug : Flags::Release));
Module wasm;
@@ -163,17 +149,9 @@ int main(int argc, const char* argv[]) {
results.get(wasm);
}
- if (passes.size() > 0) {
+ if (options.runningPasses()) {
if (options.debug) std::cerr << "running passes...\n";
- PassRunner passRunner(&wasm, passOptions);
- if (options.debug) passRunner.setDebug(true);
- for (auto& passName : passes) {
- if (passName == "O") {
- passRunner.addDefaultOptimizationPasses();
- } else {
- passRunner.add(passName);
- }
- }
+ PassRunner passRunner = options.getPassRunner(wasm);
passRunner.run();
assert(WasmValidator().validate(wasm));
}