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.cpp34
1 files changed, 32 insertions, 2 deletions
diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp
index 8dcc7e417..570cd8610 100644
--- a/src/passes/pass.cpp
+++ b/src/passes/pass.cpp
@@ -891,18 +891,48 @@ void PassRunner::runPass(Pass* pass) {
void PassRunner::runPassOnFunction(Pass* pass, Function* func) {
assert(pass->isFunctionParallel());
+
+ auto passDebug = getPassDebug();
+
+ // Add extra validation logic in pass-debug mode 2. The main logic in
+ // PassRunner::run will work at the module level, and here for a function-
+ // parallel pass we can do the same at the function level: we can print the
+ // function before the pass, run the pass on the function, and then if it
+ // fails to validate we can show an error and print the state right before the
+ // pass broke it.
+ //
+ // Skip nameless passes for this. Anything without a name is an internal
+ // component of some larger pass, and information about it won't be very
+ // useful - leave it to the entire module to fail validation in that case.
+ bool extraFunctionValidation =
+ passDebug == 2 && options.validate && !pass->name.empty();
+ std::stringstream bodyBefore;
+ if (extraFunctionValidation) {
+ bodyBefore << *func->body << '\n';
+ }
+
// function-parallel passes get a new instance per function
auto instance = std::unique_ptr<Pass>(pass->create());
std::unique_ptr<AfterEffectFunctionChecker> checker;
- if (getPassDebug()) {
+ if (passDebug) {
checker = std::unique_ptr<AfterEffectFunctionChecker>(
new AfterEffectFunctionChecker(func));
}
instance->runOnFunction(this, wasm, func);
handleAfterEffects(pass, func);
- if (getPassDebug()) {
+ if (passDebug) {
checker->check();
}
+
+ if (extraFunctionValidation) {
+ if (!WasmValidator().validate(func, *wasm, WasmValidator::Minimal)) {
+ Fatal() << "Last nested function-parallel pass (" << pass->name
+ << ") broke validation of function " << func->name
+ << ". Here is the function body before:\n"
+ << bodyBefore.str() << "\n\nAnd here it is now:\n"
+ << *func->body << '\n';
+ }
+ }
}
void PassRunner::handleAfterEffects(Pass* pass, Function* func) {