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

Restructure how functions are handled in the IR and codegen to eliminate function inlining #1823

Closed
1 task done
Tracked by #1819
emilyaherbert opened this issue Jun 2, 2022 · 3 comments
Closed
1 task done
Tracked by #1819
Labels
big this task is hard and will take a while blocked compiler: ir IRgen and sway-ir including optimization passes enhancement New feature or request P: medium

Comments

@emilyaherbert
Copy link
Contributor

emilyaherbert commented Jun 2, 2022

Once #1824 goes in, we will have the option to support recursive functions. But, in order to do so, we will need to make changes to the IR and codegen.

Blocked by:


The IR would like to organise a program into a tree. Instructions gathered into blocks, gathered into functions, gathered into modules. So having distinct functions and all their meta available to IR would be beneficial structurally and analytically.

To the best of my knowledge, the debugger is mostly interested in attributing spans to instructions, but being able to resolve full paths of symbols to instructions is important to set breakpoints (or inspect memory values). Without the absolute naming of functions this becomes impossible. @Dentosal knows more.

Originally posted by @otrho in #1557 (comment)

@emilyaherbert emilyaherbert added enhancement New feature or request big this task is hard and will take a while compiler: ir IRgen and sway-ir including optimization passes P: medium blocked labels Jun 2, 2022
@otrho
Copy link
Contributor

otrho commented Jun 3, 2022

The hardest part of removing inlining (and supporting recursion) is supporting actual function calls. I can't find an issue for this though at the moment.

Function calls are typically done with a call/ret mechanism, where ret is essentially a 'pop an arbitrary value off the stack and jump to it'.

The Fuel VM doesn't support arbitrary jumps so to get around this the current proposal is to use a 'jump table'. Each 'call' would include a token describing where the function should 'return' to which would be looked up in a static local table.

This may end up less efficient as popular functions would have a very large return table. But it could also prove more efficient in that CPS call chains could be generated and tail call optimisations are pretty much built in.

Another downside to using a return table is that library code can never be precompiled and included verbatim (i.e., linked) with user code as the return table for a library function depends on where it is called from, which varies per program of course.

@mohammadfawaz
Copy link
Contributor

Just jotting down some things here to make sure I understand the full picture correctly:

Inlining has been used in our conversations to mean two different things:

  1. Inlining the function body in the FunctionApplication AST node itself. This is not what the term "inlining" is usually used for I think.
  2. Inlining in IR (inliner pass) where the function body is actually moved and replaces the call instruction in IR. (call here is not a contract call... the contract call instruction in IR is contract_call and, of course, no inlining happens there).

We want to avoid (1) by creating a declaration engine that avoids making copies of the function body everywhere it is called. This would be a cleaner and lighter design and enables a much easier solution for the trait constraints problem.

We also want to be more flexible with (2) and not have to inline everything (inlining in the traditional sense). Some functions will still be worth inlining (some heuristic can be introduced here) and we should probably have an #[always_inline] annotation at some point that a user can apply to force inlining. Introducing this flexibility requires all the stuff that Toby is talking about above.

Am I getting this right?

@ironcev
Copy link
Member

ironcev commented Oct 28, 2024

We have the call instruction in the IR now, which gets lowered to jumps in the ASM. Functions are now inlined in a classical term, as an optimization pass.

@ironcev ironcev closed this as completed Oct 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
big this task is hard and will take a while blocked compiler: ir IRgen and sway-ir including optimization passes enhancement New feature or request P: medium
Projects
Status: Done
Development

No branches or pull requests

4 participants