summaryrefslogtreecommitdiff
path: root/src/wasm
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2023-08-17 12:09:22 -0700
committerGitHub <noreply@github.com>2023-08-17 19:09:22 +0000
commitc39ca2e1cde95b6fcef6cdfeb9326dadd75e55df (patch)
treeca9a9535fc37e7bbb23c1e9f73a4dbeb38410279 /src/wasm
parent7424929782692271a09a19572806e1760beacddc (diff)
downloadbinaryen-c39ca2e1cde95b6fcef6cdfeb9326dadd75e55df.tar.gz
binaryen-c39ca2e1cde95b6fcef6cdfeb9326dadd75e55df.tar.bz2
binaryen-c39ca2e1cde95b6fcef6cdfeb9326dadd75e55df.zip
Improve cast optimizations (#5876)
Simplify the optimization of ref.cast and ref.test in OptimizeInstructions by moving the loop that examines fallthrough values one at a time out to a shared function in properties.h. Also simplify ref.cast optimization by analyzing the cast result in just one place. In addition to simplifying the code, also make the cast optimizations more powerful by analyzing the nullability and heap type of the cast value independently, resulting in a potentially more precise analysis of the cast behavior. Also improve optimization power by considering fallthrough values when optimizing the SuccessOnlyIfNonNull case.
Diffstat (limited to 'src/wasm')
-rw-r--r--src/wasm/wasm-type.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp
index 114a83bd6..fd9838b31 100644
--- a/src/wasm/wasm-type.cpp
+++ b/src/wasm/wasm-type.cpp
@@ -1035,6 +1035,31 @@ Type Type::getLeastUpperBound(Type a, Type b) {
WASM_UNREACHABLE("unexpected type");
}
+Type Type::getGreatestLowerBound(Type a, Type b) {
+ if (a == b) {
+ return a;
+ }
+ if (!a.isRef() || !b.isRef()) {
+ return Type::unreachable;
+ }
+ auto heapA = a.getHeapType();
+ auto heapB = b.getHeapType();
+ if (heapA.getBottom() != heapB.getBottom()) {
+ return Type::unreachable;
+ }
+ auto nullability =
+ (a.isNonNullable() || b.isNonNullable()) ? NonNullable : Nullable;
+ HeapType heapType;
+ if (HeapType::isSubType(heapA, heapB)) {
+ heapType = heapA;
+ } else if (HeapType::isSubType(heapB, heapA)) {
+ heapType = heapB;
+ } else {
+ heapType = heapA.getBottom();
+ }
+ return Type(heapType, nullability);
+}
+
size_t Type::size() const {
if (isTuple()) {
return getTypeInfo(*this)->tuple.size();