diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2020-03-17 19:52:26 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-17 19:52:26 -0700 |
commit | 5946b9aa75c8257b8741f0786ebd21f37929cb36 (patch) | |
tree | f5e4926b384617d7ab0d3b8dd53710399a38a1e7 /src/passes/Asyncify.cpp | |
parent | b4a8ace5c6d7f31e6d2117529220688975b6e59b (diff) | |
download | binaryen-5946b9aa75c8257b8741f0786ebd21f37929cb36.tar.gz binaryen-5946b9aa75c8257b8741f0786ebd21f37929cb36.tar.bz2 binaryen-5946b9aa75c8257b8741f0786ebd21f37929cb36.zip |
Support tuple locals in Asyncify (#2696)
Iterate over tuple locals and separately load or store each component.
Diffstat (limited to 'src/passes/Asyncify.cpp')
-rw-r--r-- | src/passes/Asyncify.cpp | 74 |
1 files changed, 46 insertions, 28 deletions
diff --git a/src/passes/Asyncify.cpp b/src/passes/Asyncify.cpp index f8fd6085b..05c1c8954 100644 --- a/src/passes/Asyncify.cpp +++ b/src/passes/Asyncify.cpp @@ -1115,9 +1115,7 @@ private: auto* func = getFunction(); Index total = 0; for (Index i = 0; i < numPreservableLocals; i++) { - auto type = func->getLocalType(i); - auto size = type.getByteSize(); - total += size; + total += func->getLocalType(i).getByteSize(); } auto* block = builder->makeBlock(); block->list.push_back(builder->makeIncStackPos(-total)); @@ -1126,19 +1124,31 @@ private: builder->makeLocalSet(tempIndex, builder->makeGetStackPos())); Index offset = 0; for (Index i = 0; i < numPreservableLocals; i++) { - auto type = func->getLocalType(i); - auto size = type.getByteSize(); - assert(size % STACK_ALIGN == 0); - // TODO: higher alignment? - block->list.push_back(builder->makeLocalSet( - i, - builder->makeLoad(size, - true, - offset, - STACK_ALIGN, - builder->makeLocalGet(tempIndex, Type::i32), - type))); - offset += size; + const auto& types = func->getLocalType(i).expand(); + SmallVector<Expression*, 1> loads; + for (Index j = 0; j < types.size(); j++) { + auto type = types[j]; + auto size = type.getByteSize(); + assert(size % STACK_ALIGN == 0); + // TODO: higher alignment? + loads.push_back( + builder->makeLoad(size, + true, + offset, + STACK_ALIGN, + builder->makeLocalGet(tempIndex, Type::i32), + type)); + offset += size; + } + Expression* load; + if (loads.size() == 1) { + load = loads[0]; + } else if (types.size() > 1) { + load = builder->makeTupleMake(std::move(loads)); + } else { + WASM_UNREACHABLE("Unexpected empty type"); + } + block->list.push_back(builder->makeLocalSet(i, load)); } block->finalize(); return block; @@ -1155,18 +1165,26 @@ private: builder->makeLocalSet(tempIndex, builder->makeGetStackPos())); Index offset = 0; for (Index i = 0; i < numPreservableLocals; i++) { - auto type = func->getLocalType(i); - auto size = type.getByteSize(); - assert(size % STACK_ALIGN == 0); - // TODO: higher alignment? - block->list.push_back( - builder->makeStore(size, - offset, - STACK_ALIGN, - builder->makeLocalGet(tempIndex, Type::i32), - builder->makeLocalGet(i, type), - type)); - offset += size; + auto localType = func->getLocalType(i); + const auto& types = localType.expand(); + for (Index j = 0; j < types.size(); j++) { + auto type = types[j]; + auto size = type.getByteSize(); + Expression* localGet = builder->makeLocalGet(i, localType); + if (types.size() > 1) { + localGet = builder->makeTupleExtract(localGet, j); + } + assert(size % STACK_ALIGN == 0); + // TODO: higher alignment? + block->list.push_back( + builder->makeStore(size, + offset, + STACK_ALIGN, + builder->makeLocalGet(tempIndex, Type::i32), + localGet, + type)); + offset += size; + } } block->list.push_back(builder->makeIncStackPos(offset)); block->finalize(); |