diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2021-03-11 13:53:19 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-11 21:53:19 +0000 |
commit | 484563771dbca78e5323cc3f5129890aea03aed5 (patch) | |
tree | 50c869eb9ebd43cba0c5a7bd11c57129ccf61e6e /src/wasm-type.h | |
parent | d369cd6474364e5797e40af94676339af03723a9 (diff) | |
download | binaryen-484563771dbca78e5323cc3f5129890aea03aed5.tar.gz binaryen-484563771dbca78e5323cc3f5129890aea03aed5.tar.bz2 binaryen-484563771dbca78e5323cc3f5129890aea03aed5.zip |
Remove LUB calculation (#3669)
Since correct LUB calculation for recursive types is complicated, stop depending
on LUBs throughout the code base. This also fixes a validation bug in which the
validator required blocks to be typed with the LUB of all the branch types, when
in fact any upper bound should have been valid. In addition to fixing that bug,
this PR simplifies the code for break handling by not storing redundant
information about the arity of types.
Diffstat (limited to 'src/wasm-type.h')
-rw-r--r-- | src/wasm-type.h | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/src/wasm-type.h b/src/wasm-type.h index 8c1d72085..7f037d5e7 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -19,6 +19,7 @@ #include "support/name.h" #include "wasm-features.h" +#include <algorithm> #include <ostream> #include <vector> @@ -202,18 +203,42 @@ public: // Returns true if left is a subtype of right. Subtype includes itself. static bool isSubType(Type left, Type right); - // Computes the least upper bound from the type lattice. - // If one of the type is unreachable, the other type becomes the result. If - // the common supertype does not exist, returns none, a poison value. - static Type getLeastUpperBound(Type a, Type b); + // Returns true and sets `super` to the type in range [begin,end) that is a + // supertype of all types in the range iff such a type exists. This is similar + // to but more limited than calculating a proper least upper bound on the + // types. + template<typename T> static bool getSuperType(const T& types, Type& super) { + // Sort the types so that the supertype will be at the back. + std::vector<Type> sorted(types.begin(), types.end()); + std::stable_sort( + sorted.begin(), sorted.end(), [&](const Type& a, const Type& b) { + return Type::isSubType(a, b); + }); + // Check that the "highest" type found by the sort is actually a supertype + // of all the other sorted. + for (auto t : sorted) { + if (!Type::isSubType(t, sorted.back())) { + return false; + } + } + super = sorted.back(); + return true; + } - // Computes the least upper bound for all types in the given list. - template<typename T> static Type mergeTypes(const T& types) { - Type type = Type::unreachable; - for (auto other : types) { - type = Type::getLeastUpperBound(type, other); + // Ensure that `type` is a supertype of `types`. If it is not already a + // supertype, then use `getSuperType` on `types` to set `type` to a supertype. + // Assumes `getSuperType` will be able to find an appropriate type in that + // case. + template<typename T> + static void ensureSuperType(const T& types, Type& super) { + if (std::all_of(types.begin(), types.end(), [&](const Type& type) { + return isSubType(type, super); + })) { + return; + } + if (!getSuperType(types, super)) { + WASM_UNREACHABLE("Could not ensure supertype"); } - return type; } std::string toString() const; |