summaryrefslogtreecommitdiff
path: root/src/tools/optimization-options.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/optimization-options.h')
-rw-r--r--src/tools/optimization-options.h58
1 files changed, 39 insertions, 19 deletions
diff --git a/src/tools/optimization-options.h b/src/tools/optimization-options.h
index c87530536..045542ac2 100644
--- a/src/tools/optimization-options.h
+++ b/src/tools/optimization-options.h
@@ -328,32 +328,52 @@ struct OptimizationOptions : public ToolOptions {
bool runningPasses() { return passes.size() > 0; }
void runPasses(Module& wasm) {
- PassRunner passRunner(&wasm, passOptions);
- if (debug) {
- passRunner.setDebug(true);
- }
- for (auto& pass : passes) {
- // We apply the pass's intended opt and shrink levels, if any.
- auto oldOptimizeLevel = passRunner.options.optimizeLevel;
- auto oldShrinkLevel = passRunner.options.shrinkLevel;
- if (pass.optimizeLevel) {
- passRunner.options.optimizeLevel = *pass.optimizeLevel;
+ std::unique_ptr<PassRunner> passRunner;
+
+ // Flush anything in the current pass runner, and then reset it to a fresh
+ // state so it is ready for new things.
+ auto flushAndReset = [&]() {
+ if (passRunner) {
+ passRunner->run();
}
- if (pass.shrinkLevel) {
- passRunner.options.shrinkLevel = *pass.shrinkLevel;
+ passRunner = std::make_unique<PassRunner>(&wasm, passOptions);
+ if (debug) {
+ passRunner->setDebug(true);
}
+ };
+ flushAndReset();
+
+ for (auto& pass : passes) {
if (pass.name == DEFAULT_OPT_PASSES) {
- passRunner.addDefaultOptimizationPasses();
+ // This is something like -O3 or -Oz. We must run this now, in order to
+ // set the proper opt and shrink levels. To do that, first reset the
+ // runner so that anything already queued is run (since we can only run
+ // after those things).
+ flushAndReset();
+
+ // -O3/-Oz etc. always set their own optimize/shrinkLevels.
+ assert(pass.optimizeLevel);
+ assert(pass.shrinkLevel);
+ passRunner->options.optimizeLevel = *pass.optimizeLevel;
+ passRunner->options.shrinkLevel = *pass.shrinkLevel;
+
+ // Run our optimizations now, and reset the runner so that the default
+ // pass options are used later (and not the temporary optimize/
+ // shrinkLevels we just set).
+ passRunner->addDefaultOptimizationPasses();
+ flushAndReset();
} else {
- passRunner.add(pass.name);
- }
+ // This is a normal pass. Add it to the queue for execution.
+ passRunner->add(pass.name);
- // Revert back to the default levels, if we changed them.
- passRunner.options.optimizeLevel = oldOptimizeLevel;
- passRunner.options.shrinkLevel = oldShrinkLevel;
+ // Normal passes do not set their own optimize/shrinkLevels.
+ assert(!pass.optimizeLevel);
+ assert(!pass.shrinkLevel);
+ }
}
- passRunner.run();
+
+ flushAndReset();
}
};