summaryrefslogtreecommitdiff
path: root/src/ir/possible-contents.h
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-10-19 11:02:33 -0700
committerGitHub <noreply@github.com>2022-10-19 11:02:33 -0700
commit18273489e9433e399cc4f088e9352c08aec13369 (patch)
treea3f8274aee790918dfb26326dcc5ec2e33c1d5ec /src/ir/possible-contents.h
parent3b1df7e5c329d9600cfadd513b557af618c007aa (diff)
downloadbinaryen-18273489e9433e399cc4f088e9352c08aec13369.tar.gz
binaryen-18273489e9433e399cc4f088e9352c08aec13369.tar.bz2
binaryen-18273489e9433e399cc4f088e9352c08aec13369.zip
[Wasm GC] Use Cones in GUFA data reads and writes (#5157)
When we read from a struct/array using a cone type, read from the types in the cone and nothing else. Previously we used the declared type in the wasm, which might be larger (both in the base type and the depth). Likewise, in a write. To do this, this extends ConeReadLocation with a depth (previously the depth there was assumed to be infinite, and now it is to a potentially limited depth). After this we are fully utilizing cone types in GUFA, as the test changes show (or at least I can't think of any other uses of cones).
Diffstat (limited to 'src/ir/possible-contents.h')
-rw-r--r--src/ir/possible-contents.h17
1 files changed, 12 insertions, 5 deletions
diff --git a/src/ir/possible-contents.h b/src/ir/possible-contents.h
index 14ed36b4d..8a8d9b635 100644
--- a/src/ir/possible-contents.h
+++ b/src/ir/possible-contents.h
@@ -454,8 +454,10 @@ struct NullLocation {
// A special type of location that does not refer to something concrete in the
// wasm, but is used to optimize the graph. A "cone read" is a struct.get or
-// array.get of a type that is not exact, so it can read the "cone" of all the
-// subtypes. In general a read of a cone type (as opposed to an exact type) will
+// array.get of a type that is not exact, so it can read from either that type
+// of some of the subtypes (up to a particular subtype depth).
+//
+// In general a read of a cone type + depth (as opposed to an exact type) will
// require N incoming links, from each of the N subtypes - and we need that
// for each struct.get of a cone. If there are M such gets then we have N * M
// edges for this. Instead, we make a single canonical "cone read" location, and
@@ -464,11 +466,15 @@ struct NullLocation {
// data to flow along).
struct ConeReadLocation {
HeapType type;
+ // As in PossibleContents, this represents the how deep we go with subtypes.
+ // 0 means an exact type, 1 means immediate subtypes, etc. (Note that 0 is not
+ // needed since that is what DataLocation already is.)
+ Index depth;
// The index of the field in a struct, or 0 for an array (where we do not
// attempt to differentiate by index).
Index index;
bool operator==(const ConeReadLocation& other) const {
- return type == other.type && index == other.index;
+ return type == other.type && depth == other.depth && index == other.index;
}
};
@@ -572,8 +578,9 @@ template<> struct hash<wasm::NullLocation> {
template<> struct hash<wasm::ConeReadLocation> {
size_t operator()(const wasm::ConeReadLocation& loc) const {
- return std::hash<std::pair<wasm::HeapType, wasm::Index>>{}(
- {loc.type, loc.index});
+ return std::hash<
+ std::pair<wasm::HeapType, std::pair<wasm::Index, wasm::Index>>>{}(
+ {loc.type, {loc.depth, loc.index}});
}
};