summaryrefslogtreecommitdiff
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
parent9bdf71324b84796170bf099ff64117a03052d937 (diff)
downloadbinaryen-8d3bc3f67cd55e99de29b66c43dbe2806a4dcdfb.tar.gz
binaryen-8d3bc3f67cd55e99de29b66c43dbe2806a4dcdfb.tar.bz2
binaryen-8d3bc3f67cd55e99de29b66c43dbe2806a4dcdfb.zip
SimplifyGlobals: Constant-propagate constant values of immutable globals (#2234)
-rw-r--r--src/passes/SimplifyGlobals.cpp43
-rw-r--r--test/min.fromasm3
-rw-r--r--test/min.fromasm.clamp3
-rw-r--r--test/min.fromasm.imprecise3
-rw-r--r--test/passes/simplify-globals_enable-mutable-globals.txt59
-rw-r--r--test/passes/simplify-globals_enable-mutable-globals.wast30
-rw-r--r--test/unit.fromasm3
-rw-r--r--test/unit.fromasm.clamp3
-rw-r--r--test/unit.fromasm.imprecise3
9 files changed, 138 insertions, 12 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
}
};
diff --git a/test/min.fromasm b/test/min.fromasm
index 8f99f21e8..5a74603e3 100644
--- a/test/min.fromasm
+++ b/test/min.fromasm
@@ -2,7 +2,6 @@
(import "env" "memory" (memory $memory 256 256))
(data (global.get $__memory_base) "min.asm.js")
(import "env" "__memory_base" (global $__memory_base i32))
- (global $M i32 (i32.const 0))
(export "floats" (func $floats))
(export "getTempRet0" (func $ub))
(export "neg" (func $neg))
@@ -35,6 +34,6 @@
(drop
(call $ub)
)
- (global.get $M)
+ (i32.const 0)
)
)
diff --git a/test/min.fromasm.clamp b/test/min.fromasm.clamp
index 8f99f21e8..5a74603e3 100644
--- a/test/min.fromasm.clamp
+++ b/test/min.fromasm.clamp
@@ -2,7 +2,6 @@
(import "env" "memory" (memory $memory 256 256))
(data (global.get $__memory_base) "min.asm.js")
(import "env" "__memory_base" (global $__memory_base i32))
- (global $M i32 (i32.const 0))
(export "floats" (func $floats))
(export "getTempRet0" (func $ub))
(export "neg" (func $neg))
@@ -35,6 +34,6 @@
(drop
(call $ub)
)
- (global.get $M)
+ (i32.const 0)
)
)
diff --git a/test/min.fromasm.imprecise b/test/min.fromasm.imprecise
index b87a0b27f..8bf578712 100644
--- a/test/min.fromasm.imprecise
+++ b/test/min.fromasm.imprecise
@@ -1,6 +1,5 @@
(module
(import "env" "memory" (memory $memory 256 256))
- (global $M i32 (i32.const 0))
(export "floats" (func $floats))
(export "getTempRet0" (func $ub))
(export "neg" (func $neg))
@@ -33,6 +32,6 @@
(drop
(call $ub)
)
- (global.get $M)
+ (i32.const 0)
)
)
diff --git a/test/passes/simplify-globals_enable-mutable-globals.txt b/test/passes/simplify-globals_enable-mutable-globals.txt
index 407fbdaa1..010259d07 100644
--- a/test/passes/simplify-globals_enable-mutable-globals.txt
+++ b/test/passes/simplify-globals_enable-mutable-globals.txt
@@ -51,3 +51,62 @@
(global $g2 (mut i32) (global.get $g1))
(export "global-2" (global $g2))
)
+(module
+ (type $FUNCSIG$v (func))
+ (global $g1 i32 (i32.const 1))
+ (global $g2 i32 (global.get $g1))
+ (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 $g7 i32 (i32.const 3))
+ (global $g8 i32 (global.get $g7))
+ (global $g9 i32 (i32.const 4))
+ (global $ga (mut i32) (global.get $g9))
+ (global $gb (mut i32) (i32.const 5))
+ (global $gc i32 (global.get $gb))
+ (func $foo (; 0 ;) (type $FUNCSIG$v)
+ (drop
+ (i32.const 1)
+ )
+ (drop
+ (i32.const 1)
+ )
+ (drop
+ (f64.const -3.4)
+ )
+ (drop
+ (f64.const -2.8)
+ )
+ (drop
+ (i32.const 2)
+ )
+ (drop
+ (i32.const 2)
+ )
+ (drop
+ (i32.const 3)
+ )
+ (drop
+ (i32.const 3)
+ )
+ (drop
+ (i32.const 4)
+ )
+ (drop
+ (global.get $ga)
+ )
+ (drop
+ (global.get $gb)
+ )
+ (drop
+ (global.get $gc)
+ )
+ (global.set $ga
+ (i32.const 6)
+ )
+ (global.set $gb
+ (i32.const 7)
+ )
+ )
+)
diff --git a/test/passes/simplify-globals_enable-mutable-globals.wast b/test/passes/simplify-globals_enable-mutable-globals.wast
index 599f7e6ff..14038769a 100644
--- a/test/passes/simplify-globals_enable-mutable-globals.wast
+++ b/test/passes/simplify-globals_enable-mutable-globals.wast
@@ -34,4 +34,34 @@
(global $g2 (mut i32) (global.get $g1))
(export "global-2" (global $g2))
)
+(module
+ (global $g1 i32 (i32.const 1))
+ (global $g2 i32 (global.get $g1))
+ (global $g3 f64 (f64.const -3.4))
+ (global $g4 (mut f64) (f64.const -2.8))
+ (global $g5 i32 (i32.const 2))
+ (global $g6 (mut i32) (global.get $g5))
+ (global $g7 (mut i32) (i32.const 3))
+ (global $g8 i32 (global.get $g7))
+ (global $g9 i32 (i32.const 4))
+ (global $ga (mut i32) (global.get $g9))
+ (global $gb (mut i32) (i32.const 5))
+ (global $gc i32 (global.get $gb))
+ (func $foo
+ (drop (global.get $g1))
+ (drop (global.get $g2))
+ (drop (global.get $g3))
+ (drop (global.get $g4))
+ (drop (global.get $g5))
+ (drop (global.get $g6))
+ (drop (global.get $g7))
+ (drop (global.get $g8))
+ (drop (global.get $g9))
+ (drop (global.get $ga))
+ (drop (global.get $gb))
+ (drop (global.get $gc))
+ (global.set $ga (i32.const 6))
+ (global.set $gb (i32.const 7))
+ )
+)
diff --git a/test/unit.fromasm b/test/unit.fromasm
index 748be4b8e..b56f3e4fb 100644
--- a/test/unit.fromasm
+++ b/test/unit.fromasm
@@ -24,7 +24,6 @@
(import "asm2wasm" "f64-to-int" (func $f64-to-int (param f64) (result i32)))
(import "asm2wasm" "f64-rem" (func $f64-rem (param f64 f64) (result f64)))
(global $Int (mut i32) (i32.const 0))
- (global $Double f64 (f64.const 0))
(global $nonZero (mut i32) (i32.const 1337))
(global $exportedNumber i32 (i32.const 42))
(export "big_negative" (func $big_negative))
@@ -92,7 +91,7 @@
)
(if
(f64.gt
- (global.get $Double)
+ (f64.const 0)
(f64.const 0)
)
(return
diff --git a/test/unit.fromasm.clamp b/test/unit.fromasm.clamp
index 0b57f2077..3f4282103 100644
--- a/test/unit.fromasm.clamp
+++ b/test/unit.fromasm.clamp
@@ -22,7 +22,6 @@
(import "env" "emscripten_log" (func $emscripten_log))
(import "asm2wasm" "f64-rem" (func $f64-rem (param f64 f64) (result f64)))
(global $Int (mut i32) (i32.const 0))
- (global $Double f64 (f64.const 0))
(global $nonZero (mut i32) (i32.const 1337))
(global $exportedNumber i32 (i32.const 42))
(export "big_negative" (func $big_negative))
@@ -90,7 +89,7 @@
)
(if
(f64.gt
- (global.get $Double)
+ (f64.const 0)
(f64.const 0)
)
(return
diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise
index f9fc294c5..fd444c505 100644
--- a/test/unit.fromasm.imprecise
+++ b/test/unit.fromasm.imprecise
@@ -20,7 +20,6 @@
(import "env" "emscripten_log" (func $emscripten_log))
(import "asm2wasm" "f64-rem" (func $f64-rem (param f64 f64) (result f64)))
(global $Int (mut i32) (i32.const 0))
- (global $Double f64 (f64.const 0))
(global $nonZero (mut i32) (i32.const 1337))
(global $exportedNumber i32 (i32.const 42))
(export "big_negative" (func $big_negative))
@@ -88,7 +87,7 @@
)
(if
(f64.gt
- (global.get $Double)
+ (f64.const 0)
(f64.const 0)
)
(return