diff options
-rw-r--r-- | src/ast_utils.h | 1 | ||||
-rw-r--r-- | src/passes/RemoveUnusedBrs.cpp | 7 | ||||
-rw-r--r-- | src/passes/pass.cpp | 2 | ||||
-rw-r--r-- | test/emcc_O2_hello_world.fromasm | 16 | ||||
-rw-r--r-- | test/emcc_O2_hello_world.fromasm.imprecise | 16 | ||||
-rw-r--r-- | test/emcc_hello_world.fromasm | 54 | ||||
-rw-r--r-- | test/emcc_hello_world.fromasm.imprecise | 54 | ||||
-rw-r--r-- | test/memorygrowth.fromasm | 16 | ||||
-rw-r--r-- | test/memorygrowth.fromasm.imprecise | 16 | ||||
-rw-r--r-- | test/passes/remove-unused-brs.txt | 41 | ||||
-rw-r--r-- | test/passes/remove-unused-brs.wast | 39 | ||||
-rw-r--r-- | test/unit.asm.js | 12 | ||||
-rw-r--r-- | test/unit.fromasm | 11 | ||||
-rw-r--r-- | test/unit.fromasm.imprecise | 11 | ||||
-rw-r--r-- | test/unit.fromasm.imprecise.no-opts | 24 | ||||
-rw-r--r-- | test/unit.fromasm.no-opts | 24 |
16 files changed, 247 insertions, 97 deletions
diff --git a/src/ast_utils.h b/src/ast_utils.h index 0c2c318e2..8952114bc 100644 --- a/src/ast_utils.h +++ b/src/ast_utils.h @@ -105,7 +105,6 @@ struct EffectAnalyzer : public PostWalker<EffectAnalyzer, Visitor<EffectAnalyzer || (accessesMemory() && (other.writesMemory || other.calls))) { return true; } - assert(localsWritten.size() + localsRead.size() <= 1); // the code below is fast on that case, of one element vs many for (auto local : localsWritten) { if (other.localsWritten.count(local) || other.localsRead.count(local)) { return true; diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp index ffdba0768..3f909c32e 100644 --- a/src/passes/RemoveUnusedBrs.cpp +++ b/src/passes/RemoveUnusedBrs.cpp @@ -128,6 +128,13 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<R // if without an else. try to reduce if (condition) br => br_if (condition) Break* br = curr->ifTrue->dynCast<Break>(); if (br && !br->condition) { // TODO: if there is a condition, join them + // if the br has a value, then if => br_if means we always execute the value, and also the order is value,condition vs condition,value + if (br->value) { + EffectAnalyzer value(br->value); + if (value.hasSideEffects()) return; + EffectAnalyzer condition(curr->condition); + if (condition.invalidates(value)) return; + } br->condition = curr->condition; replaceCurrent(br); anotherCycle = true; diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index e43b712e5..babb4635b 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -65,6 +65,7 @@ void PassRunner::addDefaultOptimizationPasses() { add("optimize-instructions"); add("simplify-locals"); add("vacuum"); // previous pass creates garbage + add("remove-unused-brs"); // simplify-locals opens opportunities for phi optimizations add("coalesce-locals"); add("vacuum"); // previous pass creates garbage add("reorder-locals"); @@ -81,6 +82,7 @@ void PassRunner::addDefaultFunctionOptimizationPasses() { add("optimize-instructions"); add("simplify-locals"); add("vacuum"); // previous pass creates garbage + add("remove-unused-brs"); // simplify-locals opens opportunities for phi optimizations add("coalesce-locals"); add("vacuum"); // previous pass creates garbage add("reorder-locals"); diff --git a/test/emcc_O2_hello_world.fromasm b/test/emcc_O2_hello_world.fromasm index ad3f945f3..acbeb2a0b 100644 --- a/test/emcc_O2_hello_world.fromasm +++ b/test/emcc_O2_hello_world.fromasm @@ -4682,14 +4682,12 @@ ) ) (block - (if + (br_if $do-once$67 + (i32.const 31) (i32.gt_u (get_local $0) (i32.const 16777215) ) - (br $do-once$67 - (i32.const 31) - ) ) (i32.or (i32.and @@ -8190,11 +8188,7 @@ ) ) (set_local $16 - (if - (i32.eq - (get_local $18) - (i32.const 2) - ) + (select (i32.const 0) (i32.sub (get_local $2) @@ -8202,6 +8196,10 @@ (get_local $17) ) ) + (i32.eq + (get_local $18) + (i32.const 2) + ) ) ) ) diff --git a/test/emcc_O2_hello_world.fromasm.imprecise b/test/emcc_O2_hello_world.fromasm.imprecise index ad3f945f3..acbeb2a0b 100644 --- a/test/emcc_O2_hello_world.fromasm.imprecise +++ b/test/emcc_O2_hello_world.fromasm.imprecise @@ -4682,14 +4682,12 @@ ) ) (block - (if + (br_if $do-once$67 + (i32.const 31) (i32.gt_u (get_local $0) (i32.const 16777215) ) - (br $do-once$67 - (i32.const 31) - ) ) (i32.or (i32.and @@ -8190,11 +8188,7 @@ ) ) (set_local $16 - (if - (i32.eq - (get_local $18) - (i32.const 2) - ) + (select (i32.const 0) (i32.sub (get_local $2) @@ -8202,6 +8196,10 @@ (get_local $17) ) ) + (i32.eq + (get_local $18) + (i32.const 2) + ) ) ) ) diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm index c7b334e7d..02e6d6002 100644 --- a/test/emcc_hello_world.fromasm +++ b/test/emcc_hello_world.fromasm @@ -1415,11 +1415,7 @@ ) ) (set_local $14 - (if - (i32.eq - (get_local $16) - (i32.const 2) - ) + (select (i32.const 0) (i32.sub (get_local $2) @@ -1427,6 +1423,10 @@ (get_local $15) ) ) + (i32.eq + (get_local $16) + (i32.const 2) + ) ) ) ) @@ -5422,19 +5422,7 @@ ) (br $while-in$61) ) - (if - (i32.eq - (i32.shr_s - (i32.shl - (i32.load8_s - (get_local $11) - ) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 45) - ) + (select (f64.neg (f64.add (get_local $29) @@ -5453,6 +5441,18 @@ ) (get_local $29) ) + (i32.eq + (i32.shr_s + (i32.shl + (i32.load8_s + (get_local $11) + ) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const 45) + ) ) ) ) @@ -5611,7 +5611,8 @@ (i32.const 1) ) (block - (if + (br_if $do-once$64 + (get_local $1) (i32.and (get_local $13) (i32.and @@ -5622,9 +5623,6 @@ ) ) ) - (br $do-once$64 - (get_local $1) - ) ) (i32.store8 (get_local $1) @@ -5999,14 +5997,12 @@ ) (br $while-in$73) ) - (if + (br_if $do-once$70 + (get_local $8) (i32.eq (get_local $5) (i32.const 0) ) - (br $do-once$70 - (get_local $8) - ) ) (i32.store (set_local $6 @@ -14941,14 +14937,12 @@ ) (i32.const 0) (block - (if + (br_if $do-once$69 + (i32.const 31) (i32.gt_u (get_local $4) (i32.const 16777215) ) - (br $do-once$69 - (i32.const 31) - ) ) (set_local $1 (i32.shl diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise index 29492cd2c..b7e3d5f59 100644 --- a/test/emcc_hello_world.fromasm.imprecise +++ b/test/emcc_hello_world.fromasm.imprecise @@ -1413,11 +1413,7 @@ ) ) (set_local $14 - (if - (i32.eq - (get_local $16) - (i32.const 2) - ) + (select (i32.const 0) (i32.sub (get_local $2) @@ -1425,6 +1421,10 @@ (get_local $15) ) ) + (i32.eq + (get_local $16) + (i32.const 2) + ) ) ) ) @@ -5420,19 +5420,7 @@ ) (br $while-in$61) ) - (if - (i32.eq - (i32.shr_s - (i32.shl - (i32.load8_s - (get_local $11) - ) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 45) - ) + (select (f64.neg (f64.add (get_local $29) @@ -5451,6 +5439,18 @@ ) (get_local $29) ) + (i32.eq + (i32.shr_s + (i32.shl + (i32.load8_s + (get_local $11) + ) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const 45) + ) ) ) ) @@ -5609,7 +5609,8 @@ (i32.const 1) ) (block - (if + (br_if $do-once$64 + (get_local $1) (i32.and (get_local $13) (i32.and @@ -5620,9 +5621,6 @@ ) ) ) - (br $do-once$64 - (get_local $1) - ) ) (i32.store8 (get_local $1) @@ -5997,14 +5995,12 @@ ) (br $while-in$73) ) - (if + (br_if $do-once$70 + (get_local $8) (i32.eq (get_local $5) (i32.const 0) ) - (br $do-once$70 - (get_local $8) - ) ) (i32.store (set_local $6 @@ -14939,14 +14935,12 @@ ) (i32.const 0) (block - (if + (br_if $do-once$69 + (i32.const 31) (i32.gt_u (get_local $4) (i32.const 16777215) ) - (br $do-once$69 - (i32.const 31) - ) ) (set_local $1 (i32.shl diff --git a/test/memorygrowth.fromasm b/test/memorygrowth.fromasm index 07909b855..3d3f9468b 100644 --- a/test/memorygrowth.fromasm +++ b/test/memorygrowth.fromasm @@ -4750,14 +4750,12 @@ ) ) (block - (if + (br_if $do-once$67 + (i32.const 31) (i32.gt_u (get_local $0) (i32.const 16777215) ) - (br $do-once$67 - (i32.const 31) - ) ) (i32.or (i32.and @@ -8245,11 +8243,7 @@ ) ) (set_local $16 - (if - (i32.eq - (get_local $18) - (i32.const 2) - ) + (select (i32.const 0) (i32.sub (get_local $2) @@ -8257,6 +8251,10 @@ (get_local $17) ) ) + (i32.eq + (get_local $18) + (i32.const 2) + ) ) ) ) diff --git a/test/memorygrowth.fromasm.imprecise b/test/memorygrowth.fromasm.imprecise index 07909b855..3d3f9468b 100644 --- a/test/memorygrowth.fromasm.imprecise +++ b/test/memorygrowth.fromasm.imprecise @@ -4750,14 +4750,12 @@ ) ) (block - (if + (br_if $do-once$67 + (i32.const 31) (i32.gt_u (get_local $0) (i32.const 16777215) ) - (br $do-once$67 - (i32.const 31) - ) ) (i32.or (i32.and @@ -8245,11 +8243,7 @@ ) ) (set_local $16 - (if - (i32.eq - (get_local $18) - (i32.const 2) - ) + (select (i32.const 0) (i32.sub (get_local $2) @@ -8257,6 +8251,10 @@ (get_local $17) ) ) + (i32.eq + (get_local $18) + (i32.const 2) + ) ) ) ) diff --git a/test/passes/remove-unused-brs.txt b/test/passes/remove-unused-brs.txt index a8e7f29be..c3ac71057 100644 --- a/test/passes/remove-unused-brs.txt +++ b/test/passes/remove-unused-brs.txt @@ -281,4 +281,45 @@ ) ) ) + (func $side-effects-and-order (result i32) + (local $x i32) + (block $do-once$0 + (br_if $do-once$0 + (i32.const 0) + (call $b13) + ) + (i32.const 1) + ) + (block $do-once$0 + (if + (call $b13) + (br $do-once$0 + (call $b14) + ) + ) + (i32.const 1) + ) + (block $do-once$0 + (if + (i32.const 0) + (br $do-once$0 + (call $b14) + ) + ) + (i32.const 1) + ) + (block $do-once$0 + (if + (set_local $x + (i32.const 1) + ) + (br $do-once$0 + (set_local $x + (i32.const 2) + ) + ) + ) + (i32.const 1) + ) + ) ) diff --git a/test/passes/remove-unused-brs.wast b/test/passes/remove-unused-brs.wast index 8b9d42bc1..b7dc1cc25 100644 --- a/test/passes/remove-unused-brs.wast +++ b/test/passes/remove-unused-brs.wast @@ -297,5 +297,44 @@ ) ) ) + (func $side-effects-and-order (result i32) + (local $x i32) + (block $do-once$0 + (if + (call $b13) + (br $do-once$0 + (i32.const 0) + ) + ) + (i32.const 1) + ) + (block $do-once$0 + (if + (call $b13) + (br $do-once$0 + (call $b14) + ) + ) + (i32.const 1) + ) + (block $do-once$0 + (if + (i32.const 0) + (br $do-once$0 + (call $b14) + ) + ) + (i32.const 1) + ) + (block $do-once$0 + (if + (set_local $x (i32.const 1)) + (br $do-once$0 + (set_local $x (i32.const 2)) + ) + ) + (i32.const 1) + ) + ) ) diff --git a/test/unit.asm.js b/test/unit.asm.js index 2f307e085..b0e4e7594 100644 --- a/test/unit.asm.js +++ b/test/unit.asm.js @@ -247,6 +247,18 @@ function asm(global, env, buffer) { } } + function phi() { + var x = 0; + do { + if (lb(1) | 0) { + x = 0; + break; + } + x = 1; + } while (0); + return x | 0; + } + function z() { } function w() { diff --git a/test/unit.fromasm b/test/unit.fromasm index 3fb76981d..38d8c2c67 100644 --- a/test/unit.fromasm +++ b/test/unit.fromasm @@ -453,4 +453,15 @@ ) ) ) + (func $phi (result i32) + (block $do-once$0 + (br_if $do-once$0 + (i32.const 0) + (call $lb + (i32.const 1) + ) + ) + (i32.const 1) + ) + ) ) diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise index a4716941d..b493c66d0 100644 --- a/test/unit.fromasm.imprecise +++ b/test/unit.fromasm.imprecise @@ -445,4 +445,15 @@ ) ) ) + (func $phi (result i32) + (block $do-once$0 + (br_if $do-once$0 + (i32.const 0) + (call $lb + (i32.const 1) + ) + ) + (i32.const 1) + ) + ) ) diff --git a/test/unit.fromasm.imprecise.no-opts b/test/unit.fromasm.imprecise.no-opts index c3da01359..9f49824f3 100644 --- a/test/unit.fromasm.imprecise.no-opts +++ b/test/unit.fromasm.imprecise.no-opts @@ -721,6 +721,30 @@ ) ) ) + (func $phi (result i32) + (local $x i32) + (block $do-once$0 + (block + (if + (call $lb + (i32.const 1) + ) + (block + (set_local $x + (i32.const 0) + ) + (br $do-once$0) + ) + ) + (set_local $x + (i32.const 1) + ) + ) + ) + (return + (get_local $x) + ) + ) (func $z (nop) ) diff --git a/test/unit.fromasm.no-opts b/test/unit.fromasm.no-opts index 92d2d2add..ccf89c5b6 100644 --- a/test/unit.fromasm.no-opts +++ b/test/unit.fromasm.no-opts @@ -725,6 +725,30 @@ ) ) ) + (func $phi (result i32) + (local $x i32) + (block $do-once$0 + (block + (if + (call $lb + (i32.const 1) + ) + (block + (set_local $x + (i32.const 0) + ) + (br $do-once$0) + ) + ) + (set_local $x + (i32.const 1) + ) + ) + ) + (return + (get_local $x) + ) + ) (func $z (nop) ) |