Skip to content

winch: Multi-Value Part 2: Blocks#7707

Merged
saulecabrera merged 2 commits into
bytecodealliance:mainfrom
saulecabrera:winch-multi-value-blocks
Jan 8, 2024
Merged

winch: Multi-Value Part 2: Blocks#7707
saulecabrera merged 2 commits into
bytecodealliance:mainfrom
saulecabrera:winch-multi-value-blocks

Conversation

@saulecabrera
Copy link
Copy Markdown
Member

@saulecabrera saulecabrera commented Dec 19, 2023

Follow-up to: #7535

This commit adds support for the Multi-Value proposal for blocks.

In general, this change, introduces multiple building blocks to enable supporting arbitrary params and results in blocks:

  • BlockType: This enum makes it easier to categorize blocks per type and also makes it possible to defer the calculation of the ABIResults until they are actually needed rather than calculating everything upfront even though they might not be needed (when in an unreachable state).
  • Push/pop operations are now frame aware. Given that each ControlStackFrame contains all the information needed regarding params and results, this change moves the the implementation of the push and pop operations to the ControlStackFrame struct.
  • StackState: this struct holds the entry and exit invariants of each block; these invariants are pre-computed when entering the block and used throughout the code generation, to handle params, results and assert the respective invariants.

In terms of the mechanics of the implementation: when entering each block, if there are results on the stack, the expected stack pointer offsets will be calculated via the StackState, and the target_offset will be used to create the block's RetArea. Note that when entering the block and calculating the StackState no space is actually reserved for the results, any space increase in the stack is deferred until the results are popped from the value stack via
ControlStackFrame::pop_abi_results.

The trickiest bit of the implementation is handling constant values that need to be placed on the right location on the machine stack. Given that constants are generally not spilled, this means that in order to keep the machine and value stack in sync (spilled-values-wise), values must be shuffled to ensure that constants are placed in the expected location results-wise. See the comment in ControlStackFrame::adjust_stack_results for more details.


I've been continuously fuzzing this change for a bit now (~48hrs), and the fuzzer hasn't reported any new issues.

@saulecabrera saulecabrera requested review from a team as code owners December 19, 2023 21:11
@saulecabrera saulecabrera requested review from elliottt and pchickey and removed request for a team December 19, 2023 21:11
@github-actions github-actions Bot added fuzzing Issues related to our fuzzing infrastructure winch Winch issues or pull requests labels Dec 20, 2023
@github-actions
Copy link
Copy Markdown

Subscribe to Label Action

cc @fitzgen, @saulecabrera

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

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

  • fitzgen: fuzzing
  • saulecabrera: winch

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

Learn more.

@saulecabrera saulecabrera removed the request for review from pchickey January 3, 2024 13:56
@elliottt
Copy link
Copy Markdown
Member

elliottt commented Jan 4, 2024

Sorry this has sat for so long! I'll get a review done by EOD today.

Comment thread winch/codegen/src/codegen/call.rs
Copy link
Copy Markdown
Member

@elliottt elliottt left a comment

Choose a reason for hiding this comment

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

This looks great, thank you for all the comments!

Comment thread winch/codegen/src/isa/x64/masm.rs Outdated
This commit adds support for the Multi-Value proposal for blocks.

In general, this change, introduces multiple building blocks to enable
supporting arbitrary params and results in blocks:

* `BlockType`: Introduce a block type, to categorize the type of each
  block, this makes it easier to categorize blocks per type and also
  makes it possible to defer the calculation of the `ABIResults` until
  they are actually needed rather than calculating everyghing upfront
  even though they might not be needed (when in an unreachable state).
* Push/pop operations are now frame aware. Given that each
  `ControlStackFrame` contains all the information needed regarding
  params and results, this change moves the the implementation of the
  push and pop operations to the `ControlStackFrame` struct.
* `StackState`: this struct holds the entry and exit invariants of each
  block; these invariants are pre-computed when entering the block and
  used throughout the code generation, to handle params, results and
  assert the respective invariants.

In terms of the mechanics of the implementation: when entering each
block, if there are results on the stack, the expected stack pointer
offsets will be calculated via the `StackState`, and the `target_offset`
will be used to create the block's `RetArea`. Note that when entering
the block and calculating the `StackState` no space is actually reserved
for the results, any space increase in the stack is deffered until the
results are popped from the value stack via
`ControlStackFrame::pop_abi_results`.

The trickiest bit of the implementation is handling constant values that
need to be placed on the right location on the machine stack. Given that
constants are generally not spilled, this means that in order to keep
the machine and value stack in sync (spilled-values-wise), values must
be shuffled to ensure that constants are placed in the expected location results wise.
See the comment in `ControlStackFrame::adjust_stack_results` for more
details.
@saulecabrera saulecabrera force-pushed the winch-multi-value-blocks branch from 9f593ec to 9d9e038 Compare January 8, 2024 19:41
@saulecabrera saulecabrera enabled auto-merge January 8, 2024 19:51
@saulecabrera saulecabrera added this pull request to the merge queue Jan 8, 2024
Merged via the queue into bytecodealliance:main with commit 446a7f5 Jan 8, 2024
@saulecabrera saulecabrera deleted the winch-multi-value-blocks branch January 8, 2024 20:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fuzzing Issues related to our fuzzing infrastructure winch Winch issues or pull requests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants