Skip to content
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

cranelift-codegen: no_std support #9007

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ jobs:
- run: rustup target add x86_64-unknown-none
- run: cargo check --target x86_64-unknown-none -p wasmtime --no-default-features --features runtime,gc,component-model
- run: cargo check --target x86_64-unknown-none -p cranelift-control --no-default-features
- run: cargo check --target x86_64-unknown-none -p cranelift-codegen --no-default-features --features all-arch,trace-log

# Check that wasmtime compiles with panic=abort since there's some `#[cfg]`
# for specifically panic=abort there.
Expand Down
36 changes: 35 additions & 1 deletion Cargo.lock

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

11 changes: 6 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ all = 'allow'

[workspace.dependencies]
arbitrary = { version = "1.3.1" }
ahash = { version = "0.8", default-features = false }
wasmtime-wmemcheck = { path = "crates/wmemcheck", version = "=24.0.0" }
wasmtime = { path = "crates/wasmtime", version = "24.0.0", default-features = false }
wasmtime-c-api-macros = { path = "crates/c-api-macros", version = "=24.0.0" }
Expand Down Expand Up @@ -226,7 +227,7 @@ cranelift-jit = { path = "cranelift/jit", version = "0.111.0" }
cranelift-fuzzgen = { path = "cranelift/fuzzgen" }
cranelift-bforest = { path = "cranelift/bforest", version = "0.111.0" }
cranelift-bitset = { path = "cranelift/bitset", version = "0.111.0" }
cranelift-control = { path = "cranelift/control", version = "0.111.0" }
cranelift-control = { path = "cranelift/control", version = "0.111.0", default-features = false }
cranelift = { path = "cranelift/umbrella", version = "0.111.0" }

