summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2023-06-27 15:27:07 -0700
committerGitHub <noreply@github.com>2023-06-27 15:27:07 -0700
commitaaf1dac49865024fbde9d316c4a46345186217af (patch)
treef8d2e0bcee1745492a602f8fb4aa1a9b9bd6d1e8 /src
parentfd9d04ccd615b185e65a765e3587eae3f72aa867 (diff)
downloadbinaryen-aaf1dac49865024fbde9d316c4a46345186217af.tar.gz
binaryen-aaf1dac49865024fbde9d316c4a46345186217af.tar.bz2
binaryen-aaf1dac49865024fbde9d316c4a46345186217af.zip
Fix opt/shrink levels when running the optimizer multiple times, Part 2 (#5787)
This is a followup to #5333 . That fixed the selection of which passes to run, but forgot to also fix the global state of the current optimize/shrink levels. This PR fixes that. As a result, running -O3 -Oz will now work as expected: the first -O3 will run the right passes (as #5333 fixed) and while running them, the global optimize/shrinkLevels will be -O3 (and not -Oz), which this PR fixes. A specific result of this is that -O3 -Oz used to inline less, since the invocation of inlining during -O3 thought we were optimizing for size. The new test verifies that we do fully inline in the first -O3 now.
Diffstat (limited to 'src')
-rw-r--r--src/pass.h3
-rw-r--r--src/passes/pass.cpp19
-rw-r--r--src/tools/optimization-options.h58
3 files changed, 39 insertions, 41 deletions
diff --git a/src/pass.h b/src/pass.h
index 973773c49..090aa8d33 100644
--- a/src/pass.h
+++ b/src/pass.h
@@ -388,9 +388,6 @@ private:
// Whether this pass runner has run. A pass runner should only be run once.
bool ran = false;
- // Passes in |options.passesToSkip| that we have seen and skipped.
- std::unordered_set<std::string> skippedPasses;
-
void runPass(Pass* pass);
void runPassOnFunction(Pass* pass, Function* func);
diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp
index 0411dcc75..adaa42e04 100644
--- a/src/passes/pass.cpp
+++ b/src/passes/pass.cpp
@@ -698,9 +698,6 @@ void PassRunner::run() {
assert(!ran);
ran = true;
- // As we run passes, we'll notice which we skip.
- skippedPasses.clear();
-
static const int passDebug = getPassDebug();
// Emit logging information when asked for. At passDebug level 1+ we log
// the main passes, while in 2 we also log nested ones. Note that for
@@ -821,20 +818,6 @@ void PassRunner::run() {
}
flush();
}
-
- if (!isNested) {
- // All the passes the user requested to skip should have been seen, and
- // skipped. If not, the user may have had a typo in the name of a pass to
- // skip, and we will warn. (We don't do this in a nested runner because
- // those are used for various internal tasks inside passes, which would lead
- // to many spurious warnings.)
- for (auto pass : options.passesToSkip) {
- if (!skippedPasses.count(pass)) {
- std::cerr << "warning: --" << pass << " was requested to be skipped, "
- << "but it was not found in the passes that were run.\n";
- }
- }
- }
}
void PassRunner::runOnFunction(Function* func) {
@@ -956,7 +939,6 @@ void PassRunner::runPass(Pass* pass) {
assert(!pass->isFunctionParallel());
if (options.passesToSkip.count(pass->name)) {
- skippedPasses.insert(pass->name);
return;
}
@@ -980,7 +962,6 @@ void PassRunner::runPassOnFunction(Pass* pass, Function* func) {
assert(pass->isFunctionParallel());
if (options.passesToSkip.count(pass->name)) {
- skippedPasses.insert(pass->name);
return;
}
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();
}
};