From db8ee88f59a8928a3bac2b666b1195813fead8f0 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 17 Jul 2019 13:27:43 -0700 Subject: [PATCH 1/2] SimplifyGlobals: apply a constant value, replacing global.get with that constant --- src/passes/SimplifyGlobals.cpp | 41 +++++++++++++ test/min.fromasm | 3 +- test/min.fromasm.clamp | 3 +- test/min.fromasm.imprecise | 3 +- ...implify-globals_enable-mutable-globals.txt | 59 +++++++++++++++++++ ...mplify-globals_enable-mutable-globals.wast | 30 ++++++++++ test/unit.fromasm | 3 +- test/unit.fromasm.clamp | 3 +- test/unit.fromasm.imprecise | 3 +- 9 files changed, 136 insertions(+), 12 deletions(-) diff --git a/src/passes/SimplifyGlobals.cpp b/src/passes/SimplifyGlobals.cpp index 87891352d5d..8557b221df2 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 @@ struct GlobalUseScanner : public WalkerPass> { }; using NameNameMap = std::map; +using NameSet = std::set; struct GlobalUseModifier : public WalkerPass> { bool isFunctionParallel() override { return true; } @@ -76,6 +79,28 @@ struct GlobalUseModifier : public WalkerPass> { 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 +160,22 @@ 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 } }; diff --git a/test/min.fromasm b/test/min.fromasm index 8f99f21e860..5a74603e340 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 8f99f21e860..5a74603e340 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 b87a0b27fef..8bf5787125d 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 407fbdaa1ca..010259d072d 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 599f7e6ffd0..14038769a5e 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 748be4b8efd..b56f3e4fb59 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 0b57f2077b5..3f4282103b2 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 f9fc294c5e5..fd444c505bc 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 From ae2a5a16de55df6dbf1fc94a8a8800397e56391b Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 17 Jul 2019 14:20:33 -0700 Subject: [PATCH 2/2] style --- src/passes/SimplifyGlobals.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/passes/SimplifyGlobals.cpp b/src/passes/SimplifyGlobals.cpp index 8557b221df2..992126cfe0d 100644 --- a/src/passes/SimplifyGlobals.cpp +++ b/src/passes/SimplifyGlobals.cpp @@ -79,7 +79,8 @@ struct GlobalUseModifier : public WalkerPass> { NameNameMap* copiedParentMap; }; -struct ConstantGlobalApplier : public WalkerPass> { +struct ConstantGlobalApplier + : public WalkerPass> { bool isFunctionParallel() override { return true; } ConstantGlobalApplier(NameSet* constantGlobals) @@ -165,7 +166,8 @@ struct SimplifyGlobals : public Pass { // any uses). NameSet constantGlobals; for (auto& global : module->globals) { - if (!global->mutable_ && !global->imported() && global->init->is()) { + if (!global->mutable_ && !global->imported() && + global->init->is()) { constantGlobals.insert(global->name); } }