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

Question about "vm:prefer-inline" #51977

Closed
antonbashir opened this issue Apr 6, 2023 · 5 comments
Closed

Question about "vm:prefer-inline" #51977

antonbashir opened this issue Apr 6, 2023 · 5 comments
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. type-question A question about expected behavior or functionality

Comments

@antonbashir
Copy link

antonbashir commented Apr 6, 2023

Hello!

I want ask about pragma "vm:prefer-inline".
I have three questions.

First: What conditions and requirements for method to be inlined ? For example count of lines or something else
Second: Could this pragma be useful for public methods which called from other classes and using private fields like in the example below ?

@pragma(preferInlinePragma)
  void removeClient(int fd) => _serversByClients.remove(fd);

Last: Inlining is possible in JIT and AOT modes or only JIT ?

@antonbashir antonbashir changed the title Question abound "vm:prefer-inline" Question about "vm:prefer-inline" Apr 6, 2023
@lrhn lrhn added area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. type-question A question about expected behavior or functionality labels Apr 6, 2023
@alexmarkov
Copy link
Contributor

What conditions and requirements for method to be inlined ?

First, compiler needs to figure out that a particular call in the caller leads to a particular callee. For static methods and constructors this is always the case. For instance methods it depends on the class hierarchy, whether the method is overridden and whether compiler can determine (or speculate on) the actual type of the receiver. Method is less likely to be inlined if call site is polymorphic (can call multiple different methods).

After figuring out the target of the call, compiler uses a very complex heuristic to decide whether to inline a method or not. The heuristic is based on the size of the caller and the callee, number of call sites in the callee, loop nesting in the caller etc. @pragma("vm:prefer-inline") on the callee bypasses those heuristics and tells compiler to inline annotated method if it is possible.

Currently compiler cannot inline certain methods, even if they are annotated with @pragma("vm:prefer-inline"). Those include methods with a try block, methods declared async, async*, sync* and certain core library methods.

Could this pragma be useful for public methods which called from other classes and using private fields like in the example below ?

Absolutely. However, unless the method is critical for performance and you can measure that inlining of this method improves performance, consider relying on the compiler heuristic. Excessive inlining causes larger code size, and in certain cases inlining may regress performance instead of improving it.

Inlining is possible in JIT and AOT modes or only JIT ?

Both JIT and AOT compilers do the method inlining. However, the heuristic for choosing whether to inline is slightly different and based on different information. JIT can inline speculatively, based on the collected feedback from executing program. AOT compiler uses whole-program analysis to determine possible call targets which can be inlined. Both JIT and AOT respect @pragma("vm:prefer-inline") annotation.

@a-siva a-siva closed this as completed Apr 7, 2023
@incendial
Copy link
Contributor

Currently compiler cannot inline certain methods, even if they are annotated with @pragma("vm:prefer-inline"). Those include methods with a try block, methods declared async, async*, sync* and certain core library methods.

@alexmarkov hey, I'd like to add a lint rule to highlight usages of @pragma("vm:prefer-inline") that compiler can't inline. Could you please tell, is this a complete list of cases or are there any more? Also, if a function doesn't have the async keyword but still returns a Future, will the compiler be able to inline it?

@alexmarkov
Copy link
Contributor

@incendial To the best of my knowledge, the list is complete. However, I would advise against relying on the details of the compiler optimizations as they are not specified and not required by the language spec. Particular optimizations and handling of pragmas are the internal implementation details and may change without notice. The inability to inline methods with try blocks, async, async* and sync* methods is merely a limitation of the current implementation and can be lifted some day.

Methods not declared async but returning a Future can be inlined.

@incendial
Copy link
Contributor

@alexmarkov thanks for the heads up, but it looks like a useful hint to people trying to use pragmas and as you mentioned this is the internal behavior that is rather implicit and people might be not aware that their actions (setting the annotation) actually make zero impact.

Can you share how often do you change this part of the compiler? Or maybe there are some upcoming changes?

@antonbashir
Copy link
Author

To be honest warnings will be very useful in cases of code optimizations where developer is trying to achieve maximum performance and use all language capabilities. If is possible to detect method inlining then it will be very nice compiler feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. type-question A question about expected behavior or functionality
Projects
None yet
Development

No branches or pull requests

5 participants