diff options
author | Alon Zakai <azakai@google.com> | 2022-10-13 14:54:45 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-13 21:54:45 +0000 |
commit | 3e44a9fc542572592ee1ee1bdec19bf1904faaa3 (patch) | |
tree | 13228879b1d107e51771fe8dd1da03b0d113ed92 /src | |
parent | b11a8e06f9d098160a6d0c333b485249cd544d99 (diff) | |
download | binaryen-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.cpp | 24 | ||||
-rw-r--r-- | src/ir/possible-contents.h | 20 |
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 { |