Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/passes/Precompute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
// looked at.
//

#include "ir/effects.h"
#include "ir/iteration.h"
#include "ir/literal-utils.h"
#include "ir/local-graph.h"
Expand Down Expand Up @@ -195,6 +194,14 @@ class PrecomputingExpressionRunner
}
return Literal(canonical, curr->type.getHeapType());
}

Flow visitStringEncode(StringEncode* curr) {
// string.encode_wtf16_array is effectively an Array write operation, so
// just like ArraySet and ArrayCopy above we must mark it as disallowed
// (due to side effects). (And we do not support other operations than
// string.encode_wtf16_array anyhow.)
return Flow(NONCONSTANT_FLOW);
}
};

struct Precompute
Expand Down
66 changes: 60 additions & 6 deletions test/lit/passes/precompute-strings.wast
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.

;; RUN: wasm-opt %s --precompute -all -S -o - | filecheck %s
;; RUN: wasm-opt %s --precompute-propagate -all -S -o - | filecheck %s

(module
;; CHECK: (type $0 (func (result i32)))

;; CHECK: (type $1 (func (result (ref string))))

;; CHECK: (type $array16 (array (mut i16)))
(type $array16 (array (mut i16)))

;; CHECK: (type $2 (func (result (ref string))))

;; CHECK: (type $3 (func (result (ref any))))

;; CHECK: (export "get_codepoint-bad" (func $get_codepoint-bad))

;; CHECK: (export "test" (func $encode-stashed))

;; CHECK: (export "slice" (func $slice))

;; CHECK: (export "slice-bad" (func $slice-bad))
Expand Down Expand Up @@ -124,9 +128,17 @@
)

;; CHECK: (func $encode (type $0) (result i32)
;; CHECK-NEXT: (i32.const 2)
;; CHECK-NEXT: (string.encode_wtf16_array
;; CHECK-NEXT: (string.const "$_")
;; CHECK-NEXT: (array.new_default $array16
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $encode (result i32)
;; We could optimize away the encode operation here as the reference does not
;; escape, but we do not do escape analysis here.
(string.encode_wtf16_array
(string.const "$_")
(array.new_default $array16
Expand Down Expand Up @@ -156,7 +168,49 @@
)
)

;; CHECK: (func $slice (type $1) (result (ref string))
;; CHECK: (func $encode-stashed (type $3) (result (ref any))
;; CHECK-NEXT: (local $1 (ref $array16))
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (array.new_default $array16
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (string.encode_wtf16_array
;; CHECK-NEXT: (string.as_wtf16
;; CHECK-NEXT: (string.const "0123456789")
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
(func $encode-stashed (export "test") (result (ref any))
(local $1 (ref $array16))
;; Create a zero-filled array.
(local.set $1
(array.new_default $array16
(i32.const 10)
)
)
;; Fill it with some string data.
(drop
(string.encode_wtf16_array
(string.as_wtf16
(string.const "0123456789")
)
(local.get $1)
(i32.const 0)
)
)
;; Return the modified array. We must not have removed the encode operation
;; above us (it has the side effect of modifying the array, just like an
;; array.copy does).
(local.get $1)
)

;; CHECK: (func $slice (type $2) (result (ref string))
;; CHECK-NEXT: (string.const "def")
;; CHECK-NEXT: )
(func $slice (export "slice") (result (ref string))
Expand All @@ -168,7 +222,7 @@
)
)

;; CHECK: (func $slice-bad (type $1) (result (ref string))
;; CHECK: (func $slice-bad (type $2) (result (ref string))
;; CHECK-NEXT: (stringview_wtf16.slice
;; CHECK-NEXT: (string.const "abcd\c2\a3fgh")
;; CHECK-NEXT: (i32.const 3)
Expand Down