Binaryen writer seems to unnecessarily create multiple local sections for locals with same type
See the attached wasm_opt_local_issue.tar.gz. It contains a flute.wasm file.
We then optimize this file via
% wasm-opt --enable-gc --enable-reference-types --enable-multivalue --enable-exception-handling --enable-nontrapping-float-to-int --enable-sign-ext --enable-bulk-memory --enable-threads --closed-world --traps-never-happen --type-unfinalizing -Os --type-ssa --gufa -Os --type-merging -Os --type-finalizing --minimize-rec-groups -g flute.wasm -o flute.opt.wasm
When examining the resulting flute.opt.wasm using:
% wami --full-hexdump -o flute.opt.{wat,wasm}
we'll see
...
// function #221 $_WidgetsFlutterBinding&BindingBase&GestureBinding._flushPointerEventQueue
0xc7, 0x07, // body size 967
0x16, // 22 entries in locals list
0x01, 0x64, 0x01, // 1 local of type (ref $Object)
0x02, 0x64, 0x00, // 2 locals of type (ref $#Top)
0x02, 0x64, 0x0e, // 2 locals of type (ref $_StringStackTrace)
0x02, 0x63, 0x01, // 2 locals of type (ref null $Object)
0x01, 0x63, 0x99, 0x02, // 1 local of type (ref null $BoxHitTestResult)
0x01, 0x64, 0xa2, 0x01, // 1 local of type (ref $MouseTracker_6)
0x01, 0x64, 0x13, // 1 local of type (ref $_DefaultMap&_HashFieldBase&MapMixin&_HashBase&_OperatorEqualsAndHashCode&_LinkedHashMapMixin&_MapCreateIndexMixin)
0x01, 0x64, 0x93, 0x04, // 1 local of type (ref $<context file:///usr/local/google/home/kustermann/src/dart-sdk-gclient2/sdk/third_party/flute/framework/lib/src/gestures/binding.dart:420:21>)
0x01, 0x64, 0x0e, // 1 local of type (ref $_StringStackTrace)
0x01, 0x64, 0xe3, 0x06, // 1 local of type (ref $<context file:///usr/local/google/home/kustermann/src/dart-sdk-gclient2/sdk/third_party/flute/framework/lib/src/gestures/binding.dart:420:21>_2508)
0x01, 0x64, 0xf1, 0x03, // 1 local of type (ref $HitTestEntry)
0x01, 0x63, 0xc2, 0x03, // 1 local of type (ref null $_MouseState_60)
0x01, 0x64, 0xb8, 0x01, // 1 local of type (ref $PointerRouter)
0x01, 0x64, 0xc7, 0x00, // 1 local of type (ref $_GrowableListIterator_12)
0x01, 0x63, 0xe1, 0x00, // 1 local of type (ref null $_FifoCache_93)
0x01, 0x64, 0xe1, 0x00, // 1 local of type (ref $_FifoCache_93)
0x01, 0x64, 0xe1, 0x00, // 1 local of type (ref $_FifoCache_93)
0x01, 0x64, 0xbf, 0x01, // 1 local of type (ref $_CompactIterator)
0x01, 0x64, 0xb5, 0x05, // 1 local of type (ref $<context file:///usr/local/google/home/kustermann/src/dart-sdk-gclient2/sdk/third_party/flute/framework/lib/src/rendering/mouse_tracker.dart:293:23>)
...
Now notice that we have the following here
0x01, 0x64, 0xe1, 0x00, // 1 local of type (ref $_FifoCache_93)
0x01, 0x64, 0xe1, 0x00, // 1 local of type (ref $_FifoCache_93)
this could be rather encoded as
0x02, 0x64, 0xe1, 0x00, // 1 local of type (ref $_FifoCache_93)
We emit local indexes here:
https://github.com/WebAssembly/binaryen/blob/7b18dd166cebf13f4b3d75b996dccfe9552bb290/src/wasm/wasm-stack.cpp#L2959-L2963
The code above groups them by type. It looks like the only situation where we don't fully group is scratch locals, which are added late in the process. That might not be easy to fix, but it should be quite rare at least.
This is possibly due to having some locals having exact references to a type and other locals having inexact references to the same type. They will be be emitted as separate local definitions, but if custom descriptors is not enabled, the exact references will be generalized to be the same inexact reference type as the other locals.
is this still open ? @devalgupta404 are you still working on this?
Yes, this bug is still unfixed. You're welcome to upload a PR for it if you'd like :)