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 | |
parent | 9bdf71324b84796170bf099ff64117a03052d937 (diff) | |
download | binaryen-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.cpp | 43 | ||||
-rw-r--r-- | test/min.fromasm | 3 | ||||
-rw-r--r-- | test/min.fromasm.clamp | 3 | ||||
-rw-r--r-- | test/min.fromasm.imprecise | 3 | ||||
-rw-r--r-- | test/passes/simplify-globals_enable-mutable-globals.txt | 59 | ||||
-rw-r--r-- | test/passes/simplify-globals_enable-mutable-globals.wast | 30 | ||||
-rw-r--r-- | test/unit.fromasm | 3 | ||||
-rw-r--r-- | test/unit.fromasm.clamp | 3 | ||||
-rw-r--r-- | test/unit.fromasm.imprecise | 3 |
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 |