summaryrefslogtreecommitdiff
path: root/src/passes/pass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes/pass.cpp')
-rw-r--r--src/passes/pass.cpp165
1 files changed, 77 insertions, 88 deletions
diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp
index 64e48680e..7d068a7dd 100644
--- a/src/passes/pass.cpp
+++ b/src/passes/pass.cpp
@@ -49,7 +49,7 @@ void PassRegistry::registerPass(const char* name,
std::unique_ptr<Pass> PassRegistry::createPass(std::string name) {
if (passInfos.find(name) == passInfos.end()) {
- return nullptr;
+ Fatal() << "Could not find pass: " << name << "\n";
}
std::unique_ptr<Pass> ret;
ret.reset(passInfos[name].create());
@@ -372,144 +372,129 @@ void PassRegistry::registerPasses() {
// "lower-i64", "lowers i64 into pairs of i32s", createLowerInt64Pass);
}
+void PassRunner::addIfNoDWARFIssues(std::string passName) {
+ auto pass = PassRegistry::get()->createPass(passName);
+ if (!pass->invalidatesDWARF() ||
+ !Debug::shouldPreserveDWARF(options, *wasm)) {
+ doAdd(std::move(pass));
+ }
+}
+
void PassRunner::addDefaultOptimizationPasses() {
addDefaultGlobalOptimizationPrePasses();
addDefaultFunctionOptimizationPasses();
addDefaultGlobalOptimizationPostPasses();
}
-// Check whether we should preserve valid DWARF while optimizing. If so, we
-// disable optimizations that currently cause issues with debug info.
-static bool shouldPreserveDWARF(PassOptions& options, Module& wasm) {
- return options.debugInfo && Debug::hasDWARFSections(wasm);
-}
-
void PassRunner::addDefaultFunctionOptimizationPasses() {
- auto preserveDWARF = shouldPreserveDWARF(options, *wasm);
+ // All the additions here are optional if DWARF must be preserved. That is,
+ // when DWARF is relevant we run fewer optimizations.
+ // FIXME: support DWARF in all of them.
+
// Untangling to semi-ssa form is helpful (but best to ignore merges
// so as to not introduce new copies).
- // FIXME DWARF updating does not handle local changes yet.
- if (!preserveDWARF &&
- (options.optimizeLevel >= 3 || options.shrinkLevel >= 1)) {
- add("ssa-nomerge");
+ if (options.optimizeLevel >= 3 || options.shrinkLevel >= 1) {
+ addIfNoDWARFIssues("ssa-nomerge");
}
// if we are willing to work very very hard, flatten the IR and do opts
// that depend on flat IR
- // FIXME DWARF updating does not handle local changes yet.
- if (!preserveDWARF && options.optimizeLevel >= 4) {
- add("flatten");
- add("local-cse");
- }
- add("dce");
- add("remove-unused-names");
- add("remove-unused-brs");
- add("remove-unused-names");
- add("optimize-instructions");
+ if (options.optimizeLevel >= 4) {
+ addIfNoDWARFIssues("flatten");
+ addIfNoDWARFIssues("local-cse");
+ }
+ addIfNoDWARFIssues("dce");
+ addIfNoDWARFIssues("remove-unused-names");
+ addIfNoDWARFIssues("remove-unused-brs");
+ addIfNoDWARFIssues("remove-unused-names");
+ addIfNoDWARFIssues("optimize-instructions");
if (options.optimizeLevel >= 2 || options.shrinkLevel >= 2) {
- add("pick-load-signs");
+ addIfNoDWARFIssues("pick-load-signs");
}
// early propagation
if (options.optimizeLevel >= 3 || options.shrinkLevel >= 2) {
- add("precompute-propagate");
+ addIfNoDWARFIssues("precompute-propagate");
} else {
- add("precompute");
+ addIfNoDWARFIssues("precompute");
}
if (options.lowMemoryUnused) {
if (options.optimizeLevel >= 3 || options.shrinkLevel >= 1) {
- add("optimize-added-constants-propagate");
+ addIfNoDWARFIssues("optimize-added-constants-propagate");
} else {
- add("optimize-added-constants");
+ addIfNoDWARFIssues("optimize-added-constants");
}
}
if (options.optimizeLevel >= 2 || options.shrinkLevel >= 2) {
- add("code-pushing");
+ addIfNoDWARFIssues("code-pushing");
}
// don't create if/block return values yet, as coalesce can remove copies that
// that could inhibit
- add("simplify-locals-nostructure");
- add("vacuum"); // previous pass creates garbage
- add("reorder-locals");
+ addIfNoDWARFIssues("simplify-locals-nostructure");
+ addIfNoDWARFIssues("vacuum"); // previous pass creates garbage
+ addIfNoDWARFIssues("reorder-locals");
// simplify-locals opens opportunities for optimizations
- add("remove-unused-brs");
+ addIfNoDWARFIssues("remove-unused-brs");
// if we are willing to work hard, also optimize copies before coalescing
- // FIXME DWARF updating does not handle local changes yet.
- if (!preserveDWARF &&
- (options.optimizeLevel >= 3 || options.shrinkLevel >= 2)) {
- add("merge-locals"); // very slow on e.g. sqlite
- }
- // FIXME DWARF updating does not handle local changes yet.
- if (!preserveDWARF) {
- add("coalesce-locals");
- }
- add("simplify-locals");
- add("vacuum");
- add("reorder-locals");
- // FIXME DWARF updating does not handle local changes yet.
- if (!preserveDWARF) {
- add("coalesce-locals");
- add("reorder-locals");
- }
- add("vacuum");
+ if (options.optimizeLevel >= 3 || options.shrinkLevel >= 2) {
+ addIfNoDWARFIssues("merge-locals"); // very slow on e.g. sqlite
+ }
+ addIfNoDWARFIssues("coalesce-locals");
+ addIfNoDWARFIssues("simplify-locals");
+ addIfNoDWARFIssues("vacuum");
+ addIfNoDWARFIssues("reorder-locals");
+ addIfNoDWARFIssues("coalesce-locals");
+ addIfNoDWARFIssues("reorder-locals");
+ addIfNoDWARFIssues("vacuum");
if (options.optimizeLevel >= 3 || options.shrinkLevel >= 1) {
- add("code-folding");
- }
- add("merge-blocks"); // makes remove-unused-brs more effective
- add("remove-unused-brs"); // coalesce-locals opens opportunities
- add("remove-unused-names"); // remove-unused-brs opens opportunities
- add("merge-blocks"); // clean up remove-unused-brs new blocks
+ addIfNoDWARFIssues("code-folding");
+ }
+ addIfNoDWARFIssues("merge-blocks"); // makes remove-unused-brs more effective
+ addIfNoDWARFIssues(
+ "remove-unused-brs"); // coalesce-locals opens opportunities
+ addIfNoDWARFIssues(
+ "remove-unused-names"); // remove-unused-brs opens opportunities
+ addIfNoDWARFIssues("merge-blocks"); // clean up remove-unused-brs new blocks
// late propagation
if (options.optimizeLevel >= 3 || options.shrinkLevel >= 2) {
- add("precompute-propagate");
+ addIfNoDWARFIssues("precompute-propagate");
} else {
- add("precompute");
+ addIfNoDWARFIssues("precompute");
}
- add("optimize-instructions");
+ addIfNoDWARFIssues("optimize-instructions");
if (options.optimizeLevel >= 2 || options.shrinkLevel >= 1) {
- add("rse"); // after all coalesce-locals, and before a final vacuum
+ addIfNoDWARFIssues(
+ "rse"); // after all coalesce-locals, and before a final vacuum
}
- add("vacuum"); // just to be safe
+ addIfNoDWARFIssues("vacuum"); // just to be safe
}
void PassRunner::addDefaultGlobalOptimizationPrePasses() {
- // FIXME DWARF updating does not handle merging debug info with merged code.
- if (!shouldPreserveDWARF(options, *wasm)) {
- add("duplicate-function-elimination");
- }
- add("memory-packing");
+ addIfNoDWARFIssues("duplicate-function-elimination");
+ addIfNoDWARFIssues("memory-packing");
}
void PassRunner::addDefaultGlobalOptimizationPostPasses() {
- auto preserveDWARF = shouldPreserveDWARF(options, *wasm);
- // FIXME DWARF may be badly affected currently as DAE changes function
- // signatures and hence params and locals.
- if (!preserveDWARF &&
- (options.optimizeLevel >= 2 || options.shrinkLevel >= 1)) {
- add("dae-optimizing");
- }
- // FIXME DWARF updating does not handle inlining yet.
- if (!preserveDWARF &&
- (options.optimizeLevel >= 2 || options.shrinkLevel >= 2)) {
- add("inlining-optimizing");
+ if (options.optimizeLevel >= 2 || options.shrinkLevel >= 1) {
+ addIfNoDWARFIssues("dae-optimizing");
}
- // Optimizations show more functions as duplicate, so run this here in Post.
- // FIXME DWARF updating does not handle merging debug info with merged code.
- if (!preserveDWARF) {
- add("duplicate-function-elimination");
+ if (options.optimizeLevel >= 2 || options.shrinkLevel >= 2) {
+ addIfNoDWARFIssues("inlining-optimizing");
}
- add("duplicate-import-elimination");
+ // Optimizations show more functions as duplicate, so run this here in Post.
+ addIfNoDWARFIssues("duplicate-function-elimination");
+ addIfNoDWARFIssues("duplicate-import-elimination");
if (options.optimizeLevel >= 2 || options.shrinkLevel >= 2) {
- add("simplify-globals-optimizing");
+ addIfNoDWARFIssues("simplify-globals-optimizing");
} else {
- add("simplify-globals");
+ addIfNoDWARFIssues("simplify-globals");
}
- add("remove-unused-module-elements");
+ addIfNoDWARFIssues("remove-unused-module-elements");
// may allow more inlining/dae/etc., need --converge for that
- add("directize");
+ addIfNoDWARFIssues("directize");
// perform Stack IR optimizations here, at the very end of the
// optimization pipeline
if (options.optimizeLevel >= 2 || options.shrinkLevel >= 1) {
- add("generate-stack-ir");
- add("optimize-stack-ir");
+ addIfNoDWARFIssues("generate-stack-ir");
+ addIfNoDWARFIssues("optimize-stack-ir");
}
}
@@ -670,6 +655,10 @@ void PassRunner::runOnFunction(Function* func) {
}
void PassRunner::doAdd(std::unique_ptr<Pass> pass) {
+ if (Debug::shouldPreserveDWARF(options, *wasm) && pass->invalidatesDWARF()) {
+ std::cerr << "warning: running pass '" << pass->name
+ << "' which is not fully compatible with DWARF\n";
+ }
passes.emplace_back(std::move(pass));
}