summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/SimplifyGlobals.cpp19
-rw-r--r--src/passes/pass.cpp3
-rw-r--r--src/passes/passes.h1
-rw-r--r--test/lit/help/wasm-opt.test3
-rw-r--r--test/lit/help/wasm2js.test3
-rw-r--r--test/lit/passes/propagate-globals-globally.wast106
-rw-r--r--test/lit/passes/simplify-globals-nested.wast9
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)
))
)