From 365e6f239926e3da640014237b5420895ec247b9 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 19 Nov 2019 08:41:25 -0800 Subject: Optimize away invoke_ calls where possible (#2442) When we see invoke_ calls in emscripten-generated code, we know they call into JS just to do a try-catch for exceptions. If the target being called cannot throw, which we check in a whole-program manner, then we can simply skip the invoke. I confirmed that this fixes the regression in emscripten-core/emscripten#9817 (comment) (that is, with this optimization, upstream is around as fast as fastcomp). When we have native wasm exception handling, this can be extended to optimize that as well. --- test/passes/post-emscripten.wast | 71 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) (limited to 'test/passes/post-emscripten.wast') diff --git a/test/passes/post-emscripten.wast b/test/passes/post-emscripten.wast index f3656eebd..fe60858f7 100644 --- a/test/passes/post-emscripten.wast +++ b/test/passes/post-emscripten.wast @@ -1,7 +1,10 @@ (module - (memory 256 256) (type $0 (func (param i32))) (import "global.Math" "pow" (func $Math_pow (param f64 f64) (result f64))) + (import "env" "invoke_vif" (func $invoke_vif (param i32 i32 f32))) + (memory 256 256) + (table 7 7 funcref) + (elem (i32.const 0) $pow2 $pow.2 $exc $other_safe $other_unsafe $deep_safe $deep_unsafe) (func $pow2 (local $x f64) (local $y f64) @@ -57,4 +60,70 @@ ) ) ) + (func $exc + (call $invoke_vif + (i32.const 3) ;; other_safe() + (i32.const 42) + (f32.const 3.14159) + ) + (call $invoke_vif + (i32.const 4) ;; other_unsafe() + (i32.const 55) + (f32.const 2.18281828) + ) + (call $invoke_vif + (i32.const 5) ;; deep_safe() + (i32.const 100) + (f32.const 1.111) + ) + (call $invoke_vif + (i32.const 6) ;; deep_unsafe() + (i32.const 999) + (f32.const 1.414) + ) + (call $invoke_vif + (i32.add (i32.const 1) (i32.const 1)) ;; nonconstant + (i32.const 42) + (f32.const 3.14159) + ) + ) + (func $other_safe (param i32) (param f32) + ) + (func $other_unsafe (param i32) (param f32) + (drop + (call $Math_pow + (f64.const 1) + (f64.const 3) + ) + ) + ) + (func $deep_safe (param i32) (param f32) + (call $other_safe (unreachable) (unreachable)) + ) + (func $deep_unsafe (param i32) (param f32) + (call $other_unsafe (unreachable) (unreachable)) + ) +) +(module ;; no invokes + (func $call + (call $call) + ) +) +(module + (type $0 (func (param i32))) + (import "global.Math" "pow" (func $Math_pow (param f64 f64) (result f64))) + (import "env" "invoke_vif" (func $invoke_vif (param i32 i32 f32))) + (import "env" "glob" (global $glob i32)) ;; non-constant table offset + (memory 256 256) + (table 7 7 funcref) + (elem (global.get $glob) $other_safe) + (func $exc + (call $invoke_vif + (i32.const 3) ;; other_safe() + (i32.const 42) + (f32.const 3.14159) + ) + ) + (func $other_safe (param i32) (param f32) + ) ) -- cgit v1.2.3