diff options
-rwxr-xr-x | auto_update_tests.py | 5 | ||||
-rwxr-xr-x | check.py | 5 | ||||
-rw-r--r-- | src/asm2wasm.h | 18 | ||||
-rw-r--r-- | src/pass.h | 6 | ||||
-rw-r--r-- | src/tools/asm2wasm.cpp | 12 | ||||
-rw-r--r-- | src/tools/optimization-options.h | 86 | ||||
-rw-r--r-- | src/tools/wasm-opt.cpp | 26 |
7 files changed, 119 insertions, 39 deletions
diff --git a/auto_update_tests.py b/auto_update_tests.py index 1f3da6813..a2d165802 100755 --- a/auto_update_tests.py +++ b/auto_update_tests.py @@ -16,8 +16,11 @@ for asm in sorted(os.listdir('test')): cmd += ['--imprecise'] wasm += '.imprecise' if not opts: - cmd += ['--no-opts'] wasm += '.no-opts' + if precise: + cmd += ['-O0'] # test that -O0 does nothing + else: + cmd += ['-O'] if precise and opts: # test mem init importing open('a.mem', 'wb').write(asm) @@ -361,8 +361,11 @@ for asm in tests: cmd += ['--imprecise'] wasm += '.imprecise' if not opts: - cmd += ['--no-opts'] wasm += '.no-opts' + if precise: + cmd += ['-O0'] # test that -O0 does nothing + else: + cmd += ['-O'] if precise and opts: # test mem init importing open('a.mem', 'wb').write(asm) diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 5df5af271..b411dba52 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -230,7 +230,8 @@ class Asm2WasmBuilder { bool memoryGrowth; bool debug; bool imprecise; - bool optimize; + PassOptions passOptions; + bool runOptimizationPasses; bool wasmOnly; public: @@ -330,14 +331,15 @@ private: } public: - Asm2WasmBuilder(Module& wasm, bool memoryGrowth, bool debug, bool imprecise, bool optimize, bool wasmOnly) + Asm2WasmBuilder(Module& wasm, bool memoryGrowth, bool debug, bool imprecise, PassOptions passOptions, bool runOptimizationPasses, bool wasmOnly) : wasm(wasm), allocator(wasm.allocator), builder(wasm), memoryGrowth(memoryGrowth), debug(debug), imprecise(imprecise), - optimize(optimize), + passOptions(passOptions), + runOptimizationPasses(runOptimizationPasses), wasmOnly(wasmOnly) {} void processAsm(Ref ast); @@ -647,13 +649,13 @@ void Asm2WasmBuilder::processAsm(Ref ast) { // set up optimization - if (optimize) { + if (runOptimizationPasses) { Index numFunctions = 0; for (unsigned i = 1; i < body->size(); i++) { if (body[i][0] == DEFUN) numFunctions++; } optimizingBuilder = make_unique<OptimizingIncrementalModuleBuilder>(&wasm, numFunctions, [&](PassRunner& passRunner) { - passRunner.options.setDefaultOptimizationOptions(); + passRunner.options = passOptions; if (debug) { passRunner.setDebug(true); passRunner.setValidateGlobally(false); @@ -807,7 +809,7 @@ void Asm2WasmBuilder::processAsm(Ref ast) { } else if (curr[0] == DEFUN) { // function auto* func = processFunction(curr); - if (optimize) { + if (runOptimizationPasses) { optimizingBuilder->addFunction(func); } else { wasm.addFunction(func); @@ -846,7 +848,7 @@ void Asm2WasmBuilder::processAsm(Ref ast) { } } - if (optimize) { + if (runOptimizationPasses) { optimizingBuilder->finish(); PassRunner passRunner(&wasm); if (debug) { @@ -971,7 +973,7 @@ void Asm2WasmBuilder::processAsm(Ref ast) { // we didn't legalize i64s in fastcomp, and so must legalize the interface to the outside passRunner.add("legalize-js-interface"); } - if (optimize) { + if (runOptimizationPasses) { // autodrop can add some garbage passRunner.add("vacuum"); passRunner.add("remove-unused-brs"); diff --git a/src/pass.h b/src/pass.h index 334f46ac8..dc9159aa0 100644 --- a/src/pass.h +++ b/src/pass.h @@ -61,12 +61,6 @@ struct PassOptions { int optimizeLevel = 0; // 0, 1, 2 correspond to -O0, -O1, -O2, etc. int shrinkLevel = 0; // 0, 1, 2 correspond to -O0, -Os, -Oz bool ignoreImplicitTraps = false; // optimize assuming things like div by 0, bad load/store, will not trap - - void setDefaultOptimizationOptions() { - optimizeLevel = 2; - shrinkLevel = 1; - ignoreImplicitTraps = true; - } }; // diff --git a/src/tools/asm2wasm.cpp b/src/tools/asm2wasm.cpp index cd500b0d9..def361066 100644 --- a/src/tools/asm2wasm.cpp +++ b/src/tools/asm2wasm.cpp @@ -30,7 +30,8 @@ using namespace cashew; using namespace wasm; int main(int argc, const char *argv[]) { - bool opts = true; + PassOptions passOptions; + bool runOptimizationPasses = false; bool imprecise = false; bool wasmOnly = false; @@ -54,9 +55,10 @@ int main(int argc, const char *argv[]) { [](Options *o, const std::string &argument) { o->extra["total memory"] = argument; }) - .add("--no-opts", "-n", "Disable optimization passes", Options::Arguments::Zero, - [&opts](Options *o, const std::string &) { - opts = false; + #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"; }) .add("--imprecise", "-i", "Imprecise optimizations", Options::Arguments::Zero, [&imprecise](Options *o, const std::string &) { @@ -93,7 +95,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.memoryGrowth, options.debug, imprecise, opts, wasmOnly); + Asm2WasmBuilder asm2wasm(wasm, pre.memoryGrowth, options.debug, imprecise, passOptions, runOptimizationPasses, wasmOnly); asm2wasm.processAsm(asmjs); // import mem init file, if provided diff --git a/src/tools/optimization-options.h b/src/tools/optimization-options.h new file mode 100644 index 000000000..0e57cd212 --- /dev/null +++ b/src/tools/optimization-options.h @@ -0,0 +1,86 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// 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; + passOptions.ignoreImplicitTraps = true; + runOptimizationPasses = true; + }) + .add("", "-O0", "execute no optimization passes", + Options::Arguments::Zero, + [&runOptimizationPasses, &passOptions](Options*, const std::string&) { + passOptions.optimizeLevel = 0; + passOptions.shrinkLevel = 0; + passOptions.ignoreImplicitTraps = false; + }) + .add("", "-O1", "execute -O1 optimization passes", + Options::Arguments::Zero, + [&runOptimizationPasses, &passOptions](Options*, const std::string&) { + passOptions.optimizeLevel = 1; + passOptions.shrinkLevel = 0; + passOptions.ignoreImplicitTraps = true; + runOptimizationPasses = true; + }) + .add("", "-O2", "execute -O2 optimization passes", + Options::Arguments::Zero, + [&runOptimizationPasses, &passOptions](Options*, const std::string&) { + passOptions.optimizeLevel = 2; + passOptions.shrinkLevel = 0; + passOptions.ignoreImplicitTraps = true; + runOptimizationPasses = true; + }) + .add("", "-O3", "execute -O3 optimization passes", + Options::Arguments::Zero, + [&runOptimizationPasses, &passOptions](Options*, const std::string&) { + passOptions.optimizeLevel = 3; + passOptions.shrinkLevel = 0; + passOptions.ignoreImplicitTraps = true; + 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; + passOptions.ignoreImplicitTraps = true; + 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; + passOptions.ignoreImplicitTraps = true; + 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()); + }) + diff --git a/src/tools/wasm-opt.cpp b/src/tools/wasm-opt.cpp index aad87726b..1da038b8e 100644 --- a/src/tools/wasm-opt.cpp +++ b/src/tools/wasm-opt.cpp @@ -37,6 +37,7 @@ using namespace wasm; int main(int argc, const char* argv[]) { Name entry; std::vector<std::string> passes; + bool runOptimizationPasses = false; PassOptions passOptions; Options options("wasm-opt", "Optimize .wast files"); @@ -47,24 +48,7 @@ int main(int argc, const char* argv[]) { o->extra["output"] = argument; Colors::disable(); }) - .add("", "-O", "execute default optimization passes", - Options::Arguments::Zero, - [&passes, &passOptions](Options*, const std::string&) { - passOptions.setDefaultOptimizationOptions(); - passes.push_back("O"); - }) - .add("", "-Os", "execute default optimization passes, focusing on code size", - Options::Arguments::Zero, - [&passes, &passOptions](Options*, const std::string&) { - passOptions.setDefaultOptimizationOptions(); - passOptions.shrinkLevel = 1; - passes.push_back("O"); - }) - .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()); - }) + #include "optimization-options.h" .add_positional("INFILE", Options::Arguments::One, [](Options* o, const std::string& argument) { o->extra["infile"] = argument; @@ -77,6 +61,12 @@ int main(int argc, const char* argv[]) { } 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; |