summaryrefslogtreecommitdiff
path: root/src/passes/SimplifyLocals.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-08-09 09:48:45 -0700
committerGitHub <noreply@github.com>2022-08-09 09:48:45 -0700
commit94edb07713c607373c6cae088039e9a1802e1164 (patch)
treea32c86af6b9681a62e28ba22a12ea31862c5f7f5 /src/passes/SimplifyLocals.cpp
parent1610e6b3f5148d47c4f352c528db7d24bcfa598c (diff)
downloadbinaryen-94edb07713c607373c6cae088039e9a1802e1164.tar.gz
binaryen-94edb07713c607373c6cae088039e9a1802e1164.tar.bz2
binaryen-94edb07713c607373c6cae088039e9a1802e1164.zip
SimplifyLocals: ReFinalize when needed (#4878)
Diffstat (limited to 'src/passes/SimplifyLocals.cpp')
-rw-r--r--src/passes/SimplifyLocals.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/passes/SimplifyLocals.cpp b/src/passes/SimplifyLocals.cpp
index 159f09963..ee9e43b0b 100644
--- a/src/passes/SimplifyLocals.cpp
+++ b/src/passes/SimplifyLocals.cpp
@@ -53,6 +53,7 @@
#include <ir/linear-execution.h>
#include <ir/local-utils.h>
#include <ir/manipulation.h>
+#include <ir/utils.h>
#include <pass.h>
#include <wasm-builder.h>
#include <wasm-traversal.h>
@@ -120,6 +121,9 @@ struct SimplifyLocals
// local => # of local.gets for it
LocalGetCounter getCounter;
+ // In rare cases we make a change to a type that requires a refinalize.
+ bool refinalize = false;
+
static void
doNoteNonLinear(SimplifyLocals<allowTee, allowStructure, allowNesting>* self,
Expression** currp) {
@@ -254,6 +258,23 @@ struct SimplifyLocals
if (oneUse) {
// with just one use, we can sink just the value
this->replaceCurrent(set->value);
+
+ // We are replacing a local.get with the value of the local.set. That
+ // may require a refinalize in certain cases, like this:
+ //
+ // (struct.get $X 0
+ // (local.get $x)
+ // )
+ //
+ // If we replace the local.get with a more refined type then the
+ // struct.get may read a more refined type (if the subtype has a more
+ // refined type for that particular field). Note that this cannot happen
+ // in the other arm of this if-else, where we replace the local.get with
+ // a tee, since tees have the type of the local, so no types change
+ // there.
+ if (set->value->type != curr->type) {
+ refinalize = true;
+ }
} else {
this->replaceCurrent(set);
assert(!set->isTee());
@@ -889,6 +910,10 @@ struct SimplifyLocals
}
}
} while (anotherCycle);
+
+ if (refinalize) {
+ ReFinalize().walkFunctionInModule(func, this->getModule());
+ }
}
bool runMainOptimizations(Function* func) {