diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-02-18 11:23:10 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-02-18 11:23:10 -0800 |
commit | a684cff9e123db38eec9a6c7fbd423aed0b127ab (patch) | |
tree | e858880ef47ac17d7c972e10c145999c1a24d81d | |
parent | 849322a1135479f79f7d94b8b032486efe7955a8 (diff) | |
parent | 1f36e3a7ba07ba4460a2682805d259b19113727e (diff) | |
download | binaryen-a684cff9e123db38eec9a6c7fbd423aed0b127ab.tar.gz binaryen-a684cff9e123db38eec9a6c7fbd423aed0b127ab.tar.bz2 binaryen-a684cff9e123db38eec9a6c7fbd423aed0b127ab.zip |
Merge pull request #201 from WebAssembly/lower-case
Add a optional pass to lower cases
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/passes/LowerCase.cpp | 102 | ||||
-rw-r--r-- | test/passes/lower-case.txt | 88 | ||||
-rw-r--r-- | test/passes/lower-case.wast | 81 |
4 files changed, 272 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index e3ec72c6e..d927771d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,6 +76,7 @@ ADD_LIBRARY(support STATIC ${support_SOURCES}) SET(binaryen-shell_SOURCES src/binaryen-shell.cpp src/pass.cpp + src/passes/LowerCase.cpp src/passes/LowerIfElse.cpp src/passes/MergeBlocks.cpp src/passes/NameManager.cpp diff --git a/src/passes/LowerCase.cpp b/src/passes/LowerCase.cpp new file mode 100644 index 000000000..50c370bdc --- /dev/null +++ b/src/passes/LowerCase.cpp @@ -0,0 +1,102 @@ +/* + * 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. + */ + +// +// Lowers switch cases out into blocks, +// +/* + (tableswitch $switch$0 + (i32.sub + (get_local $x) + (i32.const 1) + ) + (table (case $switch-case$1) (case $switch-case$2)) (case $switch-default$3) + (case $switch-case$1 + (return + (i32.const 1) + ) + ) + (case $switch-case$2 + (return + (i32.const 2) + ) + ) + (case $switch-default$3 + (nop) + ) + ) + + into + + (block $forswitch$switch$0 + (block $switch-case$3 + (block $switch-case$2 + (block $switch-case$1 + (tableswitch $switch$0 + (i32.sub + (get_local $x) + (i32.const 1) + ) + (table (br $switch-case$1) (br $switch-case$2)) (br $switch-default$3) + ) + ) + (return + (i32.const 1) + ) + ) + (return + (i32.const 2) + ) + ) + (nop) + ) +*/ + + +#include <memory> + +#include <wasm.h> +#include <pass.h> + +namespace wasm { + +struct LowerCase : public WalkerPass<WasmWalker<LowerCase, void>> { + MixedArena* allocator; + + void prepare(PassRunner* runner, Module *module) override { + allocator = runner->allocator; + } + + void visitSwitch(Switch *curr) { + if (curr->cases.size() == 0) return; + auto top = allocator->alloc<Block>(); + top->list.push_back(curr); + for (auto& c : curr->cases) { + top->name = c.name; + auto next = allocator->alloc<Block>(); + next->list.push_back(top); + next->list.push_back(c.body); + top = next; + } + curr->cases.clear(); + top->name = Name(std::string("forswitch$") + curr->name.str); + replaceCurrent(top); + } +}; + +static RegisterPass<LowerCase> registerPass("lower-case", "lowers cases into blocks"); + +} // namespace wasm diff --git a/test/passes/lower-case.txt b/test/passes/lower-case.txt new file mode 100644 index 000000000..82651da23 --- /dev/null +++ b/test/passes/lower-case.txt @@ -0,0 +1,88 @@ +(module + (memory 0) + (func $switcher (param $x i32) (result i32) + (block $forswitch$switch$0 + (block $switch-default$3 + (block $switch-case$2 + (block $switch-case$1 + (tableswitch $switch$0 + (i32.sub + (get_local $x) + (i32.const 1) + ) + (table (br $switch-case$1) (br $switch-case$2)) (br $switch-default$3) + ) + ) + (return + (i32.const 1) + ) + ) + (return + (i32.const 2) + ) + ) + (nop) + ) + (block $forswitch$switch$4 + (block $switch-default$7 + (block $switch-case$6 + (block $switch-case$5 + (tableswitch $switch$4 + (i32.sub + (get_local $x) + (i32.const 5) + ) + (table (br $switch-case$6) (br $switch-default$7) (br $switch-default$7) (br $switch-default$7) (br $switch-default$7) (br $switch-default$7) (br $switch-default$7) (br $switch-case$5)) (br $switch-default$7) + ) + ) + (return + (i32.const 121) + ) + ) + (return + (i32.const 51) + ) + ) + (nop) + ) + (block $forswitch$label$break$Lout + (block $switch-default$16 + (block $switch-case$15 + (block $switch-case$12 + (block $switch-case$9 + (block $switch-case$8 + (tableswitch $label$break$Lout + (i32.sub + (get_local $x) + (i32.const 2) + ) + (table (br $switch-case$15) (br $switch-default$16) (br $switch-default$16) (br $switch-case$12) (br $switch-default$16) (br $switch-default$16) (br $switch-default$16) (br $switch-default$16) (br $switch-case$9) (br $switch-default$16) (br $switch-case$8)) (br $switch-default$16) + ) + ) + (br $label$break$Lout) + ) + (br $label$break$Lout) + ) + (block $block0 + (loop $while-out$10 $while-in$11 + (br $while-out$10) + (br $while-in$11) + ) + (br $label$break$Lout) + ) + ) + (block $block1 + (loop $while-out$13 $while-in$14 + (br $label$break$Lout) + (br $while-in$14) + ) + (br $label$break$Lout) + ) + ) + (nop) + ) + (return + (i32.const 0) + ) + ) +) diff --git a/test/passes/lower-case.wast b/test/passes/lower-case.wast new file mode 100644 index 000000000..70cae71a9 --- /dev/null +++ b/test/passes/lower-case.wast @@ -0,0 +1,81 @@ +(module + (func $switcher (param $x i32) (result i32) + (tableswitch $switch$0 + (i32.sub + (get_local $x) + (i32.const 1) + ) + (table (case $switch-case$1) (case $switch-case$2)) (case $switch-default$3) + (case $switch-case$1 + (return + (i32.const 1) + ) + ) + (case $switch-case$2 + (return + (i32.const 2) + ) + ) + (case $switch-default$3 + (nop) + ) + ) + (tableswitch $switch$4 + (i32.sub + (get_local $x) + (i32.const 5) + ) + (table (case $switch-case$6) (case $switch-default$7) (case $switch-default$7) (case $switch-default$7) (case $switch-default$7) (case $switch-default$7) (case $switch-default$7) (case $switch-case$5)) (case $switch-default$7) + (case $switch-case$5 + (return + (i32.const 121) + ) + ) + (case $switch-case$6 + (return + (i32.const 51) + ) + ) + (case $switch-default$7 + (nop) + ) + ) + (tableswitch $label$break$Lout + (i32.sub + (get_local $x) + (i32.const 2) + ) + (table (case $switch-case$15) (case $switch-default$16) (case $switch-default$16) (case $switch-case$12) (case $switch-default$16) (case $switch-default$16) (case $switch-default$16) (case $switch-default$16) (case $switch-case$9) (case $switch-default$16) (case $switch-case$8)) (case $switch-default$16) + (case $switch-case$8 + (br $label$break$Lout) + ) + (case $switch-case$9 + (br $label$break$Lout) + ) + (case $switch-case$12 + (block + (loop $while-out$10 $while-in$11 + (br $while-out$10) + (br $while-in$11) + ) + (br $label$break$Lout) + ) + ) + (case $switch-case$15 + (block + (loop $while-out$13 $while-in$14 + (br $label$break$Lout) + (br $while-in$14) + ) + (br $label$break$Lout) + ) + ) + (case $switch-default$16 + (nop) + ) + ) + (return + (i32.const 0) + ) + ) +) |