winch-codegen = { path = "winch/codegen", version = "=0.22.0" }
Expand All @@ -236,7 +237,7 @@ byte-array-literals = { path = "crates/wasi-preview1-component-adapter/byte-arra

# Bytecode Alliance maintained dependencies:
# ---------------------------
regalloc2 = "0.9.3"
regalloc2 = { version = "0.9.3", default-features = false }

# cap-std family:
target-lexicon = "0.12.13"
Expand Down Expand Up @@ -277,9 +278,9 @@ windows-sys = "0.52.0"
env_logger = "0.10"
log = { version = "0.4.8", default-features = false }
clap = { version = "4.3.12", default-features = false, features = ["std", "derive"] }
hashbrown = { version = "0.14", default-features = false }
hashbrown = { version = "0.14" }
capstone = "0.12.0"
once_cell = { version = "1.12.0", default-features = false }
once_cell = { version = "1.12.0", default-features = false, features = ["critical-section"] }
Copy link
Member

Choose a reason for hiding this comment

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

We'll want to find alternative solutions to this since personally I'd consider the critical-section feature as inappropriate for our use cases. That enables spin locks which just keep spinning which are not suitable anywhere outside of a kernel-with-interrupts-disabled context, so the dependencies on once_cell will need to be reworked and/or have other solutions than "just" enabling this feature.

smallvec = { version = "1.6.1", features = ["union"] }
tracing = "0.1.26"
bitflags = "2.0"
Expand Down Expand Up @@ -322,7 +323,7 @@ url = "2.3.1"
humantime = "2.0.0"
postcard = { version = "1.0.8", default-features = false, features = ['alloc'] }
criterion = { version = "0.5.0", default-features = false, features = ["html_reports", "rayon"] }
rustc-hash = "1.1.0"
rustc-hash = { version = "1.1.0", default-features = false }
libtest-mimic = "0.7.0"
semver = { version = "1.0.17", default-features = false }

Expand Down
9 changes: 6 additions & 3 deletions cranelift/codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ edition.workspace = true
workspace = true

[dependencies]
ahash = { workspace = true }
anyhow = { workspace = true, optional = true, features = ['std'] }
bumpalo = "3"
capstone = { workspace = true, optional = true }
core_maths = "0.1"
cranelift-codegen-shared = { path = "./shared", version = "0.111.0" }
cranelift-entity = { workspace = true }
cranelift-bforest = { workspace = true }
Expand All @@ -32,10 +34,10 @@ serde_derive = { workspace = true, optional = true }
postcard = { workspace = true, optional = true }
gimli = { workspace = true, features = ["write", "std"], optional = true }
smallvec = { workspace = true }
once_cell = { workspace = true }
regalloc2 = { workspace = true, features = ["checker", "trace-log"] }
souper-ir = { version = "2.1.0", optional = true }
sha2 = { version = "0.10.2", optional = true }
rustc-hash = { workspace = true }
# It is a goal of the cranelift-codegen crate to have minimal external dependencies.
# Please don't add any unless they are essential to the task of creating binary
# machine code. Integration tests that need external dependencies can be
Expand Down Expand Up @@ -97,6 +99,7 @@ enable-serde = [
"serde_derive",
"cranelift-entity/enable-serde",
"cranelift-bitset/enable-serde",
"hashbrown/serde",
"regalloc2/enable-serde",
"smallvec/serde"
]
Expand All @@ -109,7 +112,7 @@ incremental-cache = [
]

# Enable support for the Souper harvester.
souper-harvest = ["souper-ir", "souper-ir/stringify"]
souper-harvest = ["souper-ir", "souper-ir/stringify", "std"]

# Report any ISLE errors in pretty-printed style.
isle-errors = ["cranelift-isle/fancy-errors"]
Expand All @@ -121,7 +124,7 @@ isle-in-source-tree = []
# Enable tracking how long passes take in Cranelift.
#
# Enabled by default.
timing = []
timing = ["std"]

[[bench]]
name = "x64-evex-encoding"
Expand Down
6 changes: 5 additions & 1 deletion cranelift/codegen/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,11 @@ fn run_compilation(compilation: &IsleCompilation) -> Result<(), Errors> {
.iter()
.chain(compilation.untracked_inputs.iter());

let mut options = isle::codegen::CodegenOptions::default();
let mut options = isle::codegen::CodegenOptions {
no_std: true,
..Default::default()
};

// Because we include!() the generated ISLE source, we cannot
// put the global pragmas (`#![allow(...)]`) in the ISLE
// source itself; we have to put them in the source that
Expand Down
1 change: 1 addition & 0 deletions cranelift/codegen/shared/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//! `cranelift-codegen-meta` libraries.

#![deny(missing_docs)]
#![no_std]

pub mod constant_hash;
pub mod constants;
Expand Down
12 changes: 6 additions & 6 deletions cranelift/codegen/src/alias_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ use crate::{
trace,
};
use cranelift_entity::{packed_option::PackedOption, EntityRef};
use rustc_hash::{FxHashMap, FxHashSet};
use hashbrown::{HashMap, HashSet};

/// For a given program point, the vector of last-store instruction
/// indices for each disjoint category of abstract state.
Expand Down Expand Up @@ -179,14 +179,14 @@ pub struct AliasAnalysis<'a> {
domtree: &'a DominatorTree,

/// Input state to a basic block.
block_input: FxHashMap<Block, LastStores>,
block_input: HashMap<Block, LastStores>,

/// Known memory-value equivalences. This is the result of the
/// analysis. This is a mapping from (last store, address
/// expression, offset, type) to SSA `Value`.
///
/// We keep the defining inst around for quick dominance checks.
mem_values: FxHashMap<MemoryLoc, (Inst, Value)>,
mem_values: HashMap<MemoryLoc, (Inst, Value)>,
}

impl<'a> AliasAnalysis<'a> {
Expand All @@ -195,8 +195,8 @@ impl<'a> AliasAnalysis<'a> {
trace!("alias analysis: input is:\n{:?}", func);
let mut analysis = AliasAnalysis {
domtree,
block_input: FxHashMap::default(),
mem_values: FxHashMap::default(),
block_input: HashMap::default(),
mem_values: HashMap::default(),
};

analysis.compute_block_input_states(func);
Expand All @@ -205,7 +205,7 @@ impl<'a> AliasAnalysis<'a> {

fn compute_block_input_states(&mut self, func: &Function) {
let mut queue = vec![];
let mut queue_set = FxHashSet::default();
let mut queue_set = HashSet::<Block>::default();
let entry = func.layout.entry_block().unwrap();
queue.push(entry);
queue_set.insert(entry);
Expand Down
7 changes: 4 additions & 3 deletions cranelift/codegen/src/ctxhash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
//! node-internal data references some other storage (e.g., offsets into
//! an array or pool of shared data).

use ahash::AHasher;
use core::hash::{Hash, Hasher};
use hashbrown::raw::RawTable;
use std::hash::{Hash, Hasher};

/// Trait that allows for equality comparison given some external
/// context.
Expand Down Expand Up @@ -76,7 +77,7 @@ fn compute_hash<Ctx, K>(ctx: &Ctx, k: &K) -> u32
where
Ctx: CtxHash<K>,
{
let mut hasher = rustc_hash::FxHasher::default();
let mut hasher = AHasher::default();
ctx.ctx_hash(&mut hasher, k);
hasher.finish() as u32
}
Expand All @@ -94,7 +95,7 @@ impl<K, V> CtxHashMap<K, V> {
}) {
Some(bucket) => {
let data = unsafe { bucket.as_mut() };
Some(std::mem::replace(&mut data.v, v))
Some(core::mem::replace(&mut data.v, v))
}
None => {
let data = BucketData { hash, k, v };
Expand Down
5 changes: 3 additions & 2 deletions cranelift/codegen/src/data_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,13 @@ impl DataValue {
/// Write a [DataValue] to a memory location in native-endian byte order.
pub unsafe fn write_value_to(&self, p: *mut u128) {
let size = self.ty().bytes() as usize;
self.write_to_slice_ne(std::slice::from_raw_parts_mut(p as *mut u8, size));
self.write_to_slice_ne(core::slice::from_raw_parts_mut(p as *mut u8, size));
}

/// Read a [DataValue] from a memory location using a given [Type] in native-endian byte order.
pub unsafe fn read_value_from(p: *const u128, ty: Type) -> Self {
DataValue::read_from_slice_ne(
std::slice::from_raw_parts(p as *const u8, ty.bytes() as usize),
core::slice::from_raw_parts(p as *const u8, ty.bytes() as usize),
ty,
)
}
Expand Down Expand Up @@ -274,6 +274,7 @@ pub enum DataValueCastFailure {

// This is manually implementing Error and Display instead of using thiserror to reduce the amount
// of dependencies used by Cranelift.
#[cfg(feature = "std")]
impl std::error::Error for DataValueCastFailure {}

impl Display for DataValueCastFailure {
Expand Down
18 changes: 9 additions & 9 deletions cranelift/codegen/src/egraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ use crate::settings::Flags;
use crate::trace;
use crate::unionfind::UnionFind;
use core::cmp::Ordering;
use core::hash::Hasher;
use cranelift_control::ControlPlane;
use cranelift_entity::packed_option::ReservedValue;
use cranelift_entity::SecondaryMap;
use rustc_hash::FxHashSet;
use hashbrown::HashSet;
use smallvec::SmallVec;
use std::hash::Hasher;

mod cost;
mod elaborate;
Expand Down Expand Up @@ -68,7 +68,7 @@ pub struct EgraphPass<'a> {
///
/// (A canonical Value is the *oldest* Value in an eclass,
/// i.e. tree of union value-nodes).
remat_values: FxHashSet<Value>,
remat_values: HashSet<Value>,
/// Stats collected while we run this pass.
pub(crate) stats: Stats,
/// Union-find that maps all members of a Union tree (eclass) back
Expand All @@ -91,7 +91,7 @@ where
pub(crate) effectful_gvn_map: &'opt mut ScopedHashMap<(Type, InstructionData), Value>,
available_block: &'opt mut SecondaryMap<Value, Block>,
pub(crate) eclasses: &'opt mut UnionFind<Value>,
pub(crate) remat_values: &'opt mut FxHashSet<Value>,
pub(crate) remat_values: &'opt mut HashSet<Value>,
pub(crate) stats: &'opt mut Stats,
domtree: &'opt DominatorTreePreorder,
pub(crate) alias_analysis: &'opt mut AliasAnalysis<'analysis>,
Expand All @@ -100,7 +100,7 @@ where
ctrl_plane: &'opt mut ControlPlane,
// Held locally during optimization of one node (recursively):
pub(crate) rewrite_depth: usize,
pub(crate) subsume_values: FxHashSet<Value>,
pub(crate) subsume_values: HashSet<Value>,
optimized_values: SmallVec<[Value; MATCHES_LIMIT]>,
}

Expand Down Expand Up @@ -277,7 +277,7 @@ where
// A pure node always has exactly one result.
let orig_value = self.func.dfg.first_result(inst);

let mut optimized_values = std::mem::take(&mut self.optimized_values);
let mut optimized_values = core::mem::take(&mut self.optimized_values);

// Limit rewrite depth. When we apply optimization rules, they
// may create new nodes (values) and those are, recursively,
Expand Down Expand Up @@ -522,7 +522,7 @@ impl<'a> EgraphPass<'a> {
ctrl_plane,
stats: Stats::default(),
eclasses: UnionFind::with_capacity(num_values),
remat_values: FxHashSet::default(),
remat_values: HashSet::default(),
}
}

Expand Down Expand Up @@ -682,7 +682,7 @@ impl<'a> EgraphPass<'a> {
available_block: &mut available_block,
eclasses: &mut self.eclasses,
rewrite_depth: 0,
subsume_values: FxHashSet::default(),
subsume_values: HashSet::default(),
remat_values: &mut self.remat_values,
stats: &mut self.stats,
domtree: &self.domtree,
Expand Down Expand Up @@ -805,7 +805,7 @@ impl<'a> CtxEq<(Type, InstructionData), (Type, InstructionData)> for GVNContext<

impl<'a> CtxHash<(Type, InstructionData)> for GVNContext<'a> {
fn ctx_hash<H: Hasher>(&self, state: &mut H, (ty, inst): &(Type, InstructionData)) {
std::hash::Hash::hash(&ty, state);
core::hash::Hash::hash(&ty, state);
inst.hash(state, self.value_lists, |value| self.union_find.find(value));
}
}
Expand Down
Loading
Loading