summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-02-18 11:23:10 -0800
committerAlon Zakai <alonzakai@gmail.com>2016-02-18 11:23:10 -0800
commita684cff9e123db38eec9a6c7fbd423aed0b127ab (patch)
treee858880ef47ac17d7c972e10c145999c1a24d81d
parent849322a1135479f79f7d94b8b032486efe7955a8 (diff)
parent1f36e3a7ba07ba4460a2682805d259b19113727e (diff)
downloadbinaryen-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.txt1
-rw-r--r--src/passes/LowerCase.cpp102
-rw-r--r--test/passes/lower-case.txt88
-rw-r--r--test/passes/lower-case.wast81
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)
+ )
+ )
+)