Skip to content

winch: Multi-Value Part 1 #7535

Merged
saulecabrera merged 4 commits into
bytecodealliance:mainfrom
saulecabrera:winch-multi-value
Nov 14, 2023
Merged

winch: Multi-Value Part 1 #7535
saulecabrera merged 4 commits into
bytecodealliance:mainfrom
saulecabrera:winch-multi-value

Conversation

@saulecabrera
Copy link
Copy Markdown
Member

@saulecabrera saulecabrera commented Nov 14, 2023

This change adds initial support for the Multi-Value proposal to Winch, focusing on function calls, support for Multi-Value for blocks will be added on top of this change in a different pull request.

This change is divided into two main parts:

  • Infrastructure changes needed to support Multi-Value
  • Handling Multi-Value returns for function calls

Infrastructure changes needed to support Multi-Value

Some notable changes were needed in order to support this proposal, namely:

  • Introducing the notion of ABIOperands and rewriting the ABIParams and ABIResults in terms of ABIOperands.
  • In Winch's default calling convention, results are stored in reverse order: if a function produces multiple results, the first result is stored in a memory location and the last result is stored in a register; given that function results are captured in the value stack after a function call, this approach makes it trivial to maintain the following value stack invariants:
    • Spilled memory values always precede register values
    • Spilled values are stored from oldest to newest, matching their respective locations on the machine stack.
  • Introducing type-sized spills: Prior to this change, only floats produced type-sized spills, this created an inconsistency on how slots for results are handled and made it harder to manage the stack for multiple-results; this change introduces type-sized spills for integer and floats, making the spilling strategy uniform across the compiler. This might introduce some overhead, since this change is now, in the 32-bit case, introducing two instructions were previously there only used to be one (e.g. push vs sub + mov). My intention is to profile, and try to improve this strategy if needed, later on.

Handling Multi-Value returns for function calls

The approach for handling multiple results for function calls involves:

Adding an implicit extra parameter to the ABIParams definition, when a function returns multiple values; from the callee's perspective, this parameter is treated like any other "special" parameter (e.g VMContext), to which, we give it a well know LocalSlot for later referencing when storing the return values. From the caller's perspective, extra stack space is created before the call, and the address to that space is passed in to the callee, via the return pointer parameter and once the function returns, the values in the created space are captured as values in the value stack.

@saulecabrera saulecabrera requested review from a team as code owners November 14, 2023 12:49
@saulecabrera saulecabrera requested review from fitzgen and removed request for a team November 14, 2023 12:49
@github-actions github-actions Bot added the winch Winch issues or pull requests label Nov 14, 2023
@github-actions
Copy link
Copy Markdown

Subscribe to Label Action

cc @saulecabrera

Details This issue or pull request has been labeled: "winch"

Thus the following users have been cc'd because of the following labels:

  • saulecabrera: winch

To subscribe or unsubscribe from this label, edit the .github/subscribe-to-label.json configuration file.

Learn more.

This commit prepares Winch to support WebAssembly Multi-Value.

The most notorious piece of this change is the introduction of the
`ABIParams` and `ABIResults` structs which are type wrappers around the
concept of an `ABIOperand`, which is the underlying main representation
of a param or result.

This change also consolidates how the size for WebAssembly types is
derived by introducing `ABI::sizeof`, as well as introducing
`ABI::stack_slot_size` to concretely indicate the stack slot size in
bytes for stack params, which is ABI dependent.
This change adds the necessary changes at the ABI level in order to
handle multi-value.

The most notable modifications in this change are:

* Modifying Winch's  default ABI to reverse the order of results,
  ensuring that results that go in the stack should always come first;
  this makes it easier to respect the following two stack invariants:

  * Spilled memory values always precede register values
  * Spilled values are stored from oldest to newest, matching their
    respective locations on the machine stack.

* Modify all calling conventions supported by Winch so that only one result, the first one is stored in
  registers. This differs from their vanilla counterparts in that these
  ABIs can handle multiple results in registers. Given that Winch is not
  a generic code generator, keeping the ABI close to what Wasmtime
  expects makes it easier to pass multiple results at trampolines.
This commit adds more tests for multi-value and improves documentation.

prtest:full
Copy link
Copy Markdown
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM but I'm still a little sketched out by those disassembly changes where I feel like I'm only seeing one half of a change or something like that. Maybe you can explain what is going on?

Comment thread winch/codegen/src/abi/mod.rs Outdated
Comment thread winch/codegen/src/abi/mod.rs Outdated
Comment thread winch/codegen/src/abi/mod.rs Outdated
Comment thread winch/codegen/src/abi/mod.rs Outdated
Comment thread winch/codegen/src/abi/mod.rs
Comment thread winch/filetests/filetests/x64/br/as_call_all.wat
Comment thread winch/codegen/src/abi/local.rs Outdated
Comment thread winch/codegen/src/abi/local.rs
@saulecabrera saulecabrera added this pull request to the merge queue Nov 14, 2023
Merged via the queue into bytecodealliance:main with commit f0162a4 Nov 14, 2023
@saulecabrera saulecabrera deleted the winch-multi-value branch November 14, 2023 22:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

winch Winch issues or pull requests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants