Skip to content

Commit

Permalink
Cranelift: Add a new backend for emitting Pulley bytecode (#9089)
Browse files Browse the repository at this point in the history
* Cranelift: Add a new backend for emitting Pulley bytecode

This commit adds two new backends for Cranelift that emits 32- and 64-bit Pulley
bytecode. The backends are both actually the same, with a common implementation
living in `cranelift/codegen/src/isa/pulley_shared`. Each backend configures an
ISA flag that determines the pointer size, and lowering inspects this flag's
value when lowering memory accesses.

To avoid multiple ISLE compilation units, and to avoid compiling duplicate
copies of Pulley's generated `MInst`, I couldn't use `MInst` as the `MachInst`
implementation directly. Instead, there is an `InstAndKind` type that is a
newtype over the generated `MInst` but which also carries a phantom type
parameter that implements the `PulleyTargetKind` trait. There are two
implementations of this trait, a 32- and 64-bit version. This is necessary
because there are various static trait methods for the mach backend which we
must implement, and which return the pointer width, but don't have access to any
`self`. Therefore, we are forced to monomorphize some amount of code. This type
parameter is fairly infectious, and all the "big" backend
types (`PulleyBackend<P>`, `PulleyABICallSite<P>`, etc...) are parameterized
over it. Nonetheless, not everything is parameterized over a `PulleyTargetKind`,
and we manage to avoid duplicate `MInst` definitions and lowering code.

Note that many methods are still stubbed out with `todo!`s. It is expected that
we will fill in those implementations as the work on Pulley progresses.

* Trust the `pulley-interpreter` crate, as it is part of our workspace

* fix some clippy warnings

* Fix a dead-code warning from inside generated code

* Use a helper for emitting br_if+comparison instructions

* Add a helper for converting `Reg` to `pulley_interpreter::XReg`

* Add version to pulley workspace dependency

* search the pulley directory for crates in the publish script
  • Loading branch information
fitzgen authored Aug 14, 2024
1 parent 61191a2 commit b526865
Show file tree
Hide file tree
Showing 60 changed files with 8,081 additions and 22 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ wasmtime-fuzzing = { path = "crates/fuzzing" }
wasmtime-jit-icache-coherence = { path = "crates/jit-icache-coherence", version = "=25.0.0" }
wasmtime-wit-bindgen = { path = "crates/wit-bindgen", version = "=25.0.0" }
test-programs-artifacts = { path = 'crates/test-programs/artifacts' }

pulley-interpreter = { path = 'pulley', version = "=0.1.0" }
pulley-interpreter-fuzz = { path = 'pulley/fuzz' }

cranelift-wasm = { path = "cranelift/wasm", version = "0.112.0" }
Expand Down
5 changes: 4 additions & 1 deletion cranelift/codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ target-lexicon = { workspace = true }
log = { workspace = true }
serde = { workspace = true, optional = true }
serde_derive = { workspace = true, optional = true }
pulley-interpreter = { workspace = true, optional = true }
postcard = { workspace = true, optional = true }
gimli = { workspace = true, features = ["write", "std"], optional = true }
smallvec = { workspace = true }
Expand Down Expand Up @@ -81,6 +82,7 @@ x86 = []
arm64 = []
s390x = []
riscv64 = []
pulley = ["dep:pulley-interpreter", "pulley-interpreter/encode", "pulley-interpreter/disas"]
# Enable the ISA target for the host machine
host-arch = []

Expand All @@ -89,7 +91,8 @@ all-arch = [
"x86",
"arm64",
"s390x",
"riscv64"
"riscv64",
"pulley",
]

# For dependent crates that want to serialize some parts of cranelift
Expand Down
17 changes: 16 additions & 1 deletion cranelift/codegen/meta/src/isa/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::cdsl::isa::TargetIsa;
use std::fmt;

mod arm64;
mod pulley;
mod riscv64;
mod s390x;
pub(crate) mod x86;
Expand All @@ -14,6 +15,8 @@ pub enum Isa {
Arm64,
S390x,
Riscv64,
Pulley32,
Pulley64,
}

impl Isa {
Expand All @@ -32,13 +35,22 @@ impl Isa {
"s390x" => Some(Isa::S390x),
x if ["x86_64", "i386", "i586", "i686"].contains(&x) => Some(Isa::X86),
"riscv64" | "riscv64gc" | "riscv64imac" => Some(Isa::Riscv64),
"pulley32" => Some(Isa::Pulley32),
"pulley64" => Some(Isa::Pulley64),
_ => None,
}
}

/// Returns all supported isa targets.
pub fn all() -> &'static [Isa] {
&[Isa::X86, Isa::Arm64, Isa::S390x, Isa::Riscv64]
&[
Isa::X86,
Isa::Arm64,
Isa::S390x,
Isa::Riscv64,
Isa::Pulley32,
Isa::Pulley64,
]
}
}

Expand All @@ -50,6 +62,8 @@ impl fmt::Display for Isa {
Isa::Arm64 => write!(f, "arm64"),
Isa::S390x => write!(f, "s390x"),
Isa::Riscv64 => write!(f, "riscv64"),
Isa::Pulley32 => write!(f, "pulley32"),
Isa::Pulley64 => write!(f, "pulley64"),
}
}
}
Expand All @@ -61,6 +75,7 @@ pub(crate) fn define(isas: &[Isa]) -> Vec<TargetIsa> {
Isa::Arm64 => arm64::define(),
Isa::S390x => s390x::define(),
Isa::Riscv64 => riscv64::define(),
Isa::Pulley32 | Isa::Pulley64 => pulley::define(),
})
.collect()
}
14 changes: 14 additions & 0 deletions cranelift/codegen/meta/src/isa/pulley.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use crate::cdsl::{isa::TargetIsa, settings::SettingGroupBuilder};

