summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pass.h7
-rw-r--r--src/passes/Asyncify.cpp5
-rw-r--r--src/passes/DeNaN.cpp2
-rw-r--r--src/passes/ExtractFunction.cpp6
-rw-r--r--src/passes/FuncCastEmulation.cpp5
-rw-r--r--src/passes/I64ToI32Lowering.cpp3
-rw-r--r--src/passes/InstrumentLocals.cpp3
-rw-r--r--src/passes/InstrumentMemory.cpp3
-rw-r--r--src/passes/LegalizeJSInterface.cpp3
-rw-r--r--src/passes/LogExecution.cpp3
-rw-r--r--src/passes/SafeHeap.cpp2
-rw-r--r--src/passes/SpillPointers.cpp3
-rw-r--r--src/passes/StackCheck.cpp3
-rw-r--r--src/passes/pass.cpp5
14 files changed, 53 insertions, 0 deletions
diff --git a/src/pass.h b/src/pass.h
index 090aa8d33..da9a12b95 100644
--- a/src/pass.h
+++ b/src/pass.h
@@ -466,6 +466,13 @@ public:
// For more details see the LocalStructuralDominance class.
virtual bool requiresNonNullableLocalFixups() { return true; }
+ // Many passes can remove effects, for example, by finding some path is not
+ // reached and removing a throw or a call there. The few passes that *add*
+ // effects must mark themselves as such, so that we know to discard global
+ // effects after running them. For example, a logging pass that adds new calls
+ // to imports must override this to return true.
+ virtual bool addsEffects() { return false; }
+
std::string name;
PassRunner* getPassRunner() { return runner; }
diff --git a/src/passes/Asyncify.cpp b/src/passes/Asyncify.cpp
index d0674d97c..2412a754a 100644
--- a/src/passes/Asyncify.cpp
+++ b/src/passes/Asyncify.cpp
@@ -870,6 +870,8 @@ struct InstrumentedProxy : public Pass {
bool invalidatesDWARF() override { return pass->invalidatesDWARF(); }
+ bool addsEffects() override { return pass->addsEffects(); }
+
bool requiresNonNullableLocalFixups() override {
return pass->requiresNonNullableLocalFixups();
}
@@ -1610,6 +1612,9 @@ static std::string getFullImportName(Name module, Name base) {
}
struct Asyncify : public Pass {
+ // Adds calls.
+ bool addsEffects() override { return true; }
+
void run(Module* module) override {
auto& options = getPassOptions();
bool optimize = options.optimizeLevel > 0;
diff --git a/src/passes/DeNaN.cpp b/src/passes/DeNaN.cpp
index 44dd0bf15..97f71c39f 100644
--- a/src/passes/DeNaN.cpp
+++ b/src/passes/DeNaN.cpp
@@ -32,6 +32,8 @@ namespace wasm {
struct DeNaN : public WalkerPass<
ControlFlowWalker<DeNaN, UnifiedExpressionVisitor<DeNaN>>> {
+ // Adds calls.
+ bool addsEffects() override { return true; }
Name deNan32, deNan64;
diff --git a/src/passes/ExtractFunction.cpp b/src/passes/ExtractFunction.cpp
index e3f2a5538..440468ede 100644
--- a/src/passes/ExtractFunction.cpp
+++ b/src/passes/ExtractFunction.cpp
@@ -58,6 +58,9 @@ static void extract(PassRunner* runner, Module* module, Name name) {
}
struct ExtractFunction : public Pass {
+ // Turns functions into imported functions.
+ bool addsEffects() override { return true; }
+
void run(Module* module) override {
Name name = getPassOptions().getArgument(
"extract-function",
@@ -67,6 +70,9 @@ struct ExtractFunction : public Pass {
};
struct ExtractFunctionIndex : public Pass {
+ // See above.
+ bool addsEffects() override { return true; }
+
void run(Module* module) override {
std::string index =
getPassOptions().getArgument("extract-function-index",
diff --git a/src/passes/FuncCastEmulation.cpp b/src/passes/FuncCastEmulation.cpp
index 3255208fe..23eb98a8c 100644
--- a/src/passes/FuncCastEmulation.cpp
+++ b/src/passes/FuncCastEmulation.cpp
@@ -151,6 +151,11 @@ private:
};
struct FuncCastEmulation : public Pass {
+ // Changes the ABI, which alters which indirect calls will trap (normally,
+ // this should prevent traps, but it depends on code this is linked to at
+ // runtime in the case of dynamic linking etc.).
+ bool addsEffects() override { return true; }
+
void run(Module* module) override {
Index numParams = std::stoul(
getPassOptions().getArgumentOrDefault("max-func-params", "16"));
diff --git a/src/passes/I64ToI32Lowering.cpp b/src/passes/I64ToI32Lowering.cpp
index ec66b1121..0f591871b 100644
--- a/src/passes/I64ToI32Lowering.cpp
+++ b/src/passes/I64ToI32Lowering.cpp
@@ -39,6 +39,9 @@ namespace wasm {
static Name makeHighName(Name n) { return n.toString() + "$hi"; }
struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
+ // Adds calls to helper functions.
+ bool addsEffects() override { return true; }
+
struct TempVar {
TempVar(Index idx, Type ty, I64ToI32Lowering& pass)
: idx(idx), pass(pass), moved(false), ty(ty) {}
diff --git a/src/passes/InstrumentLocals.cpp b/src/passes/InstrumentLocals.cpp
index 311d4a27b..bf5de644c 100644
--- a/src/passes/InstrumentLocals.cpp
+++ b/src/passes/InstrumentLocals.cpp
@@ -68,6 +68,9 @@ Name set_funcref("set_funcref");
Name set_externref("set_externref");
struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> {
+ // Adds calls to new imports.
+ bool addsEffects() override { return true; }
+
void visitLocalGet(LocalGet* curr) {
Builder builder(*getModule());
Name import;
diff --git a/src/passes/InstrumentMemory.cpp b/src/passes/InstrumentMemory.cpp
index 486bc7c1f..b3c9aebbd 100644
--- a/src/passes/InstrumentMemory.cpp
+++ b/src/passes/InstrumentMemory.cpp
@@ -97,6 +97,9 @@ static Name array_set_index("array_set_index");
// TODO: Add support for atomicRMW/cmpxchg
struct InstrumentMemory : public WalkerPass<PostWalker<InstrumentMemory>> {
+ // Adds calls to new imports.
+ bool addsEffects() override { return true; }
+
void visitLoad(Load* curr) {
id++;
Builder builder(*getModule());
diff --git a/src/passes/LegalizeJSInterface.cpp b/src/passes/LegalizeJSInterface.cpp
index 6667862f4..3ca6b7095 100644
--- a/src/passes/LegalizeJSInterface.cpp
+++ b/src/passes/LegalizeJSInterface.cpp
@@ -54,6 +54,9 @@ static Name GET_TEMP_RET_IMPORT("getTempRet0");
static Name SET_TEMP_RET_IMPORT("setTempRet0");
struct LegalizeJSInterface : public Pass {
+ // Adds calls to new imports.
+ bool addsEffects() override { return true; }
+
bool full;
LegalizeJSInterface(bool full) : full(full) {}
diff --git a/src/passes/LogExecution.cpp b/src/passes/LogExecution.cpp
index 63ada5819..1b90842bc 100644
--- a/src/passes/LogExecution.cpp
+++ b/src/passes/LogExecution.cpp
@@ -39,6 +39,9 @@ namespace wasm {
Name LOGGER("log_execution");
struct LogExecution : public WalkerPass<PostWalker<LogExecution>> {
+ // Adds calls to new imports.
+ bool addsEffects() override { return true; }
+
void visitLoop(Loop* curr) { curr->body = makeLogCall(curr->body); }
void visitReturn(Return* curr) { replaceCurrent(makeLogCall(curr)); }
diff --git a/src/passes/SafeHeap.cpp b/src/passes/SafeHeap.cpp
index 0e9e8aeef..b2f7db567 100644
--- a/src/passes/SafeHeap.cpp
+++ b/src/passes/SafeHeap.cpp
@@ -131,6 +131,8 @@ static std::set<Name> findCalledFunctions(Module* module, Name startFunc) {
}
struct SafeHeap : public Pass {
+ // Adds calls to new imports.
+ bool addsEffects() override { return true; }
void run(Module* module) override {
assert(!module->memories.empty());
diff --git a/src/passes/SpillPointers.cpp b/src/passes/SpillPointers.cpp
index f496b8c79..3af7039cd 100644
--- a/src/passes/SpillPointers.cpp
+++ b/src/passes/SpillPointers.cpp
@@ -37,6 +37,9 @@ struct SpillPointers
: public WalkerPass<LivenessWalker<SpillPointers, Visitor<SpillPointers>>> {
bool isFunctionParallel() override { return true; }
+ // Adds writes to memory.
+ bool addsEffects() override { return true; }
+
std::unique_ptr<Pass> create() override {
return std::make_unique<SpillPointers>();
}
diff --git a/src/passes/StackCheck.cpp b/src/passes/StackCheck.cpp
index 9fba683b8..229a97f26 100644
--- a/src/passes/StackCheck.cpp
+++ b/src/passes/StackCheck.cpp
@@ -126,6 +126,9 @@ private:
};
struct StackCheck : public Pass {
+ // Adds calls to new imports.
+ bool addsEffects() override { return true; }
+
void run(Module* module) override {
Global* stackPointer = getStackPointerGlobal(*module);
if (!stackPointer) {
diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp
index 3880519da..9b03310b5 100644
--- a/src/passes/pass.cpp
+++ b/src/passes/pass.cpp
@@ -1056,6 +1056,11 @@ void PassRunner::handleAfterEffects(Pass* pass, Function* func) {
if (pass->requiresNonNullableLocalFixups()) {
TypeUpdating::handleNonDefaultableLocals(func, *wasm);
}
+
+ if (options.funcEffectsMap && pass->addsEffects()) {
+ // Effects were added, so discard any computed effects for this function.
+ options.funcEffectsMap->erase(func->name);
+ }
}
int PassRunner::getPassDebug() {