diff options
author | Alon Zakai <azakai@google.com> | 2021-10-15 13:03:33 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-15 20:03:33 +0000 |
commit | 980bb397fa713385d7e0a7f1ddc0318a3da7234c (patch) | |
tree | 6ee0f879e6c63a533e52ca1161148df177a5ff3b /src | |
parent | 0a1ac51b1e7e88f0ce89793c71333bb8bc7335d0 (diff) | |
download | binaryen-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.cpp | 33 |
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); } |