summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2023-01-10 15:08:32 -0800
committerGitHub <noreply@github.com>2023-01-10 15:08:32 -0800
commit5032e958808ef584cfd7e4be35f419b4d35488ac (patch)
treec2731f55fa7d2da849eb52d888143706988c56fd /src
parent31171ca083c7a4d1394ad7812369d385e1dd38a0 (diff)
downloadbinaryen-5032e958808ef584cfd7e4be35f419b4d35488ac.tar.gz
binaryen-5032e958808ef584cfd7e4be35f419b4d35488ac.tar.bz2
binaryen-5032e958808ef584cfd7e4be35f419b4d35488ac.zip
[Wasm GC] Add missing RefTest optimizations to parallel RefCast (#5417)
We already handled Success and Failure. Also handle SuccessOnlyIfNull and SuccessOnlyIfNonNull.
Diffstat (limited to 'src')
-rw-r--r--src/passes/OptimizeInstructions.cpp33
1 files changed, 23 insertions, 10 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index e8c6dc1fe..6d4b7b674 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -2075,17 +2075,30 @@ struct OptimizeInstructions
return;
}
- // See above in RefCast.
- auto result =
- GCTypeUtils::evaluateCastCheck(curr->ref->type, curr->castType);
- if (result == GCTypeUtils::Success) {
- replaceCurrent(builder.makeBlock(
- {builder.makeDrop(curr->ref), builder.makeConst(int32_t(1))}));
- } else if (result == GCTypeUtils::Failure) {
- replaceCurrent(builder.makeSequence(builder.makeDrop(curr->ref),
- builder.makeConst(int32_t(0))));
+ // Parallel to the code in visitRefCast
+ switch (GCTypeUtils::evaluateCastCheck(curr->ref->type, curr->castType)) {
+ case GCTypeUtils::Unknown:
+ break;
+ case GCTypeUtils::Success:
+ replaceCurrent(builder.makeBlock(
+ {builder.makeDrop(curr->ref), builder.makeConst(int32_t(1))}));
+ break;
+ case GCTypeUtils::Failure:
+ replaceCurrent(builder.makeSequence(builder.makeDrop(curr->ref),
+ builder.makeConst(int32_t(0))));
+ break;
+ case GCTypeUtils::SuccessOnlyIfNull:
+ replaceCurrent(builder.makeRefIsNull(curr->ref));
+ break;
+ case GCTypeUtils::SuccessOnlyIfNonNull:
+ // This adds an EqZ, but code size does not regress since ref.test also
+ // encodes a type, and ref.is_null does not. The EqZ may also add some
+ // work, but a cast is likely more expensive than a null check + a fast
+ // int operation.
+ replaceCurrent(
+ builder.makeUnary(EqZInt32, builder.makeRefIsNull(curr->ref)));
+ break;
}
- // TODO: we can emit a ref.is_null for SuccessOnlyIfNull etc.
}
void visitRefIsNull(RefIsNull* curr) {