summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/SimplifyGlobals.cpp61
-rw-r--r--test/passes/simplify-globals_enable-mutable-globals.txt12
2 files changed, 60 insertions, 13 deletions
diff --git a/src/passes/SimplifyGlobals.cpp b/src/passes/SimplifyGlobals.cpp
index a111f31b5..fce9df964 100644
--- a/src/passes/SimplifyGlobals.cpp
+++ b/src/passes/SimplifyGlobals.cpp
@@ -23,11 +23,15 @@
// to allow removal of the copies later.
// * Apply the constant values of immutable globals.
//
+// Some globals may not have uses after these changes, which we leave
+// to other passes to optimize.
+//
#include <atomic>
#include "ir/utils.h"
#include "pass.h"
+#include "wasm-builder.h"
#include "wasm.h"
namespace wasm {
@@ -105,9 +109,26 @@ private:
} // anonymous namespace
struct SimplifyGlobals : public Pass {
- void run(PassRunner* runner, Module* module) override {
+ PassRunner* runner;
+ Module* module;
+
+ GlobalInfoMap map;
+
+ void run(PassRunner* runner_, Module* module_) override {
+ runner = runner_;
+ module = module_;
+
+ analyze();
+
+ preferEarlierImports();
+
+ propagateConstantsToGlobals();
+
+ propagateConstantsToCode();
+ }
+
+ void analyze() {
// First, find out all the relevant info.
- GlobalInfoMap map;
for (auto& global : module->globals) {
auto& info = map[global->name];
if (global->imported()) {
@@ -128,6 +149,9 @@ struct SimplifyGlobals : public Pass {
global->mutable_ = false;
}
}
+ }
+
+ void preferEarlierImports() {
// Optimize uses of immutable globals, prefer the earlier import when
// there is a copy.
NameNameMap copiedParentMap;
@@ -155,9 +179,34 @@ struct SimplifyGlobals : public Pass {
// Apply to the gets.
GlobalUseModifier(&copiedParentMap).run(runner, module);
}
- // 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).
+ }
+
+ // Constant propagation part 1: even an mutable global with a constant
+ // value can have that value propagated to another global that reads it,
+ // since we do know the value during startup, it can't be modified until
+ // code runs.
+ void propagateConstantsToGlobals() {
+ // Go over the list of globals in order, which is the order of
+ // initialization as well, tracking their constant values.
+ std::map<Name, Literal> constantGlobals;
+ for (auto& global : module->globals) {
+ if (!global->imported()) {
+ if (auto* c = global->init->dynCast<Const>()) {
+ constantGlobals[global->name] = c->value;
+ } else if (auto* get = global->init->dynCast<GlobalGet>()) {
+ auto iter = constantGlobals.find(get->name);
+ if (iter != constantGlobals.end()) {
+ Builder builder(*module);
+ global->init = builder.makeConst(iter->second);
+ }
+ }
+ }
+ }
+ }
+
+ // Constant propagation part 2: apply the values of immutable globals
+ // with constant values to to global.gets in the code.
+ void propagateConstantsToCode() {
NameSet constantGlobals;
for (auto& global : module->globals) {
if (!global->mutable_ && !global->imported() &&
@@ -168,8 +217,6 @@ struct SimplifyGlobals : public Pass {
if (!constantGlobals.empty()) {
ConstantGlobalApplier(&constantGlobals).run(runner, module);
}
- // 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
}
};
diff --git a/test/passes/simplify-globals_enable-mutable-globals.txt b/test/passes/simplify-globals_enable-mutable-globals.txt
index 010259d07..346161f14 100644
--- a/test/passes/simplify-globals_enable-mutable-globals.txt
+++ b/test/passes/simplify-globals_enable-mutable-globals.txt
@@ -54,17 +54,17 @@
(module
(type $FUNCSIG$v (func))
(global $g1 i32 (i32.const 1))
- (global $g2 i32 (global.get $g1))
+ (global $g2 i32 (i32.const 1))
(global $g3 f64 (f64.const -3.4))
(global $g4 f64 (f64.const -2.8))
(global $g5 i32 (i32.const 2))
- (global $g6 i32 (global.get $g5))
+ (global $g6 i32 (i32.const 2))
(global $g7 i32 (i32.const 3))
- (global $g8 i32 (global.get $g7))
+ (global $g8 i32 (i32.const 3))
(global $g9 i32 (i32.const 4))
- (global $ga (mut i32) (global.get $g9))
+ (global $ga (mut i32) (i32.const 4))
(global $gb (mut i32) (i32.const 5))
- (global $gc i32 (global.get $gb))
+ (global $gc i32 (i32.const 5))
(func $foo (; 0 ;) (type $FUNCSIG$v)
(drop
(i32.const 1)
@@ -100,7 +100,7 @@
(global.get $gb)
)
(drop
- (global.get $gc)
+ (i32.const 5)
)
(global.set $ga
(i32.const 6)