summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ir/effects.h36
-rw-r--r--src/passes/GlobalEffects.cpp13
-rw-r--r--src/passes/Vacuum.cpp2
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);
}