alexcrichton opened PR #9765 from alexcrichton:pulley-new-instructions
to bytecodealliance:main
:
In helping others contribute to Pulley I've written up the steps I took
to make this commit itself. I've picked a random test inmisc_testsuite
that previously didn't work on Pulley and was relatively small. I
implemented a few lowerings and some new instructions and now the test
passes. I've addedpulley/CONTRIBUTING.md
to document the experience
along the way in case anyone else is interested to help out in the
future.
alexcrichton requested fitzgen for a review on PR #9765.
alexcrichton requested wasmtime-core-reviewers for a review on PR #9765.
alexcrichton requested wasmtime-compiler-reviewers for a review on PR #9765.
alexcrichton requested wasmtime-default-reviewers for a review on PR #9765.
alexcrichton commented on PR #9765:
I'll note that this is built on https://github.com/bytecodealliance/wasmtime/pull/9760 so only the last commit here is the guide part.
alexcrichton updated PR #9765.
fitzgen created PR review comment:
you're interested in helping to improve the situation. This is intended to be a
fitzgen created PR review comment:
Just to make it more clear which args are for
cargo
and which are forwasmtime
:$ cargo run --features pulley -- wast --target pulley64 ./tests/misc_testsuite/control-flow.wast ```` ~~~
fitzgen submitted PR review:
Looks great!
I have a bunch of nitpicks and suggestions to make things flow a little smoother IMO or to link to other references and resources, but those are tiny nitpicks and this is fantastic.
Excited to start onboarding new contributors with this!
fitzgen created PR review comment:
## Adding an instruction to Pulley
fitzgen created PR review comment:
`cranelift/codegen/src/isa/pulley_shared/lower.isle`. Our ISLE lowering rules are generally written like this: \```lisp (rule (lower <CLIF>) <Pulley>) \``` This means "when lowering Cranelift's mid-level IR down to Pulley bytecode, and we match the snippet `<CLIF>`, replace it with `<Pulley>`". (For more details, see the [ISLE Language Reference](https://github.com/bytecodealliance/wasmtime/blob/main/cranelift/isle/docs/language-reference.md) and [How ISLE is Integrated with Cranelift](https://github.com/bytecodealliance/wasmtime/blob/main/cranelift/docs/isle-integration.md).) In our case, we need to match an `sdiv` CLIF instruction that is operating on 32-bit values (this is the `(has_type $I32 ...)` bit) and then replace it with our new Pulley `xdiv32_s` instruction:
fitzgen created PR review comment:
the same test under a variety of configurations, but the test is expected to fail under Pulley. You can update the `WastTest::should_fail` method in `crates/wast-util/src/lib.rs` to say the test is expected to pass, and then you
fitzgen created PR review comment:
stray empty line
fitzgen created PR review comment:
method is used to specifically match the width and signedness of the instruction itself, signed
fitzgen created PR review comment:
Note that ISLE constructors for Pulley instructions, including the `pulley_xdivs32_s` constructor for our new `xdiv32_s` Pulley instruction, are automatically generated from the `for_each_op!` macro.
fitzgen created PR review comment:
This defines the snake-case name of the instruction (`xdiv32_s`) that is used by the disassembler and visitor trait, the upper-camel-case name of the instruction (`I32DivS`) used for the Rust type and `enum` variant, and immediates and operands in the instruction itself. In this case it's a binary operation using integer ("x") registers. Note: By convention, we tend to include the class ("x") and width ("32") of registers operated upon by an instruction in its name. This distinguishes between, for example, 32-bit integer addition (`xadd32`) and 64-bit floating point addition (`fadd64`).
fitzgen created PR review comment:
for an up-to-date list check out the `WastTest::should_fail` method in `crates/wast-util/src/lib.rs`. Here we're going
fitzgen created PR review comment:
Success! But we aren't quite done yet: the new lowerings we added might have made additional tests that previously failed start passing as well. If so, then we also want to mark those tests as expected to pass now. We can double check by running the full `wast` test suite:
fitzgen created PR review comment:
| ---------------------------------------------------------------------------- `xdiv32_s` from trait
fitzgen created PR review comment:
FWIW, I would probably name the instruction
xdivs32
but it really doesn't matter. What does matter is that the guide is consistent, so as not to confuse contributors:error[E0046]: not all trait items implemented, missing: `xdiv32_s` --> pulley/src/interp.rs:807:1 | 807 | impl OpVisitor for Interpreter<'_> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `xdiv32_s` in implementation
fitzgen created PR review comment:
assertion is no longer true! Update the `WastTest::should_fail` method in `crates/wast-util/src/lib.rs` so that it expects the test to pass and we'll see:
fitzgen created PR review comment:
Could we make
done_trap
generic over an instruction and then avoid the need to dolet me = self.current_pc::<...>();
and instead doControlFlow::Break(self.done_trap::<...>())
or even fold the
ControlFlow::Break
into the helper?This both delays the computation until its demanded (which LLVM can probably do, but might be foiled if there are zero/overflow whatever checks hidden in there) and is a little more concise at usage/call sites.
fitzgen created PR review comment:
When we run our test again we don't get a compilation error anymore, but instead we see the ISLE lowering error again! \`\`\` $ cargo run --features pulley wast --target pulley64 ./tests/misc_testsuite/control-flow.wast Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.08s Running `target/debug/wasmtime wast --target pulley64 ./tests/misc_testsuite/control-flow.wast` Error: failed to run script file './tests/misc_testsuite/control-flow.wast' Caused by: 0: failed directive on ./tests/misc_testsuite/control-flow.wast:77:1 1: Compilation error: Unsupported feature: should be implemented in ISLE: inst = `v5 = sdiv.i32 v2, v3`, type = `Some(types::I32)` \`\`\` This leads us to the next part...
alexcrichton submitted PR review.
alexcrichton created PR review comment:
Heh you can see I switched halfway through :)
alexcrichton updated PR #9765.
alexcrichton submitted PR review.
alexcrichton created PR review comment:
Excellent idea :+1:
alexcrichton requested fitzgen for a review on PR #9765.
fitzgen created PR review comment:
Maybe also link to this PR at the end?
To view the complete pull request that implemented `xdiv32_s` and `xand32` Pulley instructions and got `./tests/misc_testsuite/control-flow.wast` passing (and also introduced this documentation) check out https://github.com/bytecodealliance/wasmtime/pull/9765 Thanks for helping out!
fitzgen submitted PR review.
alexcrichton updated PR #9765.
alexcrichton has enabled auto merge for PR #9765.
alexcrichton updated PR #9765.
alexcrichton merged PR #9765.
Last updated: Dec 23 2024 at 12:05 UTC