From 3a993f98daefc9a851824f5099b76b4a427f81ed Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 23 May 2016 19:59:06 -0700 Subject: add a pass to drop return values in set_local and store (#539) --- src/passes/DropReturnValues.cpp | 79 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 src/passes/DropReturnValues.cpp (limited to 'src/passes/DropReturnValues.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 +#include +#include +#include + +namespace wasm { + +struct DropReturnValues : public WalkerPass>> { + bool isFunctionParallel() { return true; } + + std::vector 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>>::scan(self, currp); + + self->pushTask(visitPre, currp); + } +}; + +static RegisterPass registerPass("drop-return-values", "stops relying on return values from set_local and store"); + +} // namespace wasm + -- cgit v1.2.3