summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/Precompute.cpp18
-rw-r--r--src/passes/Vacuum.cpp15
-rw-r--r--test/example/c-api-kitchen-sink.txt136
-rw-r--r--test/example/c-api-kitchen-sink.txt.txt68
-rw-r--r--test/passes/precompute.txt26
-rw-r--r--test/passes/precompute.wast10
-rw-r--r--test/passes/vacuum.txt20
-rw-r--r--test/passes/vacuum.wast15
m---------test/spec0
-rw-r--r--test/unit.asm.js16
-rw-r--r--test/unit.fromasm24
-rw-r--r--test/unit.fromasm.imprecise24
-rw-r--r--test/unit.fromasm.imprecise.no-opts16
-rw-r--r--test/unit.fromasm.no-opts16
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