Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor optimization opts #1023

Merged
merged 3 commits into from
May 24, 2017
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions src/tools/asm2wasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,21 @@
#include "wasm-printing.h"
#include "wasm-io.h"
#include "wasm-validator.h"
#include "optimization-options.h"

#include "asm2wasm.h"

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,
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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; })
Expand All @@ -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());
Expand All @@ -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());
Expand All @@ -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
Expand All @@ -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();
Expand Down Expand Up @@ -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"]);
Expand Down
175 changes: 112 additions & 63 deletions src/tools/optimization-options.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
const std::string DEFAULT_OPT_PASSES = "O";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static const?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, that does sound like a good idea, but when I try it I get

in-class initialization of static data member ‘const string wasm::OptimizationOptions::DEFAULT_OPT_PASSES’ of non-literal type

call to non-constexpr function

I tried changing it to a const char* but it still complains about

error: ‘constexpr’ needed for in-class initialization of static data member ‘const char* wasm::OptimizationOptions::DEFAULT_OPT_PASSES’ of non-integral type

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works:

static constexpr char DEFAULT_OPT_PASSES[] = "O";

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, updated.


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

30 changes: 4 additions & 26 deletions src/tools/wasm-opt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "wasm-io.h"
#include "wasm-interpreter.h"
#include "shell-interface.h"
#include "optimization-options.h"

using namespace wasm;

Expand Down Expand Up @@ -93,21 +94,18 @@ 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,
[](Options* o, const std::string& argument) {
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; })
Expand All @@ -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;
Expand Down Expand Up @@ -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));
}
Expand Down