diff options
author | Alon Zakai <alonzakai@gmail.com> | 2015-11-01 15:50:59 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2015-11-01 15:50:59 -0800 |
commit | b66a85cb7379b1ec604cceed7af101227550d710 (patch) | |
tree | ca82d3b17e2d6a9cd277c54ac8fb9417bdd1f1b7 | |
parent | b2e067893efbe22132b210d5af9026b7bd59c270 (diff) | |
download | binaryen-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.h | 17 | ||||
-rw-r--r-- | test/emcc_O2_hello_world.wast | 98 | ||||
-rw-r--r-- | test/emcc_hello_world.wast | 346 | ||||
-rw-r--r-- | test/unit.wast | 8 |
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) |