summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2020-04-09 16:42:42 -0700
committerGitHub <noreply@github.com>2020-04-09 16:42:42 -0700
commitc2760038591df9e67b49bb71c9aedb70eadb5b11 (patch)
tree8122128aaf9944800c8f6ad1107ca0da4b88ba92 /src
parent1cfaf2e723968443611b06895212d4328b4881de (diff)
downloadbinaryen-c2760038591df9e67b49bb71c9aedb70eadb5b11.tar.gz
binaryen-c2760038591df9e67b49bb71c9aedb70eadb5b11.tar.bz2
binaryen-c2760038591df9e67b49bb71c9aedb70eadb5b11.zip
Handle tuples in Asyncify call support (#2743)
Instead of adding globals for hardcoded basic types, traverse the module to collect all call types that might need to be handled and emit a global for each of them. Adapted from #2712.
Diffstat (limited to 'src')
-rw-r--r--src/passes/Asyncify.cpp50
-rw-r--r--src/wasm-type.h5
-rw-r--r--src/wasm/wasm-type.cpp4
3 files changed, 50 insertions, 9 deletions
diff --git a/src/passes/Asyncify.cpp b/src/passes/Asyncify.cpp
index a6afd3444..62b14531a 100644
--- a/src/passes/Asyncify.cpp
+++ b/src/passes/Asyncify.cpp
@@ -312,17 +312,14 @@ class FakeGlobalHelper {
public:
FakeGlobalHelper(Module& module) : module(module) {
- map[Type::i32] = "asyncify_fake_call_global_i32";
- map[Type::i64] = "asyncify_fake_call_global_i64";
- map[Type::f32] = "asyncify_fake_call_global_f32";
- map[Type::f64] = "asyncify_fake_call_global_f64";
Builder builder(module);
- for (auto& pair : map) {
- auto type = pair.first;
- auto name = pair.second;
- rev[name] = type;
+ std::string prefix = "asyncify_fake_call_global_";
+ for (auto type : collectTypes()) {
+ auto global = prefix + Type(type).toString();
+ map[type] = global;
+ rev[global] = type;
module.addGlobal(builder.makeGlobal(
- name, type, LiteralUtils::makeZero(type, module), Builder::Mutable));
+ global, type, LiteralUtils::makeZero(type, module), Builder::Mutable));
}
}
@@ -346,6 +343,41 @@ public:
private:
std::map<Type, Name> map;
std::map<Name, Type> rev;
+
+ // Collect the types returned from all calls for which call support globals
+ // may need to be generated.
+ using Types = std::unordered_set<Type>;
+ Types collectTypes() {
+ ModuleUtils::ParallelFunctionAnalysis<Types> analysis(
+ module, [&](Function* func, Types& types) {
+ if (!func->body) {
+ return;
+ }
+ struct TypeCollector : PostWalker<TypeCollector> {
+ Types& types;
+ TypeCollector(Types& types) : types(types) {}
+ void visitCall(Call* curr) {
+ if (curr->type.isConcrete()) {
+ types.insert(curr->type);
+ }
+ }
+ void visitCallIndirect(CallIndirect* curr) {
+ if (curr->type.isConcrete()) {
+ types.insert(curr->type);
+ }
+ }
+ };
+ TypeCollector(types).walk(func->body);
+ });
+ Types types;
+ for (auto& pair : analysis.map) {
+ Types& functionTypes = pair.second;
+ for (auto t : functionTypes) {
+ types.insert(t);
+ }
+ }
+ return types;
+ }
};
class PatternMatcher {
diff --git a/src/wasm-type.h b/src/wasm-type.h
index f3db912d1..05cfeaef5 100644
--- a/src/wasm-type.h
+++ b/src/wasm-type.h
@@ -175,6 +175,11 @@ std::ostream& operator<<(std::ostream& os, Signature t);
} // namespace wasm
+template<> class std::hash<wasm::Type> {
+public:
+ size_t operator()(const wasm::Type& type) const;
+};
+
template<> class std::hash<wasm::Signature> {
public:
size_t operator()(const wasm::Signature& sig) const;
diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp
index da7fb50b6..aed13b6d1 100644
--- a/src/wasm/wasm-type.cpp
+++ b/src/wasm/wasm-type.cpp
@@ -35,6 +35,10 @@ public:
}
};
+size_t std::hash<wasm::Type>::operator()(const wasm::Type& type) const {
+ return std::hash<uint32_t>{}(type.getID());
+}
+
size_t std::hash<wasm::Signature>::
operator()(const wasm::Signature& sig) const {
return std::hash<uint64_t>{}(uint64_t(sig.params.getID()) << 32 |