[NFC] DeadArgumentElimination: Update allCalls incrementally
Rather than recompute the entire map of Call instructions to each target, keep it around between iterations, and just update the changed part. This requires us to track the origin of each call, so we know which data is old and stale.
This makes the pass 15% faster on some Dart and C++ testcases, and 9% faster on Kotlin and Java. On Dart this is also the slowest pass in -O3, making us overall 3% faster.
Fuzzer found an issue, so converting to draft. It turns out that we Refinalize internally, and that can remove (unreachable) calls. That makes this hang on dae-optimizing:
(module
(rec
(type $0 (func))
(type $1 (func (param (ref $2)) (result f32)))
(type $2 (struct (field (mut externref))))
(type $3 (func (result v128)))
)
(func $0 (type $3) (result v128)
(drop
(call_ref $1
(struct.new $2
(ref.as_non_null
(ref.null noextern)
)
)
(ref.func $1)
)
)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
)
(func $1 (type $1) (param $0 (ref $2)) (result f32)
(unreachable)
)
(func $2 (type $0)
(drop
(call $0)
)
)
)
We are not aware that Refinalize causes changes, so we miss the call going away, and end up confused.
Tracking Refinalize may be enough, perhaps in a separate PR.