diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-05-23 19:59:06 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-05-23 19:59:06 -0700 |
commit | 3a993f98daefc9a851824f5099b76b4a427f81ed (patch) | |
tree | 045fdedd5b5fab72f5ae5de135297b3fe2faa39f | |
parent | 57ec2122cf0971d7869e56699b768026268745ea (diff) | |
download | binaryen-3a993f98daefc9a851824f5099b76b4a427f81ed.tar.gz binaryen-3a993f98daefc9a851824f5099b76b4a427f81ed.tar.bz2 binaryen-3a993f98daefc9a851824f5099b76b4a427f81ed.zip |
add a pass to drop return values in set_local and store (#539)
-rw-r--r-- | src/passes/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/passes/DropReturnValues.cpp | 79 | ||||
-rw-r--r-- | test/passes/drop-return-values.txt | 31 | ||||
-rw-r--r-- | test/passes/drop-return-values.wast | 9 |
4 files changed, 120 insertions, 0 deletions
diff --git a/src/passes/CMakeLists.txt b/src/passes/CMakeLists.txt index 1c2a63da4..2b70fb9d4 100644 --- a/src/passes/CMakeLists.txt +++ b/src/passes/CMakeLists.txt @@ -2,6 +2,7 @@ SET(passes_SOURCES pass.cpp CoalesceLocals.cpp DeadCodeElimination.cpp + DropReturnValues.cpp LowerIfElse.cpp MergeBlocks.cpp Metrics.cpp diff --git a/src/passes/DropReturnValues.cpp b/src/passes/DropReturnValues.cpp new file mode 100644 index 000000000..b89de3011 --- /dev/null +++ b/src/passes/DropReturnValues.cpp @@ -0,0 +1,79 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Stops using return values from set_local and store nodes. +// + +#include <wasm.h> +#include <pass.h> +#include <ast_utils.h> +#include <wasm-builder.h> + +namespace wasm { + +struct DropReturnValues : public WalkerPass<PostWalker<DropReturnValues, Visitor<DropReturnValues>>> { + bool isFunctionParallel() { return true; } + + std::vector<Expression*> expressionStack; + + void visitSetLocal(SetLocal* curr) { + if (ExpressionAnalyzer::isResultUsed(expressionStack, getFunction())) { + Builder builder(*getModule()); + replaceCurrent(builder.makeSequence( + curr, + builder.makeGetLocal(curr->index, curr->type) + )); + } + } + + void visitStore(Store* curr) { + if (ExpressionAnalyzer::isResultUsed(expressionStack, getFunction())) { + Index index = getFunction()->getNumLocals(); + getFunction()->vars.emplace_back(curr->type); + Builder builder(*getModule()); + replaceCurrent(builder.makeSequence( + builder.makeSequence( + builder.makeSetLocal(index, curr->value), + curr + ), + builder.makeGetLocal(index, curr->type) + )); + curr->value = builder.makeGetLocal(index, curr->type); + } + } + + static void visitPre(DropReturnValues* self, Expression** currp) { + self->expressionStack.push_back(*currp); + } + + static void visitPost(DropReturnValues* self, Expression** currp) { + self->expressionStack.pop_back(); + } + + static void scan(DropReturnValues* self, Expression** currp) { + self->pushTask(visitPost, currp); + + WalkerPass<PostWalker<DropReturnValues, Visitor<DropReturnValues>>>::scan(self, currp); + + self->pushTask(visitPre, currp); + } +}; + +static RegisterPass<DropReturnValues> registerPass("drop-return-values", "stops relying on return values from set_local and store"); + +} // namespace wasm + diff --git a/test/passes/drop-return-values.txt b/test/passes/drop-return-values.txt new file mode 100644 index 000000000..8f372ea24 --- /dev/null +++ b/test/passes/drop-return-values.txt @@ -0,0 +1,31 @@ +(module + (memory 10) + (func $0 + (local $x i32) + (local $1 i32) + (i32.add + (block + (set_local $x + (i32.const 10) + ) + (get_local $x) + ) + (i32.const 20) + ) + (i32.add + (block + (block + (set_local $1 + (i32.const 40) + ) + (i32.store + (i32.const 30) + (get_local $1) + ) + ) + (get_local $1) + ) + (i32.const 50) + ) + ) +) diff --git a/test/passes/drop-return-values.wast b/test/passes/drop-return-values.wast new file mode 100644 index 000000000..76463cc8e --- /dev/null +++ b/test/passes/drop-return-values.wast @@ -0,0 +1,9 @@ +(module + (memory 10) + (func + (local $x i32) + (i32.add (set_local $x (i32.const 10)) (i32.const 20)) + (i32.add (i32.store (i32.const 30) (i32.const 40)) (i32.const 50)) + ) +) + |