summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2021-10-15 13:03:33 -0700
committerGitHub <noreply@github.com>2021-10-15 20:03:33 +0000
commit980bb397fa713385d7e0a7f1ddc0318a3da7234c (patch)
tree6ee0f879e6c63a533e52ca1161148df177a5ff3b /src
parent0a1ac51b1e7e88f0ce89793c71333bb8bc7335d0 (diff)
downloadbinaryen-980bb397fa713385d7e0a7f1ddc0318a3da7234c.tar.gz
binaryen-980bb397fa713385d7e0a7f1ddc0318a3da7234c.tar.bz2
binaryen-980bb397fa713385d7e0a7f1ddc0318a3da7234c.zip
[Wasm GC] Propagate immutable fields (#4251)
Very simple with the work so far, just add StructGet/ArrayGet code to check if the field is immutable, and allow the get to go through in that case.
Diffstat (limited to 'src')
-rw-r--r--src/passes/Precompute.cpp33
1 files changed, 31 insertions, 2 deletions
diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp
index 876b09acd..591245ab5 100644
--- a/src/passes/Precompute.cpp
+++ b/src/passes/Precompute.cpp
@@ -129,7 +129,25 @@ public:
return getHeapCreationFlow(flow, curr);
}
Flow visitStructSet(StructSet* curr) { return Flow(NONCONSTANT_FLOW); }
- Flow visitStructGet(StructGet* curr) { return Flow(NONCONSTANT_FLOW); }
+ Flow visitStructGet(StructGet* curr) {
+ if (curr->ref->type != Type::unreachable) {
+ // If this field is immutable then we may be able to precompute this, as
+ // if we also created the data in this function (or it was created in an
+ // immutable global) then we know the value in the field. If it is
+ // immutable, call the super method which will do the rest here. That
+ // includes checking for the data being properly created, as if it was
+ // not then we will not have a constant value for it, which means the
+ // local.get of that value will stop us.
+ auto& field =
+ curr->ref->type.getHeapType().getStruct().fields[curr->index];
+ if (field.mutable_ == Immutable) {
+ return Super::visitStructGet(curr);
+ }
+ }
+
+ // Otherwise, we've failed to precompute.
+ return Flow(NONCONSTANT_FLOW);
+ }
Flow visitArrayNew(ArrayNew* curr) {
auto flow = Super::visitArrayNew(curr);
if (flow.breaking()) {
@@ -145,7 +163,18 @@ public:
return getHeapCreationFlow(flow, curr);
}
Flow visitArraySet(ArraySet* curr) { return Flow(NONCONSTANT_FLOW); }
- Flow visitArrayGet(ArrayGet* curr) { return Flow(NONCONSTANT_FLOW); }
+ Flow visitArrayGet(ArrayGet* curr) {
+ if (curr->ref->type != Type::unreachable) {
+ // See above with struct.get
+ auto element = curr->ref->type.getHeapType().getArray().element;
+ if (element.mutable_ == Immutable) {
+ return Super::visitArrayGet(curr);
+ }
+ }
+
+ // Otherwise, we've failed to precompute.
+ return Flow(NONCONSTANT_FLOW);
+ }
Flow visitArrayLen(ArrayLen* curr) { return Flow(NONCONSTANT_FLOW); }
Flow visitArrayCopy(ArrayCopy* curr) { return Flow(NONCONSTANT_FLOW); }