diff options
author | Alon Zakai <azakai@google.com> | 2023-01-10 15:08:32 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-10 15:08:32 -0800 |
commit | 5032e958808ef584cfd7e4be35f419b4d35488ac (patch) | |
tree | c2731f55fa7d2da849eb52d888143706988c56fd /src | |
parent | 31171ca083c7a4d1394ad7812369d385e1dd38a0 (diff) | |
download | binaryen-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.cpp | 33 |
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) { |