diff options
author | Alon Zakai <azakai@google.com> | 2022-08-09 09:48:45 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-09 09:48:45 -0700 |
commit | 94edb07713c607373c6cae088039e9a1802e1164 (patch) | |
tree | a32c86af6b9681a62e28ba22a12ea31862c5f7f5 /src/passes/SimplifyLocals.cpp | |
parent | 1610e6b3f5148d47c4f352c528db7d24bcfa598c (diff) | |
download | binaryen-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.cpp | 25 |
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) { |