-
Notifications
You must be signed in to change notification settings - Fork 819
Description
It's very common that imported objects (e.g. foreign JS objects) get wrapped in a wrapper that integrates into the from-source language type hierarchy. For example a JS string that's imported will be wrapped in Dart via a JSStringImpl - which inherits from Dart's Object (top type) and therefore behaves like a Dart object.
It's very common that such wrapped imported objects are immediately unwrapped. That means the wrapper is unnecessary. It would be very nice if binaryen did remove such wrappers.
See example in global_opt_bad.tar.gz which contains the unoptimized and optimized wasm file. We optimize it 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 '--no-inline=*<noInline>*' --closed-world --traps-never-happen --type-unfinalizing -Os --type-ssa --gufa -Os --type-merging -Os --type-finalizing --minimize-rec-groups -g bad.wasm -o bad.opt.wasm
...
% wami --full-wat bad.opt.wasm -o bad.opt.wat
We can see the following code
(type $#Top (;0;) (struct (field $field0 i32)))
(type $JSStringImpl (sub final $#Top (struct (field $field0 i32) (field $_ref externref))))
...
(global $S.barbaz (import "S" "barbaz") externref)
...
(global $C329 "barbaz" (ref $JSStringImpl) (i32.const 4) (global.get $S.barbaz) (struct.new $JSStringImpl))
...
(func $_invokeMain (export "$invokeMain") (param $var0 (ref extern))
....
global.get $C329 "barbaz"
struct.get $JSStringImpl $_ref
call $dart2wasm._274 (import)
...Since we struct.get a non-mutable field from a global and the global has simple initializer that just puts an imported global into the field, it should be easy to fold this away into e.g.
(type $#Top (;0;) (struct (field $field0 i32)))
(type $JSStringImpl (sub final $#Top (struct (field $field0 i32) (field $_ref externref))))
...
(global $S.barbaz (import "S" "barbaz") externref)
...
(func $_invokeMain (export "$invokeMain") (param $var0 (ref extern))
....
(global.get $S.barbaz)
call $dart2wasm._274 (import)
...This would make code size smaller as well as reduce number of globals.
This pattern occurs quite a lot for us, so it would make a difference if wasm-opt could do this.