diff options
author | Alon Zakai <azakai@google.com> | 2023-04-20 15:13:46 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-20 15:13:46 -0700 |
commit | 2cd0f408f39c78e3bb0f141ee4d1b9ce2a4f1c16 (patch) | |
tree | 6c42291e561d6df3527635a3b4905219cba96b39 | |
parent | b2be62116ed18e39cec1558d5b77fa1626d03ee1 (diff) | |
download | binaryen-2cd0f408f39c78e3bb0f141ee4d1b9ce2a4f1c16.tar.gz binaryen-2cd0f408f39c78e3bb0f141ee4d1b9ce2a4f1c16.tar.bz2 binaryen-2cd0f408f39c78e3bb0f141ee4d1b9ce2a4f1c16.zip |
[Wasm GC] ReFinalize when needed in SimplifyGlobals (#5682)
-rw-r--r-- | src/passes/SimplifyGlobals.cpp | 27 | ||||
-rw-r--r-- | test/lit/passes/simplify-globals-gc.wast | 33 |
2 files changed, 56 insertions, 4 deletions
diff --git a/src/passes/SimplifyGlobals.cpp b/src/passes/SimplifyGlobals.cpp index f9bccab23..97e91bbab 100644 --- a/src/passes/SimplifyGlobals.cpp +++ b/src/passes/SimplifyGlobals.cpp @@ -328,6 +328,10 @@ struct ConstantGlobalApplier : public WalkerPass< LinearExecutionWalker<ConstantGlobalApplier, UnifiedExpressionVisitor<ConstantGlobalApplier>>> { + using super = WalkerPass< + LinearExecutionWalker<ConstantGlobalApplier, + UnifiedExpressionVisitor<ConstantGlobalApplier>>>; + bool isFunctionParallel() override { return true; } ConstantGlobalApplier(NameSet* constantGlobals, bool optimize) @@ -337,6 +341,16 @@ struct ConstantGlobalApplier return std::make_unique<ConstantGlobalApplier>(constantGlobals, optimize); } + bool refinalize = false; + + void replaceCurrent(Expression* rep) { + if (rep->type != getCurrent()->type) { + // This operation will change the type, so refinalize. + refinalize = true; + } + super::replaceCurrent(rep); + } + void visitExpression(Expression* curr) { if (auto* set = curr->dynCast<GlobalSet>()) { if (Properties::isConstantExpression(set->value)) { @@ -386,10 +400,15 @@ struct ConstantGlobalApplier } void visitFunction(Function* curr) { - if (replaced && optimize) { - PassRunner runner(getPassRunner()); - runner.addDefaultFunctionOptimizationPasses(); - runner.runOnFunction(curr); + if (replaced) { + if (refinalize) { + ReFinalize().walkFunctionInModule(curr, this->getModule()); + } + if (optimize) { + PassRunner runner(getPassRunner()); + runner.addDefaultFunctionOptimizationPasses(); + runner.runOnFunction(curr); + } } } diff --git a/test/lit/passes/simplify-globals-gc.wast b/test/lit/passes/simplify-globals-gc.wast new file mode 100644 index 000000000..da49cdf61 --- /dev/null +++ b/test/lit/passes/simplify-globals-gc.wast @@ -0,0 +1,33 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; NOTE: This test was ported using port_passes_tests_to_lit.py and could be cleaned up. + +;; RUN: foreach %s %t wasm-opt --simplify-globals -all -S -o - | filecheck %s + +(module + ;; CHECK: (type $A (func)) + (type $A (func)) + + ;; CHECK: (global $global$0 funcref (ref.func $func)) + (global $global$0 (mut funcref) (ref.func $func)) + + ;; CHECK: (elem declare func $func) + + ;; CHECK: (func $func (type $A) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.cast $A + ;; CHECK-NEXT: (ref.func $func) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $func + (drop + (ref.cast null $A + ;; This global can be replaced with a ref.func of $func. That has a more + ;; refined type, so we should refinalize (if we do not, then the ref.cast + ;; will fail to validate as it must become a non-nullable cast). + (global.get $global$0) + ) + ) + ) +) + |