Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[dart2wasm] Implement inlining functions with function expressions in the body #55027

Open
osa1 opened this issue Feb 27, 2024 · 1 comment
Open
Labels
area-dart2wasm Issues for the dart2wasm compiler. type-performance Issue relates to performance or code size

Comments

@osa1
Copy link
Member

osa1 commented Feb 27, 2024

Consider this function from the protobuf library:

void _readPacked(CodedBufferReader input, void Function() readFunc) {
  input._withLimit(input.readInt32(), () {
    while (!input.isAtEnd()) {
      readFunc();
    }
  });
}

Assuming wasm-opt can inline and eliminate dart2wasm closures with just one call site, inlining this can potentially yield performance improvements, as it would eliminate tear-off allocations in the call sites.

Doing the same transformation manually yielded great improvements: google/protobuf.dart#911.

However we currently can't do this, because function expressions currently prevent inlining:

if (membersContainingInnerFunctions.contains(member)) return false;

We should remove this restriction and allow inlining functions with function expressions.

@osa1 osa1 added the area-dart2wasm Issues for the dart2wasm compiler. label Feb 27, 2024
@osa1 osa1 changed the title [dart2wasm] Implement inlining functions that take function arguments [dart2wasm] Implement inlining functions with function expressions in the body Feb 27, 2024
@osa1
Copy link
Member Author

osa1 commented Feb 28, 2024

I wasn't sure what is missing here and what needs to be done, so I've run the tests (with optimizations) with the membersContainingInnerFunctions line removed.

These are the failing tests:

  • language/optimize/inferrer_synthesized_super_constructor_test
  • language/constructor/evaluation_redirecting_constructor_test
  • language/type_variable/field_initializer_closure_test
  • language/super/call2_test
  • language/regress/regress25246_1_test
  • language/type_variable/field_initializer_closure2_test
  • language/variance/variance_out_field_test
  • language/constructor/constructor6_test
  • language/variance/variance_in_field_test
  • language/variance/variance_inout_field_test
  • lib/js/export/static_interop_mock/mockito_test

They all fail with the same error:

[parse exception: Reached function end without seeing End opcode (at 0:97305)]
Fatal: error parsing wasm (try --debug for more info)

A small repro:

class A {
  @pragma("wasm:prefer-inline")
  Function foo = (int x) {};
}

class B extends A {
  void m(int x) {
    foo(x);
  }
}

main() {
  var b = B();
  b.m(123);
}

It looks like the function to the closure is missing an end. wami output looks like this:

128319|  (func $_TypeUniverse.substituteFunctionTypeArgument (;850;) (param $var0 (ref $_FunctionType)) (param $var1 (ref $Array<_Type>)) (result (ref $_FunctionType))
...
128354|  )
128356|  (func $A. closure at file:///usr/local/google/home/omersa/dart/sdk_wasm/test/test.dart:2:18 (;851;) (param $var0 (ref struct)) (param $var1 i64) (result noneref)
128358|  (func $new B (initializer) (;852;) (result (ref $#ClosureBase))
...
128392|  )

Note that the closing paranthesis is missing for $A. closure at ....

(Minor: we should probably drop the . in the closure name: $A closure at ...)

@mkustermann mkustermann added the type-performance Issue relates to performance or code size label May 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-dart2wasm Issues for the dart2wasm compiler. type-performance Issue relates to performance or code size
Projects
None yet
Development

No branches or pull requests

2 participants