Try fixing DAE
diff --git a/src/passes/param-utils.cpp b/src/passes/param-utils.cpp index 6861756..f4381a0 100644 --- a/src/passes/param-utils.cpp +++ b/src/passes/param-utils.cpp
@@ -262,6 +262,19 @@ continue; } + // If the parameter is not used in any of the functions, writing the + // constant value to it is redundant and creates a dead local set. + bool used = false; + for (auto* func : funcs) { + if (getUsedParams(func, module).count(i)) { + used = true; + break; + } + } + if (!used) { + continue; + } + // Optimize: write the constant value in the function bodies, making them // ignore the parameter's value. Builder builder(*module);
diff --git a/test/lit/passes/dae-gc.wast b/test/lit/passes/dae-gc.wast index ec0136a..b4abdd4 100644 --- a/test/lit/passes/dae-gc.wast +++ b/test/lit/passes/dae-gc.wast
@@ -17,22 +17,15 @@ ) ;; CHECK: (func $bar (type $0) ;; CHECK-NEXT: (local $0 i31ref) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (ref.i31 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (ref.i31 - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (ref.i31 + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $bar (param $0 i31ref) @@ -186,15 +179,7 @@ ;; CHECK: (func $1 (type $0) ;; CHECK-NEXT: (local $0 (ref string)) ;; CHECK-NEXT: (local $1 (ref string)) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (string.const "929") - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (string.const "310") - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $1 (param $0 (ref string)) (param $1 (ref string)) ;; The parameters here will be removed, and the constant values placed in the
diff --git a/test/lit/passes/dae-typessa-repeat-types.wast b/test/lit/passes/dae-typessa-repeat-types.wast index 7072d21..a50300f 100644 --- a/test/lit/passes/dae-typessa-repeat-types.wast +++ b/test/lit/passes/dae-typessa-repeat-types.wast
@@ -11,11 +11,11 @@ ;; Trigger TypeSSA ;; CHECK: (type $2 (func)) - ;; CHECK: (type $3 (func (result i32 (ref (exact $struct))))) - ;; CHECK: (type $array_1 (sub $array (array (mut i32)))) - ;; CHECK: (type $5 (func (result i32 (ref $struct)))) + ;; CHECK: (type $4 (func (result i32 (ref $struct)))) + + ;; CHECK: (type $5 (func (result i32 (ref (exact $struct))))) ;; CHECK: (global $array (ref $array) (array.new $array_1 ;; CHECK-NEXT: (i32.const 0) @@ -43,15 +43,10 @@ ;; CHECK: (func $callee (type $2) ;; CHECK-NEXT: (local $0 anyref) ;; CHECK-NEXT: (tuple.drop 2 - ;; CHECK-NEXT: (block (type $3) (result i32 (ref (exact $struct))) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (type $3) (result i32 (ref (exact $struct))) - ;; CHECK-NEXT: (tuple.make 2 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (struct.new_default $struct) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (type $5) (result i32 (ref (exact $struct))) + ;; CHECK-NEXT: (tuple.make 2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (struct.new_default $struct) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -67,7 +62,7 @@ ) ) - ;; CHECK: (func $other (type $5) (result i32 (ref $struct)) + ;; CHECK: (func $other (type $4) (result i32 (ref $struct)) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) (func $other (result i32 (ref $struct))
diff --git a/test/lit/passes/dae_all-features.wast b/test/lit/passes/dae_all-features.wast index 41bcb73..5cb0f03 100644 --- a/test/lit/passes/dae_all-features.wast +++ b/test/lit/passes/dae_all-features.wast
@@ -30,11 +30,6 @@ (elem (i32.const 0) $a9 $c8) ;; CHECK: (func $a (type $0) ;; CHECK-NEXT: (local $0 i32) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $a (param $x i32)) ;; CHECK: (func $b (type $0) @@ -45,9 +40,6 @@ ) ;; CHECK: (func $a1 (type $0) ;; CHECK-NEXT: (local $0 i32) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) (func $a1 (param $x i32) @@ -112,11 +104,6 @@ ) ;; CHECK: (func $a4 (type $0) ;; CHECK-NEXT: (local $0 i32) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $a4 (param $x i32) ;; This function is called with one constant and one unreachable. We can @@ -244,13 +231,8 @@ ) ;; CHECK: (func $a10 (type $0) ;; CHECK-NEXT: (local $0 i32) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $a10) - ;; CHECK-NEXT: (call $a10) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $a10) + ;; CHECK-NEXT: (call $a10) ;; CHECK-NEXT: ) (func $a10 (param $x i32) ;; recursion (call $a10 (i32.const 1)) @@ -417,9 +399,6 @@ ) ;; CHECK: (func $bar (type $1) (result i32) ;; CHECK-NEXT: (local $0 i32) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 7) ;; CHECK-NEXT: ) (func $bar (param $x i32) (result i32) @@ -436,9 +415,6 @@ ;; CHECK: (func $foo (type $T) (result i32) ;; CHECK-NEXT: (local $0 i32) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 42) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (return_call_indirect $0 (type $T) ;; CHECK-NEXT: (i32.const 0) @@ -537,11 +513,6 @@ ;; CHECK: (func $0 (type $0) ;; CHECK-NEXT: (local $0 i31ref) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (ref.i31 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $0 (param $x i31ref) @@ -674,22 +645,17 @@ ;; CHECK: (func $0 (type $0) ;; CHECK-NEXT: (local $0 i32) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return) ;; CHECK-NEXT: ) (func $0 (param $0 i32) (result i32) ;; The returns here are nested in each other, and one is a recursive call to @@ -840,15 +806,7 @@ ;; CHECK-NEXT: (local $0 i64) ;; CHECK-NEXT: (local $1 i64) ;; CHECK-NEXT: (local $2 v128) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i64.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i64.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) (func $target (param $0 i64) (param $1 v128) (param $2 i64) (result f32) ;; All parameters here should vanish.
diff --git a/test/lit/passes/dae_tnh.wast b/test/lit/passes/dae_tnh.wast index 6e78283..b1f9d91 100644 --- a/test/lit/passes/dae_tnh.wast +++ b/test/lit/passes/dae_tnh.wast
@@ -116,9 +116,6 @@ ;; CHECK: (func $target (type $0) (param $0 i32) ;; CHECK-NEXT: (local $1 f64) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (f64.const 4.2) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: )
diff --git a/test/lit/passes/signature-pruning.wast b/test/lit/passes/signature-pruning.wast index d86e855..c2ffc51 100644 --- a/test/lit/passes/signature-pruning.wast +++ b/test/lit/passes/signature-pruning.wast
@@ -1309,9 +1309,6 @@ ;; CHECK: (func $other (type $other) ;; CHECK-NEXT: (local $0 anyref) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $other (type $other) (param anyref)