-
Notifications
You must be signed in to change notification settings - Fork 924
SinglePass: add support for riscv64 target #5711
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
base: main
Are you sure you want to change the base?
Conversation
This is only the basic plumbing and architecture, the actual implementation is to follow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds experimental RISC-V 64-bit support to the Wasmer SinglePass compiler, enabling WebAssembly compilation for RISC-V architecture. The implementation includes core instruction encoding, trap handling, unwinding support, and comprehensive test coverage.
Key changes:
- New RISC-V machine backend with full instruction set implementation (6219 lines)
- Trap handling and unwinding support for RISC-V architecture
- CI/CD integration with QEMU-based testing for RISC-V target
- Test suite adaptations for RISC-V-specific limitations (jump instruction range)
Reviewed Changes
Copilot reviewed 23 out of 26 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/compiler-singlepass/src/machine_riscv.rs | Core RISC-V machine implementation with instruction encoding and code generation |
| lib/compiler-singlepass/src/riscv_decl.rs | RISC-V register definitions and calling convention support |
| lib/compiler-singlepass/src/emitter_riscv.rs | RISC-V instruction emitter (not shown in diff) |
| lib/vm/src/trap/traphandlers.rs | Added RISC-V trap code extraction from illegal instructions |
| lib/compiler-singlepass/src/unwind.rs | RISC-V DWARF unwinding support |
| tests/compilers/issues.rs | Test adaptations for RISC-V limitations and Cranelift workaround |
| lib/compiler-singlepass/Cargo.toml | Added tempfile dependency and riscv feature flag |
| .cargo/config.toml | RISC-V cross-compilation and QEMU runner configuration |
| .github/workflows/build.yml | CI integration for RISC-V WAST test suite |
| lib/compiler-singlepass/README.md | Updated documentation to list riscv64 as experimental target |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
|
The PR received a couple of fixed that very identified and reduced from running the RISC-V Singlepass compiler on tests for the following Rust crates:
|
|
Hey so I was testing the latest commit from this branch, and I found an issue. The quirky code can be found here: https://github.com/marxin/wasmer/blob/69720a4374dbeb56fac98431be56c5823ed70f70/lib/compiler-singlepass/src/codegen.rs#L2343-L2350 Per this definition, we know that signature index / id is actually 32 bit in size, not 64 bit. We had a fix that solves the problem, however this fix is quite simple, so feel free to use any commit to include the fix. |
Thanks for it, picked the revision. |
|
Hey so upon more testings, we have more to report here. First, here are some test wasm files: The first thing to mention is probably a bug: one of the wasm files attached above would fail the compilation process using the singlepass compiler, but works just fine using the LLVM compiler: I spent some time digging this, I think the issue is that singlepass compiler uses Next, I want to discuss on generated code performance of the singlepass compiler. It is worth noting that singlepass compiler generates much larger wasm files than LLVM compiler, in our tests, most singlepass binaries are 10x the size of LLVM binaries: It's worth mentioning that the runtime performance is much worse: we have a test that involves running all the wasm files above. For LLVM binaries, the test finished in about ~347 seconds, but for singlepass binaries, the test won't stop after running for 11 hours(and it is still running). All the other running environment in the test stays the same, it's just that in one test we use LLVM binaries from those wasm files, in another test we use singlepass binaries from those wasm files. Even if we did the math now(note one test is still running after 5 hours), we are talking about ~100x runtime performance, and ~10x code size between LLVM compiler and singlepass compiler. I totally get that singlepass compiler will be slower, but is it expected that for larger programs, singlepass compiler can be this slow? Is there any chance that some particular code sequences in those wasm files cause a regression somewhere? Can you help confirm if this matches your own testing between the 2 compilers? Or perhaps I made a mistake in my fix, and the code runs in an infinite loop? As always, huge kudos for the work, and thanks a lot for the help! |
|
Upon further checking, I think I misunderstood what So what really needs to do here, is to change this line to a Let me know what you think might be a proper way to solve this. Thanks! |
|
Okay so after some more tries, I think I've fixed the issues. A proposed fix can be found here: wakabat@e065880. This fix passes all our current tests. Feel free to review and incorporate it into this PR. |
The PR adds the rudimentary support for RISC-V 64-bit target into the SinglePass compiler.
Even though, the code still needs some polishing and various TODOs must be addressed, the compiler can pass all (104) thespectests.TODOs:
location_cmp+jmp_on_Xneeds polishing as RISC-V target does not provide a FLAGS register (Singlepass: refactor condition jumps to single fn (jmp_on_condition) #5750).spec/address.wastis flaky (sometimes trap is not properly triggered)compilertests (including the WASI tests) are green nowMachinetrait - wipe unused entry points in the TraitMinor improvements: