Skip to content

winch: Add a subset of known libcalls and improve call emission#7228

Merged
saulecabrera merged 4 commits intobytecodealliance:mainfrom
saulecabrera:winch-final-builtins
Oct 13, 2023
Merged

winch: Add a subset of known libcalls and improve call emission#7228
saulecabrera merged 4 commits intobytecodealliance:mainfrom
saulecabrera:winch-final-builtins

Conversation

@saulecabrera
Copy link
Copy Markdown
Member

This change is a follow up to:

One of the objectives of this change is to make it easy to emit function calls at the MacroAssembler layer, for cases in which it's challenging to know ahead-of-time if a particular functionality can be achieved natively (e.g. rounding and SSE4.2). The original implementation of function call emission, made this objective difficult to achieve and it was also difficult to reason about.
I decided to simplify the overall approach to function calls as part of this PR; in essence, the call module now exposes a single function FnCall::emit which is reponsible of gathtering the dependencies and orchestrating the emission of the call. This new approach deliberately avoids holding any state regarding the function call for simplicity.

This change also standardizes the usage of Callee as the main entrypoint for function call emission, as of this change 4 Callee types exist (Local, Builtin, Import, FuncRef), each callee kind is mappable to a CalleeKind which is the materialized version of a callee which Cranelift understands.

This change also moves the creation of the BuiltinFunctions to the ISA level given that they can be safely used accross multiple function compilations.

Finally, this change also introduces support for some of the "well-known" libcalls and hooks those libcalls at the MacroAssembler::float_round callsite.

--

prtest:full

This change is a follow up to:
- bytecodealliance#7155
- bytecodealliance#7035

One of the objectives of this change is to make it easy to emit
function calls at the MacroAssembler layer, for cases in which it's
challenging to know ahead-of-time if a particular functionality can be
achieved natively (e.g. rounding and SSE4.2).  The original implementation
of function call emission, made this objective difficult to achieve and
it was also difficult to reason about.
I decided to simplify the overall approach to function calls as part of
this PR; in essence, the `call` module now exposes a single function
`FnCall::emit` which is reponsible of gathtering the dependencies and
orchestrating the emission of the call. This new approach deliberately
avoids holding any state regarding the function call for simplicity.

This change also standardizes the usage of `Callee` as the main
entrypoint for function call emission, as of this change 4 `Callee`
types exist (`Local`, `Builtin`, `Import`, `FuncRef`), each callee kind
is mappable to a `CalleeKind` which is the materialized version of
a callee which Cranelift understands.

This change also moves the creation of the `BuiltinFunctions` to the
`ISA` level given that they can be safely used accross multiple function
compilations.

Finally, this change also introduces support for some of the
"well-known" libcalls and hooks those libcalls at the
`MacroAssembler::float_round` callsite.

--

prtest:full
@saulecabrera saulecabrera requested review from a team as code owners October 12, 2023 17:08
@saulecabrera saulecabrera requested review from cfallin and fitzgen and removed request for a team October 12, 2023 17:08
@saulecabrera
Copy link
Copy Markdown
Member Author

@elliottt this is the change that I mentioned earlier this week during the Cranelift weekly meeting.

@saulecabrera saulecabrera requested review from elliottt and removed request for cfallin October 12, 2023 17:08
@github-actions github-actions bot added the winch Winch issues or pull requests label Oct 12, 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.

Comment on lines +18 to +19
/// The built-in function base, relative to the VMContext.
base: u32,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is the offset within the vmctx of the whole BuiltinFunctionsArray?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I assume that the base and offset fields will be added together ultimately to do load(vmctx + base + offset) and I wonder if it makes sense to just store the base + offset here, rather than the two parts separately.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I don't think that this will work (unless I'm missing something). The reason why I'm storing both separately is that loading the builtin's address requires two loads:

  • base = load(vmctx + base)
  • builtin_addr = load(base + index)

@saulecabrera saulecabrera changed the title winch: Add known a subset of known libcalls and improve call emission winch: Add a subset of known libcalls and improve call emission Oct 12, 2023
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 is looking great, I'm so happy to see the default cases for fp rounding operations now!

context.stack.push(src.into());
} else {
todo!("libcall fallback for rounding is not implemented")
FnCall::emit::<Self, Self::Ptr, _>(self, context, |context| {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Awesome! 🎉

/// be generally used as the single entry point to access
/// the compound functionality provided by its elements.
pub(crate) struct CodeGenContext<'a> {
pub(crate) struct CodeGenContext<'a, 'b: 'a> {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Does 'b actually outlive 'a here, or would it be possible to collapse these down to just 'a?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It actually outlives 'a; the changes in this PR make it so the compiled_function function at the ISA level gets a reference to BuiltinFunctions, which will outlive any of the other structs created in the body of the compile_function function (e.g. FuncEnv and VMOffsets) and on top of that, there's is a third lifetime ('data, previously 'c) which represents the lifetime of any references to the original WebAssembly binary through wasmtime_environ::ModuleTranslation.

/// Contains all information about the module and runtime that is accessible to
/// to a particular function during code generation.
pub struct FuncEnv<'a, P: PtrSize> {
pub struct FuncEnv<'a, 'translation: 'a, 'data: 'translation, P: PtrSize> {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Similarly to the CodeGenContext parameters, can this be simplified down to using the 'a lifetime for everything?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah, the same comment applies here too.

@saulecabrera
Copy link
Copy Markdown
Member Author

I've addressed all of the review comments (thanks @fitzgen and @elliottt). I'll go ahead and merge this, but happy to follow up on any of the comments if need be.

@saulecabrera saulecabrera added this pull request to the merge queue Oct 13, 2023
Merged via the queue into bytecodealliance:main with commit 4f47f3e Oct 13, 2023
@saulecabrera saulecabrera deleted the winch-final-builtins branch October 13, 2023 19:47
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.

3 participants