From 8c786f698807663dd6f98be2bc895dc2ff403654 Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Thu, 12 Sep 2019 09:45:55 -0700 Subject: [PATCH 1/8] wip --- src/passes/SimplifyGlobals.cpp | 54 +++++++++++++++++++++++--- src/passes/pass.cpp | 10 ++++- src/passes/passes.h | 1 + test/passes/O4_disable-bulk-memory.txt | 2 +- 4 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/passes/SimplifyGlobals.cpp b/src/passes/SimplifyGlobals.cpp index fce9df96428..6d51dca39b8 100644 --- a/src/passes/SimplifyGlobals.cpp +++ b/src/passes/SimplifyGlobals.cpp @@ -84,26 +84,61 @@ struct GlobalUseModifier : public WalkerPass> { }; struct ConstantGlobalApplier - : public WalkerPass> { + : public WalkerPass> { bool isFunctionParallel() override { return true; } - ConstantGlobalApplier(NameSet* constantGlobals) - : constantGlobals(constantGlobals) {} + ConstantGlobalApplier(NameSet* constantGlobals, bool optimize) + : constantGlobals(constantGlobals), optimize(optimize) {} ConstantGlobalApplier* create() override { - return new ConstantGlobalApplier(constantGlobals); + return new ConstantGlobalApplier(constantGlobals, optimize); + } + + void visitGlobalSet(GlobalSet* curr) { + if (auto* c = curr->value->dynCast()) { + currConstantGlobals[curr->name] = c->value; + } } void visitGlobalGet(GlobalGet* curr) { + // Check if the global is known to be constant all the time. if (constantGlobals->count(curr->name)) { auto* global = getModule()->getGlobal(curr->name); assert(global->init->is()); replaceCurrent(ExpressionManipulator::copy(global->init, *getModule())); + replaced = true; + return; + } + // Check if the global has a known value in this linear trace. + auto iter = currConstantGlobals.find(curr->name); + if (iter != currConstantGlobals.end()) { + Builder builder(*getModule()); + replaceCurrent(builder.makeConst(iter->second)); + replaced = true; + } + } + + static void doNoteNonLinear(ConstantGlobalApplier* self, + Expression** currp) { + self->currConstantGlobals.clear(); + } + + void visitFunction(Function* curr) { + if (replaced && optimize) { + PassRunner runner(getModule(), getPassRunner()->options); + runner.setIsNested(true); + runner.addDefaultFunctionOptimizationPasses(); + runner.runOnFunction(curr); } } private: NameSet* constantGlobals; + bool optimize; + bool replaced = false; + + // The globals currently constant in the linear trace. + std::map currConstantGlobals; }; } // anonymous namespace @@ -113,6 +148,9 @@ struct SimplifyGlobals : public Pass { Module* module; GlobalInfoMap map; + bool optimize; + + SimplifyGlobals(bool optimize=false) : optimize(optimize) {} void run(PassRunner* runner_, Module* module_) override { runner = runner_; @@ -215,11 +253,15 @@ struct SimplifyGlobals : public Pass { } } if (!constantGlobals.empty()) { - ConstantGlobalApplier(&constantGlobals).run(runner, module); + ConstantGlobalApplier(&constantGlobals, optimize).run(runner, module); } } }; -Pass* createSimplifyGlobalsPass() { return new SimplifyGlobals(); } +Pass* createSimplifyGlobalsPass() { return new SimplifyGlobals(false); } + +Pass* createSimplifyGlobalsOptimizingPass() { + return new SimplifyGlobals(true); +} } // namespace wasm diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index daa575c6d36..0398157c09b 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -267,6 +267,10 @@ void PassRegistry::registerPasses() { registerPass("simplify-globals", "miscellaneous globals-related optimizations", createSimplifyGlobalsPass); + registerPass("simplify-globals-optimizing", + "miscellaneous globals-related optimizations, and optimizes " + "where we replaced global.gets with constants", + createSimplifyGlobalsPass); registerPass("simplify-locals", "miscellaneous locals-related optimizations", createSimplifyLocalsPass); @@ -416,7 +420,11 @@ void PassRunner::addDefaultGlobalOptimizationPostPasses() { // optimizations show more functions as duplicate add("duplicate-function-elimination"); add("duplicate-import-elimination"); - add("simplify-globals"); + if (options.optimizeLevel >= 2 || options.shrinkLevel >= 2) { + add("simplify-globals-optimizing"); + } else { + add("simplify-globals"); + } add("remove-unused-module-elements"); add("memory-packing"); // may allow more inlining/dae/etc., need --converge for that diff --git a/src/passes/passes.h b/src/passes/passes.h index 115e9bab635..6342ea15bb1 100644 --- a/src/passes/passes.h +++ b/src/passes/passes.h @@ -92,6 +92,7 @@ Pass* createRedundantSetEliminationPass(); Pass* createSafeHeapPass(); Pass* createSimplifyLocalsPass(); Pass* createSimplifyGlobalsPass(); +Pass* createSimplifyGlobalsOptimizingPass(); Pass* createSimplifyLocalsNoNestingPass(); Pass* createSimplifyLocalsNoTeePass(); Pass* createSimplifyLocalsNoStructurePass(); diff --git a/test/passes/O4_disable-bulk-memory.txt b/test/passes/O4_disable-bulk-memory.txt index 455d8101d91..2f354eb5903 100644 --- a/test/passes/O4_disable-bulk-memory.txt +++ b/test/passes/O4_disable-bulk-memory.txt @@ -1284,7 +1284,7 @@ (i32.const 104) ) (global.set $global$1 - (global.get $global$0) + (i32.const 104) ) ) (func $null (; 12 ;) (; has Stack IR ;) (type $0) From cf8a297984522f671a5195e6b21ff0007ee9a294 Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Thu, 12 Sep 2019 09:57:28 -0700 Subject: [PATCH 2/8] tests --- src/passes/SimplifyGlobals.cpp | 4 +- ...bals-optimizing_enable-mutable-globals.txt | 156 ++++++++++++++++++ ...als-optimizing_enable-mutable-globals.wast | 92 +++++++++++ ...implify-globals_enable-mutable-globals.txt | 44 +++++ ...mplify-globals_enable-mutable-globals.wast | 25 +++ 5 files changed, 318 insertions(+), 3 deletions(-) create mode 100644 test/passes/simplify-globals-optimizing_enable-mutable-globals.txt create mode 100644 test/passes/simplify-globals-optimizing_enable-mutable-globals.wast diff --git a/src/passes/SimplifyGlobals.cpp b/src/passes/SimplifyGlobals.cpp index 6d51dca39b8..8ab417df29a 100644 --- a/src/passes/SimplifyGlobals.cpp +++ b/src/passes/SimplifyGlobals.cpp @@ -252,9 +252,7 @@ struct SimplifyGlobals : public Pass { constantGlobals.insert(global->name); } } - if (!constantGlobals.empty()) { - ConstantGlobalApplier(&constantGlobals, optimize).run(runner, module); - } + ConstantGlobalApplier(&constantGlobals, optimize).run(runner, module); } }; diff --git a/test/passes/simplify-globals-optimizing_enable-mutable-globals.txt b/test/passes/simplify-globals-optimizing_enable-mutable-globals.txt new file mode 100644 index 00000000000..1d5723d7c7d --- /dev/null +++ b/test/passes/simplify-globals-optimizing_enable-mutable-globals.txt @@ -0,0 +1,156 @@ +(module + (type $FUNCSIG$v (func)) + (import "env" "global-1" (global $g1 i32)) + (global $g2 i32 (global.get $g1)) + (func $foo (; 0 ;) (type $FUNCSIG$v) + (drop + (global.get $g1) + ) + (drop + (global.get $g1) + ) + ) +) +(module + (type $FUNCSIG$v (func)) + (import "env" "global-1" (global $g1 i32)) + (global $g2 i32 (global.get $g1)) + (global $g3 i32 (global.get $g2)) + (global $g4 i32 (global.get $g3)) + (func $foo (; 0 ;) (type $FUNCSIG$v) + (drop + (global.get $g1) + ) + (drop + (global.get $g1) + ) + (drop + (global.get $g1) + ) + (drop + (global.get $g1) + ) + ) +) +(module + (import "env" "global-1" (global $g1 (mut i32))) + (global $g2 i32 (global.get $g1)) +) +(module + (type $FUNCSIG$v (func)) + (import "env" "global-1" (global $g1 i32)) + (global $g2 (mut i32) (global.get $g1)) + (func $foo (; 0 ;) (type $FUNCSIG$v) + (global.set $g2 + (unreachable) + ) + ) +) +(module + (import "env" "global-1" (global $g1 (mut i32))) + (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 (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 (i32.const 2)) + (global $g7 i32 (i32.const 3)) + (global $g8 i32 (i32.const 3)) + (global $g9 i32 (i32.const 4)) + (global $ga (mut i32) (i32.const 4)) + (global $gb (mut i32) (i32.const 5)) + (global $gc i32 (i32.const 5)) + (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 + (i32.const 5) + ) + (global.set $ga + (i32.const 6) + ) + (global.set $gb + (i32.const 7) + ) + ) +) +(module + (type $FUNCSIG$ii (func (param i32) (result i32))) + (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) + (func $f (; 0 ;) (type $FUNCSIG$ii) (param $x i32) (result i32) + (global.set $g1 + (i32.const 100) + ) + (global.set $g2 + (local.get $x) + ) + (if + (local.get $x) + (return + (i32.const 0) + ) + ) + (local.set $x + (i32.add + (global.get $g1) + (global.get $g2) + ) + ) + (if + (local.get $x) + (return + (i32.const 1) + ) + ) + (global.set $g1 + (i32.const 200) + ) + (global.set $g2 + (local.get $x) + ) + (local.set $x + (i32.add + (i32.const 200) + (global.get $g2) + ) + ) + (local.get $x) + ) +) diff --git a/test/passes/simplify-globals-optimizing_enable-mutable-globals.wast b/test/passes/simplify-globals-optimizing_enable-mutable-globals.wast new file mode 100644 index 00000000000..609980c1159 --- /dev/null +++ b/test/passes/simplify-globals-optimizing_enable-mutable-globals.wast @@ -0,0 +1,92 @@ +(module + (import "env" "global-1" (global $g1 i32)) + (global $g2 (mut i32) (global.get $g1)) + (func $foo + (drop (global.get $g1)) + (drop (global.get $g2)) + ) +) +(module + (import "env" "global-1" (global $g1 i32)) + (global $g2 (mut i32) (global.get $g1)) + (global $g3 (mut i32) (global.get $g2)) + (global $g4 (mut i32) (global.get $g3)) + (func $foo + (drop (global.get $g1)) + (drop (global.get $g2)) + (drop (global.get $g3)) + (drop (global.get $g4)) + ) +) +(module + (import "env" "global-1" (global $g1 (mut i32))) + (global $g2 (mut i32) (global.get $g1)) +) +(module + (import "env" "global-1" (global $g1 i32)) + (global $g2 (mut i32) (global.get $g1)) + (func $foo + (global.set $g2 (unreachable)) + ) +) +(module + (import "env" "global-1" (global $g1 (mut i32))) + (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)) + ) +) +(module + (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) + (func $f (param $x i32) (result i32) + (global.set $g1 (i32.const 100)) + (global.set $g2 (local.get $x)) + (if (local.get $x) (return (i32.const 0))) + (local.set $x + (i32.add + (global.get $g1) + (global.get $g2) + ) + ) + (if (local.get $x) (return (i32.const 1))) + (global.set $g1 (i32.const 200)) + (global.set $g2 (local.get $x)) + (local.set $x + (i32.add + (global.get $g1) + (global.get $g2) + ) + ) + (local.get $x) + ) +) + diff --git a/test/passes/simplify-globals_enable-mutable-globals.txt b/test/passes/simplify-globals_enable-mutable-globals.txt index 346161f1400..1d5723d7c7d 100644 --- a/test/passes/simplify-globals_enable-mutable-globals.txt +++ b/test/passes/simplify-globals_enable-mutable-globals.txt @@ -110,3 +110,47 @@ ) ) ) +(module + (type $FUNCSIG$ii (func (param i32) (result i32))) + (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) + (func $f (; 0 ;) (type $FUNCSIG$ii) (param $x i32) (result i32) + (global.set $g1 + (i32.const 100) + ) + (global.set $g2 + (local.get $x) + ) + (if + (local.get $x) + (return + (i32.const 0) + ) + ) + (local.set $x + (i32.add + (global.get $g1) + (global.get $g2) + ) + ) + (if + (local.get $x) + (return + (i32.const 1) + ) + ) + (global.set $g1 + (i32.const 200) + ) + (global.set $g2 + (local.get $x) + ) + (local.set $x + (i32.add + (i32.const 200) + (global.get $g2) + ) + ) + (local.get $x) + ) +) diff --git a/test/passes/simplify-globals_enable-mutable-globals.wast b/test/passes/simplify-globals_enable-mutable-globals.wast index 14038769a5e..609980c1159 100644 --- a/test/passes/simplify-globals_enable-mutable-globals.wast +++ b/test/passes/simplify-globals_enable-mutable-globals.wast @@ -64,4 +64,29 @@ (global.set $gb (i32.const 7)) ) ) +(module + (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) + (func $f (param $x i32) (result i32) + (global.set $g1 (i32.const 100)) + (global.set $g2 (local.get $x)) + (if (local.get $x) (return (i32.const 0))) + (local.set $x + (i32.add + (global.get $g1) + (global.get $g2) + ) + ) + (if (local.get $x) (return (i32.const 1))) + (global.set $g1 (i32.const 200)) + (global.set $g2 (local.get $x)) + (local.set $x + (i32.add + (global.get $g1) + (global.get $g2) + ) + ) + (local.get $x) + ) +) From 099c0a5ff87cbceddf9ccbf4a2bb27122d681edf Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Thu, 12 Sep 2019 10:09:37 -0700 Subject: [PATCH 3/8] fix --- src/passes/pass.cpp | 2 +- ...bals-optimizing_enable-mutable-globals.txt | 83 +++++++------------ ...als-optimizing_enable-mutable-globals.wast | 18 ++++ ...implify-globals_enable-mutable-globals.txt | 23 +++++ ...mplify-globals_enable-mutable-globals.wast | 18 ++++ 5 files changed, 90 insertions(+), 54 deletions(-) diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index 0398157c09b..7d17510fc37 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -270,7 +270,7 @@ void PassRegistry::registerPasses() { registerPass("simplify-globals-optimizing", "miscellaneous globals-related optimizations, and optimizes " "where we replaced global.gets with constants", - createSimplifyGlobalsPass); + createSimplifyGlobalsOptimizingPass); registerPass("simplify-locals", "miscellaneous locals-related optimizations", createSimplifyLocalsPass); diff --git a/test/passes/simplify-globals-optimizing_enable-mutable-globals.txt b/test/passes/simplify-globals-optimizing_enable-mutable-globals.txt index 1d5723d7c7d..8b3e7488d18 100644 --- a/test/passes/simplify-globals-optimizing_enable-mutable-globals.txt +++ b/test/passes/simplify-globals-optimizing_enable-mutable-globals.txt @@ -66,42 +66,6 @@ (global $gb (mut i32) (i32.const 5)) (global $gc i32 (i32.const 5)) (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 - (i32.const 5) - ) (global.set $ga (i32.const 6) ) @@ -114,27 +78,26 @@ (type $FUNCSIG$ii (func (param i32) (result i32))) (global $g1 (mut i32) (i32.const 1)) (global $g2 (mut i32) (i32.const 1)) - (func $f (; 0 ;) (type $FUNCSIG$ii) (param $x i32) (result i32) + (func $f (; 0 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) (global.set $g1 (i32.const 100) ) (global.set $g2 - (local.get $x) + (local.get $0) ) (if - (local.get $x) + (local.get $0) (return (i32.const 0) ) ) - (local.set $x - (i32.add - (global.get $g1) - (global.get $g2) - ) - ) (if - (local.get $x) + (local.tee $0 + (i32.add + (global.get $g1) + (global.get $g2) + ) + ) (return (i32.const 1) ) @@ -143,14 +106,28 @@ (i32.const 200) ) (global.set $g2 - (local.get $x) + (local.get $0) ) - (local.set $x - (i32.add - (i32.const 200) - (global.get $g2) - ) + (i32.add + (global.get $g2) + (i32.const 200) + ) + ) +) +(module + (type $FUNCSIG$ii (func (param i32) (result i32))) + (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) + (func $f (; 0 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + (global.set $g1 + (i32.const 100) + ) + (global.set $g2 + (local.get $0) + ) + (i32.add + (global.get $g2) + (i32.const 200) ) - (local.get $x) ) ) diff --git a/test/passes/simplify-globals-optimizing_enable-mutable-globals.wast b/test/passes/simplify-globals-optimizing_enable-mutable-globals.wast index 609980c1159..c0076c583fa 100644 --- a/test/passes/simplify-globals-optimizing_enable-mutable-globals.wast +++ b/test/passes/simplify-globals-optimizing_enable-mutable-globals.wast @@ -89,4 +89,22 @@ (local.get $x) ) ) +(module + (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) + (func $f (param $x i32) (result i32) + (global.set $g1 (i32.const 100)) + (global.set $g2 (local.get $x)) + (local.set $x + (i32.add + (i32.add + (global.get $g1) + (global.get $g1) + ) + (global.get $g2) + ) + ) + (local.get $x) + ) +) diff --git a/test/passes/simplify-globals_enable-mutable-globals.txt b/test/passes/simplify-globals_enable-mutable-globals.txt index 1d5723d7c7d..b6123050460 100644 --- a/test/passes/simplify-globals_enable-mutable-globals.txt +++ b/test/passes/simplify-globals_enable-mutable-globals.txt @@ -154,3 +154,26 @@ (local.get $x) ) ) +(module + (type $FUNCSIG$ii (func (param i32) (result i32))) + (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) + (func $f (; 0 ;) (type $FUNCSIG$ii) (param $x i32) (result i32) + (global.set $g1 + (i32.const 100) + ) + (global.set $g2 + (local.get $x) + ) + (local.set $x + (i32.add + (i32.add + (i32.const 100) + (i32.const 100) + ) + (global.get $g2) + ) + ) + (local.get $x) + ) +) diff --git a/test/passes/simplify-globals_enable-mutable-globals.wast b/test/passes/simplify-globals_enable-mutable-globals.wast index 609980c1159..c0076c583fa 100644 --- a/test/passes/simplify-globals_enable-mutable-globals.wast +++ b/test/passes/simplify-globals_enable-mutable-globals.wast @@ -89,4 +89,22 @@ (local.get $x) ) ) +(module + (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) + (func $f (param $x i32) (result i32) + (global.set $g1 (i32.const 100)) + (global.set $g2 (local.get $x)) + (local.set $x + (i32.add + (i32.add + (global.get $g1) + (global.get $g1) + ) + (global.get $g2) + ) + ) + (local.get $x) + ) +) From ebc60683086de51e0243e8c23e763c87aa567034 Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Thu, 12 Sep 2019 17:21:55 -0700 Subject: [PATCH 4/8] update test --- test/unit.fromasm | 19 ++----------------- test/unit.fromasm.clamp | 19 ++----------------- test/unit.fromasm.imprecise | 19 ++----------------- test/wasm2js/conversions-modified.2asm.js.opt | 2 +- 4 files changed, 7 insertions(+), 52 deletions(-) diff --git a/test/unit.fromasm b/test/unit.fromasm index b56f3e4fb59..1080e709256 100644 --- a/test/unit.fromasm +++ b/test/unit.fromasm @@ -89,15 +89,6 @@ (f64.const -3.4) ) ) - (if - (f64.gt - (f64.const 0) - (f64.const 0) - ) - (return - (f64.const 5.6) - ) - ) (f64.const 1.2) ) (func $doubleCompares (; 10 ;) (; has Stack IR ;) (param $0 f64) (param $1 f64) (result f64) @@ -529,7 +520,7 @@ (global.set $Int (i32.const 30) ) - (global.get $Int) + (i32.const 30) ) (func $usesGlobalSet2 (; 36 ;) (; has Stack IR ;) (result i32) (global.set $Int @@ -1134,13 +1125,7 @@ (global.set $Int (i32.const 1) ) - (i32.add - (i32.and - (global.get $Int) - (i32.const 7) - ) - (i32.const 16) - ) + (i32.const 17) ) ) (call $emscripten_log) diff --git a/test/unit.fromasm.clamp b/test/unit.fromasm.clamp index 3f4282103b2..b98fe30c662 100644 --- a/test/unit.fromasm.clamp +++ b/test/unit.fromasm.clamp @@ -87,15 +87,6 @@ (f64.const -3.4) ) ) - (if - (f64.gt - (f64.const 0) - (f64.const 0) - ) - (return - (f64.const 5.6) - ) - ) (f64.const 1.2) ) (func $doubleCompares (; 9 ;) (; has Stack IR ;) (param $0 f64) (param $1 f64) (result f64) @@ -577,7 +568,7 @@ (global.set $Int (i32.const 30) ) - (global.get $Int) + (i32.const 30) ) (func $usesGlobalSet2 (; 37 ;) (; has Stack IR ;) (result i32) (global.set $Int @@ -1177,13 +1168,7 @@ (global.set $Int (i32.const 1) ) - (i32.add - (i32.and - (global.get $Int) - (i32.const 7) - ) - (i32.const 16) - ) + (i32.const 17) ) ) (call $emscripten_log) diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise index fd444c505bc..04528ad476e 100644 --- a/test/unit.fromasm.imprecise +++ b/test/unit.fromasm.imprecise @@ -85,15 +85,6 @@ (f64.const -3.4) ) ) - (if - (f64.gt - (f64.const 0) - (f64.const 0) - ) - (return - (f64.const 5.6) - ) - ) (f64.const 1.2) ) (func $doubleCompares (; 9 ;) (; has Stack IR ;) (param $0 f64) (param $1 f64) (result f64) @@ -517,7 +508,7 @@ (global.set $Int (i32.const 30) ) - (global.get $Int) + (i32.const 30) ) (func $usesGlobalSet2 (; 35 ;) (; has Stack IR ;) (result i32) (global.set $Int @@ -1112,13 +1103,7 @@ (global.set $Int (i32.const 1) ) - (i32.add - (i32.and - (global.get $Int) - (i32.const 7) - ) - (i32.const 16) - ) + (i32.const 17) ) ) (call $emscripten_log) diff --git a/test/wasm2js/conversions-modified.2asm.js.opt b/test/wasm2js/conversions-modified.2asm.js.opt index 418589d01d7..fceed0c6c1d 100644 --- a/test/wasm2js/conversions-modified.2asm.js.opt +++ b/test/wasm2js/conversions-modified.2asm.js.opt @@ -133,7 +133,7 @@ function asmFunc(global, env, buffer) { function legalstub$1($0) { i64toi32_i32$HIGH_BITS = 0; - setTempRet0(i64toi32_i32$HIGH_BITS | 0); + setTempRet0(0); return $0; } From e935b8abda1de7eba36f9dcbe15826abb448a9f0 Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Thu, 12 Sep 2019 19:10:39 -0700 Subject: [PATCH 5/8] fix --- src/passes/SimplifyGlobals.cpp | 52 ++++++++++++------- ...bals-optimizing_enable-mutable-globals.txt | 30 +++++++++++ ...als-optimizing_enable-mutable-globals.wast | 17 ++++++ ...implify-globals_enable-mutable-globals.txt | 30 +++++++++++ ...mplify-globals_enable-mutable-globals.wast | 17 ++++++ 5 files changed, 126 insertions(+), 20 deletions(-) diff --git a/src/passes/SimplifyGlobals.cpp b/src/passes/SimplifyGlobals.cpp index 8ab417df29a..2961b2b48c0 100644 --- a/src/passes/SimplifyGlobals.cpp +++ b/src/passes/SimplifyGlobals.cpp @@ -29,6 +29,7 @@ #include +#include "ir/effects.h" #include "ir/utils.h" #include "pass.h" #include "wasm-builder.h" @@ -84,7 +85,7 @@ struct GlobalUseModifier : public WalkerPass> { }; struct ConstantGlobalApplier - : public WalkerPass> { + : public WalkerPass>> { bool isFunctionParallel() override { return true; } ConstantGlobalApplier(NameSet* constantGlobals, bool optimize) @@ -94,27 +95,38 @@ struct ConstantGlobalApplier return new ConstantGlobalApplier(constantGlobals, optimize); } - void visitGlobalSet(GlobalSet* curr) { - if (auto* c = curr->value->dynCast()) { - currConstantGlobals[curr->name] = c->value; - } - } - - void visitGlobalGet(GlobalGet* curr) { - // Check if the global is known to be constant all the time. - if (constantGlobals->count(curr->name)) { - auto* global = getModule()->getGlobal(curr->name); - assert(global->init->is()); - replaceCurrent(ExpressionManipulator::copy(global->init, *getModule())); - replaced = true; + void visitExpression(Expression* curr) { + if (auto* set = curr->dynCast()) { + if (auto* c = set->value->dynCast()) { + currConstantGlobals[set->name] = c->value; + } else { + currConstantGlobals.erase(set->name); + } + return; + } else if (auto* get = curr->dynCast()) { + // Check if the global is known to be constant all the time. + if (constantGlobals->count(get->name)) { + auto* global = getModule()->getGlobal(get->name); + assert(global->init->is()); + replaceCurrent(ExpressionManipulator::copy(global->init, *getModule())); + replaced = true; + return; + } + // Check if the global has a known value in this linear trace. + auto iter = currConstantGlobals.find(get->name); + if (iter != currConstantGlobals.end()) { + Builder builder(*getModule()); + replaceCurrent(builder.makeConst(iter->second)); + replaced = true; + } return; } - // Check if the global has a known value in this linear trace. - auto iter = currConstantGlobals.find(curr->name); - if (iter != currConstantGlobals.end()) { - Builder builder(*getModule()); - replaceCurrent(builder.makeConst(iter->second)); - replaced = true; + // Otherwise, invalidate if we need to. + EffectAnalyzer effects(getPassOptions()); + effects.visit(curr); + assert(effects.globalsWritten.empty()); // handled above + if (effects.calls) { + currConstantGlobals.clear(); } } diff --git a/test/passes/simplify-globals-optimizing_enable-mutable-globals.txt b/test/passes/simplify-globals-optimizing_enable-mutable-globals.txt index 8b3e7488d18..c69f91965e8 100644 --- a/test/passes/simplify-globals-optimizing_enable-mutable-globals.txt +++ b/test/passes/simplify-globals-optimizing_enable-mutable-globals.txt @@ -131,3 +131,33 @@ ) ) ) +(module + (type $FUNCSIG$ii (func (param i32) (result i32))) + (global $g1 (mut i32) (i32.const 1)) + (func $no (; 0 ;) (type $FUNCSIG$ii) (param $x i32) (result i32) + (global.set $g1 + (i32.const 100) + ) + (drop + (call $no + (i32.const 200) + ) + ) + (global.get $g1) + ) + (func $no2 (; 1 ;) (type $FUNCSIG$ii) (param $x i32) (result i32) + (global.set $g1 + (i32.const 100) + ) + (global.set $g1 + (local.get $x) + ) + (global.get $g1) + ) + (func $yes (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + (global.set $g1 + (i32.const 100) + ) + (i32.const 100) + ) +) diff --git a/test/passes/simplify-globals-optimizing_enable-mutable-globals.wast b/test/passes/simplify-globals-optimizing_enable-mutable-globals.wast index c0076c583fa..2d610ca3309 100644 --- a/test/passes/simplify-globals-optimizing_enable-mutable-globals.wast +++ b/test/passes/simplify-globals-optimizing_enable-mutable-globals.wast @@ -107,4 +107,21 @@ (local.get $x) ) ) +(module + (global $g1 (mut i32) (i32.const 1)) + (func $no (param $x i32) (result i32) + (global.set $g1 (i32.const 100)) + (drop (call $no (i32.const 200))) ;; invalidate + (global.get $g1) + ) + (func $no2 (param $x i32) (result i32) + (global.set $g1 (i32.const 100)) + (global.set $g1 (local.get $x)) ;; invalidate + (global.get $g1) + ) + (func $yes (param $x i32) (result i32) + (global.set $g1 (i32.const 100)) + (global.get $g1) + ) +) diff --git a/test/passes/simplify-globals_enable-mutable-globals.txt b/test/passes/simplify-globals_enable-mutable-globals.txt index b6123050460..1eb586edbaa 100644 --- a/test/passes/simplify-globals_enable-mutable-globals.txt +++ b/test/passes/simplify-globals_enable-mutable-globals.txt @@ -177,3 +177,33 @@ (local.get $x) ) ) +(module + (type $FUNCSIG$ii (func (param i32) (result i32))) + (global $g1 (mut i32) (i32.const 1)) + (func $no (; 0 ;) (type $FUNCSIG$ii) (param $x i32) (result i32) + (global.set $g1 + (i32.const 100) + ) + (drop + (call $no + (i32.const 200) + ) + ) + (global.get $g1) + ) + (func $no2 (; 1 ;) (type $FUNCSIG$ii) (param $x i32) (result i32) + (global.set $g1 + (i32.const 100) + ) + (global.set $g1 + (local.get $x) + ) + (global.get $g1) + ) + (func $yes (; 2 ;) (type $FUNCSIG$ii) (param $x i32) (result i32) + (global.set $g1 + (i32.const 100) + ) + (i32.const 100) + ) +) diff --git a/test/passes/simplify-globals_enable-mutable-globals.wast b/test/passes/simplify-globals_enable-mutable-globals.wast index c0076c583fa..2d610ca3309 100644 --- a/test/passes/simplify-globals_enable-mutable-globals.wast +++ b/test/passes/simplify-globals_enable-mutable-globals.wast @@ -107,4 +107,21 @@ (local.get $x) ) ) +(module + (global $g1 (mut i32) (i32.const 1)) + (func $no (param $x i32) (result i32) + (global.set $g1 (i32.const 100)) + (drop (call $no (i32.const 200))) ;; invalidate + (global.get $g1) + ) + (func $no2 (param $x i32) (result i32) + (global.set $g1 (i32.const 100)) + (global.set $g1 (local.get $x)) ;; invalidate + (global.get $g1) + ) + (func $yes (param $x i32) (result i32) + (global.set $g1 (i32.const 100)) + (global.get $g1) + ) +) From 06993eadc8ceb34d8aaa2fa53f666af0d7a176e1 Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Thu, 12 Sep 2019 19:14:41 -0700 Subject: [PATCH 6/8] opt --- .../simplify-globals-optimizing_enable-mutable-globals.txt | 4 ++++ .../simplify-globals-optimizing_enable-mutable-globals.wast | 2 ++ test/passes/simplify-globals_enable-mutable-globals.txt | 4 ++++ test/passes/simplify-globals_enable-mutable-globals.wast | 2 ++ 4 files changed, 12 insertions(+) diff --git a/test/passes/simplify-globals-optimizing_enable-mutable-globals.txt b/test/passes/simplify-globals-optimizing_enable-mutable-globals.txt index c69f91965e8..3511927ffb1 100644 --- a/test/passes/simplify-globals-optimizing_enable-mutable-globals.txt +++ b/test/passes/simplify-globals-optimizing_enable-mutable-globals.txt @@ -134,6 +134,7 @@ (module (type $FUNCSIG$ii (func (param i32) (result i32))) (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) (func $no (; 0 ;) (type $FUNCSIG$ii) (param $x i32) (result i32) (global.set $g1 (i32.const 100) @@ -158,6 +159,9 @@ (global.set $g1 (i32.const 100) ) + (global.set $g2 + (local.get $0) + ) (i32.const 100) ) ) diff --git a/test/passes/simplify-globals-optimizing_enable-mutable-globals.wast b/test/passes/simplify-globals-optimizing_enable-mutable-globals.wast index 2d610ca3309..f8a099e95f4 100644 --- a/test/passes/simplify-globals-optimizing_enable-mutable-globals.wast +++ b/test/passes/simplify-globals-optimizing_enable-mutable-globals.wast @@ -109,6 +109,7 @@ ) (module (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) (func $no (param $x i32) (result i32) (global.set $g1 (i32.const 100)) (drop (call $no (i32.const 200))) ;; invalidate @@ -121,6 +122,7 @@ ) (func $yes (param $x i32) (result i32) (global.set $g1 (i32.const 100)) + (global.set $g2 (local.get $x)) ;; almost invalidate (global.get $g1) ) ) diff --git a/test/passes/simplify-globals_enable-mutable-globals.txt b/test/passes/simplify-globals_enable-mutable-globals.txt index 1eb586edbaa..e0971742b7c 100644 --- a/test/passes/simplify-globals_enable-mutable-globals.txt +++ b/test/passes/simplify-globals_enable-mutable-globals.txt @@ -180,6 +180,7 @@ (module (type $FUNCSIG$ii (func (param i32) (result i32))) (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) (func $no (; 0 ;) (type $FUNCSIG$ii) (param $x i32) (result i32) (global.set $g1 (i32.const 100) @@ -204,6 +205,9 @@ (global.set $g1 (i32.const 100) ) + (global.set $g2 + (local.get $x) + ) (i32.const 100) ) ) diff --git a/test/passes/simplify-globals_enable-mutable-globals.wast b/test/passes/simplify-globals_enable-mutable-globals.wast index 2d610ca3309..f8a099e95f4 100644 --- a/test/passes/simplify-globals_enable-mutable-globals.wast +++ b/test/passes/simplify-globals_enable-mutable-globals.wast @@ -109,6 +109,7 @@ ) (module (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) (func $no (param $x i32) (result i32) (global.set $g1 (i32.const 100)) (drop (call $no (i32.const 200))) ;; invalidate @@ -121,6 +122,7 @@ ) (func $yes (param $x i32) (result i32) (global.set $g1 (i32.const 100)) + (global.set $g2 (local.get $x)) ;; almost invalidate (global.get $g1) ) ) From fd7fb763ffdfc1e9fbf935acc339b091648d90d3 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 13 Sep 2019 13:32:31 -0700 Subject: [PATCH 7/8] style --- src/passes/SimplifyGlobals.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/passes/SimplifyGlobals.cpp b/src/passes/SimplifyGlobals.cpp index 2961b2b48c0..bc5582a39a7 100644 --- a/src/passes/SimplifyGlobals.cpp +++ b/src/passes/SimplifyGlobals.cpp @@ -85,7 +85,9 @@ struct GlobalUseModifier : public WalkerPass> { }; struct ConstantGlobalApplier - : public WalkerPass>> { + : public WalkerPass< + LinearExecutionWalker>> { bool isFunctionParallel() override { return true; } ConstantGlobalApplier(NameSet* constantGlobals, bool optimize) @@ -130,8 +132,7 @@ struct ConstantGlobalApplier } } - static void doNoteNonLinear(ConstantGlobalApplier* self, - Expression** currp) { + static void doNoteNonLinear(ConstantGlobalApplier* self, Expression** currp) { self->currConstantGlobals.clear(); } @@ -162,7 +163,7 @@ struct SimplifyGlobals : public Pass { GlobalInfoMap map; bool optimize; - SimplifyGlobals(bool optimize=false) : optimize(optimize) {} + SimplifyGlobals(bool optimize = false) : optimize(optimize) {} void run(PassRunner* runner_, Module* module_) override { runner = runner_; From d342c2a9d6b24dc2c9c89f96d8244d085676323e Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 13 Sep 2019 16:04:26 -0700 Subject: [PATCH 8/8] comments --- src/passes/SimplifyGlobals.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/passes/SimplifyGlobals.cpp b/src/passes/SimplifyGlobals.cpp index bc5582a39a7..88f27f8bef8 100644 --- a/src/passes/SimplifyGlobals.cpp +++ b/src/passes/SimplifyGlobals.cpp @@ -22,10 +22,17 @@ // * 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. +// * Apply the constant values of previous global.sets, in a linear +// execution trace. // // Some globals may not have uses after these changes, which we leave // to other passes to optimize. // +// This pass has a "optimize" variant (similar to inlining and DAE) +// that also runs general function optimizations where we managed to replace +// a constant value. That is helpful as such a replacement often opens up +// further optimization opportunities. +// #include