diff options
Diffstat (limited to 'src/passes/MergeBlocks.cpp')
-rw-r--r-- | src/passes/MergeBlocks.cpp | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/src/passes/MergeBlocks.cpp b/src/passes/MergeBlocks.cpp new file mode 100644 index 000000000..3d7afc4cb --- /dev/null +++ b/src/passes/MergeBlocks.cpp @@ -0,0 +1,56 @@ +/* + * Copyright 2015 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. + */ + +// +// Merges blocks to their parents. +// + +#include <wasm.h> +#include <pass.h> + +namespace wasm { + +struct MergeBlocks : public Pass { + void visitBlock(Block *curr) override { + bool more = true; + while (more) { + more = false; + for (size_t i = 0; i < curr->list.size(); i++) { + Block* child = curr->list[i]->dyn_cast<Block>(); + if (!child) continue; + if (child->name.is()) continue; // named blocks can have breaks to them (and certainly do, if we ran RemoveUnusedNames and RemoveUnusedBrs) + ExpressionList merged; + for (size_t j = 0; j < i; j++) { + merged.push_back(curr->list[j]); + } + for (auto item : child->list) { + merged.push_back(item); + } + for (size_t j = i + 1; j < curr->list.size(); j++) { + merged.push_back(curr->list[j]); + } + curr->list = merged; + more = true; + break; + } + } + } +}; + +static RegisterPass<MergeBlocks> registerPass("merge-blocks", "merges blocks to their parents"); + +} // namespace wasm + |