summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/Precompute.cpp2
-rw-r--r--test/lit/passes/precompute-gc-immutable.wast92
-rw-r--r--test/lit/passes/precompute-gc.wast2
-rw-r--r--test/passes/Oz_fuzz-exec_all-features.txt30
4 files changed, 104 insertions, 22 deletions
diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp
index 5baf2331f..d2f3543ad 100644
--- a/src/passes/Precompute.cpp
+++ b/src/passes/Precompute.cpp
@@ -178,7 +178,7 @@ public:
// Otherwise, we've failed to precompute.
return Flow(NONCONSTANT_FLOW);
}
- Flow visitArrayLen(ArrayLen* curr) { return Flow(NONCONSTANT_FLOW); }
+ // ArrayLen is not disallowed here as it is an immutable property.
Flow visitArrayCopy(ArrayCopy* curr) { return Flow(NONCONSTANT_FLOW); }
// Generates heap info for a heap-allocating expression.
diff --git a/test/lit/passes/precompute-gc-immutable.wast b/test/lit/passes/precompute-gc-immutable.wast
index c2a96bd23..a3bef210f 100644
--- a/test/lit/passes/precompute-gc-immutable.wast
+++ b/test/lit/passes/precompute-gc-immutable.wast
@@ -9,7 +9,14 @@
;; CHECK: (type $struct-mut (struct (field (mut i32))))
(type $struct-mut (struct (mut i32)))
- ;; CHECK: (func $propagate (type $2)
+ ;; CHECK: (type $array-mut (array (mut i32)))
+
+ ;; CHECK: (type $array-imm (array i32))
+ (type $array-imm (array i32))
+
+ (type $array-mut (array (mut i32)))
+
+ ;; CHECK: (func $propagate-struct (type $2)
;; CHECK-NEXT: (local $ref-imm (ref null $struct-imm))
;; CHECK-NEXT: (local $ref-mut (ref null $struct-mut))
;; CHECK-NEXT: (local.set $ref-imm
@@ -31,7 +38,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $propagate
+ (func $propagate-struct
(local $ref-imm (ref null $struct-imm))
(local $ref-mut (ref null $struct-mut))
;; We can propagate from an immutable field of a struct created in this
@@ -59,6 +66,85 @@
)
)
+ ;; CHECK: (func $propagate-array (type $2)
+ ;; CHECK-NEXT: (local $ref-imm (ref null $array-imm))
+ ;; CHECK-NEXT: (local $ref-mut (ref null $array-mut))
+ ;; CHECK-NEXT: (local.set $ref-imm
+ ;; CHECK-NEXT: (array.new_fixed $array-imm 3
+ ;; CHECK-NEXT: (i32.const 10)
+ ;; CHECK-NEXT: (i32.const 20)
+ ;; CHECK-NEXT: (i32.const 30)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $helper
+ ;; CHECK-NEXT: (i32.const 30)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $helper
+ ;; CHECK-NEXT: (i32.const 3)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $ref-mut
+ ;; CHECK-NEXT: (array.new_fixed $array-mut 3
+ ;; CHECK-NEXT: (i32.const 10)
+ ;; CHECK-NEXT: (i32.const 20)
+ ;; CHECK-NEXT: (i32.const 30)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $helper
+ ;; CHECK-NEXT: (array.get $array-mut
+ ;; CHECK-NEXT: (local.get $ref-mut)
+ ;; CHECK-NEXT: (i32.const 2)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $helper
+ ;; CHECK-NEXT: (i32.const 3)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $propagate-array
+ (local $ref-imm (ref null $array-imm))
+ (local $ref-mut (ref null $array-mut))
+ ;; We can propagate from a slot in an immutable array created in this
+ ;; function, and also get the length.
+ (local.set $ref-imm
+ (array.new_fixed $array-imm 3
+ (i32.const 10)
+ (i32.const 20)
+ (i32.const 30)
+ )
+ )
+ (call $helper
+ (array.get $array-imm ;; this returns 30
+ (local.get $ref-imm)
+ (i32.const 2)
+ )
+ )
+ (call $helper
+ (array.len ;; this returns 3
+ (local.get $ref-imm)
+ )
+ )
+ ;; But the same thing on a mutable array fails.
+ (local.set $ref-mut
+ (array.new_fixed $array-mut 3
+ (i32.const 10)
+ (i32.const 20)
+ (i32.const 30)
+ )
+ )
+ (call $helper
+ (array.get $array-mut
+ (local.get $ref-mut)
+ (i32.const 2)
+ )
+ )
+ ;; We can, however, optimize array.len in both cases as that is an
+ ;; immutable property.
+ (call $helper
+ (array.len ;; this returns 3
+ (local.get $ref-mut)
+ )
+ )
+ )
+
;; CHECK: (func $non-constant (type $1) (param $param i32)
;; CHECK-NEXT: (local $ref (ref null $struct-imm))
;; CHECK-NEXT: (local.set $ref
@@ -118,7 +204,7 @@
)
)
- ;; CHECK: (func $param (type $4) (param $ref-imm (ref null $struct-imm))
+ ;; CHECK: (func $param (type $6) (param $ref-imm (ref null $struct-imm))
;; CHECK-NEXT: (call $helper
;; CHECK-NEXT: (struct.get $struct-imm 0
;; CHECK-NEXT: (local.get $ref-imm)
diff --git a/test/lit/passes/precompute-gc.wast b/test/lit/passes/precompute-gc.wast
index 8d4b56ce7..824587df9 100644
--- a/test/lit/passes/precompute-gc.wast
+++ b/test/lit/passes/precompute-gc.wast
@@ -20,8 +20,6 @@
(type $struct_i8 (struct (field i8)))
- (type $array16 (array (mut i16)))
-
(type $func-return-i32 (func (result i32)))
;; CHECK: (import "fuzzing-support" "log-i32" (func $log (type $4) (param i32)))
diff --git a/test/passes/Oz_fuzz-exec_all-features.txt b/test/passes/Oz_fuzz-exec_all-features.txt
index 2f1428160..20cbca924 100644
--- a/test/passes/Oz_fuzz-exec_all-features.txt
+++ b/test/passes/Oz_fuzz-exec_all-features.txt
@@ -100,17 +100,16 @@
)
(func $arrays (type $void_func) (; has Stack IR ;)
(local $0 (ref $bytes))
- (call $log
- (array.len
- (local.tee $0
- (array.new $bytes
- (i32.const 42)
- (i32.const 50)
- )
- )
+ (local.set $0
+ (array.new $bytes
+ (i32.const 42)
+ (i32.const 50)
)
)
(call $log
+ (i32.const 50)
+ )
+ (call $log
(array.get_u $bytes
(local.get $0)
(i32.const 10)
@@ -271,17 +270,16 @@
)
(func $array.new_fixed (type $void_func) (; has Stack IR ;)
(local $0 (ref $bytes))
- (call $log
- (array.len
- (local.tee $0
- (array.new_fixed $bytes 2
- (i32.const 42)
- (i32.const 50)
- )
- )
+ (local.set $0
+ (array.new_fixed $bytes 2
+ (i32.const 42)
+ (i32.const 50)
)
)
(call $log
+ (i32.const 2)
+ )
+ (call $log
(array.get_u $bytes
(local.get $0)
(i32.const 0)