summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2021-11-04 11:56:45 -0700
committerGitHub <noreply@github.com>2021-11-04 11:56:45 -0700
commit6695d87fa9c406666e9ff1fb0d211107a0367000 (patch)
tree1149db4bba02c3117a71eccbf00789f3dc112df0 /test
parentf1947db456df4576ac857a535f16cba3ffbfdc37 (diff)
downloadbinaryen-6695d87fa9c406666e9ff1fb0d211107a0367000.tar.gz
binaryen-6695d87fa9c406666e9ff1fb0d211107a0367000.tar.bz2
binaryen-6695d87fa9c406666e9ff1fb0d211107a0367000.zip
ChildLocalizer: Do not use locals needlessly (#4292)
We only need to use locals if there are effects we can't remove, or if they interact with other children. Improve the comment to explain what the ChildLocalizer is working towards: a state where all the children of the expression can be reordered or removed freely (local.gets have that property, as do other things if they have no relevant effects). Aside from avoiding wasteful locals, this is necessary for running GlobalTypeOptimization on j2wasm: That code will do a global.get of an rtt, and those cannot be placed in locals.
Diffstat (limited to 'test')
-rw-r--r--test/lit/passes/gto-removals.wast85
1 files changed, 84 insertions, 1 deletions
diff --git a/test/lit/passes/gto-removals.wast b/test/lit/passes/gto-removals.wast
index e74a09d5a..188019fab 100644
--- a/test/lit/passes/gto-removals.wast
+++ b/test/lit/passes/gto-removals.wast
@@ -394,16 +394,23 @@
;; CHECK: (type $struct (struct_subtype (field i32) (field (rtt $struct)) data))
(type $struct (struct i32 f64 (ref any) (rtt $struct)))
- ;; CHECK: (type $ref|any|_=>_none (func_subtype (param (ref any)) func))
;; CHECK: (type $none_=>_none (func_subtype func))
+ ;; CHECK: (type $ref|any|_=>_none (func_subtype (param (ref any)) func))
+
;; CHECK: (type $i32_=>_i32 (func_subtype (param i32) (result i32) func))
;; CHECK: (type $i32_=>_f64 (func_subtype (param i32) (result f64) func))
;; CHECK: (type $i32_=>_ref|any| (func_subtype (param i32) (result (ref any)) func))
+ ;; CHECK: (global $imm-i32 i32 (i32.const 1234))
+ (global $imm-i32 i32 (i32.const 1234))
+
+ ;; CHECK: (global $mut-i32 (mut i32) (i32.const 5678))
+ (global $mut-i32 (mut i32) (i32.const 5678))
+
;; CHECK: (func $gets (param $x (ref any))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
@@ -475,6 +482,82 @@
)
)
+ ;; CHECK: (func $new-side-effect-global-imm
+ ;; CHECK-NEXT: (local $0 f64)
+ ;; CHECK-NEXT: (local $1 anyref)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (block (result (ref $struct))
+ ;; CHECK-NEXT: (local.set $0
+ ;; CHECK-NEXT: (call $helper1
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $1
+ ;; CHECK-NEXT: (call $helper2
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new $struct
+ ;; CHECK-NEXT: (global.get $imm-i32)
+ ;; CHECK-NEXT: (rtt.canon $struct)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $new-side-effect-global-imm
+ ;; As above, the 2nd&3rd fields here will be removed. The first field does
+ ;; a global.get, which has effects, but those effects do not interact with
+ ;; anything else (since it is an immutable global), so we do not need a
+ ;; local for it.
+ (drop
+ (struct.new $struct
+ (global.get $imm-i32)
+ (call $helper1 (i32.const 0))
+ (call $helper2 (i32.const 1))
+ (rtt.canon $struct)
+ )
+ )
+ )
+
+ ;; CHECK: (func $new-side-effect-global-mut
+ ;; CHECK-NEXT: (local $0 i32)
+ ;; CHECK-NEXT: (local $1 f64)
+ ;; CHECK-NEXT: (local $2 anyref)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (block (result (ref $struct))
+ ;; CHECK-NEXT: (local.set $0
+ ;; CHECK-NEXT: (global.get $mut-i32)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $1
+ ;; CHECK-NEXT: (call $helper1
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $2
+ ;; CHECK-NEXT: (call $helper2
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new $struct
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: (rtt.canon $struct)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $new-side-effect-global-mut
+ ;; As above, but the global is mutable, so we will use a local: the calls
+ ;; might alter that global, in theory.
+ (drop
+ (struct.new $struct
+ (global.get $mut-i32)
+ (call $helper1 (i32.const 0))
+ (call $helper2 (i32.const 1))
+ (rtt.canon $struct)
+ )
+ )
+ )
+
;; CHECK: (func $new-unreachable
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block ;; (replaces something unreachable we can't emit)