summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2019-07-18 17:08:14 -0700
committerGitHub <noreply@github.com>2019-07-18 17:08:14 -0700
commit8d3bc3f67cd55e99de29b66c43dbe2806a4dcdfb (patch)
tree1ace18f31e002a4303057c5d7c31559fc6e71813 /src
parent9bdf71324b84796170bf099ff64117a03052d937 (diff)
downloadbinaryen-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.cpp43
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
}
};