Skip to content

Commit

Permalink
Feat riscv llvm and cranelift (#3244)
Browse files Browse the repository at this point in the history
* Basic changes for RISC-V support

* RISC-V in compiler LLVM

* RISC-V support in dylib engine

* RISC-V support in universal engine

* Various small fixes

* [RISCV] LLVM-riscv working, with some ignored tests to be worked on later

* Update rustc to 4.65 (1.64 has some issue with riscv64 target)

* Fixed some (new) Linting issues

* Updated Cargo.toml and remove split-debuginfo for Windows build

* Removed profile.dev from Cargo.toml as it cannot be per platform (breaks Windows). split-debug info is now the default value

* Enable Cranelift compiler for RISCV

* Update crates and fixed all the new clippy errors

* Taken review remarks into account

* Removed change from deny.toml, it's not needed anymore

* Added some more comment about llvm abi hack

* Added doc about current state of RISCV support

* Fixed (newer) linter

---------

Co-authored-by: Toru Nayuki <[email protected]>
  • Loading branch information
ptitSeb and tnayuki authored Mar 22, 2023
1 parent a72e655 commit 7500ce7
Show file tree
Hide file tree
Showing 50 changed files with 358 additions and 105 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/benchmark.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.64
toolchain: 1.65
- name: Configure cargo data directory
# After this point, all cargo registry and crate data is stored in
# $GITHUB_WORKSPACE/.cargo_home. This allows us to cache only the files
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ jobs:
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.64
toolchain: 1.65
target: ${{ matrix.target }}
- name: Install Rust nightly (to build capi-headless)
uses: dtolnay/rust-toolchain@stable
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/cloudcompiler.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.64
toolchain: 1.65
target: ${{ matrix.target }}
- name: Install wasm32-wasi target
shell: bash
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/documentation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.64
toolchain: 1.65
- name: Install LLVM
shell: bash
run: |
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.64
toolchain: 1.65
components: rustfmt, clippy
- name: Install libtinfo
shell: bash
Expand Down Expand Up @@ -95,7 +95,7 @@ jobs:
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.64
toolchain: 1.65
- name: Install NodeJS
uses: actions/setup-node@v2
with:
Expand Down Expand Up @@ -263,7 +263,7 @@ jobs:
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.64
toolchain: 1.65
target: ${{ matrix.metadata.target }}
- name: Install Rust nightly (to build capi-headless)
uses: dtolnay/rust-toolchain@stable
Expand Down Expand Up @@ -487,7 +487,7 @@ jobs:
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.64
toolchain: 1.65
target: ${{ matrix.metadata.target }}
- name: Install LLVM (macOS Apple Silicon)
if: matrix.metadata.os == 'macos-11.0' && !matrix.metadata.llvm_url
Expand Down Expand Up @@ -587,7 +587,7 @@ jobs:
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.64
toolchain: 1.65
target: ${{ matrix.metadata.target }}
- name: Cache
uses: whywaita/actions-cache-s3@v2
Expand Down
44 changes: 27 additions & 17 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,6 @@ test-universal = ["test-generator/test-universal"]
# that raise signals because that interferes with tarpaulin.
coverage = []

[profile.dev]
split-debuginfo = "unpacked"

#[profile.release]
#debug = true

Expand Down
28 changes: 22 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,24 @@ SHELL=/usr/bin/env bash
# |------------|----------|--------------|-------|
# | Cranelift | Linux | amd64 | glibc |
# | LLVM | Darwin | aarch64 | musl |
# | Singlepass | Windows | | |
# | Singlepass | Windows | riscv | |
# |------------|----------|--------------|-------|
#
# Here is what works and what doesn't:
#
# * Cranelift works everywhere,
#
# * LLVM works on Linux+Darwin/`amd64`,
# but it doesn't work on */`aarch64` or Windows/*.
# and linux+`aarch64`, linux+`riscv`
# but it doesn't work on Darwin/`aarch64` or Windows/`aarch64`.
#
# * Singlepass works on Linux+Darwin/`amd64`, but
# it doesn't work on */`aarch64` or Windows/*.
# * Singlepass works on Linux+Darwin+Windows/`amd64`,
# and Linux+Darwin/`aarch64`
# it doesn't work on */`riscv`.
#
# * Windows isn't tested on `aarch64`, that's why we consider it's not
# working, but it might possibly be.
# * The Only target for `riscv` familly of processor is the RV64, with the `GC` extensions


#####
Expand All @@ -45,6 +48,7 @@ IS_FREEBSD := 0
IS_WINDOWS := 0
IS_AMD64 := 0
IS_AARCH64 := 0
IS_RISCV64 := 0

# Test Windows apart because it doesn't support `uname -s`.
ifeq ($(OS), Windows_NT)
Expand Down Expand Up @@ -75,6 +79,8 @@ else
IS_AMD64 := 1
else ifneq (, $(filter $(uname), aarch64 arm64))
IS_AARCH64 := 1
else ifneq (, $(filter $(uname), riscv64))
IS_RISCV64 := 1
else
# We use spaces instead of tabs to indent `$(error)`
# otherwise it's considered as a command outside a
Expand Down Expand Up @@ -116,8 +122,16 @@ compilers :=

# If the user didn't disable the Cranelift compiler…
ifneq ($(ENABLE_CRANELIFT), 0)
# … then it can always be enabled.
compilers += cranelift
# … then maybe the user forced to enable the Cranelift compiler.
ifeq ($(ENABLE_CRANELIFT), 1)
compilers += cranelift
# … otherwise, we try to check whether Cranelift works on this host.
else
compilers += cranelift
endif
endif

ifneq (, $(findstring cranelift,$(compilers)))
ENABLE_CRANELIFT := 1
endif

Expand Down Expand Up @@ -235,6 +249,8 @@ ifeq ($(ENABLE_LLVM), 1)
compilers_engines += llvm-universal
else ifeq ($(IS_AARCH64), 1)
compilers_engines += llvm-universal
else ifeq ($(IS_RISCV64), 1)
compilers_engines += llvm-universal
endif
endif
endif
Expand Down
12 changes: 12 additions & 0 deletions docs/RISCV.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Current state of the RISCV support

Only Cranelift and LLVM compiler are supported.
Singlepass can be done, but no ressources are allocated on this task for now.

Both LLVM and Cranelift support are quite new, and so it is expected to have a few things not working well.

LLVM code needs a hack to force the ABI to "lp64d", and some tested with funciton & float/double values are still not working correctly and have be disable for now.

On Cranelift, SIMD is not supported as the CPU doesn't have official SIMD/Vector extension for now, and no Workaround is in place.

Test have be conducted on actual hardware, with a Vision Fixe 2 board running Debian. Some previous tests have also be done on a Vison Five 1 running Fedora (with LLVM only).
4 changes: 2 additions & 2 deletions lib/api/src/access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ pub(super) enum RefCow<'a, T> {
impl<'a, T> AsRef<T> for RefCow<'a, T> {
fn as_ref(&self) -> &T {
match self {
Self::Borrowed(val) => *val,
Self::Borrowed(val) => val,
Self::Owned(val, _) => val,
}
}
Expand All @@ -130,7 +130,7 @@ impl<'a, T> AsMut<T> for RefCow<'a, T> {
// not leak the bytes into the memory
// https://stackoverflow.com/questions/61114026/does-stdptrwrite-transfer-the-uninitialized-ness-of-the-bytes-it-writes
match self {
Self::Borrowed(val) => *val,
Self::Borrowed(val) => val,
Self::Owned(val, modified) => {
*modified = true;
val
Expand Down
1 change: 1 addition & 0 deletions lib/api/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ impl Imports {
/// Resolve and return a vector of imports in the order they are defined in the `module`'s source code.
///
/// This means the returned `Vec<Extern>` might be a subset of the imports contained in `self`.
#[allow(clippy::result_large_err)]
pub fn imports_for_module(&self, module: &Module) -> Result<Vec<Extern>, LinkError> {
let mut ret = vec![];
for import in module.imports() {
Expand Down
2 changes: 2 additions & 0 deletions lib/api/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ impl Instance {
/// Those are, as defined by the spec:
/// * Link errors that happen when plugging the imports into the instance
/// * Runtime errors that happen when running the module `start` function.
#[allow(clippy::result_large_err)]
pub fn new(
store: &mut impl AsStoreMut,
module: &Module,
Expand All @@ -81,6 +82,7 @@ impl Instance {
/// Those are, as defined by the spec:
/// * Link errors that happen when plugging the imports into the instance
/// * Runtime errors that happen when running the module `start` function.
#[allow(clippy::result_large_err)]
pub fn new_by_index(
store: &mut impl AsStoreMut,
module: &Module,
Expand Down
2 changes: 2 additions & 0 deletions lib/api/src/sys/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ impl From<wasmer_compiler::InstantiationError> for InstantiationError {
}

impl Instance {
#[allow(clippy::result_large_err)]
pub(crate) fn new(
store: &mut impl AsStoreMut,
module: &Module,
Expand All @@ -55,6 +56,7 @@ impl Instance {
Ok((instance, exports))
}

#[allow(clippy::result_large_err)]
pub(crate) fn new_by_index(
store: &mut impl AsStoreMut,
module: &Module,
Expand Down
1 change: 1 addition & 0 deletions lib/api/src/sys/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ impl Module {
Self { artifact }
}

#[allow(clippy::result_large_err)]
pub(crate) fn instantiate(
&self,
store: &mut impl AsStoreMut,
Expand Down
2 changes: 1 addition & 1 deletion lib/cache/src/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl Display for Hash {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let mut buffer = [0_u8; 64];

hex::encode_to_slice(&self.0, &mut buffer)
hex::encode_to_slice(self.0, &mut buffer)
.expect("Can never fail with a hard-coded buffer length");
let s = std::str::from_utf8(&buffer).map_err(|_| fmt::Error)?;

Expand Down
Loading

0 comments on commit 7500ce7

Please sign in to comment.