summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-10-13 14:54:45 -0700
committerGitHub <noreply@github.com>2022-10-13 21:54:45 +0000
commit3e44a9fc542572592ee1ee1bdec19bf1904faaa3 (patch)
tree13228879b1d107e51771fe8dd1da03b0d113ed92 /src
parentb11a8e06f9d098160a6d0c333b485249cd544d99 (diff)
downloadbinaryen-3e44a9fc542572592ee1ee1bdec19bf1904faaa3.tar.gz
binaryen-3e44a9fc542572592ee1ee1bdec19bf1904faaa3.tar.bz2
binaryen-3e44a9fc542572592ee1ee1bdec19bf1904faaa3.zip
[Wasm GC][GUFA] Avoid Many in roots (#5142)
Instead of Many, use a proper Cone Type for the data, as appropriate.
Diffstat (limited to 'src')
-rw-r--r--src/ir/possible-contents.cpp24
-rw-r--r--src/ir/possible-contents.h20
2 files changed, 36 insertions, 8 deletions
diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp
index cd8bd1516..2efd61391 100644
--- a/src/ir/possible-contents.cpp
+++ b/src/ir/possible-contents.cpp
@@ -1205,6 +1205,9 @@ struct InfoCollector
PossibleContents contents = PossibleContents::many()) {
// TODO Use a cone type here when relevant
if (isRelevant(curr)) {
+ if (contents.isMany()) {
+ contents = PossibleContents::fromType(curr->type);
+ }
addRoot(ExpressionLocation{curr, 0}, contents);
}
}
@@ -1399,8 +1402,10 @@ Flower::Flower(Module& wasm) : wasm(wasm) {
if (func->imported()) {
// Imports return unknown values.
- for (Index i = 0; i < func->getResults().size(); i++) {
- finder.addRoot(ResultLocation{func, i}, PossibleContents::many());
+ auto results = func->getResults();
+ for (Index i = 0; i < results.size(); i++) {
+ finder.addRoot(ResultLocation{func, i},
+ PossibleContents::fromType(results[i]));
}
return;
}
@@ -1423,7 +1428,8 @@ Flower::Flower(Module& wasm) : wasm(wasm) {
for (auto& global : wasm.globals) {
if (global->imported()) {
// Imports are unknown values.
- finder.addRoot(GlobalLocation{global->name}, PossibleContents::many());
+ finder.addRoot(GlobalLocation{global->name},
+ PossibleContents::fromType(global->type));
continue;
}
auto* init = global->init;
@@ -1477,8 +1483,9 @@ Flower::Flower(Module& wasm) : wasm(wasm) {
// that we can't see, so anything might arrive there.
auto calledFromOutside = [&](Name funcName) {
auto* func = wasm.getFunction(funcName);
+ auto params = func->getParams();
for (Index i = 0; i < func->getParams().size(); i++) {
- roots[ParamLocation{func, i}] = PossibleContents::many();
+ roots[ParamLocation{func, i}] = PossibleContents::fromType(params[i]);
}
};
@@ -1509,8 +1516,9 @@ Flower::Flower(Module& wasm) : wasm(wasm) {
// Exported mutable globals are roots, since the outside may write any
// value to them.
auto name = ex->value;
- if (wasm.getGlobal(name)->mutable_) {
- roots[GlobalLocation{name}] = PossibleContents::many();
+ auto* global = wasm.getGlobal(name);
+ if (global->mutable_) {
+ roots[GlobalLocation{name}] = PossibleContents::fromType(global->type);
}
}
}
@@ -1974,9 +1982,9 @@ void Flower::dump(Location location) {
std::cout << " tagloc " << loc->tag << '\n';
} else if (auto* loc = std::get_if<ParamLocation>(&location)) {
std::cout << " paramloc " << loc->func->name << " : " << loc->index
- << " tupleIndex " << loc->tupleIndex << '\n';
+ << '\n';
} else if (auto* loc = std::get_if<ResultLocation>(&location)) {
- std::cout << " resultloc " << loc->func->name << " : " << loc->index
+ std::cout << " resultloc $" << loc->func->name << " : " << loc->index
<< '\n';
} else if (auto* loc = std::get_if<GlobalLocation>(&location)) {
std::cout << " globalloc " << loc->name << '\n';
diff --git a/src/ir/possible-contents.h b/src/ir/possible-contents.h
index ee817deae..14ed36b4d 100644
--- a/src/ir/possible-contents.h
+++ b/src/ir/possible-contents.h
@@ -131,6 +131,26 @@ public:
}
static PossibleContents many() { return PossibleContents{Many()}; }
+ // Helper for creating a PossibleContents based on a wasm type, that is, where
+ // all we know is the wasm type.
+ static PossibleContents fromType(Type type) {
+ assert(type != Type::none);
+
+ if (type.isRef()) {
+ // For a reference, subtyping matters.
+ return fullConeType(type);
+ }
+
+ if (type == Type::unreachable) {
+ // Nothing is possible here.
+ return none();
+ }
+
+ // Otherwise, this is a concrete MVP type.
+ assert(type.isConcrete());
+ return exactType(type);
+ }
+
PossibleContents& operator=(const PossibleContents& other) = default;
bool operator==(const PossibleContents& other) const {