summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-12-15 13:46:35 -0800
committerGitHub <noreply@github.com>2022-12-15 13:46:35 -0800
commitbead42c46d48e4c5584f035f7a805911dc59ae35 (patch)
tree4079c1b3e7e850ad568fbb1b957aba985258425b /src
parent7769196090e7ce2c150cd8a58fad0c89430d3d2b (diff)
downloadbinaryen-bead42c46d48e4c5584f035f7a805911dc59ae35.tar.gz
binaryen-bead42c46d48e4c5584f035f7a805911dc59ae35.tar.bz2
binaryen-bead42c46d48e4c5584f035f7a805911dc59ae35.zip
Properly use pass options in nested pass runners (up to -O1) (#5351)
This fixes a TODO. There is a runtime cost to this in higher opt levels, as passing through -O3 makes nested optimization work take longer. But it can lead to better results. For now, this PR moves us from 0 before to a maximum of 1, as a compromise. 1 does not regress compile times, but there may be further benefits to allowing 2 and 3 in the future. Also fix a fuzzer bug that becomes uncovered by tihs PR: Now that we actually optimize in simplify-globals, we need to handle the case of the optimizer there seeing a call with the effects of writing to a global (we had an assert on that never happening, but with function effects that can happen, and so a GlobalSet is not the only thing that can set a global). Aside from the opt and shrink levels this passes through all other options, like trapsNeverHappen.
Diffstat (limited to 'src')
-rw-r--r--src/pass.h17
-rw-r--r--src/passes/SimplifyGlobals.cpp16
2 files changed, 25 insertions, 8 deletions
diff --git a/src/pass.h b/src/pass.h
index f4b15a320..2cb661e72 100644
--- a/src/pass.h
+++ b/src/pass.h
@@ -488,10 +488,19 @@ public:
assert(getPassRunner());
// Parallel pass running is implemented in the PassRunner.
if (isFunctionParallel()) {
- // TODO: We should almost certainly be propagating pass options here, but
- // that is a widespread change, so make sure it doesn't unacceptably
- // regress compile times.
- PassRunner runner(module /*, getPassOptions()*/);
+ // Reduce opt/shrink levels to a maximum of one in nested runners like
+ // these, to balance runtime. We definitely want the full levels in the
+ // main passes we run, but nested pass runners are of secondary
+ // importance.
+ // TODO Investigate the impact of allowing the levels to just pass
+ // through. That seems to cause at least some regression in compile
+ // times in -O3, however, but with careful measurement we may find
+ // the benefits are worth it. For now -O1 is a reasonable compromise
+ // as it has basically linear runtime, unlike -O2 and -O3.
+ auto options = getPassOptions();
+ options.optimizeLevel = std::min(options.optimizeLevel, 1);
+ options.shrinkLevel = std::min(options.shrinkLevel, 1);
+ PassRunner runner(module, options);
runner.setIsNested(true);
runner.add(create());
runner.run();
diff --git a/src/passes/SimplifyGlobals.cpp b/src/passes/SimplifyGlobals.cpp
index 463261d35..f9bccab23 100644
--- a/src/passes/SimplifyGlobals.cpp
+++ b/src/passes/SimplifyGlobals.cpp
@@ -364,12 +364,20 @@ struct ConstantGlobalApplier
}
return;
}
- // Otherwise, invalidate if we need to.
- EffectAnalyzer effects(getPassOptions(), *getModule());
- effects.visit(curr);
- assert(effects.globalsWritten.empty()); // handled above
+
+ // Otherwise, invalidate if we need to. Note that we handled a GlobalSet
+ // earlier, but also need to handle calls. A general call forces us to
+ // forget everything, but in some cases we can do better, if we have a call
+ // and have computed function effects for it.
+ ShallowEffectAnalyzer effects(getPassOptions(), *getModule(), curr);
if (effects.calls) {
+ // Forget everything.
currConstantGlobals.clear();
+ } else {
+ // Forget just the globals written, if any.
+ for (auto writtenGlobal : effects.globalsWritten) {
+ currConstantGlobals.erase(writtenGlobal);
+ }
}
}