-
Notifications
You must be signed in to change notification settings - Fork 796
Require specific array types for string ops #7810
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
The operations for creating strings from arrays and decoding strings into arrays previously accepted any array types with i8 or i16 elements, depending on the specific operation. This violates the principal types properties of the WebAssembly type system and was a bug in the design of the defunct stringref proposal. In practice, these operations are only useful when lowered to calls to the standard JS string builtins, which have strict requirements about what array types they accept. Reflect those requirements by restricting the array types we allow to be used with the string Expressions in our IR. This allows us to remove the special casing for these operations in ChildTyper. Since Precompute only worked on string operations taking immutable arrays, but those arrays are now invalid to use with string operations, let it precompute on mutable arrays in the special case where the array allocation is an immediate child of the string operation so it is known not to escape elsewhere. Hopefully this is enough to prevent serious optimization regressions.
// Certain heap types are used by standard operations. Provide central accessors | ||
// for them to avoid having to build them everywhere they are used. | ||
HeapType getMutI8Array(); | ||
HeapType getMutI16Array(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be in ir/array*.h
perhaps?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will eventually get more types, not all of which are arrays. In particular I'm thinking of (type (struct (field (mut i32))))
, which we will need for waitqueueref
.
src/passes/Precompute.cpp
Outdated
@@ -213,23 +213,23 @@ class PrecomputingExpressionRunner | |||
|
|||
Flow visitStringNew(StringNew* curr) { | |||
if (curr->op != StringNewWTF16Array) { | |||
// TODO: handle other string ops. For now we focus on JS-like strings. | |||
// TOOD: handle other string ops. For now we focus on JS-like strings. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// TOOD: handle other string ops. For now we focus on JS-like strings. | |
// TODO: handle other string ops. For now we focus on JS-like strings. |
src/passes/Precompute.cpp
Outdated
@@ -213,23 +213,23 @@ class PrecomputingExpressionRunner | |||
|
|||
Flow visitStringNew(StringNew* curr) { | |||
if (curr->op != StringNewWTF16Array) { | |||
// TODO: handle other string ops. For now we focus on JS-like strings. | |||
// TOOD: 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment mentions string.encode, but in string.new - looks like it might have been copy-pasted from StringEncode, below? Might as well fix it here.
type.getArray().element == array16Element) { | ||
updates[type] = array16; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we still need this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, because now it's no longer possible for any array operation to take a reference to an array type other than the one this code is introducing. Basically we're requiring that this replacement would be a no-op by construction.
;; CHECK-NEXT: ) | ||
(func $string.new-immutable (result externref) | ||
;; This array is immutable and we can optimize here. | ||
(func $string.new-mutable-indirect (result externref) | ||
(string.new_wtf16_array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a comment comparing to the above.
The operations for creating strings from arrays and decoding strings
into arrays previously accepted any array types with i8 or i16 elements,
depending on the specific operation. This violates the principal types
properties of the WebAssembly type system and was a bug in the design of
the defunct stringref proposal.
In practice, these operations are only useful when lowered to calls to
the standard JS string builtins, which have strict requirements about
what array types they accept. Reflect those requirements by restricting
the array types we allow to be used with the string Expressions in our
IR. This allows us to remove the special casing for these operations in
ChildTyper.
Since Precompute only worked on string operations taking immutable
arrays, but those arrays are now invalid to use with string operations,
let it precompute on mutable arrays in the special case where the array
allocation is an immediate child of the string operation so it is known
not to escape elsewhere. Hopefully this is enough to prevent serious
optimization regressions.