Open mkustermann opened 8 months ago
Existing kernel level transformations don't help us here, perhaps we could generalize the partial instantiator we've added in fd954d426fa, maybe with a pragma like:
@pragma('wasm:instantiate')
T max<T extends num>(T a, T b) { ... }
which will make dart2wasm generate different copies of the function based on the type argument, and when in the call sites when the type argument is known call the right instantiation. @mkustermann wdyt?
which will make dart2wasm generate different copies of the function based on the type argument, and when in the call sites when the type argument is known call the right instantiation. @mkustermann wdyt?
Yes, I think we should have versions specialized to the static types of the arguments on the call site (e.g. a max<int>
, max<double>
, max<num>
that have their signature types strengthened to take (int, int) -> int
, (double, double) -> double
, (num, num) -> num
) .
We still let binaryen decide whether (from code size perspective) it makes sense to inline those copies of max
/ min
/ ...
Right now the
min()
andmax()
are never inlined, they are very slow. Even when force inlining we generate very bad code. It shows up on material3 demo profile (e.g. used in_computeSizes()
method).For example this simple program that only uses constants:
turns into this monster when using
-O4
and adding@pragma('wasm:prefer-inline')
to themax
function:Almost all call sites will know that values are integers or doubles, so we really should take advantage of that. We should also try to do int64 comparisons and double comparisons inline as much as possible instead of method calls.