diff options
Diffstat (limited to 'src/ir/effects.h')
-rw-r--r-- | src/ir/effects.h | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/src/ir/effects.h b/src/ir/effects.h index ad3ab235d..5578b3b3b 100644 --- a/src/ir/effects.h +++ b/src/ir/effects.h @@ -31,7 +31,8 @@ public: Module& module, Expression* ast = nullptr) : ignoreImplicitTraps(passOptions.ignoreImplicitTraps), - trapsNeverHappen(passOptions.trapsNeverHappen), module(module), + trapsNeverHappen(passOptions.trapsNeverHappen), + funcEffectsMap(passOptions.funcEffectsMap), module(module), features(module.features) { if (ast) { walk(ast); @@ -40,6 +41,7 @@ public: bool ignoreImplicitTraps; bool trapsNeverHappen; + std::shared_ptr<FuncEffectsMap> funcEffectsMap; Module& module; FeatureSet features; @@ -261,7 +263,7 @@ public: return false; } - void mergeIn(EffectAnalyzer& other) { + void mergeIn(const EffectAnalyzer& other) { branchesOut = branchesOut || other.branchesOut; calls = calls || other.calls; readsMemory = readsMemory || other.readsMemory; @@ -422,14 +424,35 @@ private: return; } + if (curr->isReturn) { + parent.branchesOut = true; + } + + if (parent.funcEffectsMap) { + auto iter = parent.funcEffectsMap->find(curr->target); + if (iter != parent.funcEffectsMap->end()) { + // We have effect information for this call target, and can just use + // that. The one change we may want to make is to remove throws_, if + // the target function throws and we know that will be caught anyhow, + // the same as the code below for the general path. + const auto& targetEffects = iter->second; + if (targetEffects.throws_ && parent.tryDepth > 0) { + auto filteredEffects = targetEffects; + filteredEffects.throws_ = false; + parent.mergeIn(filteredEffects); + } else { + // Just merge in all the effects. + parent.mergeIn(targetEffects); + } + return; + } + } + parent.calls = true; // When EH is enabled, any call can throw. if (parent.features.hasExceptionHandling() && parent.tryDepth == 0) { parent.throws_ = true; } - if (curr->isReturn) { - parent.branchesOut = true; - } } void visitCallIndirect(CallIndirect* curr) { parent.calls = true; |