diff options
-rw-r--r-- | src/passes/SimplifyGlobals.cpp | 19 | ||||
-rw-r--r-- | src/passes/pass.cpp | 3 | ||||
-rw-r--r-- | src/passes/passes.h | 1 | ||||
-rw-r--r-- | test/lit/help/wasm-opt.test | 3 | ||||
-rw-r--r-- | test/lit/help/wasm2js.test | 3 | ||||
-rw-r--r-- | test/lit/passes/propagate-globals-globally.wast | 106 | ||||
-rw-r--r-- | test/lit/passes/simplify-globals-nested.wast | 9 |
7 files changed, 140 insertions, 4 deletions
diff --git a/src/passes/SimplifyGlobals.cpp b/src/passes/SimplifyGlobals.cpp index 323ebd6a7..d4a6e1f3b 100644 --- a/src/passes/SimplifyGlobals.cpp +++ b/src/passes/SimplifyGlobals.cpp @@ -673,11 +673,12 @@ struct SimplifyGlobals : public Pass { // go, as well as applying them where possible. for (auto& global : module->globals) { if (!global->imported()) { + // Apply globals to this value, which may turn it into a constant we can + // further propagate, or it may already have been one. + applyGlobals(global->init); if (Properties::isConstantExpression(global->init)) { constantGlobals[global->name] = getLiteralsFromConstExpression(global->init); - } else { - applyGlobals(global->init); } } } @@ -762,10 +763,24 @@ struct SimplifyGlobals : public Pass { } }; +// A pass mainly useful for testing that only performs the operation to +// propagate constant values between globals. +struct PropagateGlobalsGlobally : public SimplifyGlobals { + void run(Module* module_) override { + module = module_; + + propagateConstantsToGlobals(); + } +}; + Pass* createSimplifyGlobalsPass() { return new SimplifyGlobals(false); } Pass* createSimplifyGlobalsOptimizingPass() { return new SimplifyGlobals(true); } +Pass* createPropagateGlobalsGloballyPass() { + return new PropagateGlobalsGlobally(); +} + } // namespace wasm diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index c00a5e706..1fe81cbfc 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -369,6 +369,9 @@ void PassRegistry::registerPasses() { registerPass("print-stack-ir", "print out Stack IR (useful for internal debugging)", createPrintStackIRPass); + registerPass("propagate-globals-globally", + "propagate global values to other globals (useful for tests)", + createPropagateGlobalsGloballyPass); registerPass("remove-non-js-ops", "removes operations incompatible with js", createRemoveNonJSOpsPass); diff --git a/src/passes/passes.h b/src/passes/passes.h index 3f8b3fe6b..c3ab7773f 100644 --- a/src/passes/passes.h +++ b/src/passes/passes.h @@ -123,6 +123,7 @@ Pass* createPrintCallGraphPass(); Pass* createPrintFeaturesPass(); Pass* createPrintFunctionMapPass(); Pass* createPrintStackIRPass(); +Pass* createPropagateGlobalsGloballyPass(); Pass* createRemoveNonJSOpsPass(); Pass* createRemoveImportsPass(); Pass* createRemoveMemoryPass(); diff --git a/test/lit/help/wasm-opt.test b/test/lit/help/wasm-opt.test index 88fc2448a..be5924cf7 100644 --- a/test/lit/help/wasm-opt.test +++ b/test/lit/help/wasm-opt.test @@ -374,6 +374,9 @@ ;; CHECK-NEXT: --print-stack-ir print out Stack IR (useful for ;; CHECK-NEXT: internal debugging) ;; CHECK-NEXT: +;; CHECK-NEXT: --propagate-globals-globally propagate global values to other +;; CHECK-NEXT: globals (useful for tests) +;; CHECK-NEXT: ;; CHECK-NEXT: --remove-imports removes imports and replaces ;; CHECK-NEXT: them with nops ;; CHECK-NEXT: diff --git a/test/lit/help/wasm2js.test b/test/lit/help/wasm2js.test index 43243b99a..aadefe8fc 100644 --- a/test/lit/help/wasm2js.test +++ b/test/lit/help/wasm2js.test @@ -324,6 +324,9 @@ ;; CHECK-NEXT: --print-stack-ir print out Stack IR (useful for ;; CHECK-NEXT: internal debugging) ;; CHECK-NEXT: +;; CHECK-NEXT: --propagate-globals-globally propagate global values to other +;; CHECK-NEXT: globals (useful for tests) +;; CHECK-NEXT: ;; CHECK-NEXT: --remove-imports removes imports and replaces ;; CHECK-NEXT: them with nops ;; CHECK-NEXT: diff --git a/test/lit/passes/propagate-globals-globally.wast b/test/lit/passes/propagate-globals-globally.wast new file mode 100644 index 000000000..36d875b17 --- /dev/null +++ b/test/lit/passes/propagate-globals-globally.wast @@ -0,0 +1,106 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: foreach %s %t wasm-opt --propagate-globals-globally -all -S -o - | filecheck %s +;; RUN: foreach %s %t wasm-opt --simplify-globals -all -S -o - | filecheck %s --check-prefix SIMGB + +;; Check that propagate-globals-globally propagates constants globally but not +;; to code. Also run simplify-globals for comparison, which does do that. + +(module + ;; CHECK: (type $struct (struct (field stringref) (field stringref))) + ;; SIMGB: (type $struct (struct (field stringref) (field stringref))) + (type $struct (struct stringref stringref)) + + ;; CHECK: (type $1 (func)) + + ;; CHECK: (global $A i32 (i32.const 42)) + ;; SIMGB: (type $1 (func)) + + ;; SIMGB: (global $A i32 (i32.const 42)) + (global $A i32 (i32.const 42)) + + ;; CHECK: (global $B i32 (i32.const 42)) + ;; SIMGB: (global $B i32 (i32.const 42)) + (global $B i32 (global.get $A)) + + ;; CHECK: (global $C i32 (i32.add + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: )) + ;; SIMGB: (global $C i32 (i32.add + ;; SIMGB-NEXT: (i32.const 42) + ;; SIMGB-NEXT: (i32.const 42) + ;; SIMGB-NEXT: )) + (global $C i32 (i32.add + ;; Both of these can be optimized, including $B which reads from $A. + (global.get $B) + (global.get $A) + )) + + ;; CHECK: (global $D (ref string) (string.const "foo")) + ;; SIMGB: (global $D (ref string) (string.const "foo")) + (global $D (ref string) (string.const "foo")) + + ;; CHECK: (global $E (ref string) (string.const "bar")) + ;; SIMGB: (global $E (ref string) (string.const "bar")) + (global $E (ref string) (string.const "bar")) + + ;; CHECK: (global $G (ref $struct) (struct.new $struct + ;; CHECK-NEXT: (string.const "foo") + ;; CHECK-NEXT: (string.const "bar") + ;; CHECK-NEXT: )) + ;; SIMGB: (global $G (ref $struct) (struct.new $struct + ;; SIMGB-NEXT: (string.const "foo") + ;; SIMGB-NEXT: (string.const "bar") + ;; SIMGB-NEXT: )) + (global $G (ref $struct) (struct.new $struct + (global.get $D) + (global.get $E) + )) + + ;; CHECK: (func $test (type $1) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $A) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $B) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $C) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $D) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; SIMGB: (func $test (type $1) + ;; SIMGB-NEXT: (drop + ;; SIMGB-NEXT: (i32.const 42) + ;; SIMGB-NEXT: ) + ;; SIMGB-NEXT: (drop + ;; SIMGB-NEXT: (i32.const 42) + ;; SIMGB-NEXT: ) + ;; SIMGB-NEXT: (drop + ;; SIMGB-NEXT: (global.get $C) + ;; SIMGB-NEXT: ) + ;; SIMGB-NEXT: (drop + ;; SIMGB-NEXT: (string.const "foo") + ;; SIMGB-NEXT: ) + ;; SIMGB-NEXT: ) + (func $test + ;; We should not change anything here: this pass propagates globals + ;; *globally*, and not to functions. (but simplify-globals does, except for + ;; $C which is not constant) + (drop + (global.get $A) + ) + (drop + (global.get $B) + ) + (drop + (global.get $C) + ) + (drop + (global.get $D) + ) + ) +) diff --git a/test/lit/passes/simplify-globals-nested.wast b/test/lit/passes/simplify-globals-nested.wast index 925d71161..48116e198 100644 --- a/test/lit/passes/simplify-globals-nested.wast +++ b/test/lit/passes/simplify-globals-nested.wast @@ -6,8 +6,11 @@ ;; Test that we propagate globals into nested children of other globals. (module - ;; CHECK: (type $struct (struct (field i32) (field i32))) - (type $struct (struct i32 i32)) + ;; CHECK: (type $struct (struct (field i32) (field i32) (field i32))) + (type $struct (struct i32 i32 i32)) + + ;; CHECK: (import "x" "y" (global $no i32)) + (import "x" "y" (global $no i32)) ;; CHECK: (global $a i32 (i32.const 42)) (global $a i32 (i32.const 42)) @@ -17,10 +20,12 @@ ;; CHECK: (global $struct (ref $struct) (struct.new $struct ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: (global.get $no) ;; CHECK-NEXT: (i32.const 1337) ;; CHECK-NEXT: )) (global $struct (ref $struct) (struct.new $struct (global.get $a) + (global.get $no) ;; the middle item cannot be optimized (global.get $b) )) ) |