diff options
author | Alon Zakai <azakai@google.com> | 2023-06-27 15:27:07 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-27 15:27:07 -0700 |
commit | aaf1dac49865024fbde9d316c4a46345186217af (patch) | |
tree | f8d2e0bcee1745492a602f8fb4aa1a9b9bd6d1e8 /src | |
parent | fd9d04ccd615b185e65a765e3587eae3f72aa867 (diff) | |
download | binaryen-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.h | 3 | ||||
-rw-r--r-- | src/passes/pass.cpp | 19 | ||||
-rw-r--r-- | src/tools/optimization-options.h | 58 |
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(); } }; |