diff options
-rw-r--r-- | src/passes/Precompute.cpp | 18 | ||||
-rw-r--r-- | src/passes/Vacuum.cpp | 15 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.txt | 136 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.txt.txt | 68 | ||||
-rw-r--r-- | test/passes/precompute.txt | 26 | ||||
-rw-r--r-- | test/passes/precompute.wast | 10 | ||||
-rw-r--r-- | test/passes/vacuum.txt | 20 | ||||
-rw-r--r-- | test/passes/vacuum.wast | 15 | ||||
m--------- | test/spec | 0 | ||||
-rw-r--r-- | test/unit.asm.js | 16 | ||||
-rw-r--r-- | test/unit.fromasm | 24 | ||||
-rw-r--r-- | test/unit.fromasm.imprecise | 24 | ||||
-rw-r--r-- | test/unit.fromasm.imprecise.no-opts | 16 | ||||
-rw-r--r-- | test/unit.fromasm.no-opts | 16 |
14 files changed, 138 insertions, 266 deletions
diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp index a341ba938..008058d58 100644 --- a/src/passes/Precompute.cpp +++ b/src/passes/Precompute.cpp @@ -15,23 +15,14 @@ */ // -// Removes dead, i.e. unreachable, code. -// -// We keep a record of when control flow is reachable. When it isn't, we -// kill (turn into unreachable). We then fold away entire unreachable -// expressions. -// -// When dead code causes an operation to not happen, like a store, a call -// or an add, we replace with a block with a list of what does happen. -// That isn't necessarily smaller, but blocks are friendlier to other -// optimizations: blocks can be merged and eliminated, and they clearly -// have no side effects. +// Computes code at compile time where possible. // #include <wasm.h> #include <pass.h> #include <wasm-builder.h> #include <wasm-interpreter.h> +#include <ast_utils.h> namespace wasm { @@ -90,7 +81,7 @@ struct Precompute : public WalkerPass<PostWalker<Precompute, UnifiedExpressionVi Pass* create() override { return new Precompute; } void visitExpression(Expression* curr) { - if (curr->is<Const>()) return; + if (curr->is<Const>() || curr->is<Nop>()) return; // try to evaluate this into a const Flow flow; try { @@ -99,8 +90,11 @@ struct Precompute : public WalkerPass<PostWalker<Precompute, UnifiedExpressionVi return; } if (flow.breaking()) return; // TODO: can create a break as a replacement in some cases (not NONSTANDALONE) + // this was precomputed if (isConcreteWasmType(flow.value.type)) { replaceCurrent(Builder(*getModule()).makeConst(flow.value)); + } else { + ExpressionManipulator::nop(curr); } } }; diff --git a/src/passes/Vacuum.cpp b/src/passes/Vacuum.cpp index 03becb04c..c3fed2328 100644 --- a/src/passes/Vacuum.cpp +++ b/src/passes/Vacuum.cpp @@ -186,6 +186,21 @@ struct Vacuum : public WalkerPass<ExpressionStackWalker<Vacuum, Visitor<Vacuum>> } void visitIf(If* curr) { + // if the condition is a constant, just apply it + // we can just return the ifTrue or ifFalse. + if (auto* value = curr->condition->dynCast<Const>()) { + if (value->value.getInteger()) { + replaceCurrent(curr->ifTrue); + return; + } else { + if (curr->ifFalse) { + replaceCurrent(curr->ifFalse); + } else { + ExpressionManipulator::nop(curr); + } + return; + } + } if (curr->ifFalse) { if (curr->ifFalse->is<Nop>()) { curr->ifFalse = nullptr; diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index b7b4821ac..b66982140 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -1054,29 +1054,12 @@ optimized: (br $shape$0$continue) ) ) - (func $split (type $v) - (call $check - (i32.const 0) - ) - (if - (i32.const 55) - (call $check - (i32.const 1) - ) - (call $check - (i32.const 2) - ) - ) - ) (func $if (type $v) (call $check (i32.const 0) ) - (if - (i32.const 55) - (call $check - (i32.const 1) - ) + (call $check + (i32.const 1) ) (call $check (i32.const 2) @@ -1086,14 +1069,8 @@ optimized: (call $check (i32.const 0) ) - (if - (i32.const 55) - (call $check - (i32.const 1) - ) - (call $check - (i32.const 2) - ) + (call $check + (i32.const 1) ) (call $check (i32.const 3) @@ -1108,10 +1085,7 @@ optimized: (call $check (i32.const 1) ) - (br_if $shape$0$continue - (i32.const 10) - ) - (br $block$3$break) + (br $shape$0$continue) ) ) (call $check @@ -1128,26 +1102,17 @@ optimized: (call $check (i32.const 1) ) - (br_if $block$7$break - (i32.const 0) - ) (call $check (i32.const 2) ) - (br_if $block$4$break - (i32.const -6) - ) - (br $shape$1$continue) + (br $block$4$break) ) ) (call $check (i32.const 3) ) - (if - (i32.const -10) - (call $check - (i32.const 4) - ) + (call $check + (i32.const 4) ) (call $check (i32.const 5) @@ -1162,23 +1127,6 @@ optimized: (i32.const 0) ) (block $switch$1$leave - (block $switch$1$default - (block $switch$1$case$3 - (block $switch$1$case$2 - (br_table $switch$1$default $switch$1$default $switch$1$case$2 $switch$1$default $switch$1$case$3 $switch$1$case$2 $switch$1$default - (i32.const -99) - ) - ) - (call $check - (i32.const 1) - ) - (br $switch$1$leave) - ) - (call $check - (i32.const 2) - ) - (br $switch$1$leave) - ) (call $check (i32.const 3) ) @@ -3113,29 +3061,12 @@ optimized: (br $shape$0$continue) ) ) - (func $split (type $v) - (call $check - (i32.const 0) - ) - (if - (i32.const 55) - (call $check - (i32.const 1) - ) - (call $check - (i32.const 2) - ) - ) - ) (func $if (type $v) (call $check (i32.const 0) ) - (if - (i32.const 55) - (call $check - (i32.const 1) - ) + (call $check + (i32.const 1) ) (call $check (i32.const 2) @@ -3145,14 +3076,8 @@ optimized: (call $check (i32.const 0) ) - (if - (i32.const 55) - (call $check - (i32.const 1) - ) - (call $check - (i32.const 2) - ) + (call $check + (i32.const 1) ) (call $check (i32.const 3) @@ -3167,10 +3092,7 @@ optimized: (call $check (i32.const 1) ) - (br_if $shape$0$continue - (i32.const 10) - ) - (br $block$3$break) + (br $shape$0$continue) ) ) (call $check @@ -3187,26 +3109,17 @@ optimized: (call $check (i32.const 1) ) - (br_if $block$7$break - (i32.const 0) - ) (call $check (i32.const 2) ) - (br_if $block$4$break - (i32.const -6) - ) - (br $shape$1$continue) + (br $block$4$break) ) ) (call $check (i32.const 3) ) - (if - (i32.const -10) - (call $check - (i32.const 4) - ) + (call $check + (i32.const 4) ) (call $check (i32.const 5) @@ -3221,23 +3134,6 @@ optimized: (i32.const 0) ) (block $switch$1$leave - (block $switch$1$default - (block $switch$1$case$3 - (block $switch$1$case$2 - (br_table $switch$1$default $switch$1$default $switch$1$case$2 $switch$1$default $switch$1$case$3 $switch$1$case$2 $switch$1$default - (i32.const -99) - ) - ) - (call $check - (i32.const 1) - ) - (br $switch$1$leave) - ) - (call $check - (i32.const 2) - ) - (br $switch$1$leave) - ) (call $check (i32.const 3) ) diff --git a/test/example/c-api-kitchen-sink.txt.txt b/test/example/c-api-kitchen-sink.txt.txt index a6f6e0853..b42c1ec34 100644 --- a/test/example/c-api-kitchen-sink.txt.txt +++ b/test/example/c-api-kitchen-sink.txt.txt @@ -1047,29 +1047,12 @@ (br $shape$0$continue) ) ) - (func $split (type $v) - (call $check - (i32.const 0) - ) - (if - (i32.const 55) - (call $check - (i32.const 1) - ) - (call $check - (i32.const 2) - ) - ) - ) (func $if (type $v) (call $check (i32.const 0) ) - (if - (i32.const 55) - (call $check - (i32.const 1) - ) + (call $check + (i32.const 1) ) (call $check (i32.const 2) @@ -1079,14 +1062,8 @@ (call $check (i32.const 0) ) - (if - (i32.const 55) - (call $check - (i32.const 1) - ) - (call $check - (i32.const 2) - ) + (call $check + (i32.const 1) ) (call $check (i32.const 3) @@ -1101,10 +1078,7 @@ (call $check (i32.const 1) ) - (br_if $shape$0$continue - (i32.const 10) - ) - (br $block$3$break) + (br $shape$0$continue) ) ) (call $check @@ -1121,26 +1095,17 @@ (call $check (i32.const 1) ) - (br_if $block$7$break - (i32.const 0) - ) (call $check (i32.const 2) ) - (br_if $block$4$break - (i32.const -6) - ) - (br $shape$1$continue) + (br $block$4$break) ) ) (call $check (i32.const 3) ) - (if - (i32.const -10) - (call $check - (i32.const 4) - ) + (call $check + (i32.const 4) ) (call $check (i32.const 5) @@ -1155,23 +1120,6 @@ (i32.const 0) ) (block $switch$1$leave - (block $switch$1$default - (block $switch$1$case$3 - (block $switch$1$case$2 - (br_table $switch$1$default $switch$1$default $switch$1$case$2 $switch$1$default $switch$1$case$3 $switch$1$case$2 $switch$1$default - (i32.const -99) - ) - ) - (call $check - (i32.const 1) - ) - (br $switch$1$leave) - ) - (call $check - (i32.const 2) - ) - (br $switch$1$leave) - ) (call $check (i32.const 3) ) diff --git a/test/passes/precompute.txt b/test/passes/precompute.txt index 9825594b6..cbf0f23a7 100644 --- a/test/passes/precompute.txt +++ b/test/passes/precompute.txt @@ -2,26 +2,28 @@ (memory 0) (type $0 (func (param i32))) (func $x (type $0) (param $x i32) - (drop - (i32.const 3) - ) + (nop) (drop (i32.add (i32.const 1) (get_local $x) ) ) - (drop - (i32.const 6) - ) - (drop - (i32.const -1) - ) - (drop - (i32.const 3) - ) + (nop) + (nop) + (nop) (loop $in (br $in) ) + (nop) + (block $c + (nop) + (call $x + (i32.const 4) + ) + (br_if $c + (i32.const 1) + ) + ) ) ) diff --git a/test/passes/precompute.wast b/test/passes/precompute.wast index 808485a34..e57522578 100644 --- a/test/passes/precompute.wast +++ b/test/passes/precompute.wast @@ -41,5 +41,15 @@ (loop $in (br $in) ) + (block $b + (br_if $b (i32.const 0)) + (br_if $b (i32.const 1)) + (call $x (i32.const 4)) + ) + (block $c + (br_if $c (i32.const 0)) + (call $x (i32.const 4)) + (br_if $c (i32.const 1)) + ) ) ) diff --git a/test/passes/vacuum.txt b/test/passes/vacuum.txt index 6b5d63b2a..73be2fea4 100644 --- a/test/passes/vacuum.txt +++ b/test/passes/vacuum.txt @@ -143,23 +143,24 @@ (unreachable) ) ) - (func $if-drop (type $0) + (func $if-drop (type $3) (result i32) (block $out (if - (i32.const 0) + (call $if-drop) (drop (call $int) ) (br $out) ) (if - (i32.const 1) + (call $if-drop) (br $out) (drop (call $int) ) ) ) + (i32.const 1) ) (func $drop-silly (type $0) (drop @@ -210,11 +211,22 @@ (func $if2drops (type $3) (result i32) (drop (if - (i32.const 1) + (call $if2drops) (call $if2drops) (call $if2drops) ) ) (i32.const 2) ) + (func $if-const (type $1) (param $x i32) + (call $if-const + (i32.const 3) + ) + (call $if-const + (i32.const 5) + ) + (call $if-const + (i32.const 7) + ) + ) ) diff --git a/test/passes/vacuum.wast b/test/passes/vacuum.wast index 3584df3ff..559deb971 100644 --- a/test/passes/vacuum.wast +++ b/test/passes/vacuum.wast @@ -299,21 +299,22 @@ (unreachable) ) ) - (func $if-drop + (func $if-drop (result i32) (block $out (drop - (if (i32.const 0) + (if (call $if-drop) (call $int) (br $out) ) ) (drop - (if (i32.const 1) + (if (call $if-drop) (br $out) (call $int) ) ) ) + (i32.const 1) ) (func $drop-silly (drop @@ -414,7 +415,7 @@ ) (func $if2drops (result i32) (if - (i32.const 1) + (call $if2drops) (drop (call $if2drops) ) @@ -424,4 +425,10 @@ ) (i32.const 2) ) + (func $if-const (param $x i32) + (if (i32.const 0) (call $if-const (i32.const 1))) + (if (i32.const 2) (call $if-const (i32.const 3))) + (if (i32.const 0) (call $if-const (i32.const 4)) (call $if-const (i32.const 5))) + (if (i32.const 6) (call $if-const (i32.const 7)) (call $if-const (i32.const 8))) + ) ) diff --git a/test/spec b/test/spec -Subproject 237f9ee630e951149e73d32633aa78616559519 +Subproject ef185d9cc6466f6d60c0117218f6d2144389676 diff --git a/test/unit.asm.js b/test/unit.asm.js index 7b4b2a96f..c3adb2a3a 100644 --- a/test/unit.asm.js +++ b/test/unit.asm.js @@ -205,7 +205,7 @@ function asm(global, env, buffer) { print(1); do { print(5); - if (0) continue; + if (return_int()) continue; } while (0); print(2); } @@ -266,7 +266,7 @@ function asm(global, env, buffer) { function smallIf() { do { - if (2) { + if (return_int() | 0) { lb(3) | 0; } else { break; @@ -275,7 +275,7 @@ function asm(global, env, buffer) { } function dropCall() { - if (0) { + if (return_int() | 0) { phi(); // drop this setTempRet0(10); // this too zeroInit(setTempRet0(10) | 0); @@ -328,8 +328,8 @@ function asm(global, env, buffer) { function conditionalTypeFun() { var x = 0, y = +0; - x = 1 ? abort(5) | 0 : 2; - y = 3 ? +abort(7) : 4.5; + x = return_int() | 0 ? abort(5) | 0 : 2; + y = return_int() | 0 ? +abort(7) : 4.5; } function loadSigned(x) { @@ -358,7 +358,7 @@ function asm(global, env, buffer) { Int = x; globalOpts(); x = Int; - if (1) Int = 20; // but this does interfere + if (return_int() | 0) Int = 20; // but this does interfere Int = x; globalOpts(); x = Int; @@ -367,7 +367,7 @@ function asm(global, env, buffer) { } function dropCallImport() { - if (1) return_int() | 0; + if (return_int() | 0) return_int() | 0; } function loophi(x, y) { @@ -399,7 +399,7 @@ function asm(global, env, buffer) { j = 0; while(1) { temp = j; - if (1) { + if (return_int() | 0) { if (temp) { i$lcssa = i; break L7; diff --git a/test/unit.fromasm b/test/unit.fromasm index 123e087e6..e08babd28 100644 --- a/test/unit.fromasm +++ b/test/unit.fromasm @@ -358,7 +358,7 @@ (i32.const 5) ) (br_if $unlikely-continue$3 - (i32.const 0) + (call $return_int) ) ) (call $print @@ -509,7 +509,7 @@ ) (func $smallIf (if - (i32.const 2) + (call $return_int) (drop (call $lb (i32.const 3) @@ -519,7 +519,7 @@ ) (func $dropCall (result i32) (if - (i32.const 0) + (call $return_int) (block (drop (call $phi) @@ -594,7 +594,7 @@ (func $conditionalTypeFun (drop (if - (i32.const 1) + (call $return_int) (i32.trunc_s/f64 (call $abort (f64.convert_s/i32 @@ -607,7 +607,7 @@ ) (drop (if - (i32.const 3) + (call $return_int) (call $abort (f64.convert_s/i32 (i32.const 7) @@ -696,7 +696,7 @@ (get_global $Int) ) (if - (i32.const 1) + (call $return_int) (set_global $Int (i32.const 20) ) @@ -715,7 +715,7 @@ ) (func $dropCallImport (if - (i32.const 1) + (call $return_int) (drop (call $return_int) ) @@ -768,7 +768,7 @@ (get_local $0) ) (if - (i32.const 1) + (call $return_int) (br_if $label$break$L7 (get_local $2) ) @@ -1013,13 +1013,7 @@ ) ) (func $jumpThreadDrop (result i32) - (local $0 i32) - (set_local $0 - (call $return_int) - ) - (block $jumpthreading$outer$2 - ) - (get_local $0) + (call $return_int) ) (func $dropIgnoredImportInIf (param $0 i32) (param $1 i32) (param $2 i32) (if diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise index b170c8b82..f99b02e82 100644 --- a/test/unit.fromasm.imprecise +++ b/test/unit.fromasm.imprecise @@ -339,7 +339,7 @@ (i32.const 5) ) (br_if $unlikely-continue$3 - (i32.const 0) + (call $return_int) ) ) (call $print @@ -490,7 +490,7 @@ ) (func $smallIf (if - (i32.const 2) + (call $return_int) (drop (call $lb (i32.const 3) @@ -500,7 +500,7 @@ ) (func $dropCall (result i32) (if - (i32.const 0) + (call $return_int) (block (drop (call $phi) @@ -575,7 +575,7 @@ (func $conditionalTypeFun (drop (if - (i32.const 1) + (call $return_int) (i32.trunc_s/f64 (call $abort (f64.convert_s/i32 @@ -588,7 +588,7 @@ ) (drop (if - (i32.const 3) + (call $return_int) (call $abort (f64.convert_s/i32 (i32.const 7) @@ -677,7 +677,7 @@ (get_global $Int) ) (if - (i32.const 1) + (call $return_int) (set_global $Int (i32.const 20) ) @@ -696,7 +696,7 @@ ) (func $dropCallImport (if - (i32.const 1) + (call $return_int) (drop (call $return_int) ) @@ -749,7 +749,7 @@ (get_local $0) ) (if - (i32.const 1) + (call $return_int) (br_if $label$break$L7 (get_local $2) ) @@ -994,13 +994,7 @@ ) ) (func $jumpThreadDrop (result i32) - (local $0 i32) - (set_local $0 - (call $return_int) - ) - (block $jumpthreading$outer$2 - ) - (get_local $0) + (call $return_int) ) (func $dropIgnoredImportInIf (param $0 i32) (param $1 i32) (param $2 i32) (if diff --git a/test/unit.fromasm.imprecise.no-opts b/test/unit.fromasm.imprecise.no-opts index 913920f8b..16a10861b 100644 --- a/test/unit.fromasm.imprecise.no-opts +++ b/test/unit.fromasm.imprecise.no-opts @@ -591,7 +591,7 @@ (i32.const 5) ) (if - (i32.const 0) + (call $return_int) (br $unlikely-continue$3) ) ) @@ -857,7 +857,7 @@ (func $smallIf (block $do-once$0 (if - (i32.const 2) + (call $return_int) (drop (call $lb (i32.const 3) @@ -870,7 +870,7 @@ ) (func $dropCall (result i32) (if - (i32.const 0) + (call $return_int) (block (drop (call $phi) @@ -986,7 +986,7 @@ (local $y f64) (set_local $x (if - (i32.const 1) + (call $return_int) (i32.trunc_s/f64 (call $abort (f64.convert_s/i32 @@ -999,7 +999,7 @@ ) (set_local $y (if - (i32.const 3) + (call $return_int) (call $abort (f64.convert_s/i32 (i32.const 7) @@ -1131,7 +1131,7 @@ (get_global $Int) ) (if - (i32.const 1) + (call $return_int) (set_global $Int (i32.const 20) ) @@ -1150,7 +1150,7 @@ ) (func $dropCallImport (if - (i32.const 1) + (call $return_int) (drop (call $return_int) ) @@ -1219,7 +1219,7 @@ (get_local $j) ) (if - (i32.const 1) + (call $return_int) (if (get_local $temp) (block diff --git a/test/unit.fromasm.no-opts b/test/unit.fromasm.no-opts index 21e7ea79e..58f63e66c 100644 --- a/test/unit.fromasm.no-opts +++ b/test/unit.fromasm.no-opts @@ -597,7 +597,7 @@ (i32.const 5) ) (if - (i32.const 0) + (call $return_int) (br $unlikely-continue$3) ) ) @@ -863,7 +863,7 @@ (func $smallIf (block $do-once$0 (if - (i32.const 2) + (call $return_int) (drop (call $lb (i32.const 3) @@ -876,7 +876,7 @@ ) (func $dropCall (result i32) (if - (i32.const 0) + (call $return_int) (block (drop (call $phi) @@ -992,7 +992,7 @@ (local $y f64) (set_local $x (if - (i32.const 1) + (call $return_int) (i32.trunc_s/f64 (call $abort (f64.convert_s/i32 @@ -1005,7 +1005,7 @@ ) (set_local $y (if - (i32.const 3) + (call $return_int) (call $abort (f64.convert_s/i32 (i32.const 7) @@ -1137,7 +1137,7 @@ (get_global $Int) ) (if - (i32.const 1) + (call $return_int) (set_global $Int (i32.const 20) ) @@ -1156,7 +1156,7 @@ ) (func $dropCallImport (if - (i32.const 1) + (call $return_int) (drop (call $return_int) ) @@ -1225,7 +1225,7 @@ (get_local $j) ) (if - (i32.const 1) + (call $return_int) (if (get_local $temp) (block |