diff options
author | Alon Zakai <azakai@google.com> | 2019-07-18 17:08:14 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-07-18 17:08:14 -0700 |
commit | 8d3bc3f67cd55e99de29b66c43dbe2806a4dcdfb (patch) | |
tree | 1ace18f31e002a4303057c5d7c31559fc6e71813 /src | |
parent | 9bdf71324b84796170bf099ff64117a03052d937 (diff) | |
download | binaryen-8d3bc3f67cd55e99de29b66c43dbe2806a4dcdfb.tar.gz binaryen-8d3bc3f67cd55e99de29b66c43dbe2806a4dcdfb.tar.bz2 binaryen-8d3bc3f67cd55e99de29b66c43dbe2806a4dcdfb.zip |
SimplifyGlobals: Constant-propagate constant values of immutable globals (#2234)
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/SimplifyGlobals.cpp | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/passes/SimplifyGlobals.cpp b/src/passes/SimplifyGlobals.cpp index 87891352d..992126cfe 100644 --- a/src/passes/SimplifyGlobals.cpp +++ b/src/passes/SimplifyGlobals.cpp @@ -21,10 +21,12 @@ // globals immutable. // * If an immutable global is a copy of another, use the earlier one, // to allow removal of the copies later. +// * Apply the constant values of immutable globals. // #include <atomic> +#include "ir/utils.h" #include "pass.h" #include "wasm.h" @@ -54,6 +56,7 @@ private: }; using NameNameMap = std::map<Name, Name>; +using NameSet = std::set<Name>; struct GlobalUseModifier : public WalkerPass<PostWalker<GlobalUseModifier>> { bool isFunctionParallel() override { return true; } @@ -76,6 +79,29 @@ private: NameNameMap* copiedParentMap; }; +struct ConstantGlobalApplier + : public WalkerPass<PostWalker<ConstantGlobalApplier>> { + bool isFunctionParallel() override { return true; } + + ConstantGlobalApplier(NameSet* constantGlobals) + : constantGlobals(constantGlobals) {} + + ConstantGlobalApplier* create() override { + return new ConstantGlobalApplier(constantGlobals); + } + + void visitGlobalGet(GlobalGet* curr) { + if (constantGlobals->count(curr->name)) { + auto* global = getModule()->getGlobal(curr->name); + assert(global->init->is<Const>()); + replaceCurrent(ExpressionManipulator::copy(global->init, *getModule())); + } + } + +private: + NameSet* constantGlobals; +}; + } // anonymous namespace struct SimplifyGlobals : public Pass { @@ -135,6 +161,23 @@ struct SimplifyGlobals : public Pass { subRunner.add<GlobalUseModifier>(&copiedParentMap); subRunner.run(); } + // If any immutable globals have constant values, we can just apply them + // (the global itself will be removed by another pass, as it/ won't have + // any uses). + NameSet constantGlobals; + for (auto& global : module->globals) { + if (!global->mutable_ && !global->imported() && + global->init->is<Const>()) { + constantGlobals.insert(global->name); + } + } + if (!constantGlobals.empty()) { + PassRunner subRunner(module, runner->options); + subRunner.add<ConstantGlobalApplier>(&constantGlobals); + subRunner.run(); + } + // TODO a mutable global's initial value can be applied to another global + // after it, as the mutable one can't mutate during instance startup } }; |