diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/effects.h | 36 | ||||
-rw-r--r-- | src/passes/GlobalEffects.cpp | 13 | ||||
-rw-r--r-- | src/passes/Vacuum.cpp | 2 |
3 files changed, 32 insertions, 19 deletions
diff --git a/src/ir/effects.h b/src/ir/effects.h index 4b8c9a921..c2ba794d9 100644 --- a/src/ir/effects.h +++ b/src/ir/effects.h @@ -27,16 +27,22 @@ namespace wasm { class EffectAnalyzer { public: - EffectAnalyzer(const PassOptions& passOptions, - Module& module, - Expression* ast = nullptr) + EffectAnalyzer(const PassOptions& passOptions, Module& module) : ignoreImplicitTraps(passOptions.ignoreImplicitTraps), trapsNeverHappen(passOptions.trapsNeverHappen), funcEffectsMap(passOptions.funcEffectsMap), module(module), - features(module.features) { - if (ast) { - walk(ast); - } + features(module.features) {} + + EffectAnalyzer(const PassOptions& passOptions, + Module& module, + Expression* ast) + : EffectAnalyzer(passOptions, module) { + walk(ast); + } + + EffectAnalyzer(const PassOptions& passOptions, Module& module, Function* func) + : EffectAnalyzer(passOptions, module) { + walk(func); } bool ignoreImplicitTraps; @@ -59,6 +65,22 @@ public: post(); } + // Walk an entire function body. This will ignore effects that are not + // noticeable from the perspective of the caller, that is, effects that are + // only noticeable during the call, but "vanish" when the call stack is + // unwound. + void walk(Function* func) { + walk(func->body); + + // We can ignore branching out of the function body - this can only be + // a return, and that is only noticeable in the function, not outside. + branchesOut = false; + + // When the function exits, changes to locals cannot be noticed any more. + localsWritten.clear(); + localsRead.clear(); + } + // Core effect tracking // Definitely branches out of this expression, or does a return, etc. diff --git a/src/passes/GlobalEffects.cpp b/src/passes/GlobalEffects.cpp index 1dd91e5d7..2f816a0bd 100644 --- a/src/passes/GlobalEffects.cpp +++ b/src/passes/GlobalEffects.cpp @@ -49,8 +49,8 @@ struct GenerateGlobalEffects : public Pass { } // Gather the effects. - auto effects = std::make_unique<EffectAnalyzer>( - runner->options, *module, func->body); + auto effects = + std::make_unique<EffectAnalyzer>(runner->options, *module, func); // If the body has a call, give up - that means we can't infer a more // specific set of effects than the pessimistic case of just assuming @@ -60,15 +60,6 @@ struct GenerateGlobalEffects : public Pass { return; } - // We can ignore branching out of the function body - this can only be - // a return, and that is only noticeable in the function, not outside. - effects->branchesOut = false; - - // Ignore local effects - when the function exits, those become - // unnoticeable anyhow. - effects->localsWritten.clear(); - effects->localsRead.clear(); - // Save the useful effects we found. storedEffects = std::move(effects); }); diff --git a/src/passes/Vacuum.cpp b/src/passes/Vacuum.cpp index 208e973da..a29c74a89 100644 --- a/src/passes/Vacuum.cpp +++ b/src/passes/Vacuum.cpp @@ -390,7 +390,7 @@ struct Vacuum : public WalkerPass<ExpressionStackWalker<Vacuum>> { ExpressionManipulator::nop(curr->body); } if (curr->getResults() == Type::none && - !EffectAnalyzer(getPassOptions(), *getModule(), curr->body) + !EffectAnalyzer(getPassOptions(), *getModule(), curr) .hasUnremovableSideEffects()) { ExpressionManipulator::nop(curr->body); } |