diff options
author | Alon Zakai <alonzakai@gmail.com> | 2017-06-28 22:05:05 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-28 22:05:05 -0700 |
commit | e488da5adbef2613c08fe205db5b79b1765a4af3 (patch) | |
tree | e3cab840dcbf7d8d4ccf1f47a742fbfc41e1d5ef /src/ast/label-utils.h | |
parent | e2c08d42ab0ffc05d980ae2d34fee0e77b201134 (diff) | |
download | binaryen-e488da5adbef2613c08fe205db5b79b1765a4af3.tar.gz binaryen-e488da5adbef2613c08fe205db5b79b1765a4af3.tar.bz2 binaryen-e488da5adbef2613c08fe205db5b79b1765a4af3.zip |
Code folding (#1076)
Adds a pass that folds code, i.e. merges it when possible. See details in comment in the pass implementation cpp.
This is enabled by default in -Os and -Oz. Seems risky to enable anywhere else, as it does add branches - likely predictable ones so maybe no slowdown, but still some risk.
Code size numbers:
wasm-backend: 196331
+ binaryen -Os (before): 182598
+ binaryen -Os (with folding): 181943
asm2wasm -Os (before): 172463
asm2wasm -Os (with folding): 168774
So this reduces wasm-backend output by an additional 0.5% than it could before. Mainly this is because the wasm backend already has code folding, whereas on asm2wasm output, where we didn't have folding before, this saves over 2%. The 0.5% improvement on the wasm backend's output might be because this can fold more types of code than LLVM can (it can fold nested control flow, in particular).
Diffstat (limited to 'src/ast/label-utils.h')
-rw-r--r-- | src/ast/label-utils.h | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/ast/label-utils.h b/src/ast/label-utils.h new file mode 100644 index 000000000..6ec9ecf5d --- /dev/null +++ b/src/ast/label-utils.h @@ -0,0 +1,62 @@ +/* + * Copyright 2017 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. + */ + +#ifndef wasm_ast_label_h +#define wasm_ast_label_h + +#include "wasm.h" +#include "wasm-traversal.h" + +namespace wasm { + +namespace LabelUtils { + +// Handles branch/loop labels in a function; makes it easy to add new +// ones without duplicates +class LabelManager : public PostWalker<LabelManager> { +public: + LabelManager(Function* func) { + walkFunction(func); + } + + Name getUnique(std::string prefix) { + while (1) { + auto curr = Name(prefix + std::to_string(counter++)); + if (labels.find(curr) == labels.end()) { + labels.insert(curr); + return curr; + } + } + } + + void visitBlock(Block* curr) { + labels.insert(curr->name); + } + void visitLoop(Loop* curr) { + labels.insert(curr->name); + } + +private: + std::set<Name> labels; + size_t counter = 0; +}; + +} // namespace LabelUtils + +} // namespace wasm + +#endif // wasm_ast_label_h + |