| ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. |
| |
| ;; Test optimization decisions while varying the minimum benefit percentage |
| ;; parameter. Zero means any benefit, no matter how small, is worthwhile, while |
| ;; higher values demand more benefit before doing any work. |
| ;; |
| ;; Test with --traps-never-happen (tnh) here so that we optimize more, making it |
| ;; easier to show the effects. This is also more realistic for toolchains like |
| ;; Java/Kotlin/Dart, which is good coverage. |
| |
| ;; RUN: foreach %s %t wasm-opt --monomorphize -all -tnh -S -o - | filecheck %s --check-prefix DEFAULT |
| ;; RUN: foreach %s %t wasm-opt --monomorphize --pass-arg=monomorphize-min-benefit@0 -all -tnh -S -o - | filecheck %s --check-prefix ZERO___ |
| ;; RUN: foreach %s %t wasm-opt --monomorphize --pass-arg=monomorphize-min-benefit@33 -all -tnh -S -o - | filecheck %s --check-prefix THIRD__ |
| ;; RUN: foreach %s %t wasm-opt --monomorphize --pass-arg=monomorphize-min-benefit@66 -all -tnh -S -o - | filecheck %s --check-prefix TWOTRDS |
| ;; RUN: foreach %s %t wasm-opt --monomorphize --pass-arg=monomorphize-min-benefit@100 -all -tnh -S -o - | filecheck %s --check-prefix HUNDRED |
| |
| (module |
| (memory 10 20) |
| |
| ;; DEFAULT: (type $0 (func (param i32 i32 i32 i32 i32))) |
| |
| ;; DEFAULT: (type $1 (func (param i32))) |
| |
| ;; DEFAULT: (memory $0 10 20) |
| |
| ;; DEFAULT: (func $target (type $0) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) |
| ;; DEFAULT-NEXT: (i32.store |
| ;; DEFAULT-NEXT: (i32.const 10) |
| ;; DEFAULT-NEXT: (i32.div_s |
| ;; DEFAULT-NEXT: (local.get $0) |
| ;; DEFAULT-NEXT: (i32.add |
| ;; DEFAULT-NEXT: (local.get $0) |
| ;; DEFAULT-NEXT: (i32.const 1) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: (i32.store |
| ;; DEFAULT-NEXT: (i32.const 20) |
| ;; DEFAULT-NEXT: (i32.div_s |
| ;; DEFAULT-NEXT: (local.get $1) |
| ;; DEFAULT-NEXT: (i32.add |
| ;; DEFAULT-NEXT: (local.get $1) |
| ;; DEFAULT-NEXT: (i32.const 1) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: (i32.store |
| ;; DEFAULT-NEXT: (i32.const 30) |
| ;; DEFAULT-NEXT: (i32.div_s |
| ;; DEFAULT-NEXT: (local.get $2) |
| ;; DEFAULT-NEXT: (i32.add |
| ;; DEFAULT-NEXT: (local.get $2) |
| ;; DEFAULT-NEXT: (i32.const 1) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: (i32.store |
| ;; DEFAULT-NEXT: (i32.const 40) |
| ;; DEFAULT-NEXT: (i32.div_s |
| ;; DEFAULT-NEXT: (local.get $3) |
| ;; DEFAULT-NEXT: (i32.add |
| ;; DEFAULT-NEXT: (local.get $3) |
| ;; DEFAULT-NEXT: (i32.const 1) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: (i32.store |
| ;; DEFAULT-NEXT: (i32.const 50) |
| ;; DEFAULT-NEXT: (i32.div_s |
| ;; DEFAULT-NEXT: (local.get $4) |
| ;; DEFAULT-NEXT: (i32.add |
| ;; DEFAULT-NEXT: (local.get $4) |
| ;; DEFAULT-NEXT: (i32.const 1) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; ZERO___: (type $0 (func (param i32))) |
| |
| ;; ZERO___: (type $1 (func (param i32 i32 i32 i32 i32))) |
| |
| ;; ZERO___: (type $2 (func)) |
| |
| ;; ZERO___: (type $3 (func (param i32 i32))) |
| |
| ;; ZERO___: (type $4 (func (param i32 i32 i32))) |
| |
| ;; ZERO___: (type $5 (func (param i32 i32 i32 i32))) |
| |
| ;; ZERO___: (memory $0 10 20) |
| |
| ;; ZERO___: (func $target (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 10) |
| ;; ZERO___-NEXT: (i32.div_s |
| ;; ZERO___-NEXT: (local.get $0) |
| ;; ZERO___-NEXT: (i32.add |
| ;; ZERO___-NEXT: (local.get $0) |
| ;; ZERO___-NEXT: (i32.const 1) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 20) |
| ;; ZERO___-NEXT: (i32.div_s |
| ;; ZERO___-NEXT: (local.get $1) |
| ;; ZERO___-NEXT: (i32.add |
| ;; ZERO___-NEXT: (local.get $1) |
| ;; ZERO___-NEXT: (i32.const 1) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 30) |
| ;; ZERO___-NEXT: (i32.div_s |
| ;; ZERO___-NEXT: (local.get $2) |
| ;; ZERO___-NEXT: (i32.add |
| ;; ZERO___-NEXT: (local.get $2) |
| ;; ZERO___-NEXT: (i32.const 1) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 40) |
| ;; ZERO___-NEXT: (i32.div_s |
| ;; ZERO___-NEXT: (local.get $3) |
| ;; ZERO___-NEXT: (i32.add |
| ;; ZERO___-NEXT: (local.get $3) |
| ;; ZERO___-NEXT: (i32.const 1) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 50) |
| ;; ZERO___-NEXT: (i32.div_s |
| ;; ZERO___-NEXT: (local.get $4) |
| ;; ZERO___-NEXT: (i32.add |
| ;; ZERO___-NEXT: (local.get $4) |
| ;; ZERO___-NEXT: (i32.const 1) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; THIRD__: (type $0 (func (param i32))) |
| |
| ;; THIRD__: (type $1 (func (param i32 i32 i32 i32 i32))) |
| |
| ;; THIRD__: (type $2 (func)) |
| |
| ;; THIRD__: (type $3 (func (param i32 i32))) |
| |
| ;; THIRD__: (memory $0 10 20) |
| |
| ;; THIRD__: (func $target (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) |
| ;; THIRD__-NEXT: (i32.store |
| ;; THIRD__-NEXT: (i32.const 10) |
| ;; THIRD__-NEXT: (i32.div_s |
| ;; THIRD__-NEXT: (local.get $0) |
| ;; THIRD__-NEXT: (i32.add |
| ;; THIRD__-NEXT: (local.get $0) |
| ;; THIRD__-NEXT: (i32.const 1) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (i32.store |
| ;; THIRD__-NEXT: (i32.const 20) |
| ;; THIRD__-NEXT: (i32.div_s |
| ;; THIRD__-NEXT: (local.get $1) |
| ;; THIRD__-NEXT: (i32.add |
| ;; THIRD__-NEXT: (local.get $1) |
| ;; THIRD__-NEXT: (i32.const 1) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (i32.store |
| ;; THIRD__-NEXT: (i32.const 30) |
| ;; THIRD__-NEXT: (i32.div_s |
| ;; THIRD__-NEXT: (local.get $2) |
| ;; THIRD__-NEXT: (i32.add |
| ;; THIRD__-NEXT: (local.get $2) |
| ;; THIRD__-NEXT: (i32.const 1) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (i32.store |
| ;; THIRD__-NEXT: (i32.const 40) |
| ;; THIRD__-NEXT: (i32.div_s |
| ;; THIRD__-NEXT: (local.get $3) |
| ;; THIRD__-NEXT: (i32.add |
| ;; THIRD__-NEXT: (local.get $3) |
| ;; THIRD__-NEXT: (i32.const 1) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (i32.store |
| ;; THIRD__-NEXT: (i32.const 50) |
| ;; THIRD__-NEXT: (i32.div_s |
| ;; THIRD__-NEXT: (local.get $4) |
| ;; THIRD__-NEXT: (i32.add |
| ;; THIRD__-NEXT: (local.get $4) |
| ;; THIRD__-NEXT: (i32.const 1) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; TWOTRDS: (type $0 (func (param i32 i32 i32 i32 i32))) |
| |
| ;; TWOTRDS: (type $1 (func (param i32))) |
| |
| ;; TWOTRDS: (type $2 (func)) |
| |
| ;; TWOTRDS: (memory $0 10 20) |
| |
| ;; TWOTRDS: (func $target (type $0) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) |
| ;; TWOTRDS-NEXT: (i32.store |
| ;; TWOTRDS-NEXT: (i32.const 10) |
| ;; TWOTRDS-NEXT: (i32.div_s |
| ;; TWOTRDS-NEXT: (local.get $0) |
| ;; TWOTRDS-NEXT: (i32.add |
| ;; TWOTRDS-NEXT: (local.get $0) |
| ;; TWOTRDS-NEXT: (i32.const 1) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (i32.store |
| ;; TWOTRDS-NEXT: (i32.const 20) |
| ;; TWOTRDS-NEXT: (i32.div_s |
| ;; TWOTRDS-NEXT: (local.get $1) |
| ;; TWOTRDS-NEXT: (i32.add |
| ;; TWOTRDS-NEXT: (local.get $1) |
| ;; TWOTRDS-NEXT: (i32.const 1) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (i32.store |
| ;; TWOTRDS-NEXT: (i32.const 30) |
| ;; TWOTRDS-NEXT: (i32.div_s |
| ;; TWOTRDS-NEXT: (local.get $2) |
| ;; TWOTRDS-NEXT: (i32.add |
| ;; TWOTRDS-NEXT: (local.get $2) |
| ;; TWOTRDS-NEXT: (i32.const 1) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (i32.store |
| ;; TWOTRDS-NEXT: (i32.const 40) |
| ;; TWOTRDS-NEXT: (i32.div_s |
| ;; TWOTRDS-NEXT: (local.get $3) |
| ;; TWOTRDS-NEXT: (i32.add |
| ;; TWOTRDS-NEXT: (local.get $3) |
| ;; TWOTRDS-NEXT: (i32.const 1) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (i32.store |
| ;; TWOTRDS-NEXT: (i32.const 50) |
| ;; TWOTRDS-NEXT: (i32.div_s |
| ;; TWOTRDS-NEXT: (local.get $4) |
| ;; TWOTRDS-NEXT: (i32.add |
| ;; TWOTRDS-NEXT: (local.get $4) |
| ;; TWOTRDS-NEXT: (i32.const 1) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; HUNDRED: (type $0 (func (param i32 i32 i32 i32 i32))) |
| |
| ;; HUNDRED: (type $1 (func (param i32))) |
| |
| ;; HUNDRED: (memory $0 10 20) |
| |
| ;; HUNDRED: (func $target (type $0) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) |
| ;; HUNDRED-NEXT: (i32.store |
| ;; HUNDRED-NEXT: (i32.const 10) |
| ;; HUNDRED-NEXT: (i32.div_s |
| ;; HUNDRED-NEXT: (local.get $0) |
| ;; HUNDRED-NEXT: (i32.add |
| ;; HUNDRED-NEXT: (local.get $0) |
| ;; HUNDRED-NEXT: (i32.const 1) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: (i32.store |
| ;; HUNDRED-NEXT: (i32.const 20) |
| ;; HUNDRED-NEXT: (i32.div_s |
| ;; HUNDRED-NEXT: (local.get $1) |
| ;; HUNDRED-NEXT: (i32.add |
| ;; HUNDRED-NEXT: (local.get $1) |
| ;; HUNDRED-NEXT: (i32.const 1) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: (i32.store |
| ;; HUNDRED-NEXT: (i32.const 30) |
| ;; HUNDRED-NEXT: (i32.div_s |
| ;; HUNDRED-NEXT: (local.get $2) |
| ;; HUNDRED-NEXT: (i32.add |
| ;; HUNDRED-NEXT: (local.get $2) |
| ;; HUNDRED-NEXT: (i32.const 1) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: (i32.store |
| ;; HUNDRED-NEXT: (i32.const 40) |
| ;; HUNDRED-NEXT: (i32.div_s |
| ;; HUNDRED-NEXT: (local.get $3) |
| ;; HUNDRED-NEXT: (i32.add |
| ;; HUNDRED-NEXT: (local.get $3) |
| ;; HUNDRED-NEXT: (i32.const 1) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: (i32.store |
| ;; HUNDRED-NEXT: (i32.const 50) |
| ;; HUNDRED-NEXT: (i32.div_s |
| ;; HUNDRED-NEXT: (local.get $4) |
| ;; HUNDRED-NEXT: (i32.add |
| ;; HUNDRED-NEXT: (local.get $4) |
| ;; HUNDRED-NEXT: (i32.const 1) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| (func $target (param $a i32) (param $b i32) (param $c i32) (param $d i32) (param $e i32) |
| ;; This function takes five parameters and uses each one to do some work. In |
| ;; Each of the following identical stores, when we know one of the five |
| ;; params, we can compute in full the value stored. (The store offsets |
| ;; differ to guard against a future dead store elimination.) |
| (i32.store |
| (i32.const 10) |
| (i32.div_s |
| (local.get $a) |
| (i32.add |
| (local.get $a) |
| (i32.const 1) |
| ) |
| ) |
| ) |
| (i32.store |
| (i32.const 20) |
| (i32.div_s |
| (local.get $b) |
| (i32.add |
| (local.get $b) |
| (i32.const 1) |
| ) |
| ) |
| ) |
| (i32.store |
| (i32.const 30) |
| (i32.div_s |
| (local.get $c) |
| (i32.add |
| (local.get $c) |
| (i32.const 1) |
| ) |
| ) |
| ) |
| (i32.store |
| (i32.const 40) |
| (i32.div_s |
| (local.get $d) |
| (i32.add |
| (local.get $d) |
| (i32.const 1) |
| ) |
| ) |
| ) |
| (i32.store |
| (i32.const 50) |
| (i32.div_s |
| (local.get $e) |
| (i32.add |
| (local.get $e) |
| (i32.const 1) |
| ) |
| ) |
| ) |
| ) |
| |
| ;; DEFAULT: (func $calls (type $1) (param $x i32) |
| ;; DEFAULT-NEXT: (call $target |
| ;; DEFAULT-NEXT: (i32.const 42) |
| ;; DEFAULT-NEXT: (i32.const 42) |
| ;; DEFAULT-NEXT: (i32.const 42) |
| ;; DEFAULT-NEXT: (i32.const 42) |
| ;; DEFAULT-NEXT: (i32.const 42) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: (call $target |
| ;; DEFAULT-NEXT: (local.get $x) |
| ;; DEFAULT-NEXT: (i32.const 42) |
| ;; DEFAULT-NEXT: (i32.const 42) |
| ;; DEFAULT-NEXT: (i32.const 42) |
| ;; DEFAULT-NEXT: (i32.const 42) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: (call $target |
| ;; DEFAULT-NEXT: (local.get $x) |
| ;; DEFAULT-NEXT: (local.get $x) |
| ;; DEFAULT-NEXT: (i32.const 42) |
| ;; DEFAULT-NEXT: (i32.const 42) |
| ;; DEFAULT-NEXT: (i32.const 42) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: (call $target |
| ;; DEFAULT-NEXT: (local.get $x) |
| ;; DEFAULT-NEXT: (local.get $x) |
| ;; DEFAULT-NEXT: (local.get $x) |
| ;; DEFAULT-NEXT: (i32.const 42) |
| ;; DEFAULT-NEXT: (i32.const 42) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: (call $target |
| ;; DEFAULT-NEXT: (local.get $x) |
| ;; DEFAULT-NEXT: (local.get $x) |
| ;; DEFAULT-NEXT: (local.get $x) |
| ;; DEFAULT-NEXT: (local.get $x) |
| ;; DEFAULT-NEXT: (i32.const 42) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: (call $target |
| ;; DEFAULT-NEXT: (local.get $x) |
| ;; DEFAULT-NEXT: (local.get $x) |
| ;; DEFAULT-NEXT: (local.get $x) |
| ;; DEFAULT-NEXT: (local.get $x) |
| ;; DEFAULT-NEXT: (local.get $x) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; ZERO___: (func $calls (type $0) (param $x i32) |
| ;; ZERO___-NEXT: (call $target_2) |
| ;; ZERO___-NEXT: (call $target_3 |
| ;; ZERO___-NEXT: (local.get $x) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (call $target_4 |
| ;; ZERO___-NEXT: (local.get $x) |
| ;; ZERO___-NEXT: (local.get $x) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (call $target_5 |
| ;; ZERO___-NEXT: (local.get $x) |
| ;; ZERO___-NEXT: (local.get $x) |
| ;; ZERO___-NEXT: (local.get $x) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (call $target_6 |
| ;; ZERO___-NEXT: (local.get $x) |
| ;; ZERO___-NEXT: (local.get $x) |
| ;; ZERO___-NEXT: (local.get $x) |
| ;; ZERO___-NEXT: (local.get $x) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (call $target |
| ;; ZERO___-NEXT: (local.get $x) |
| ;; ZERO___-NEXT: (local.get $x) |
| ;; ZERO___-NEXT: (local.get $x) |
| ;; ZERO___-NEXT: (local.get $x) |
| ;; ZERO___-NEXT: (local.get $x) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; THIRD__: (func $calls (type $0) (param $x i32) |
| ;; THIRD__-NEXT: (call $target_2) |
| ;; THIRD__-NEXT: (call $target_3 |
| ;; THIRD__-NEXT: (local.get $x) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (call $target_4 |
| ;; THIRD__-NEXT: (local.get $x) |
| ;; THIRD__-NEXT: (local.get $x) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (call $target |
| ;; THIRD__-NEXT: (local.get $x) |
| ;; THIRD__-NEXT: (local.get $x) |
| ;; THIRD__-NEXT: (local.get $x) |
| ;; THIRD__-NEXT: (i32.const 42) |
| ;; THIRD__-NEXT: (i32.const 42) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (call $target |
| ;; THIRD__-NEXT: (local.get $x) |
| ;; THIRD__-NEXT: (local.get $x) |
| ;; THIRD__-NEXT: (local.get $x) |
| ;; THIRD__-NEXT: (local.get $x) |
| ;; THIRD__-NEXT: (i32.const 42) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (call $target |
| ;; THIRD__-NEXT: (local.get $x) |
| ;; THIRD__-NEXT: (local.get $x) |
| ;; THIRD__-NEXT: (local.get $x) |
| ;; THIRD__-NEXT: (local.get $x) |
| ;; THIRD__-NEXT: (local.get $x) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; TWOTRDS: (func $calls (type $1) (param $x i32) |
| ;; TWOTRDS-NEXT: (call $target_2) |
| ;; TWOTRDS-NEXT: (call $target |
| ;; TWOTRDS-NEXT: (local.get $x) |
| ;; TWOTRDS-NEXT: (i32.const 42) |
| ;; TWOTRDS-NEXT: (i32.const 42) |
| ;; TWOTRDS-NEXT: (i32.const 42) |
| ;; TWOTRDS-NEXT: (i32.const 42) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (call $target |
| ;; TWOTRDS-NEXT: (local.get $x) |
| ;; TWOTRDS-NEXT: (local.get $x) |
| ;; TWOTRDS-NEXT: (i32.const 42) |
| ;; TWOTRDS-NEXT: (i32.const 42) |
| ;; TWOTRDS-NEXT: (i32.const 42) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (call $target |
| ;; TWOTRDS-NEXT: (local.get $x) |
| ;; TWOTRDS-NEXT: (local.get $x) |
| ;; TWOTRDS-NEXT: (local.get $x) |
| ;; TWOTRDS-NEXT: (i32.const 42) |
| ;; TWOTRDS-NEXT: (i32.const 42) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (call $target |
| ;; TWOTRDS-NEXT: (local.get $x) |
| ;; TWOTRDS-NEXT: (local.get $x) |
| ;; TWOTRDS-NEXT: (local.get $x) |
| ;; TWOTRDS-NEXT: (local.get $x) |
| ;; TWOTRDS-NEXT: (i32.const 42) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (call $target |
| ;; TWOTRDS-NEXT: (local.get $x) |
| ;; TWOTRDS-NEXT: (local.get $x) |
| ;; TWOTRDS-NEXT: (local.get $x) |
| ;; TWOTRDS-NEXT: (local.get $x) |
| ;; TWOTRDS-NEXT: (local.get $x) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; HUNDRED: (func $calls (type $1) (param $x i32) |
| ;; HUNDRED-NEXT: (call $target |
| ;; HUNDRED-NEXT: (i32.const 42) |
| ;; HUNDRED-NEXT: (i32.const 42) |
| ;; HUNDRED-NEXT: (i32.const 42) |
| ;; HUNDRED-NEXT: (i32.const 42) |
| ;; HUNDRED-NEXT: (i32.const 42) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: (call $target |
| ;; HUNDRED-NEXT: (local.get $x) |
| ;; HUNDRED-NEXT: (i32.const 42) |
| ;; HUNDRED-NEXT: (i32.const 42) |
| ;; HUNDRED-NEXT: (i32.const 42) |
| ;; HUNDRED-NEXT: (i32.const 42) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: (call $target |
| ;; HUNDRED-NEXT: (local.get $x) |
| ;; HUNDRED-NEXT: (local.get $x) |
| ;; HUNDRED-NEXT: (i32.const 42) |
| ;; HUNDRED-NEXT: (i32.const 42) |
| ;; HUNDRED-NEXT: (i32.const 42) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: (call $target |
| ;; HUNDRED-NEXT: (local.get $x) |
| ;; HUNDRED-NEXT: (local.get $x) |
| ;; HUNDRED-NEXT: (local.get $x) |
| ;; HUNDRED-NEXT: (i32.const 42) |
| ;; HUNDRED-NEXT: (i32.const 42) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: (call $target |
| ;; HUNDRED-NEXT: (local.get $x) |
| ;; HUNDRED-NEXT: (local.get $x) |
| ;; HUNDRED-NEXT: (local.get $x) |
| ;; HUNDRED-NEXT: (local.get $x) |
| ;; HUNDRED-NEXT: (i32.const 42) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: (call $target |
| ;; HUNDRED-NEXT: (local.get $x) |
| ;; HUNDRED-NEXT: (local.get $x) |
| ;; HUNDRED-NEXT: (local.get $x) |
| ;; HUNDRED-NEXT: (local.get $x) |
| ;; HUNDRED-NEXT: (local.get $x) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| (func $calls (param $x i32) |
| ;; Call the target with an increasing amount of non-constant params, 0-5. |
| ;; |
| ;; With 5 unknowns, the call context is trivial and we do nothing. All the |
| ;; differences are therefore on 0-4: |
| ;; |
| ;; * ZERO monomorphizes all of 0-4. |
| ;; * THIRD monomorphizes only 0-2. |
| ;; * TWOTRDS monomorphizes just 0. |
| ;; * HUNDRED monomorphizes none at all. |
| |
| (call $target |
| (i32.const 42) |
| (i32.const 42) |
| (i32.const 42) |
| (i32.const 42) |
| (i32.const 42) |
| ) |
| (call $target |
| (local.get $x) |
| (i32.const 42) |
| (i32.const 42) |
| (i32.const 42) |
| (i32.const 42) |
| ) |
| (call $target |
| (local.get $x) |
| (local.get $x) |
| (i32.const 42) |
| (i32.const 42) |
| (i32.const 42) |
| ) |
| (call $target |
| (local.get $x) |
| (local.get $x) |
| (local.get $x) |
| (i32.const 42) |
| (i32.const 42) |
| ) |
| (call $target |
| (local.get $x) |
| (local.get $x) |
| (local.get $x) |
| (local.get $x) |
| (i32.const 42) |
| ) |
| (call $target |
| (local.get $x) |
| (local.get $x) |
| (local.get $x) |
| (local.get $x) |
| (local.get $x) |
| ) |
| ) |
| ) |
| |
| ;; ZERO___: (func $target_2 (type $2) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 10) |
| ;; ZERO___-NEXT: (i32.const 0) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 20) |
| ;; ZERO___-NEXT: (i32.const 0) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 30) |
| ;; ZERO___-NEXT: (i32.const 0) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 40) |
| ;; ZERO___-NEXT: (i32.const 0) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 50) |
| ;; ZERO___-NEXT: (i32.const 0) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| |
| ;; ZERO___: (func $target_3 (type $0) (param $0 i32) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 10) |
| ;; ZERO___-NEXT: (i32.div_s |
| ;; ZERO___-NEXT: (local.get $0) |
| ;; ZERO___-NEXT: (i32.add |
| ;; ZERO___-NEXT: (local.get $0) |
| ;; ZERO___-NEXT: (i32.const 1) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 20) |
| ;; ZERO___-NEXT: (i32.const 0) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 30) |
| ;; ZERO___-NEXT: (i32.const 0) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 40) |
| ;; ZERO___-NEXT: (i32.const 0) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 50) |
| ;; ZERO___-NEXT: (i32.const 0) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| |
| ;; ZERO___: (func $target_4 (type $3) (param $0 i32) (param $1 i32) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 10) |
| ;; ZERO___-NEXT: (i32.div_s |
| ;; ZERO___-NEXT: (local.get $0) |
| ;; ZERO___-NEXT: (i32.add |
| ;; ZERO___-NEXT: (local.get $0) |
| ;; ZERO___-NEXT: (i32.const 1) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 20) |
| ;; ZERO___-NEXT: (i32.div_s |
| ;; ZERO___-NEXT: (local.get $1) |
| ;; ZERO___-NEXT: (i32.add |
| ;; ZERO___-NEXT: (local.get $1) |
| ;; ZERO___-NEXT: (i32.const 1) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 30) |
| ;; ZERO___-NEXT: (i32.const 0) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 40) |
| ;; ZERO___-NEXT: (i32.const 0) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 50) |
| ;; ZERO___-NEXT: (i32.const 0) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| |
| ;; ZERO___: (func $target_5 (type $4) (param $0 i32) (param $1 i32) (param $2 i32) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 10) |
| ;; ZERO___-NEXT: (i32.div_s |
| ;; ZERO___-NEXT: (local.get $0) |
| ;; ZERO___-NEXT: (i32.add |
| ;; ZERO___-NEXT: (local.get $0) |
| ;; ZERO___-NEXT: (i32.const 1) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 20) |
| ;; ZERO___-NEXT: (i32.div_s |
| ;; ZERO___-NEXT: (local.get $1) |
| ;; ZERO___-NEXT: (i32.add |
| ;; ZERO___-NEXT: (local.get $1) |
| ;; ZERO___-NEXT: (i32.const 1) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 30) |
| ;; ZERO___-NEXT: (i32.div_s |
| ;; ZERO___-NEXT: (local.get $2) |
| ;; ZERO___-NEXT: (i32.add |
| ;; ZERO___-NEXT: (local.get $2) |
| ;; ZERO___-NEXT: (i32.const 1) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 40) |
| ;; ZERO___-NEXT: (i32.const 0) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 50) |
| ;; ZERO___-NEXT: (i32.const 0) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| |
| ;; ZERO___: (func $target_6 (type $5) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 10) |
| ;; ZERO___-NEXT: (i32.div_s |
| ;; ZERO___-NEXT: (local.get $0) |
| ;; ZERO___-NEXT: (i32.add |
| ;; ZERO___-NEXT: (local.get $0) |
| ;; ZERO___-NEXT: (i32.const 1) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 20) |
| ;; ZERO___-NEXT: (i32.div_s |
| ;; ZERO___-NEXT: (local.get $1) |
| ;; ZERO___-NEXT: (i32.add |
| ;; ZERO___-NEXT: (local.get $1) |
| ;; ZERO___-NEXT: (i32.const 1) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 30) |
| ;; ZERO___-NEXT: (i32.div_s |
| ;; ZERO___-NEXT: (local.get $2) |
| ;; ZERO___-NEXT: (i32.add |
| ;; ZERO___-NEXT: (local.get $2) |
| ;; ZERO___-NEXT: (i32.const 1) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 40) |
| ;; ZERO___-NEXT: (i32.div_s |
| ;; ZERO___-NEXT: (local.get $3) |
| ;; ZERO___-NEXT: (i32.add |
| ;; ZERO___-NEXT: (local.get $3) |
| ;; ZERO___-NEXT: (i32.const 1) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (i32.store |
| ;; ZERO___-NEXT: (i32.const 50) |
| ;; ZERO___-NEXT: (i32.const 0) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| |
| ;; THIRD__: (func $target_2 (type $2) |
| ;; THIRD__-NEXT: (i32.store |
| ;; THIRD__-NEXT: (i32.const 10) |
| ;; THIRD__-NEXT: (i32.const 0) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (i32.store |
| ;; THIRD__-NEXT: (i32.const 20) |
| ;; THIRD__-NEXT: (i32.const 0) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (i32.store |
| ;; THIRD__-NEXT: (i32.const 30) |
| ;; THIRD__-NEXT: (i32.const 0) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (i32.store |
| ;; THIRD__-NEXT: (i32.const 40) |
| ;; THIRD__-NEXT: (i32.const 0) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (i32.store |
| ;; THIRD__-NEXT: (i32.const 50) |
| ;; THIRD__-NEXT: (i32.const 0) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| |
| ;; THIRD__: (func $target_3 (type $0) (param $0 i32) |
| ;; THIRD__-NEXT: (i32.store |
| ;; THIRD__-NEXT: (i32.const 10) |
| ;; THIRD__-NEXT: (i32.div_s |
| ;; THIRD__-NEXT: (local.get $0) |
| ;; THIRD__-NEXT: (i32.add |
| ;; THIRD__-NEXT: (local.get $0) |
| ;; THIRD__-NEXT: (i32.const 1) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (i32.store |
| ;; THIRD__-NEXT: (i32.const 20) |
| ;; THIRD__-NEXT: (i32.const 0) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (i32.store |
| ;; THIRD__-NEXT: (i32.const 30) |
| ;; THIRD__-NEXT: (i32.const 0) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (i32.store |
| ;; THIRD__-NEXT: (i32.const 40) |
| ;; THIRD__-NEXT: (i32.const 0) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (i32.store |
| ;; THIRD__-NEXT: (i32.const 50) |
| ;; THIRD__-NEXT: (i32.const 0) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| |
| ;; THIRD__: (func $target_4 (type $3) (param $0 i32) (param $1 i32) |
| ;; THIRD__-NEXT: (i32.store |
| ;; THIRD__-NEXT: (i32.const 10) |
| ;; THIRD__-NEXT: (i32.div_s |
| ;; THIRD__-NEXT: (local.get $0) |
| ;; THIRD__-NEXT: (i32.add |
| ;; THIRD__-NEXT: (local.get $0) |
| ;; THIRD__-NEXT: (i32.const 1) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (i32.store |
| ;; THIRD__-NEXT: (i32.const 20) |
| ;; THIRD__-NEXT: (i32.div_s |
| ;; THIRD__-NEXT: (local.get $1) |
| ;; THIRD__-NEXT: (i32.add |
| ;; THIRD__-NEXT: (local.get $1) |
| ;; THIRD__-NEXT: (i32.const 1) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (i32.store |
| ;; THIRD__-NEXT: (i32.const 30) |
| ;; THIRD__-NEXT: (i32.const 0) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (i32.store |
| ;; THIRD__-NEXT: (i32.const 40) |
| ;; THIRD__-NEXT: (i32.const 0) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (i32.store |
| ;; THIRD__-NEXT: (i32.const 50) |
| ;; THIRD__-NEXT: (i32.const 0) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| |
| ;; TWOTRDS: (func $target_2 (type $2) |
| ;; TWOTRDS-NEXT: (i32.store |
| ;; TWOTRDS-NEXT: (i32.const 10) |
| ;; TWOTRDS-NEXT: (i32.const 0) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (i32.store |
| ;; TWOTRDS-NEXT: (i32.const 20) |
| ;; TWOTRDS-NEXT: (i32.const 0) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (i32.store |
| ;; TWOTRDS-NEXT: (i32.const 30) |
| ;; TWOTRDS-NEXT: (i32.const 0) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (i32.store |
| ;; TWOTRDS-NEXT: (i32.const 40) |
| ;; TWOTRDS-NEXT: (i32.const 0) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (i32.store |
| ;; TWOTRDS-NEXT: (i32.const 50) |
| ;; TWOTRDS-NEXT: (i32.const 0) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| (module |
| ;; DEFAULT: (type $A (sub (struct (field i32)))) |
| ;; ZERO___: (type $A (sub (struct (field i32)))) |
| ;; THIRD__: (type $A (sub (struct (field i32)))) |
| ;; TWOTRDS: (type $A (sub (struct (field i32)))) |
| ;; HUNDRED: (type $A (sub (struct (field i32)))) |
| (type $A (sub (struct (field i32)))) |
| |
| ;; DEFAULT: (type $1 (func)) |
| |
| ;; DEFAULT: (type $2 (func (param anyref) (result (ref $A)))) |
| |
| ;; DEFAULT: (type $3 (func (param anyref i32))) |
| |
| ;; DEFAULT: (type $4 (func (param (ref $A)))) |
| |
| ;; DEFAULT: (type $5 (func (param anyref))) |
| |
| ;; DEFAULT: (type $6 (func (param i32))) |
| |
| ;; DEFAULT: (import "a" "b" (func $import (type $1))) |
| ;; ZERO___: (type $1 (func)) |
| |
| ;; ZERO___: (type $2 (func (param anyref) (result (ref $A)))) |
| |
| ;; ZERO___: (type $3 (func (param anyref i32))) |
| |
| ;; ZERO___: (type $4 (func (param anyref))) |
| |
| ;; ZERO___: (type $5 (func (param i32) (result (ref $A)))) |
| |
| ;; ZERO___: (type $6 (func (param i32))) |
| |
| ;; ZERO___: (type $7 (func (result (ref $A)))) |
| |
| ;; ZERO___: (type $8 (func (param (ref $A)))) |
| |
| ;; ZERO___: (import "a" "b" (func $import (type $1))) |
| ;; THIRD__: (type $1 (func)) |
| |
| ;; THIRD__: (type $2 (func (param anyref) (result (ref $A)))) |
| |
| ;; THIRD__: (type $3 (func (param anyref i32))) |
| |
| ;; THIRD__: (type $4 (func (param (ref $A)))) |
| |
| ;; THIRD__: (type $5 (func (param anyref))) |
| |
| ;; THIRD__: (type $6 (func (param i32) (result (ref $A)))) |
| |
| ;; THIRD__: (type $7 (func (param i32))) |
| |
| ;; THIRD__: (type $8 (func (result (ref $A)))) |
| |
| ;; THIRD__: (import "a" "b" (func $import (type $1))) |
| ;; TWOTRDS: (type $1 (func)) |
| |
| ;; TWOTRDS: (type $2 (func (param anyref) (result (ref $A)))) |
| |
| ;; TWOTRDS: (type $3 (func (param anyref i32))) |
| |
| ;; TWOTRDS: (type $4 (func (param (ref $A)))) |
| |
| ;; TWOTRDS: (type $5 (func (param anyref))) |
| |
| ;; TWOTRDS: (type $6 (func (param i32))) |
| |
| ;; TWOTRDS: (import "a" "b" (func $import (type $1))) |
| ;; HUNDRED: (type $1 (func (param anyref) (result (ref $A)))) |
| |
| ;; HUNDRED: (type $2 (func (param anyref i32))) |
| |
| ;; HUNDRED: (type $3 (func)) |
| |
| ;; HUNDRED: (type $4 (func (param (ref $A)))) |
| |
| ;; HUNDRED: (import "a" "b" (func $import (type $3))) |
| (import "a" "b" (func $import)) |
| |
| ;; DEFAULT: (import "a" "c" (func $import2 (type $4) (param (ref $A)))) |
| ;; ZERO___: (import "a" "c" (func $import2 (type $8) (param (ref $A)))) |
| ;; THIRD__: (import "a" "c" (func $import2 (type $4) (param (ref $A)))) |
| ;; TWOTRDS: (import "a" "c" (func $import2 (type $4) (param (ref $A)))) |
| ;; HUNDRED: (import "a" "c" (func $import2 (type $4) (param (ref $A)))) |
| (import "a" "c" (func $import2 (param (ref $A)))) |
| |
| ;; DEFAULT: (func $target-long (type $2) (param $0 anyref) (result (ref $A)) |
| ;; DEFAULT-NEXT: (call $import) |
| ;; DEFAULT-NEXT: (call $import) |
| ;; DEFAULT-NEXT: (call $import) |
| ;; DEFAULT-NEXT: (call $import) |
| ;; DEFAULT-NEXT: (call $import) |
| ;; DEFAULT-NEXT: (call $import) |
| ;; DEFAULT-NEXT: (ref.cast (ref $A) |
| ;; DEFAULT-NEXT: (local.get $0) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; ZERO___: (func $target-long (type $2) (param $0 anyref) (result (ref $A)) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (ref.cast (ref $A) |
| ;; ZERO___-NEXT: (local.get $0) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; THIRD__: (func $target-long (type $2) (param $0 anyref) (result (ref $A)) |
| ;; THIRD__-NEXT: (call $import) |
| ;; THIRD__-NEXT: (call $import) |
| ;; THIRD__-NEXT: (call $import) |
| ;; THIRD__-NEXT: (call $import) |
| ;; THIRD__-NEXT: (call $import) |
| ;; THIRD__-NEXT: (call $import) |
| ;; THIRD__-NEXT: (ref.cast (ref $A) |
| ;; THIRD__-NEXT: (local.get $0) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; TWOTRDS: (func $target-long (type $2) (param $0 anyref) (result (ref $A)) |
| ;; TWOTRDS-NEXT: (call $import) |
| ;; TWOTRDS-NEXT: (call $import) |
| ;; TWOTRDS-NEXT: (call $import) |
| ;; TWOTRDS-NEXT: (call $import) |
| ;; TWOTRDS-NEXT: (call $import) |
| ;; TWOTRDS-NEXT: (call $import) |
| ;; TWOTRDS-NEXT: (ref.cast (ref $A) |
| ;; TWOTRDS-NEXT: (local.get $0) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; HUNDRED: (func $target-long (type $1) (param $0 anyref) (result (ref $A)) |
| ;; HUNDRED-NEXT: (call $import) |
| ;; HUNDRED-NEXT: (call $import) |
| ;; HUNDRED-NEXT: (call $import) |
| ;; HUNDRED-NEXT: (call $import) |
| ;; HUNDRED-NEXT: (call $import) |
| ;; HUNDRED-NEXT: (call $import) |
| ;; HUNDRED-NEXT: (ref.cast (ref $A) |
| ;; HUNDRED-NEXT: (local.get $0) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| (func $target-long (param $any anyref) (result (ref $A)) |
| ;; This function does a cast, aside from a lot of other work. The other work |
| ;; causes us to only optimize when we are ok with getting a very small % of |
| ;; improvement. |
| (call $import) |
| (call $import) |
| (call $import) |
| (call $import) |
| (call $import) |
| (call $import) |
| (ref.cast (ref $A) |
| (local.get $any) |
| ) |
| ) |
| |
| ;; DEFAULT: (func $target-short (type $2) (param $0 anyref) (result (ref $A)) |
| ;; DEFAULT-NEXT: (ref.cast (ref $A) |
| ;; DEFAULT-NEXT: (local.get $0) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; ZERO___: (func $target-short (type $2) (param $0 anyref) (result (ref $A)) |
| ;; ZERO___-NEXT: (ref.cast (ref $A) |
| ;; ZERO___-NEXT: (local.get $0) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; THIRD__: (func $target-short (type $2) (param $0 anyref) (result (ref $A)) |
| ;; THIRD__-NEXT: (ref.cast (ref $A) |
| ;; THIRD__-NEXT: (local.get $0) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; TWOTRDS: (func $target-short (type $2) (param $0 anyref) (result (ref $A)) |
| ;; TWOTRDS-NEXT: (ref.cast (ref $A) |
| ;; TWOTRDS-NEXT: (local.get $0) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; HUNDRED: (func $target-short (type $1) (param $0 anyref) (result (ref $A)) |
| ;; HUNDRED-NEXT: (ref.cast (ref $A) |
| ;; HUNDRED-NEXT: (local.get $0) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| (func $target-short (param $any anyref) (result (ref $A)) |
| ;; As above, but without all the work in the middle: this is really just a |
| ;; simple casting function, and we can remove almost all the work here when |
| ;; we remove the cast, meaning we optimize in more cases. |
| (ref.cast (ref $A) |
| (local.get $any) |
| ) |
| ) |
| |
| ;; DEFAULT: (func $calls-long (type $3) (param $x anyref) (param $y i32) |
| ;; DEFAULT-NEXT: (call $import2 |
| ;; DEFAULT-NEXT: (call $target-long |
| ;; DEFAULT-NEXT: (local.get $x) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: (drop |
| ;; DEFAULT-NEXT: (call $target-long |
| ;; DEFAULT-NEXT: (local.get $x) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: (call $import2 |
| ;; DEFAULT-NEXT: (call $target-long |
| ;; DEFAULT-NEXT: (struct.new $A |
| ;; DEFAULT-NEXT: (local.get $y) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: (drop |
| ;; DEFAULT-NEXT: (call $target-long |
| ;; DEFAULT-NEXT: (struct.new $A |
| ;; DEFAULT-NEXT: (local.get $y) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: (call $import2 |
| ;; DEFAULT-NEXT: (call $target-long |
| ;; DEFAULT-NEXT: (struct.new $A |
| ;; DEFAULT-NEXT: (i32.const 42) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: (drop |
| ;; DEFAULT-NEXT: (call $target-long |
| ;; DEFAULT-NEXT: (struct.new $A |
| ;; DEFAULT-NEXT: (i32.const 42) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; ZERO___: (func $calls-long (type $3) (param $x anyref) (param $y i32) |
| ;; ZERO___-NEXT: (call $import2 |
| ;; ZERO___-NEXT: (call $target-long |
| ;; ZERO___-NEXT: (local.get $x) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (call $target-long_6 |
| ;; ZERO___-NEXT: (local.get $x) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (call $import2 |
| ;; ZERO___-NEXT: (call $target-long_7 |
| ;; ZERO___-NEXT: (local.get $y) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (call $target-long_8 |
| ;; ZERO___-NEXT: (local.get $y) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (call $import2 |
| ;; ZERO___-NEXT: (call $target-long_9) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (call $target-long_10) |
| ;; ZERO___-NEXT: ) |
| ;; THIRD__: (func $calls-long (type $3) (param $x anyref) (param $y i32) |
| ;; THIRD__-NEXT: (call $import2 |
| ;; THIRD__-NEXT: (call $target-long |
| ;; THIRD__-NEXT: (local.get $x) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (drop |
| ;; THIRD__-NEXT: (call $target-long |
| ;; THIRD__-NEXT: (local.get $x) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (call $import2 |
| ;; THIRD__-NEXT: (call $target-long |
| ;; THIRD__-NEXT: (struct.new $A |
| ;; THIRD__-NEXT: (local.get $y) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (drop |
| ;; THIRD__-NEXT: (call $target-long |
| ;; THIRD__-NEXT: (struct.new $A |
| ;; THIRD__-NEXT: (local.get $y) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (call $import2 |
| ;; THIRD__-NEXT: (call $target-long |
| ;; THIRD__-NEXT: (struct.new $A |
| ;; THIRD__-NEXT: (i32.const 42) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (call $target-long_6) |
| ;; THIRD__-NEXT: ) |
| ;; TWOTRDS: (func $calls-long (type $3) (param $x anyref) (param $y i32) |
| ;; TWOTRDS-NEXT: (call $import2 |
| ;; TWOTRDS-NEXT: (call $target-long |
| ;; TWOTRDS-NEXT: (local.get $x) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (drop |
| ;; TWOTRDS-NEXT: (call $target-long |
| ;; TWOTRDS-NEXT: (local.get $x) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (call $import2 |
| ;; TWOTRDS-NEXT: (call $target-long |
| ;; TWOTRDS-NEXT: (struct.new $A |
| ;; TWOTRDS-NEXT: (local.get $y) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (drop |
| ;; TWOTRDS-NEXT: (call $target-long |
| ;; TWOTRDS-NEXT: (struct.new $A |
| ;; TWOTRDS-NEXT: (local.get $y) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (call $import2 |
| ;; TWOTRDS-NEXT: (call $target-long |
| ;; TWOTRDS-NEXT: (struct.new $A |
| ;; TWOTRDS-NEXT: (i32.const 42) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (drop |
| ;; TWOTRDS-NEXT: (call $target-long |
| ;; TWOTRDS-NEXT: (struct.new $A |
| ;; TWOTRDS-NEXT: (i32.const 42) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; HUNDRED: (func $calls-long (type $2) (param $x anyref) (param $y i32) |
| ;; HUNDRED-NEXT: (call $import2 |
| ;; HUNDRED-NEXT: (call $target-long |
| ;; HUNDRED-NEXT: (local.get $x) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: (drop |
| ;; HUNDRED-NEXT: (call $target-long |
| ;; HUNDRED-NEXT: (local.get $x) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: (call $import2 |
| ;; HUNDRED-NEXT: (call $target-long |
| ;; HUNDRED-NEXT: (struct.new $A |
| ;; HUNDRED-NEXT: (local.get $y) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: (drop |
| ;; HUNDRED-NEXT: (call $target-long |
| ;; HUNDRED-NEXT: (struct.new $A |
| ;; HUNDRED-NEXT: (local.get $y) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: (call $import2 |
| ;; HUNDRED-NEXT: (call $target-long |
| ;; HUNDRED-NEXT: (struct.new $A |
| ;; HUNDRED-NEXT: (i32.const 42) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: (drop |
| ;; HUNDRED-NEXT: (call $target-long |
| ;; HUNDRED-NEXT: (struct.new $A |
| ;; HUNDRED-NEXT: (i32.const 42) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| (func $calls-long (param $x anyref) (param $y i32) |
| ;; Various calls to $target-long. Because of the large amount of work that |
| ;; cannot be removed there, all we do here is: |
| ;; * Optimize in all cases when the minimum benefit is 0% (except the |
| ;; first call, which is a trivial call context). Removing a cast is |
| ;; enough to justify optimizing. |
| ;; * In 33% we optimize only the very last case. There we remove both a |
| ;; cast and a struct.new, which ends up just over 33%. |
| ;; * In 66% and 100% we optimize nothing at all. |
| |
| ;; Call with an unknown input and the output is sent to an import. |
| (call $import2 |
| (call $target-long |
| (local.get $x) |
| ) |
| ) |
| ;; Ditto, but drop the output. |
| (drop |
| (call $target-long |
| (local.get $x) |
| ) |
| ) |
| ;; Calls with a struct.new input. |
| (call $import2 |
| (call $target-long |
| (struct.new $A |
| (local.get $y) |
| ) |
| ) |
| ) |
| (drop |
| (call $target-long |
| (struct.new $A |
| (local.get $y) |
| ) |
| ) |
| ) |
| ;; Now the struct.new has a constant input. |
| (call $import2 |
| (call $target-long |
| (struct.new $A |
| (i32.const 42) |
| ) |
| ) |
| ) |
| (drop |
| (call $target-long |
| (struct.new $A |
| (i32.const 42) |
| ) |
| ) |
| ) |
| ) |
| |
| ;; DEFAULT: (func $calls-short (type $3) (param $x anyref) (param $y i32) |
| ;; DEFAULT-NEXT: (call $import2 |
| ;; DEFAULT-NEXT: (call $target-short |
| ;; DEFAULT-NEXT: (local.get $x) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: (call $target-short_6 |
| ;; DEFAULT-NEXT: (local.get $x) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: (call $import2 |
| ;; DEFAULT-NEXT: (call $target-short |
| ;; DEFAULT-NEXT: (struct.new $A |
| ;; DEFAULT-NEXT: (local.get $y) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: (call $target-short_7 |
| ;; DEFAULT-NEXT: (local.get $y) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: (call $import2 |
| ;; DEFAULT-NEXT: (call $target-short |
| ;; DEFAULT-NEXT: (struct.new $A |
| ;; DEFAULT-NEXT: (i32.const 42) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: ) |
| ;; DEFAULT-NEXT: (call $target-short_8) |
| ;; DEFAULT-NEXT: ) |
| ;; ZERO___: (func $calls-short (type $3) (param $x anyref) (param $y i32) |
| ;; ZERO___-NEXT: (call $import2 |
| ;; ZERO___-NEXT: (call $target-short |
| ;; ZERO___-NEXT: (local.get $x) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (call $target-short_11 |
| ;; ZERO___-NEXT: (local.get $x) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (call $import2 |
| ;; ZERO___-NEXT: (call $target-short_12 |
| ;; ZERO___-NEXT: (local.get $y) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (call $target-short_13 |
| ;; ZERO___-NEXT: (local.get $y) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (call $import2 |
| ;; ZERO___-NEXT: (call $target-short_14) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (call $target-short_15) |
| ;; ZERO___-NEXT: ) |
| ;; THIRD__: (func $calls-short (type $3) (param $x anyref) (param $y i32) |
| ;; THIRD__-NEXT: (call $import2 |
| ;; THIRD__-NEXT: (call $target-short |
| ;; THIRD__-NEXT: (local.get $x) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (call $target-short_7 |
| ;; THIRD__-NEXT: (local.get $x) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (call $import2 |
| ;; THIRD__-NEXT: (call $target-short_8 |
| ;; THIRD__-NEXT: (local.get $y) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (call $target-short_9 |
| ;; THIRD__-NEXT: (local.get $y) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (call $import2 |
| ;; THIRD__-NEXT: (call $target-short_10) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: (call $target-short_11) |
| ;; THIRD__-NEXT: ) |
| ;; TWOTRDS: (func $calls-short (type $3) (param $x anyref) (param $y i32) |
| ;; TWOTRDS-NEXT: (call $import2 |
| ;; TWOTRDS-NEXT: (call $target-short |
| ;; TWOTRDS-NEXT: (local.get $x) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (call $target-short_6 |
| ;; TWOTRDS-NEXT: (local.get $x) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (call $import2 |
| ;; TWOTRDS-NEXT: (call $target-short |
| ;; TWOTRDS-NEXT: (struct.new $A |
| ;; TWOTRDS-NEXT: (local.get $y) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (call $target-short_7 |
| ;; TWOTRDS-NEXT: (local.get $y) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (call $import2 |
| ;; TWOTRDS-NEXT: (call $target-short |
| ;; TWOTRDS-NEXT: (struct.new $A |
| ;; TWOTRDS-NEXT: (i32.const 42) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: ) |
| ;; TWOTRDS-NEXT: (call $target-short_8) |
| ;; TWOTRDS-NEXT: ) |
| ;; HUNDRED: (func $calls-short (type $2) (param $x anyref) (param $y i32) |
| ;; HUNDRED-NEXT: (call $import2 |
| ;; HUNDRED-NEXT: (call $target-short |
| ;; HUNDRED-NEXT: (local.get $x) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: (drop |
| ;; HUNDRED-NEXT: (call $target-short |
| ;; HUNDRED-NEXT: (local.get $x) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: (call $import2 |
| ;; HUNDRED-NEXT: (call $target-short |
| ;; HUNDRED-NEXT: (struct.new $A |
| ;; HUNDRED-NEXT: (local.get $y) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: (drop |
| ;; HUNDRED-NEXT: (call $target-short |
| ;; HUNDRED-NEXT: (struct.new $A |
| ;; HUNDRED-NEXT: (local.get $y) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: (call $import2 |
| ;; HUNDRED-NEXT: (call $target-short |
| ;; HUNDRED-NEXT: (struct.new $A |
| ;; HUNDRED-NEXT: (i32.const 42) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: (drop |
| ;; HUNDRED-NEXT: (call $target-short |
| ;; HUNDRED-NEXT: (struct.new $A |
| ;; HUNDRED-NEXT: (i32.const 42) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| ;; HUNDRED-NEXT: ) |
| (func $calls-short (param $x anyref) (param $y i32) |
| ;; As above, but now calling the short function: |
| ;; * 0% is the same with the long function: any improvement is enough. |
| ;; * 33% optimizes them all (but for the first, which is a trivial call |
| ;; context). |
| ;; * 66% optimizes a few less cases: when the output isn't dropped then we |
| ;; can't do enough work to justify it. |
| ;; * 100% optimizes nothing. |
| (call $import2 |
| (call $target-short |
| (local.get $x) |
| ) |
| ) |
| (drop |
| (call $target-short |
| (local.get $x) |
| ) |
| ) |
| (call $import2 |
| (call $target-short |
| (struct.new $A |
| (local.get $y) |
| ) |
| ) |
| ) |
| (drop |
| (call $target-short |
| (struct.new $A |
| (local.get $y) |
| ) |
| ) |
| ) |
| (call $import2 |
| (call $target-short |
| (struct.new $A |
| (i32.const 42) |
| ) |
| ) |
| ) |
| (drop |
| (call $target-short |
| (struct.new $A |
| (i32.const 42) |
| ) |
| ) |
| ) |
| ) |
| ) |
| ;; DEFAULT: (func $target-short_6 (type $5) (param $0 anyref) |
| ;; DEFAULT-NEXT: (nop) |
| ;; DEFAULT-NEXT: ) |
| |
| ;; DEFAULT: (func $target-short_7 (type $6) (param $0 i32) |
| ;; DEFAULT-NEXT: (nop) |
| ;; DEFAULT-NEXT: ) |
| |
| ;; DEFAULT: (func $target-short_8 (type $1) |
| ;; DEFAULT-NEXT: (nop) |
| ;; DEFAULT-NEXT: ) |
| |
| ;; ZERO___: (func $target-long_6 (type $4) (param $0 anyref) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: ) |
| |
| ;; ZERO___: (func $target-long_7 (type $5) (param $0 i32) (result (ref $A)) |
| ;; ZERO___-NEXT: (local $1 (ref $A)) |
| ;; ZERO___-NEXT: (local.set $1 |
| ;; ZERO___-NEXT: (struct.new $A |
| ;; ZERO___-NEXT: (local.get $0) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (local.get $1) |
| ;; ZERO___-NEXT: ) |
| |
| ;; ZERO___: (func $target-long_8 (type $6) (param $0 i32) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: ) |
| |
| ;; ZERO___: (func $target-long_9 (type $7) (result (ref $A)) |
| ;; ZERO___-NEXT: (local $0 (ref $A)) |
| ;; ZERO___-NEXT: (local.set $0 |
| ;; ZERO___-NEXT: (struct.new $A |
| ;; ZERO___-NEXT: (i32.const 42) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (local.get $0) |
| ;; ZERO___-NEXT: ) |
| |
| ;; ZERO___: (func $target-long_10 (type $1) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: (call $import) |
| ;; ZERO___-NEXT: ) |
| |
| ;; ZERO___: (func $target-short_11 (type $4) (param $0 anyref) |
| ;; ZERO___-NEXT: (nop) |
| ;; ZERO___-NEXT: ) |
| |
| ;; ZERO___: (func $target-short_12 (type $5) (param $0 i32) (result (ref $A)) |
| ;; ZERO___-NEXT: (struct.new $A |
| ;; ZERO___-NEXT: (local.get $0) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| |
| ;; ZERO___: (func $target-short_13 (type $6) (param $0 i32) |
| ;; ZERO___-NEXT: (nop) |
| ;; ZERO___-NEXT: ) |
| |
| ;; ZERO___: (func $target-short_14 (type $7) (result (ref $A)) |
| ;; ZERO___-NEXT: (struct.new $A |
| ;; ZERO___-NEXT: (i32.const 42) |
| ;; ZERO___-NEXT: ) |
| ;; ZERO___-NEXT: ) |
| |
| ;; ZERO___: (func $target-short_15 (type $1) |
| ;; ZERO___-NEXT: (nop) |
| ;; ZERO___-NEXT: ) |
| |
| ;; THIRD__: (func $target-long_6 (type $1) |
| ;; THIRD__-NEXT: (call $import) |
| ;; THIRD__-NEXT: (call $import) |
| ;; THIRD__-NEXT: (call $import) |
| ;; THIRD__-NEXT: (call $import) |
| ;; THIRD__-NEXT: (call $import) |
| ;; THIRD__-NEXT: (call $import) |
| ;; THIRD__-NEXT: ) |
| |
| ;; THIRD__: (func $target-short_7 (type $5) (param $0 anyref) |
| ;; THIRD__-NEXT: (nop) |
| ;; THIRD__-NEXT: ) |
| |
| ;; THIRD__: (func $target-short_8 (type $6) (param $0 i32) (result (ref $A)) |
| ;; THIRD__-NEXT: (struct.new $A |
| ;; THIRD__-NEXT: (local.get $0) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| |
| ;; THIRD__: (func $target-short_9 (type $7) (param $0 i32) |
| ;; THIRD__-NEXT: (nop) |
| ;; THIRD__-NEXT: ) |
| |
| ;; THIRD__: (func $target-short_10 (type $8) (result (ref $A)) |
| ;; THIRD__-NEXT: (struct.new $A |
| ;; THIRD__-NEXT: (i32.const 42) |
| ;; THIRD__-NEXT: ) |
| ;; THIRD__-NEXT: ) |
| |
| ;; THIRD__: (func $target-short_11 (type $1) |
| ;; THIRD__-NEXT: (nop) |
| ;; THIRD__-NEXT: ) |
| |
| ;; TWOTRDS: (func $target-short_6 (type $5) (param $0 anyref) |
| ;; TWOTRDS-NEXT: (nop) |
| ;; TWOTRDS-NEXT: ) |
| |
| ;; TWOTRDS: (func $target-short_7 (type $6) (param $0 i32) |
| ;; TWOTRDS-NEXT: (nop) |
| ;; TWOTRDS-NEXT: ) |
| |
| ;; TWOTRDS: (func $target-short_8 (type $1) |
| ;; TWOTRDS-NEXT: (nop) |
| ;; TWOTRDS-NEXT: ) |