diff options
author | Alon Zakai <alonzakai@gmail.com> | 2017-11-17 16:50:31 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-17 16:50:31 -0800 |
commit | da0c45566118c863f12a2edb004e28a084ef5660 (patch) | |
tree | f4a2e4ca3309ab1251999a9f779ac3d0622a0c90 /src | |
parent | dcdaa5de3b2c63a1349faacfe921527d972fc95c (diff) | |
download | binaryen-da0c45566118c863f12a2edb004e28a084ef5660.tar.gz binaryen-da0c45566118c863f12a2edb004e28a084ef5660.tar.bz2 binaryen-da0c45566118c863f12a2edb004e28a084ef5660.zip |
Flatten tee (#1296)
* flatten tee_local in flatten, as it leads to more-optimizable code (tee_local, when nested, can introduce side effects in bad places).
* also fix some test stuff from recent merges
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/Flatten.cpp | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/src/passes/Flatten.cpp b/src/passes/Flatten.cpp index 00130838e..53fd6a02b 100644 --- a/src/passes/Flatten.cpp +++ b/src/passes/Flatten.cpp @@ -46,6 +46,8 @@ // anything else is written to a local earlier. // 2. Disallow block, loop, and if return values, i.e., do not use // control flow to pass around values. +// 3. Disallow tee_local, setting a local is always done in a set_local +// on a non-nested-expression location. // #include <wasm.h> @@ -185,7 +187,19 @@ struct Flatten : public WalkerPass<ExpressionStackWalker<Flatten, UnifiedExpress ourPreludes.swap(iter->second); } // special handling - if (auto* br = curr->dynCast<Break>()) { + if (auto* set = curr->dynCast<SetLocal>()) { + if (set->isTee()) { + // we disallow tee_local + if (set->value->type == unreachable) { + replaceCurrent(set->value); // trivial, no set happens + } else { + // use a set in a prelude + a get + set->setTee(false); + ourPreludes.push_back(set); + replaceCurrent(builder.makeGetLocal(set->index, set->value->type)); + } + } + } else if (auto* br = curr->dynCast<Break>()) { if (br->value) { auto type = br->value->type; if (isConcreteWasmType(type)) { |