summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2015-11-01 15:50:59 -0800
committerAlon Zakai <alonzakai@gmail.com>2015-11-01 15:50:59 -0800
commitb66a85cb7379b1ec604cceed7af101227550d710 (patch)
treeca82d3b17e2d6a9cd277c54ac8fb9417bdd1f1b7
parentb2e067893efbe22132b210d5af9026b7bd59c270 (diff)
downloadbinaryen-b66a85cb7379b1ec604cceed7af101227550d710.tar.gz
binaryen-b66a85cb7379b1ec604cceed7af101227550d710.tar.bz2
binaryen-b66a85cb7379b1ec604cceed7af101227550d710.zip
optimize away breaks at the end of a block to that same block
-rw-r--r--src/asm2wasm.h17
-rw-r--r--test/emcc_O2_hello_world.wast98
-rw-r--r--test/emcc_hello_world.wast346
-rw-r--r--test/unit.wast8
4 files changed, 174 insertions, 295 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h
index 94107ae78..448cf2f0f 100644
--- a/src/asm2wasm.h
+++ b/src/asm2wasm.h
@@ -1033,11 +1033,18 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
}
void Asm2WasmBuilder::optimize() {
- struct BlockRemover : public WasmWalker {
- BlockRemover() : WasmWalker(nullptr) {}
+ struct BlockBreakOptimizer : public WasmWalker {
+ BlockBreakOptimizer() : WasmWalker(nullptr) {}
Expression* visitBlock(Block *curr) override {
- if (curr->list.size() != 1) return curr;
+ if (curr->list.size() > 1) {
+ // we can't remove the block, but if it ends in a break on this very block, then just put the value there
+ Break *last = curr->list[curr->list.size()-1]->dyn_cast<Break>();
+ if (last && last->value && last->name == curr->name) {
+ curr->list[curr->list.size()-1] = last->value;
+ }
+ return curr;
+ }
// just one element; maybe we can return just the element
if (curr->name.isNull()) return curr->list[0];
// we might be broken to, but if it's a trivial singleton child break, we can optimize here as well
@@ -1064,9 +1071,9 @@ void Asm2WasmBuilder::optimize() {
}
};
- BlockRemover blockRemover;
+ BlockBreakOptimizer blockBreakOptimizer;
for (auto function : wasm.functions) {
- blockRemover.startWalk(function);
+ blockBreakOptimizer.startWalk(function);
}
}
diff --git a/test/emcc_O2_hello_world.wast b/test/emcc_O2_hello_world.wast
index 5c3562b7c..d767cc408 100644
--- a/test/emcc_O2_hello_world.wast
+++ b/test/emcc_O2_hello_world.wast
@@ -7555,9 +7555,7 @@
(set_local $i13
(i32.const 0)
)
- (break $topmost
- (get_local $i13)
- )
+ (get_local $i13)
)
)
(func $_free (param $i1 i32)
@@ -10410,9 +10408,7 @@
(i32.const 8)
(get_local $i4)
)
- (break $topmost
- (get_local $i24)
- )
+ (get_local $i24)
)
)
(func $___fwritex (param $i1 i32) (param $i2 i32) (param $i3 i32) (result i32)
@@ -10685,9 +10681,7 @@
)
)
)
- (break $topmost
- (get_local $i8)
- )
+ (get_local $i8)
)
)
(func $_fflush (param $i1 i32) (result i32)
@@ -10886,9 +10880,7 @@
)
)
)
- (break $topmost
- (get_local $i2)
- )
+ (get_local $i2)
)
)
(func $_strlen (param $i1 i32) (result i32)
@@ -11091,11 +11083,9 @@
)
)
)
- (break $topmost
- (i32.sub
- (get_local $i7)
- (get_local $i2)
- )
+ (i32.sub
+ (get_local $i7)
+ (get_local $i2)
)
)
)
@@ -11282,9 +11272,7 @@
(i32.const 8)
(get_local $i3)
)
- (break $topmost
- (get_local $i10)
- )
+ (get_local $i10)
)
)
(func $___fflush_unlocked (param $i1 i32) (result i32)
@@ -11425,9 +11413,7 @@
)
)
)
- (break $topmost
- (get_local $i4)
- )
+ (get_local $i4)
)
)
(func $_memcpy (param $i1 i32) (param $i2 i32) (param $i3 i32) (result i32)
@@ -11582,9 +11568,7 @@
)
)
)
- (break $topmost
- (get_local $i4)
- )
+ (get_local $i4)
)
)
(func $runPostSets
@@ -11738,11 +11722,9 @@
)
)
)
- (break $topmost
- (i32.sub
- (get_local $i1)
- (get_local $i3)
- )
+ (i32.sub
+ (get_local $i1)
+ (get_local $i3)
)
)
)
@@ -11870,14 +11852,12 @@
(get_local $i2)
)
)
- (break $topmost
- (i32.shr_s
- (i32.shl
- (get_local $i4)
- (i32.const 31)
- )
+ (i32.shr_s
+ (i32.shl
+ (get_local $i4)
(i32.const 31)
)
+ (i32.const 31)
)
)
)
@@ -11973,9 +11953,7 @@
(i32.const 8)
(get_local $i4)
)
- (break $topmost
- (get_local $i7)
- )
+ (get_local $i7)
)
)
(func $___towrite (param $i1 i32) (result i32)
@@ -12086,9 +12064,7 @@
)
)
)
- (break $topmost
- (get_local $i4)
- )
+ (get_local $i4)
)
)
(func $_fwrite (param $i1 i32) (param $i2 i32) (param $i3 i32) (param $i4 i32) (result i32)
@@ -12174,9 +12150,7 @@
)
)
)
- (break $topmost
- (get_local $i9)
- )
+ (get_local $i9)
)
)
(func $___stdout_write (param $i1 i32) (param $i2 i32) (param $i3 i32) (result i32)
@@ -12275,9 +12249,7 @@
(i32.const 8)
(get_local $i4)
)
- (break $topmost
- (get_local $i5)
- )
+ (get_local $i5)
)
)
(func $copyTempDouble (param $i1 i32)
@@ -12429,9 +12401,7 @@
(i32.const 8)
(get_local $i2)
)
- (break $topmost
- (get_local $i1)
- )
+ (get_local $i1)
)
)
(func $copyTempFloat (param $i1 i32)
@@ -12515,9 +12485,7 @@
(get_local $i1)
)
)
- (break $topmost
- (get_local $i2)
- )
+ (get_local $i2)
)
)
(func $dynCall_iiii (param $i1 i32) (param $i2 i32) (param $i3 i32) (param $i4 i32) (result i32)
@@ -12557,9 +12525,7 @@
(i32.const -16)
)
)
- (break $topmost
- (get_local $i2)
- )
+ (get_local $i2)
)
)
(func $___errno_location (result i32)
@@ -12584,9 +12550,7 @@
)
)
)
- (break $topmost
- (get_local $i1)
- )
+ (get_local $i1)
)
)
(func $setThrew (param $i1 i32) (param $i2 i32)
@@ -12669,9 +12633,7 @@
(func $b1 (param $i1 i32) (param $i2 i32) (param $i3 i32) (result i32)
(block $topmost
(nop)
- (break $topmost
- (i32.const 0)
- )
+ (i32.const 0)
)
)
(func $stackRestore (param $i1 i32)
@@ -12689,9 +12651,7 @@
(func $b0 (param $i1 i32) (result i32)
(block $topmost
(nop)
- (break $topmost
- (i32.const 0)
- )
+ (i32.const 0)
)
)
(func $___unlockfile (param $i1 i32)
@@ -12713,9 +12673,7 @@
(call $_puts
(i32.const 672)
)
- (break $topmost
- (i32.const 0)
- )
+ (i32.const 0)
)
)
(func $stackSave (result i32)
diff --git a/test/emcc_hello_world.wast b/test/emcc_hello_world.wast
index 6686b0762..d2813f141 100644
--- a/test/emcc_hello_world.wast
+++ b/test/emcc_hello_world.wast
@@ -66,9 +66,7 @@
)
(nop)
)
- (break $topmost
- (get_local $ret)
- )
+ (get_local $ret)
)
)
(func $stackSave (result i32)
@@ -334,9 +332,7 @@
(i32.const 8)
(get_local $sp)
)
- (break $topmost
- (i32.const 0)
- )
+ (i32.const 0)
)
)
(func $_frexp (param $$x f64) (param $$e i32) (result f64)
@@ -407,9 +403,7 @@
)
)
(nop)
- (break $topmost
- (get_local $$retval$0)
- )
+ (get_local $$retval$0)
)
)
(func $_frexpl (param $$x f64) (param $$e i32) (result f64)
@@ -428,9 +422,7 @@
(get_local $$e)
)
)
- (break $topmost
- (get_local $$call)
- )
+ (get_local $$call)
)
)
(func $_strerror (param $$e i32) (result i32)
@@ -655,9 +647,7 @@
)
)
)
- (break $topmost
- (get_local $$s$0$lcssa)
- )
+ (get_local $$s$0$lcssa)
)
)
(func $___errno_location (result i32)
@@ -711,9 +701,7 @@
)
)
)
- (break $topmost
- (get_local $$retval$0)
- )
+ (get_local $$retval$0)
)
)
(func $___stdio_close (param $$f i32) (result i32)
@@ -780,9 +768,7 @@
(i32.const 8)
(get_local $sp)
)
- (break $topmost
- (get_local $$call1)
- )
+ (get_local $$call1)
)
)
(func $___stdout_write (param $$f i32) (param $$buf i32) (param $$len i32) (result i32)
@@ -942,9 +928,7 @@
(i32.const 8)
(get_local $sp)
)
- (break $topmost
- (get_local $$call3)
- )
+ (get_local $$call3)
)
)
(func $___stdio_seek (param $$f i32) (param $$off i32) (param $$whence i32) (result i32)
@@ -1093,9 +1077,7 @@
(i32.const 8)
(get_local $sp)
)
- (break $topmost
- (get_local $$1)
- )
+ (get_local $$1)
)
)
(func $_fflush (param $$f i32) (result i32)
@@ -1428,9 +1410,7 @@
)
)
)
- (break $topmost
- (get_local $$retval$0)
- )
+ (get_local $$retval$0)
)
)
(func $_printf (param $$fmt i32) (param $$varargs i32) (result i32)
@@ -1488,9 +1468,7 @@
(i32.const 8)
(get_local $sp)
)
- (break $topmost
- (get_local $$call)
- )
+ (get_local $$call)
)
)
(func $___lockfile (param $$f i32) (result i32)
@@ -1502,9 +1480,7 @@
(i32.const 8)
)
)
- (break $topmost
- (i32.const 0)
- )
+ (i32.const 0)
)
)
(func $___unlockfile (param $$f i32)
@@ -2179,9 +2155,7 @@
(i32.const 8)
(get_local $sp)
)
- (break $topmost
- (get_local $$retval$0)
- )
+ (get_local $$retval$0)
)
)
(func $_vfprintf (param $$f i32) (param $$fmt i32) (param $$ap i32) (result i32)
@@ -2653,9 +2627,7 @@
(i32.const 8)
(get_local $sp)
)
- (break $topmost
- (get_local $$retval$0)
- )
+ (get_local $$retval$0)
)
)
(func $___fwritex (param $$s i32) (param $$l i32) (param $$f i32) (result i32)
@@ -3059,9 +3031,7 @@
)
)
)
- (break $topmost
- (get_local $$retval$0)
- )
+ (get_local $$retval$0)
)
)
(func $___towrite (param $$f i32) (result i32)
@@ -3258,9 +3228,7 @@
)
)
)
- (break $topmost
- (get_local $$retval$0)
- )
+ (get_local $$retval$0)
)
)
(func $_wcrtomb (param $$s i32) (param $$wc i32) (param $$st i32) (result i32)
@@ -3712,9 +3680,7 @@
)
)
)
- (break $topmost
- (get_local $$retval$0)
- )
+ (get_local $$retval$0)
)
)
(func $_wctomb (param $$s i32) (param $$wc i32) (result i32)
@@ -3753,9 +3719,7 @@
)
)
)
- (break $topmost
- (get_local $$retval$0)
- )
+ (get_local $$retval$0)
)
)
(func $_memchr (param $$src i32) (param $$c i32) (param $$n i32) (result i32)
@@ -4356,9 +4320,7 @@
(i32.const 0)
)
)
- (break $topmost
- (get_local $$cond)
- )
+ (get_local $$cond)
)
)
(func $___syscall_ret (param $$r i32) (result i32)
@@ -4407,9 +4369,7 @@
(get_local $$r)
)
)
- (break $topmost
- (get_local $$retval$0)
- )
+ (get_local $$retval$0)
)
)
(func $___fflush_unlocked (param $$f i32) (result i32)
@@ -4626,9 +4586,7 @@
)
)
)
- (break $topmost
- (get_local $$retval$0)
- )
+ (get_local $$retval$0)
)
)
(func $_cleanup (param $$p i32)
@@ -9180,9 +9138,7 @@
(i32.const 8)
(get_local $sp)
)
- (break $topmost
- (get_local $$retval$0)
- )
+ (get_local $$retval$0)
)
)
(func $_pop_arg_336 (param $$arg i32) (param $$type i32) (param $$ap i32)
@@ -9724,9 +9680,7 @@
)
)
)
- (break $topmost
- (get_local $$s$addr$1$lcssa)
- )
+ (get_local $$s$addr$1$lcssa)
)
)
(func $_pad (param $$f i32) (param $$c i32) (param $$w i32) (param $$l i32) (param $$fl i32)
@@ -21172,9 +21126,7 @@
(set_local $$retval$0
(i32.const 0)
)
- (break $topmost
- (get_local $$retval$0)
- )
+ (get_local $$retval$0)
)
)
(func $_free (param $$mem i32)
@@ -24742,14 +24694,12 @@
(i32.const 0)
)
)
- (break $topmost
- (block
- (i32.store align=4
- (i32.const 168)
- (get_local $h)
- )
- (get_local $l)
+ (block
+ (i32.store align=4
+ (i32.const 168)
+ (get_local $h)
)
+ (get_local $l)
)
)
)
@@ -24787,14 +24737,12 @@
(i32.const 0)
)
)
- (break $topmost
- (block
- (i32.store align=4
- (i32.const 168)
- (get_local $h)
- )
- (get_local $l)
+ (block
+ (i32.store align=4
+ (i32.const 168)
+ (get_local $h)
)
+ (get_local $l)
)
)
)
@@ -24946,11 +24894,9 @@
)
)
)
- (break $topmost
- (i32.sub
- (get_local $ptr)
- (get_local $num)
- )
+ (i32.sub
+ (get_local $ptr)
+ (get_local $num)
)
)
)
@@ -25003,13 +24949,11 @@
(i32.const 168)
(i32.const 0)
)
- (break $topmost
- (i32.shr_u
- (get_local $high)
- (i32.sub
- (get_local $bits)
- (i32.const 32)
- )
+ (i32.shr_u
+ (get_local $high)
+ (i32.sub
+ (get_local $bits)
+ (i32.const 32)
)
)
)
@@ -25075,9 +25019,7 @@
)
)
)
- (break $topmost
- (i32.const 0)
- )
+ (i32.const 0)
)
)
(func $_memcpy (param $dest i32) (param $src i32) (param $num i32) (result i32)
@@ -25232,9 +25174,7 @@
)
)
)
- (break $topmost
- (get_local $ret)
- )
+ (get_local $ret)
)
)
(func $_bitshift64Ashr (param $low i32) (param $high i32) (param $bits i32) (result i32)
@@ -25293,13 +25233,11 @@
(i32.const 0)
)
)
- (break $topmost
- (i32.shr_s
- (get_local $high)
- (i32.sub
- (get_local $bits)
- (i32.const 32)
- )
+ (i32.shr_s
+ (get_local $high)
+ (i32.sub
+ (get_local $bits)
+ (i32.const 32)
)
)
)
@@ -25385,21 +25323,19 @@
)
)
)
- (break $topmost
- (i32.add
- (i32.load8_s align=1
- (i32.add
- (i32.load align=4
- (i32.const 40)
- )
- (i32.shr_u
- (get_local $x)
- (i32.const 24)
- )
+ (i32.add
+ (i32.load8_s align=1
+ (i32.add
+ (i32.load align=4
+ (i32.const 40)
+ )
+ (i32.shr_u
+ (get_local $x)
+ (i32.const 24)
)
)
- (i32.const 24)
)
+ (i32.const 24)
)
)
)
@@ -25460,47 +25396,45 @@
(get_local $$1)
)
)
- (break $topmost
- (block
- (i32.store align=4
- (i32.const 168)
+ (block
+ (i32.store align=4
+ (i32.const 168)
+ (i32.add
(i32.add
- (i32.add
- (i32.shr_u
- (get_local $$8)
- (i32.const 16)
- )
- (i32.mul
- (get_local $$11)
- (get_local $$6)
- )
- )
(i32.shr_u
- (i32.add
- (i32.and
- (get_local $$8)
- (i32.const 65535)
- )
- (get_local $$12)
- )
+ (get_local $$8)
(i32.const 16)
)
+ (i32.mul
+ (get_local $$11)
+ (get_local $$6)
+ )
)
- )
- (i32.or
- (i32.const 0)
- (i32.or
- (i32.shl
- (i32.add
+ (i32.shr_u
+ (i32.add
+ (i32.and
(get_local $$8)
- (get_local $$12)
+ (i32.const 65535)
)
- (i32.const 16)
+ (get_local $$12)
)
- (i32.and
- (get_local $$3)
- (i32.const 65535)
+ (i32.const 16)
+ )
+ )
+ )
+ (i32.or
+ (i32.const 0)
+ (i32.or
+ (i32.shl
+ (i32.add
+ (get_local $$8)
+ (get_local $$12)
)
+ (i32.const 16)
+ )
+ (i32.and
+ (get_local $$3)
+ (i32.const 65535)
)
)
)
@@ -25682,9 +25616,7 @@
(get_local $$7$1)
)
)
- (break $topmost
- (get_local $$10$0)
- )
+ (get_local $$10$0)
)
)
(func $___remdi3 (param $$a$0 i32) (param $$a$1 i32) (param $$b$0 i32) (param $$b$1 i32) (result i32)
@@ -25879,14 +25811,12 @@
(i32.const 8)
(get_local $__stackBase__)
)
- (break $topmost
- (block
- (i32.store align=4
- (i32.const 168)
- (get_local $$10$1)
- )
- (get_local $$10$0)
+ (block
+ (i32.store align=4
+ (i32.const 168)
+ (get_local $$10$1)
)
+ (get_local $$10$0)
)
)
)
@@ -25920,35 +25850,33 @@
(get_local $$y_sroa_0_0_extract_trunc)
)
)
- (break $topmost
- (block
- (i32.store align=4
- (i32.const 168)
- (i32.or
+ (block
+ (i32.store align=4
+ (i32.const 168)
+ (i32.or
+ (i32.add
(i32.add
- (i32.add
- (i32.mul
- (get_local $$b$1)
- (get_local $$x_sroa_0_0_extract_trunc)
- )
- (get_local $$2)
+ (i32.mul
+ (get_local $$b$1)
+ (get_local $$x_sroa_0_0_extract_trunc)
)
- (get_local $$1$1)
- )
- (i32.and
- (get_local $$1$1)
- (i32.const 0)
+ (get_local $$2)
)
+ (get_local $$1$1)
)
- )
- (i32.or
- (i32.const 0)
(i32.and
- (get_local $$1$0)
- (i32.const -1)
+ (get_local $$1$1)
+ (i32.const 0)
)
)
)
+ (i32.or
+ (i32.const 0)
+ (i32.and
+ (get_local $$1$0)
+ (i32.const -1)
+ )
+ )
)
)
)
@@ -25964,9 +25892,7 @@
(i32.const 0)
)
)
- (break $topmost
- (get_local $$1$0)
- )
+ (get_local $$1$0)
)
)
(func $___uremdi3 (param $$a$0 i32) (param $$a$1 i32) (param $$b$0 i32) (param $$b$1 i32) (result i32)
@@ -26001,21 +25927,19 @@
(i32.const 8)
(get_local $__stackBase__)
)
- (break $topmost
- (block
- (i32.store align=4
- (i32.const 168)
- (i32.load align=4
- (i32.add
- (get_local $$rem)
- (i32.const 4)
- )
- )
- )
+ (block
+ (i32.store align=4
+ (i32.const 168)
(i32.load align=4
- (get_local $$rem)
+ (i32.add
+ (get_local $$rem)
+ (i32.const 4)
+ )
)
)
+ (i32.load align=4
+ (get_local $$rem)
+ )
)
)
)
@@ -27350,14 +27274,12 @@
(get_local $$carry_0_lcssa$0)
)
)
- (break $topmost
- (block
- (i32.store align=4
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
+ (block
+ (i32.store align=4
+ (i32.const 168)
+ (get_local $$_0$1)
)
+ (get_local $$_0$0)
)
)
)
@@ -27384,17 +27306,13 @@
(func $b0 (param $p0 i32) (result i32)
(block $topmost
(nop)
- (break $topmost
- (i32.const 0)
- )
+ (i32.const 0)
)
)
(func $b1 (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32)
(block $topmost
(nop)
- (break $topmost
- (i32.const 0)
- )
+ (i32.const 0)
)
)
(func $b2 (param $p0 i32)
diff --git a/test/unit.wast b/test/unit.wast
index b331fa74e..4f68a6a33 100644
--- a/test/unit.wast
+++ b/test/unit.wast
@@ -73,9 +73,7 @@
(f64.const 5.6)
)
)
- (break $topmost
- (f64.const 1.2)
- )
+ (f64.const 1.2)
)
)
(func $doubleCompares (param $x f64) (param $y f64) (result f64)
@@ -119,9 +117,7 @@
(get_local $x)
)
)
- (break $topmost
- (get_local $y)
- )
+ (get_local $y)
)
)
(func $intOps (result i32)