pub(crate) fn define() -> TargetIsa {
let mut settings = SettingGroupBuilder::new("pulley");
settings.add_enum(
"pointer_width",
"The width of pointers for this Pulley target",
"Supported values:\n\
* 'pointer32'\n\
* 'pointer64'\n",
vec!["pointer32", "pointer64"],
);
TargetIsa::new("pulley", settings.build())
}
18 changes: 17 additions & 1 deletion cranelift/codegen/meta/src/isle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,17 @@ pub fn get_isle_compilations(

// Directory for mid-end optimizations.
let src_opts = codegen_crate_dir.join("src").join("opts");

// Directories for lowering backends.
let src_isa_x64 = codegen_crate_dir.join("src").join("isa").join("x64");
let src_isa_aarch64 = codegen_crate_dir.join("src").join("isa").join("aarch64");
let src_isa_s390x = codegen_crate_dir.join("src").join("isa").join("s390x");

let src_isa_risc_v = codegen_crate_dir.join("src").join("isa").join("riscv64");
let src_isa_pulley_shared = codegen_crate_dir
.join("src")
.join("isa")
.join("pulley_shared");

// This is a set of ISLE compilation units.
//
// The format of each entry is:
Expand Down Expand Up @@ -121,6 +126,17 @@ pub fn get_isle_compilations(
],
untracked_inputs: vec![clif_lower_isle.clone()],
},
// The Pulley instruction selector.
IsleCompilation {
output: gen_dir.join("isle_pulley_shared.rs"),
inputs: vec![
prelude_isle.clone(),
prelude_lower_isle.clone(),
src_isa_pulley_shared.join("inst.isle"),
src_isa_pulley_shared.join("lower.isle"),
],
untracked_inputs: vec![clif_lower_isle.clone()],
},
],
}
}
6 changes: 3 additions & 3 deletions cranelift/codegen/src/isa/aarch64/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -722,12 +722,12 @@ impl ABIMachineSpec for AArch64MachineDeps {
// present, resize the incoming argument area of the frame to accommodate those arguments.
let incoming_args_diff = frame_layout.tail_args_size - frame_layout.incoming_args_size;
if incoming_args_diff > 0 {
// Decrement SP to account for the additional space required by a tail call
// Decrement SP to account for the additional space required by a tail call.
insts.extend(Self::gen_sp_reg_adjust(-(incoming_args_diff as i32)));

// Move fp and lr down
// Move fp and lr down.
if setup_frame {
// Reload the frame pointer from the stack
// Reload the frame pointer from the stack.
insts.push(Inst::ULoad64 {
rd: regs::writable_fp_reg(),
mem: AMode::SPOffset {
Expand Down
1 change: 0 additions & 1 deletion cranelift/codegen/src/isa/aarch64/lower/isle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use crate::ir::{condcodes, ArgumentExtension};
use crate::isa;
use crate::isa::aarch64::inst::{FPULeftShiftImm, FPURightShiftImm, ReturnCallInfo};
use crate::isa::aarch64::AArch64Backend;
use crate::isle_common_prelude_methods;
use crate::machinst::isle::*;
use crate::{
binemit::CodeOffset,
Expand Down
9 changes: 9 additions & 0 deletions cranelift/codegen/src/isa/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ pub mod riscv64;
#[cfg(feature = "s390x")]
mod s390x;

#[cfg(feature = "pulley")]
mod pulley32;
#[cfg(feature = "pulley")]
mod pulley64;
#[cfg(feature = "pulley")]
mod pulley_shared;

pub mod unwind;

mod call_conv;
Expand Down Expand Up @@ -104,6 +111,8 @@ pub fn lookup(triple: Triple) -> Result<Builder, LookupError> {
Architecture::Aarch64 { .. } => isa_builder!(aarch64, (feature = "arm64"), triple),
Architecture::S390x { .. } => isa_builder!(s390x, (feature = "s390x"), triple),
Architecture::Riscv64 { .. } => isa_builder!(riscv64, (feature = "riscv64"), triple),
Architecture::Pulley32 => isa_builder!(pulley32, (feature = "pulley"), triple),
Architecture::Pulley64 => isa_builder!(pulley64, (feature = "pulley"), triple),
_ => Err(LookupError::Unsupported),
}
}
Expand Down
13 changes: 13 additions & 0 deletions cranelift/codegen/src/isa/pulley32.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
pub use super::pulley_shared::isa_builder;

use super::pulley_shared::PulleyTargetKind;
use crate::isa::pulley_shared::PointerWidth;

#[derive(Debug, Default, Clone, Copy)]
pub(crate) struct Pulley32;

impl PulleyTargetKind for Pulley32 {
fn pointer_width() -> PointerWidth {
PointerWidth::PointerWidth32
}
}
13 changes: 13 additions & 0 deletions cranelift/codegen/src/isa/pulley64.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
pub use super::pulley_shared::isa_builder;

use super::pulley_shared::PulleyTargetKind;
use crate::isa::pulley_shared::PointerWidth;

#[derive(Debug, Default, Clone, Copy)]
pub(crate) struct Pulley64;

impl PulleyTargetKind for Pulley64 {
fn pointer_width() -> PointerWidth {
PointerWidth::PointerWidth64
}
}
Loading

0 comments on commit b526865

Please sign in to comment.