From 8d3bc3f67cd55e99de29b66c43dbe2806a4dcdfb Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 18 Jul 2019 17:08:14 -0700 Subject: SimplifyGlobals: Constant-propagate constant values of immutable globals (#2234) --- src/passes/SimplifyGlobals.cpp | 43 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'src') 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 +#include "ir/utils.h" #include "pass.h" #include "wasm.h" @@ -54,6 +56,7 @@ private: }; using NameNameMap = std::map; +using NameSet = std::set; struct GlobalUseModifier : public WalkerPass> { bool isFunctionParallel() override { return true; } @@ -76,6 +79,29 @@ private: NameNameMap* copiedParentMap; }; +struct ConstantGlobalApplier + : public WalkerPass> { + 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()); + 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(&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()) { + constantGlobals.insert(global->name); + } + } + if (!constantGlobals.empty()) { + PassRunner subRunner(module, runner->options); + subRunner.add(&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 } }; -- cgit v1.2.3