summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2021-04-13 15:29:13 -0700
committerGitHub <noreply@github.com>2021-04-13 15:29:13 -0700
commitd321458d57e6977ceaba90099e80b80cf6d472ed (patch)
tree4c57ee8d9f6828ab588b925c71e9dd543f669322 /src
parentb0af95200a37d76eccf285dcb45b4ed6162212d0 (diff)
downloadbinaryen-d321458d57e6977ceaba90099e80b80cf6d472ed.tar.gz
binaryen-d321458d57e6977ceaba90099e80b80cf6d472ed.tar.bz2
binaryen-d321458d57e6977ceaba90099e80b80cf6d472ed.zip
[Wasm GC] Full precompute support for GC (#3803)
The precompute pass ignored all reference types, but that was overly pessimistic: we can precompute some of them, namely a null and a reference to a function are fully precomputable, etc. To allow that to work, add missing integration in getFallthrough as well. With this, we can precompute quite a lot of field accesses in the existing -Oz testcase, as can be seen from the output. That testcase runs --fuzz-exec so it prints out all those logged values, proving they have not changed.
Diffstat (limited to 'src')
-rw-r--r--src/ir/properties.h4
-rw-r--r--src/passes/Precompute.cpp14
2 files changed, 12 insertions, 6 deletions
diff --git a/src/ir/properties.h b/src/ir/properties.h
index 8ae7befba..c4deac9d5 100644
--- a/src/ir/properties.h
+++ b/src/ir/properties.h
@@ -259,6 +259,10 @@ inline Expression* getFallthrough(Expression* curr,
if (!EffectAnalyzer(passOptions, features, tryy->body).throws) {
return getFallthrough(tryy->body, passOptions, features);
}
+ } else if (auto* as = curr->dynCast<RefAs>()) {
+ return getFallthrough(as->value, passOptions, features);
+ } else if (auto* br = curr->dynCast<BrOn>()) {
+ return getFallthrough(br->ref, passOptions, features);
}
return curr;
}
diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp
index ae488a01f..85e09f875 100644
--- a/src/passes/Precompute.cpp
+++ b/src/passes/Precompute.cpp
@@ -173,13 +173,13 @@ struct Precompute
if (flow.getType().hasVector()) {
return;
}
+ if (!canEmitConstantFor(flow.values)) {
+ return;
+ }
if (flow.breaking()) {
if (flow.breakTo == NONCONSTANT_FLOW) {
return;
}
- if (!canEmitConstantFor(flow.values)) {
- return;
- }
if (flow.breakTo == RETURN_FLOW) {
// this expression causes a return. if it's already a return, reuse the
// node
@@ -365,15 +365,17 @@ private:
if (value.type.isFunction()) {
return true;
}
+ // All other reference types cannot be precomputed.
+ if (value.type.isRef()) {
+ return false;
+ }
return canEmitConstantFor(value.type);
}
bool canEmitConstantFor(Type type) {
- // Don't try to precompute a reference. We can't replace it with a constant
- // expression, as that would make a copy of it by value.
// For now, don't try to precompute an Rtt. TODO figure out when that would
// be safe and useful.
- return !type.isRef() && !type.isRtt();
+ return !type.isRtt();
}
};