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
22 changes: 22 additions & 0 deletions src/passes/Precompute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,28 @@ class PrecomputingExpressionRunner
return Literal(canonical, curr->type.getHeapType());
}

Flow visitStringNew(StringNew* curr) {
if (curr->op != StringNewWTF16Array) {
// TODO: handle other string ops. For now we focus on JS-like strings.
return Flow(NONCONSTANT_FLOW);
}

// string.encode_wtf16_array is effectively an Array read operation, so
// just like ArrayGet above we must check for immutability.
auto ptrType = curr->ptr->type;
if (ptrType.isRef()) {
auto heapType = ptrType.getHeapType();
if (heapType.isArray()) {
if (heapType.getArray().element.mutable_ == Immutable) {
return Super::visitStringNew(curr);
}
}
}

// Otherwise, this is mutable or unreachable or otherwise uninteresting.
return Flow(NONCONSTANT_FLOW);
}

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
Expand Down
52 changes: 50 additions & 2 deletions test/lit/passes/precompute-strings.wast
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@
;; CHECK: (type $array16 (array (mut i16)))
(type $array16 (array (mut i16)))

(type $array16-imm (array i16))

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

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

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

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

Expand Down Expand Up @@ -169,7 +173,7 @@
)
)

;; CHECK: (func $encode-stashed (type $3) (result (ref any))
;; CHECK: (func $encode-stashed (type $4) (result (ref any))
;; CHECK-NEXT: (local $1 (ref $array16))
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (array.new_default $array16
Expand Down Expand Up @@ -234,4 +238,48 @@
(i32.const 6)
)
)

;; CHECK: (func $string.new-mutable (type $3) (result anyref)
;; CHECK-NEXT: (string.new_wtf16_array
;; CHECK-NEXT: (array.new_fixed $array16 4
;; CHECK-NEXT: (i32.const 65)
;; CHECK-NEXT: (i32.const 66)
;; CHECK-NEXT: (i32.const 67)
;; CHECK-NEXT: (i32.const 68)
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (i32.const 4)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $string.new-mutable (result anyref)
;; We do not precompute this because the array is mutable, and we do not yet
;; do an analysis to see that it does not "escape" into places that modify it.
(string.new_wtf16_array
(array.new_fixed $array16 4
(i32.const 65)
(i32.const 66)
(i32.const 67)
(i32.const 68)
)
(i32.const 0)
(i32.const 4)
)
)

;; CHECK: (func $string.new-immutable (type $3) (result anyref)
;; CHECK-NEXT: (string.const "ABCD")
;; CHECK-NEXT: )
(func $string.new-immutable (result anyref)
;; This array is immutable and we can optimize here.
(string.new_wtf16_array
(array.new_fixed $array16-imm 4
(i32.const 65)
(i32.const 66)
(i32.const 67)
(i32.const 68)
)
(i32.const 0)
(i32.const 4)
)
)
)