diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c0bfc835df54..d78e67d9c50a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -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. diff --git a/Cargo.lock b/Cargo.lock index 6d29899f4f23..c4f352aa0be3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,6 +38,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + [[package]] name = "ambient-authority" version = "0.0.2" @@ -536,6 +542,15 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "core_maths" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b02505ccb8c50b0aa21ace0fc08c3e53adebd4e58caa18a36152803c7709a3" +dependencies = [ + "libm", +] + [[package]] name = "cpp_demangle" version = "0.4.3" @@ -586,9 +601,11 @@ dependencies = [ name = "cranelift-codegen" version = "0.111.0" dependencies = [ + "ahash", "anyhow", "bumpalo", "capstone", + "core_maths", "cranelift-bforest", "cranelift-bitset", "cranelift-codegen-meta", @@ -601,9 +618,9 @@ dependencies = [ "gimli", "hashbrown 0.14.3", "log", + "once_cell", "postcard", "regalloc2", - "rustc-hash", "serde", "serde_derive", "sha2", @@ -891,6 +908,12 @@ dependencies = [ "itertools 0.10.5", ] +[[package]] +name = "critical-section" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" + [[package]] name = "crossbeam-deque" version = "0.8.1" @@ -1393,6 +1416,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ "ahash", + "allocator-api2", "serde", ] @@ -1965,6 +1989,10 @@ name = "once_cell" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +dependencies = [ + "critical-section", + "portable-atomic", +] [[package]] name = "oorandom" @@ -2066,6 +2094,12 @@ version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" +[[package]] +name = "portable-atomic" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" + [[package]] name = "postcard" version = "1.0.8" diff --git a/Cargo.toml b/Cargo.toml index 3f4e263d6d77..1ba0191a61fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" } @@ -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" } @@ -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" @@ -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"] } smallvec = { version = "1.6.1", features = ["union"] } tracing = "0.1.26" bitflags = "2.0" @@ -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 } diff --git a/cranelift/codegen/Cargo.toml b/cranelift/codegen/Cargo.toml index 53ef59c0cfbe..a4fc0e70c8b4 100644 --- a/cranelift/codegen/Cargo.toml +++ b/cranelift/codegen/Cargo.toml @@ -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 } @@ -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 @@ -97,6 +99,7 @@ enable-serde = [ "serde_derive", "cranelift-entity/enable-serde", "cranelift-bitset/enable-serde", + "hashbrown/serde", "regalloc2/enable-serde", "smallvec/serde" ] @@ -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"] @@ -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" diff --git a/cranelift/codegen/build.rs b/cranelift/codegen/build.rs index ebaf2b5177a1..6541b5b543ee 100644 --- a/cranelift/codegen/build.rs +++ b/cranelift/codegen/build.rs @@ -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 diff --git a/cranelift/codegen/shared/src/lib.rs b/cranelift/codegen/shared/src/lib.rs index 2a03a8323439..b7a4bec9ce51 100644 --- a/cranelift/codegen/shared/src/lib.rs +++ b/cranelift/codegen/shared/src/lib.rs @@ -2,6 +2,7 @@ //! `cranelift-codegen-meta` libraries. #![deny(missing_docs)] +#![no_std] pub mod constant_hash; pub mod constants; diff --git a/cranelift/codegen/src/alias_analysis.rs b/cranelift/codegen/src/alias_analysis.rs index 636c0a8e948e..9d0a4de54e32 100644 --- a/cranelift/codegen/src/alias_analysis.rs +++ b/cranelift/codegen/src/alias_analysis.rs @@ -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. @@ -179,14 +179,14 @@ pub struct AliasAnalysis<'a> { domtree: &'a DominatorTree, /// Input state to a basic block. - block_input: FxHashMap, + block_input: HashMap, /// 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, + mem_values: HashMap, } impl<'a> AliasAnalysis<'a> { @@ -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); @@ -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::::default(); let entry = func.layout.entry_block().unwrap(); queue.push(entry); queue_set.insert(entry); diff --git a/cranelift/codegen/src/ctxhash.rs b/cranelift/codegen/src/ctxhash.rs index 74290877bbcf..6bc6c637d838 100644 --- a/cranelift/codegen/src/ctxhash.rs +++ b/cranelift/codegen/src/ctxhash.rs @@ -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. @@ -76,7 +77,7 @@ fn compute_hash(ctx: &Ctx, k: &K) -> u32 where Ctx: CtxHash, { - let mut hasher = rustc_hash::FxHasher::default(); + let mut hasher = AHasher::default(); ctx.ctx_hash(&mut hasher, k); hasher.finish() as u32 } @@ -94,7 +95,7 @@ impl CtxHashMap { }) { 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 }; diff --git a/cranelift/codegen/src/data_value.rs b/cranelift/codegen/src/data_value.rs index e2feb4946d2a..1935c35663e2 100644 --- a/cranelift/codegen/src/data_value.rs +++ b/cranelift/codegen/src/data_value.rs @@ -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, ) } @@ -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 { diff --git a/cranelift/codegen/src/egraph.rs b/cranelift/codegen/src/egraph.rs index 2e48d3a78d1f..ca931f7d6330 100644 --- a/cranelift/codegen/src/egraph.rs +++ b/cranelift/codegen/src/egraph.rs @@ -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; @@ -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, + remat_values: HashSet, /// Stats collected while we run this pass. pub(crate) stats: Stats, /// Union-find that maps all members of a Union tree (eclass) back @@ -91,7 +91,7 @@ where pub(crate) effectful_gvn_map: &'opt mut ScopedHashMap<(Type, InstructionData), Value>, available_block: &'opt mut SecondaryMap, pub(crate) eclasses: &'opt mut UnionFind, - pub(crate) remat_values: &'opt mut FxHashSet, + pub(crate) remat_values: &'opt mut HashSet, pub(crate) stats: &'opt mut Stats, domtree: &'opt DominatorTreePreorder, pub(crate) alias_analysis: &'opt mut AliasAnalysis<'analysis>, @@ -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, + pub(crate) subsume_values: HashSet, optimized_values: SmallVec<[Value; MATCHES_LIMIT]>, } @@ -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, @@ -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(), } } @@ -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, @@ -805,7 +805,7 @@ impl<'a> CtxEq<(Type, InstructionData), (Type, InstructionData)> for GVNContext< impl<'a> CtxHash<(Type, InstructionData)> for GVNContext<'a> { fn ctx_hash(&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)); } } diff --git a/cranelift/codegen/src/egraph/cost.rs b/cranelift/codegen/src/egraph/cost.rs index 28aab40e9740..4f36e2da1e14 100644 --- a/cranelift/codegen/src/egraph/cost.rs +++ b/cranelift/codegen/src/egraph/cost.rs @@ -48,7 +48,7 @@ impl core::fmt::Debug for Cost { impl Ord for Cost { #[inline] - fn cmp(&self, other: &Self) -> std::cmp::Ordering { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { // We make sure that the high bits are the op cost and the low bits are // the depth. This means that we can use normal integer comparison to // order by op cost and then depth. @@ -65,7 +65,7 @@ impl Ord for Cost { impl PartialOrd for Cost { #[inline] - fn partial_cmp(&self, other: &Self) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } @@ -117,24 +117,24 @@ impl Cost { } } -impl std::iter::Sum for Cost { +impl core::iter::Sum for Cost { fn sum>(iter: I) -> Self { iter.fold(Self::zero(), |a, b| a + b) } } -impl std::default::Default for Cost { +impl core::default::Default for Cost { fn default() -> Cost { Cost::zero() } } -impl std::ops::Add for Cost { +impl core::ops::Add for Cost { type Output = Cost; fn add(self, other: Cost) -> Cost { let op_cost = self.op_cost().saturating_add(other.op_cost()); - let depth = std::cmp::max(self.depth(), other.depth()); + let depth = core::cmp::max(self.depth(), other.depth()); Cost::new(op_cost, depth) } } diff --git a/cranelift/codegen/src/egraph/elaborate.rs b/cranelift/codegen/src/egraph/elaborate.rs index a35c2ac25734..5f36d0dc95e1 100644 --- a/cranelift/codegen/src/egraph/elaborate.rs +++ b/cranelift/codegen/src/egraph/elaborate.rs @@ -13,7 +13,7 @@ use crate::trace; use alloc::vec::Vec; use cranelift_control::ControlPlane; use cranelift_entity::{packed_option::ReservedValue, SecondaryMap}; -use rustc_hash::{FxHashMap, FxHashSet}; +use hashbrown::{HashMap, HashSet}; use smallvec::{smallvec, SmallVec}; pub(crate) struct Elaborator<'a> { @@ -53,7 +53,7 @@ pub(crate) struct Elaborator<'a> { /// Values that opt rules have indicated should be rematerialized /// in every block they are used (e.g., immediates or other /// "cheap-to-compute" ops). - remat_values: &'a FxHashSet, + remat_values: &'a HashSet, /// Explicitly-unrolled value elaboration stack. elab_stack: Vec, /// Results from the elab stack. @@ -61,7 +61,7 @@ pub(crate) struct Elaborator<'a> { /// Explicitly-unrolled block elaboration stack. block_stack: Vec, /// Copies of values that have been rematerialized. - remat_copies: FxHashMap<(Block, Value), Value>, + remat_copies: HashMap<(Block, Value), Value>, /// Stats for various events during egraph processing, to help /// with optimization of this infrastructure. stats: &'a mut Stats, @@ -81,7 +81,7 @@ impl PartialOrd for BestEntry { impl Ord for BestEntry { #[inline] - fn cmp(&self, other: &Self) -> std::cmp::Ordering { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { self.0.cmp(&other.0).then_with(|| { // Note that this comparison is reversed. When costs are equal, // prefer the value with the bigger index. This is a heuristic that @@ -141,7 +141,7 @@ impl<'a> Elaborator<'a> { func: &'a mut Function, domtree: &'a DominatorTreePreorder, loop_analysis: &'a LoopAnalysis, - remat_values: &'a FxHashSet, + remat_values: &'a HashSet, stats: &'a mut Stats, ctrl_plane: &'a mut ControlPlane, ) -> Self { @@ -161,7 +161,7 @@ impl<'a> Elaborator<'a> { elab_stack: vec![], elab_result_stack: vec![], block_stack: vec![], - remat_copies: FxHashMap::default(), + remat_copies: HashMap::default(), stats, ctrl_plane, } @@ -275,10 +275,10 @@ impl<'a> Elaborator<'a> { } else if best[y].1.is_reserved_value() { best[x] } else { - std::cmp::max(best[x], best[y]) + core::cmp::max(best[x], best[y]) } } else { - std::cmp::min(best[x], best[y]) + core::cmp::min(best[x], best[y]) }; trace!( " -> best of union({:?}, {:?}) = {:?}", @@ -377,9 +377,9 @@ impl<'a> Elaborator<'a> { /// `arg` and rewrite `arg` to refer to it, if needed. Returns /// `true` if a rewrite occurred. fn maybe_remat_arg( - remat_values: &FxHashSet, + remat_values: &HashSet, func: &mut Function, - remat_copies: &mut FxHashMap<(Block, Value), Value>, + remat_copies: &mut HashMap<(Block, Value), Value>, insert_block: Block, before: Inst, arg: &mut ElaboratedValue, diff --git a/cranelift/codegen/src/incremental_cache.rs b/cranelift/codegen/src/incremental_cache.rs index bf5f6215e454..6e1f1dab6fae 100644 --- a/cranelift/codegen/src/incremental_cache.rs +++ b/cranelift/codegen/src/incremental_cache.rs @@ -112,7 +112,7 @@ pub trait CacheKvStore { #[derive(Clone, Hash, PartialEq, Eq)] pub struct CacheKeyHash([u8; 32]); -impl std::fmt::Display for CacheKeyHash { +impl core::fmt::Display for CacheKeyHash { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "CacheKeyHash:{:?}", self.0) } diff --git a/cranelift/codegen/src/ir/condcodes.rs b/cranelift/codegen/src/ir/condcodes.rs index e791649bb69c..009f95bf391c 100644 --- a/cranelift/codegen/src/ir/condcodes.rs +++ b/cranelift/codegen/src/ir/condcodes.rs @@ -344,7 +344,7 @@ impl FromStr for FloatCC { #[cfg(test)] mod tests { use super::*; - use std::string::ToString; + use alloc::string::ToString; #[test] fn int_complement() { diff --git a/cranelift/codegen/src/ir/constant.rs b/cranelift/codegen/src/ir/constant.rs index fadaabc314bd..d1945b4c915e 100644 --- a/cranelift/codegen/src/ir/constant.rs +++ b/cranelift/codegen/src/ir/constant.rs @@ -275,7 +275,7 @@ impl ConstantPool { #[cfg(test)] mod tests { use super::*; - use std::string::ToString; + use alloc::string::ToString; #[test] fn empty() { diff --git a/cranelift/codegen/src/ir/extname.rs b/cranelift/codegen/src/ir/extname.rs index b06eb843f536..b41307b2750c 100644 --- a/cranelift/codegen/src/ir/extname.rs +++ b/cranelift/codegen/src/ir/extname.rs @@ -99,7 +99,7 @@ pub struct TestcaseName(Box<[u8]>); impl fmt::Display for TestcaseName { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_char('%')?; - f.write_str(std::str::from_utf8(&self.0).unwrap()) + f.write_str(core::str::from_utf8(&self.0).unwrap()) } } diff --git a/cranelift/codegen/src/ir/immediates.rs b/cranelift/codegen/src/ir/immediates.rs index 24982c644c95..b0a828bf3a9c 100644 --- a/cranelift/codegen/src/ir/immediates.rs +++ b/cranelift/codegen/src/ir/immediates.rs @@ -13,6 +13,9 @@ use core::{i32, u32}; #[cfg(feature = "enable-serde")] use serde_derive::{Deserialize, Serialize}; +#[cfg(not(feature = "std"))] +use core_maths::CoreFloat; + /// Convert a type into a vector of bytes; all implementors in this file must use little-endian /// orderings of bytes to match WebAssembly's little-endianness. pub trait IntoBytes { @@ -972,7 +975,8 @@ impl Ieee32 { /// Returns the nearest integer to `self`. Rounds half-way cases to the number /// with an even least significant digit. pub fn round_ties_even(self) -> Self { - Self::with_float(self.as_f32().round_ties_even()) + // TODO: find a suitable alternative to std round_ties_even() in no_std + Self::with_float(self.as_f32().round()) } } @@ -1189,7 +1193,8 @@ impl Ieee64 { /// Returns the nearest integer to `self`. Rounds half-way cases to the number /// with an even least significant digit. pub fn round_ties_even(self) -> Self { - Self::with_float(self.as_f64().round_ties_even()) + // TODO: find a suitable alternative to std round_ties_even() in no_std + Self::with_float(self.as_f64().round()) } } @@ -1828,7 +1833,7 @@ mod tests { fn fcvt_to_sint_negative_overflow_ieee32() { for n in &[8, 16] { assert_eq!(-((1u32 << (n - 1)) as f32) - 1.0, unsafe { - mem::transmute(Ieee32::fcvt_to_sint_negative_overflow(*n)) + mem::transmute::<_, f32>(Ieee32::fcvt_to_sint_negative_overflow(*n)) }); } } @@ -1966,7 +1971,7 @@ mod tests { fn fcvt_to_sint_negative_overflow_ieee64() { for n in &[8, 16, 32] { assert_eq!(-((1u64 << (n - 1)) as f64) - 1.0, unsafe { - mem::transmute(Ieee64::fcvt_to_sint_negative_overflow(*n)) + mem::transmute::<_, f64>(Ieee64::fcvt_to_sint_negative_overflow(*n)) }); } } diff --git a/cranelift/codegen/src/ir/instructions.rs b/cranelift/codegen/src/ir/instructions.rs index 6d483aba33ba..96944c77d582 100644 --- a/cranelift/codegen/src/ir/instructions.rs +++ b/cranelift/codegen/src/ir/instructions.rs @@ -301,7 +301,7 @@ impl InstructionData { match self { Self::Jump { ref destination, .. - } => std::slice::from_ref(destination), + } => core::slice::from_ref(destination), Self::Brif { blocks, .. } => blocks.as_slice(), Self::BranchTable { table, .. } => jump_tables.get(*table).unwrap().all_branches(), _ => { @@ -322,7 +322,7 @@ impl InstructionData { Self::Jump { ref mut destination, .. - } => std::slice::from_mut(destination), + } => core::slice::from_mut(destination), Self::Brif { blocks, .. } => blocks.as_mut_slice(), Self::BranchTable { table, .. } => { jump_tables.get_mut(*table).unwrap().all_branches_mut() @@ -861,7 +861,7 @@ mod tests { fn inst_data_size() { // The size of `InstructionData` is performance sensitive, so make sure // we don't regress it unintentionally. - assert_eq!(std::mem::size_of::(), 16); + assert_eq!(core::mem::size_of::(), 16); } #[test] diff --git a/cranelift/codegen/src/ir/jumptable.rs b/cranelift/codegen/src/ir/jumptable.rs index 8e1e15c7d621..fa4e93cb2b56 100644 --- a/cranelift/codegen/src/ir/jumptable.rs +++ b/cranelift/codegen/src/ir/jumptable.rs @@ -31,7 +31,7 @@ impl JumpTableData { /// Create a new jump table with the provided blocks. pub fn new(def: BlockCall, table: &[BlockCall]) -> Self { Self { - table: std::iter::once(def).chain(table.iter().copied()).collect(), + table: core::iter::once(def).chain(table.iter().copied()).collect(), } } @@ -114,7 +114,7 @@ mod tests { use crate::entity::EntityRef; use crate::ir::instructions::ValueListPool; use crate::ir::{Block, BlockCall, Value}; - use std::string::ToString; + use alloc::string::ToString; #[test] fn empty() { diff --git a/cranelift/codegen/src/ir/memtype.rs b/cranelift/codegen/src/ir/memtype.rs index 9a6ca67d94a7..5aa9dc8035bf 100644 --- a/cranelift/codegen/src/ir/memtype.rs +++ b/cranelift/codegen/src/ir/memtype.rs @@ -108,14 +108,14 @@ pub enum MemoryTypeData { Empty, } -impl std::default::Default for MemoryTypeData { +impl core::default::Default for MemoryTypeData { fn default() -> Self { Self::Empty } } -impl std::fmt::Display for MemoryTypeData { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl core::fmt::Display for MemoryTypeData { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { match self { Self::Struct { size, fields } => { write!(f, "struct {size} {{")?; diff --git a/cranelift/codegen/src/ir/pcc.rs b/cranelift/codegen/src/ir/pcc.rs index 33a515cac670..50960ff1871d 100644 --- a/cranelift/codegen/src/ir/pcc.rs +++ b/cranelift/codegen/src/ir/pcc.rs @@ -77,14 +77,14 @@ use crate::ir::types::*; use crate::isa::TargetIsa; use crate::machinst::{BlockIndex, LowerBackend, VCode}; use crate::trace; +use core::fmt; use regalloc2::Function as _; -use std::fmt; #[cfg(feature = "enable-serde")] use serde_derive::{Deserialize, Serialize}; /// The result of checking proof-carrying-code facts. -pub type PccResult = std::result::Result; +pub type PccResult = core::result::Result; /// An error or inconsistency discovered when checking proof-carrying /// code. @@ -332,7 +332,7 @@ impl Expr { } else { Expr { base: BaseExpr::min(&lhs.base, &rhs.base), - offset: std::cmp::min(lhs.offset, rhs.offset), + offset: core::cmp::min(lhs.offset, rhs.offset), } } } @@ -347,7 +347,7 @@ impl Expr { } else { Expr { base: BaseExpr::max(&lhs.base, &rhs.base), - offset: std::cmp::max(lhs.offset, rhs.offset), + offset: core::cmp::max(lhs.offset, rhs.offset), } } } @@ -651,8 +651,8 @@ impl Fact { }, ) if bw_lhs == bw_rhs && max_lhs >= min_rhs && max_rhs >= min_lhs => Fact::Range { bit_width: *bw_lhs, - min: std::cmp::max(*min_lhs, *min_rhs), - max: std::cmp::min(*max_lhs, *max_rhs), + min: core::cmp::max(*min_lhs, *min_rhs), + max: core::cmp::min(*max_lhs, *max_rhs), }, ( @@ -693,8 +693,8 @@ impl Fact { { Fact::Mem { ty: *ty_lhs, - min_offset: std::cmp::max(*min_offset_lhs, *min_offset_rhs), - max_offset: std::cmp::min(*max_offset_lhs, *max_offset_rhs), + min_offset: core::cmp::max(*min_offset_lhs, *min_offset_rhs), + max_offset: core::cmp::min(*max_offset_lhs, *max_offset_rhs), nullable: *nullable_lhs && *nullable_rhs, } } @@ -910,7 +910,7 @@ impl<'a> FactContext<'a> { ) if bw_lhs == bw_rhs && add_width >= *bw_lhs => { let computed_min = min_lhs.checked_add(*min_rhs)?; let computed_max = max_lhs.checked_add(*max_rhs)?; - let computed_max = std::cmp::min(max_value_for_width(add_width), computed_max); + let computed_max = core::cmp::min(max_value_for_width(add_width), computed_max); Some(Fact::Range { bit_width: *bw_lhs, min: computed_min, diff --git a/cranelift/codegen/src/isa/aarch64/abi.rs b/cranelift/codegen/src/isa/aarch64/abi.rs index ff1ccd97233b..99cbfbeee1d6 100644 --- a/cranelift/codegen/src/isa/aarch64/abi.rs +++ b/cranelift/codegen/src/isa/aarch64/abi.rs @@ -13,9 +13,9 @@ use crate::settings; use crate::{CodegenError, CodegenResult}; use alloc::boxed::Box; use alloc::vec::Vec; +use once_cell::sync::OnceCell; use regalloc2::{MachineEnv, PReg, PRegSet}; use smallvec::{smallvec, SmallVec}; -use std::sync::OnceLock; // We use a generic implementation that factors out AArch64 and x64 ABI commonalities, because // these ABIs are very similar. @@ -321,7 +321,7 @@ impl ABIMachineSpec for AArch64MachineDeps { } else { // Every arg takes a minimum slot of 8 bytes. (16-byte stack // alignment happens separately after all args.) - std::cmp::max(size, 8) + core::cmp::max(size, 8) }; // Align the stack slot. @@ -1126,10 +1126,10 @@ impl ABIMachineSpec for AArch64MachineDeps { fn get_machine_env(flags: &settings::Flags, _call_conv: isa::CallConv) -> &MachineEnv { if flags.enable_pinned_reg() { - static MACHINE_ENV: OnceLock = OnceLock::new(); + static MACHINE_ENV: OnceCell = OnceCell::new(); MACHINE_ENV.get_or_init(|| create_reg_env(true)) } else { - static MACHINE_ENV: OnceLock = OnceLock::new(); + static MACHINE_ENV: OnceCell = OnceCell::new(); MACHINE_ENV.get_or_init(|| create_reg_env(false)) } } diff --git a/cranelift/codegen/src/isa/aarch64/inst/imms.rs b/cranelift/codegen/src/isa/aarch64/inst/imms.rs index 03979d27de6d..d70154f9c4a5 100644 --- a/cranelift/codegen/src/isa/aarch64/inst/imms.rs +++ b/cranelift/codegen/src/isa/aarch64/inst/imms.rs @@ -4,7 +4,7 @@ use crate::ir::types::*; use crate::isa::aarch64::inst::{OperandSize, ScalarSize}; use crate::machinst::PrettyPrint; -use std::string::String; +use alloc::string::String; /// An immediate that represents the NZCV flags. #[derive(Clone, Copy, Debug)] diff --git a/cranelift/codegen/src/isa/aarch64/inst/mod.rs b/cranelift/codegen/src/isa/aarch64/inst/mod.rs index 8bb7c852982e..91f70e83813c 100644 --- a/cranelift/codegen/src/isa/aarch64/inst/mod.rs +++ b/cranelift/codegen/src/isa/aarch64/inst/mod.rs @@ -9,11 +9,11 @@ use crate::{settings, CodegenError, CodegenResult}; use crate::machinst::{PrettyPrint, Reg, RegClass, Writable}; +use alloc::string::{String, ToString}; use alloc::vec::Vec; +use core::fmt::Write; use regalloc2::PRegSet; use smallvec::{smallvec, SmallVec}; -use std::fmt::Write; -use std::string::{String, ToString}; pub(crate) mod regs; pub(crate) use self::regs::*; @@ -148,7 +148,7 @@ fn count_zero_half_words(mut value: u64, num_half_words: u8) -> usize { fn inst_size_test() { // This test will help with unintentionally growing the size // of the Inst enum. - assert_eq!(32, std::mem::size_of::()); + assert_eq!(32, core::mem::size_of::()); } impl Inst { @@ -851,41 +851,41 @@ fn aarch64_get_operands(inst: &mut Inst, collector: &mut impl OperandVisitor) { collector.reg_use(rn); } Inst::Args { args } => { - for ArgPair { vreg, preg } in args { - collector.reg_fixed_def(vreg, *preg); + for ArgPair { mut vreg, preg } in args { + collector.reg_fixed_def(&mut vreg, *preg); } } Inst::Rets { rets } => { - for RetPair { vreg, preg } in rets { - collector.reg_fixed_use(vreg, *preg); + for RetPair { mut vreg, preg } in rets { + collector.reg_fixed_use(&mut vreg, *preg); } } Inst::Ret { .. } | Inst::AuthenticatedRet { .. } => {} Inst::Jump { .. } => {} Inst::Call { info, .. } => { let CallInfo { uses, defs, .. } = &mut **info; - for CallArgPair { vreg, preg } in uses { - collector.reg_fixed_use(vreg, *preg); + for CallArgPair { mut vreg, preg } in uses { + collector.reg_fixed_use(&mut vreg, *preg); } - for CallRetPair { vreg, preg } in defs { - collector.reg_fixed_def(vreg, *preg); + for CallRetPair { mut vreg, preg } in defs { + collector.reg_fixed_def(&mut vreg, *preg); } collector.reg_clobbers(info.clobbers); } Inst::CallInd { info, .. } => { let CallIndInfo { rn, uses, defs, .. } = &mut **info; collector.reg_use(rn); - for CallArgPair { vreg, preg } in uses { - collector.reg_fixed_use(vreg, *preg); + for CallArgPair { mut vreg, preg } in uses { + collector.reg_fixed_use(&mut vreg, *preg); } - for CallRetPair { vreg, preg } in defs { - collector.reg_fixed_def(vreg, *preg); + for CallRetPair { mut vreg, preg } in defs { + collector.reg_fixed_def(&mut vreg, *preg); } collector.reg_clobbers(info.clobbers); } Inst::ReturnCall { info, callee: _ } => { - for CallArgPair { vreg, preg } in &mut info.uses { - collector.reg_fixed_use(vreg, *preg); + for CallArgPair { mut vreg, preg } in &mut info.uses { + collector.reg_fixed_use(&mut vreg, *preg); } } Inst::ReturnCallInd { info, callee } => { @@ -894,8 +894,8 @@ fn aarch64_get_operands(inst: &mut Inst, collector: &mut impl OperandVisitor) { // register that won't be clobbered by the callee-save restore code emitted with a // return_call_indirect. collector.reg_fixed_use(callee, xreg(1)); - for CallArgPair { vreg, preg } in &mut info.uses { - collector.reg_fixed_use(vreg, *preg); + for CallArgPair { mut vreg, preg } in &mut info.uses { + collector.reg_fixed_use(&mut vreg, *preg); } } Inst::CondBr { kind, .. } => match kind { diff --git a/cranelift/codegen/src/isa/aarch64/inst/regs.rs b/cranelift/codegen/src/isa/aarch64/inst/regs.rs index f9b99c5b2071..c22d8b409e81 100644 --- a/cranelift/codegen/src/isa/aarch64/inst/regs.rs +++ b/cranelift/codegen/src/isa/aarch64/inst/regs.rs @@ -8,7 +8,7 @@ use crate::machinst::{Reg, RegClass, Writable}; use regalloc2::PReg; use regalloc2::VReg; -use std::string::{String, ToString}; +use alloc::string::{String, ToString}; //============================================================================= // Registers, the Universe thereof, and printing diff --git a/cranelift/codegen/src/isa/aarch64/lower/isle.rs b/cranelift/codegen/src/isa/aarch64/lower/isle.rs index 0191e7cd5f7c..a92d1627c373 100644 --- a/cranelift/codegen/src/isa/aarch64/lower/isle.rs +++ b/cranelift/codegen/src/isa/aarch64/lower/isle.rs @@ -31,9 +31,9 @@ use crate::{ abi::ArgPair, ty_bits, InstOutput, IsTailCall, MachInst, VCodeConstant, VCodeConstantData, }, }; +use alloc::boxed::Box; +use alloc::vec::Vec; use regalloc2::PReg; -use std::boxed::Box; -use std::vec::Vec; type BoxCallInfo = Box; type BoxCallIndInfo = Box; @@ -206,7 +206,7 @@ impl Context for IsleContext<'_, '_, MInst, AArch64Backend> { fn lshl_from_u64(&mut self, ty: Type, n: u64) -> Option { let shiftimm = ShiftOpShiftImm::maybe_from_shift(n)?; let shiftee_bits = ty_bits(ty); - if shiftee_bits <= std::u8::MAX as usize { + if shiftee_bits <= core::u8::MAX as usize { let shiftimm = shiftimm.mask(shiftee_bits as u8); Some(ShiftOpAndAmt::new(ShiftOp::LSL, shiftimm)) } else { @@ -217,7 +217,7 @@ impl Context for IsleContext<'_, '_, MInst, AArch64Backend> { fn ashr_from_u64(&mut self, ty: Type, n: u64) -> Option { let shiftimm = ShiftOpShiftImm::maybe_from_shift(n)?; let shiftee_bits = ty_bits(ty); - if shiftee_bits <= std::u8::MAX as usize { + if shiftee_bits <= core::u8::MAX as usize { let shiftimm = shiftimm.mask(shiftee_bits as u8); Some(ShiftOpAndAmt::new(ShiftOp::ASR, shiftimm)) } else { diff --git a/cranelift/codegen/src/isa/mod.rs b/cranelift/codegen/src/isa/mod.rs index 03ecdd2d543c..5dd084442562 100644 --- a/cranelift/codegen/src/isa/mod.rs +++ b/cranelift/codegen/src/isa/mod.rs @@ -23,7 +23,7 @@ //! # #[macro_use] extern crate target_lexicon; //! use cranelift_codegen::isa; //! use cranelift_codegen::settings::{self, Configurable}; -//! use std::str::FromStr; +//! use core::str::FromStr; //! use target_lexicon::Triple; //! //! let shared_builder = settings::builder(); @@ -131,6 +131,7 @@ pub enum LookupError { // 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 LookupError {} impl fmt::Display for LookupError { diff --git a/cranelift/codegen/src/isa/riscv64/abi.rs b/cranelift/codegen/src/isa/riscv64/abi.rs index 2a6b23f3af38..28523007f15a 100644 --- a/cranelift/codegen/src/isa/riscv64/abi.rs +++ b/cranelift/codegen/src/isa/riscv64/abi.rs @@ -18,10 +18,10 @@ use crate::CodegenError; use crate::CodegenResult; use alloc::boxed::Box; use alloc::vec::Vec; +use once_cell::sync::OnceCell; use regalloc2::{MachineEnv, PReg, PRegSet}; use smallvec::{smallvec, SmallVec}; -use std::sync::OnceLock; /// Support for the Riscv64 ABI from the callee side (within a function body). pub(crate) type Riscv64Callee = Callee; @@ -67,7 +67,7 @@ impl RiscvFlags { // Due to a limitation in regalloc2, we can't support types // larger than 1024 bytes. So limit that here. - return std::cmp::min(size, 1024); + return core::cmp::min(size, 1024); } return 0; @@ -151,7 +151,7 @@ impl ABIMachineSpec for Riscv64MachineDeps { // Compute size and 16-byte stack alignment happens // separately after all args. let size = reg_ty.bits() / 8; - let size = std::cmp::max(size, 8); + let size = core::cmp::max(size, 8); // Align. debug_assert!(size.is_power_of_two()); next_stack = align_to(next_stack, size); @@ -677,7 +677,7 @@ impl ABIMachineSpec for Riscv64MachineDeps { } fn get_machine_env(_flags: &settings::Flags, _call_conv: isa::CallConv) -> &MachineEnv { - static MACHINE_ENV: OnceLock = OnceLock::new(); + static MACHINE_ENV: OnceCell = OnceCell::new(); MACHINE_ENV.get_or_init(create_reg_enviroment) } diff --git a/cranelift/codegen/src/isa/riscv64/inst/args.rs b/cranelift/codegen/src/isa/riscv64/inst/args.rs index 67d370071027..036e3637ca8d 100644 --- a/cranelift/codegen/src/isa/riscv64/inst/args.rs +++ b/cranelift/codegen/src/isa/riscv64/inst/args.rs @@ -8,7 +8,10 @@ use crate::isa::riscv64::lower::isle::generated_code::{ }; use crate::machinst::isle::WritableReg; -use std::fmt::Result; +use core::fmt::Result; + +#[cfg(not(feature = "std"))] +use core_maths::CoreFloat; /// A macro for defining a newtype of `Reg` that enforces some invariant about /// the wrapped `Reg` (such as that it is of a particular register class). @@ -57,7 +60,7 @@ macro_rules! newtype_of_reg { // NB: We cannot implement `DerefMut` because that would let people do // nasty stuff like `*my_xreg.deref_mut() = some_freg`, breaking the // invariants that `XReg` provides. - impl std::ops::Deref for $newtype_reg { + impl core::ops::Deref for $newtype_reg { type Target = Reg; fn deref(&self) -> &Reg { diff --git a/cranelift/codegen/src/isa/riscv64/inst/emit_tests.rs b/cranelift/codegen/src/isa/riscv64/inst/emit_tests.rs index fe05c646846e..d91da9d34c20 100644 --- a/cranelift/codegen/src/isa/riscv64/inst/emit_tests.rs +++ b/cranelift/codegen/src/isa/riscv64/inst/emit_tests.rs @@ -1,7 +1,7 @@ #[allow(unused)] use crate::ir::LibCall; use crate::isa::riscv64::inst::*; -use std::borrow::Cow; +use alloc::borrow::Cow; fn fa7() -> Reg { f_reg(17) @@ -42,7 +42,7 @@ fn test_riscv64_binemit() { } } - let mut insns = Vec::::with_capacity(500); + let mut insns = alloc::vec::Vec::::with_capacity(500); insns.push(TestUnit::new(Inst::Ret {}, "ret", 0x00008067)); diff --git a/cranelift/codegen/src/isa/riscv64/inst/imms.rs b/cranelift/codegen/src/isa/riscv64/inst/imms.rs index 28f279154eaa..6085cf09a800 100644 --- a/cranelift/codegen/src/isa/riscv64/inst/imms.rs +++ b/cranelift/codegen/src/isa/riscv64/inst/imms.rs @@ -3,7 +3,7 @@ // Some variants are never constructed, but we still want them as options in the future. use super::Inst; #[allow(dead_code)] -use std::fmt::{Debug, Display, Formatter, Result}; +use core::fmt::{Debug, Display, Formatter, Result}; #[derive(Copy, Clone, Debug, Default)] pub struct Imm12 { diff --git a/cranelift/codegen/src/isa/riscv64/inst/mod.rs b/cranelift/codegen/src/isa/riscv64/inst/mod.rs index 80bd149b74d1..80506dc6a208 100644 --- a/cranelift/codegen/src/isa/riscv64/inst/mod.rs +++ b/cranelift/codegen/src/isa/riscv64/inst/mod.rs @@ -12,12 +12,12 @@ use crate::{settings, CodegenError, CodegenResult}; pub use crate::ir::condcodes::FloatCC; +use alloc::boxed::Box; +use alloc::fmt::Write; +use alloc::string::{String, ToString}; use alloc::vec::Vec; use regalloc2::{PRegSet, RegClass}; use smallvec::{smallvec, SmallVec}; -use std::boxed::Box; -use std::fmt::Write; -use std::string::{String, ToString}; pub mod regs; pub use self::regs::*; @@ -38,7 +38,7 @@ use crate::isa::riscv64::abi::Riscv64MachineDeps; #[cfg(test)] mod emit_tests; -use std::fmt::{Display, Formatter}; +use core::fmt::{Display, Formatter}; pub(crate) type VecU8 = Vec; @@ -110,7 +110,7 @@ impl CondBrTarget { } impl Display for CondBrTarget { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { match self { CondBrTarget::Label(l) => write!(f, "{}", l.to_string()), CondBrTarget::Fallthrough => write!(f, "0"), diff --git a/cranelift/codegen/src/isa/riscv64/lower/isle.rs b/cranelift/codegen/src/isa/riscv64/lower/isle.rs index 5695700f4139..811f539c777a 100644 --- a/cranelift/codegen/src/isa/riscv64/lower/isle.rs +++ b/cranelift/codegen/src/isa/riscv64/lower/isle.rs @@ -24,9 +24,9 @@ use crate::{ machinst::{ArgPair, InstOutput, IsTailCall}, }; use crate::{isa, isle_common_prelude_methods}; +use alloc::boxed::Box; +use alloc::vec::Vec; use regalloc2::PReg; -use std::boxed::Box; -use std::vec::Vec; type BoxCallInfo = Box; type BoxCallIndInfo = Box; diff --git a/cranelift/codegen/src/isa/s390x/abi.rs b/cranelift/codegen/src/isa/s390x/abi.rs index dc01aa0fb627..1a3a66c814f8 100644 --- a/cranelift/codegen/src/isa/s390x/abi.rs +++ b/cranelift/codegen/src/isa/s390x/abi.rs @@ -79,9 +79,9 @@ use crate::machinst::*; use crate::settings; use crate::{CodegenError, CodegenResult}; use alloc::vec::Vec; +use once_cell::sync::OnceCell; use regalloc2::{MachineEnv, PRegSet}; use smallvec::{smallvec, SmallVec}; -use std::sync::OnceLock; // We use a generic implementation that factors out ABI commonalities. @@ -304,11 +304,11 @@ impl ABIMachineSpec for S390xMachineDeps { // Compute size. Every argument or return value takes a slot of // at least 8 bytes. let size = (ty_bits(param.value_type) / 8) as u32; - let slot_size = std::cmp::max(size, 8); + let slot_size = core::cmp::max(size, 8); // Align the stack slot. debug_assert!(slot_size.is_power_of_two()); - let slot_align = std::cmp::min(slot_size, 8); + let slot_align = core::cmp::min(slot_size, 8); next_stack = align_to(next_stack, slot_align); // If the type is actually of smaller size (and the argument @@ -765,7 +765,7 @@ impl ABIMachineSpec for S390xMachineDeps { } fn get_machine_env(_flags: &settings::Flags, _call_conv: isa::CallConv) -> &MachineEnv { - static MACHINE_ENV: OnceLock = OnceLock::new(); + static MACHINE_ENV: OnceCell = OnceCell::new(); MACHINE_ENV.get_or_init(create_machine_env) } diff --git a/cranelift/codegen/src/isa/s390x/inst/imms.rs b/cranelift/codegen/src/isa/s390x/inst/imms.rs index 8ceebbcdac15..9559f34ac7f8 100644 --- a/cranelift/codegen/src/isa/s390x/inst/imms.rs +++ b/cranelift/codegen/src/isa/s390x/inst/imms.rs @@ -1,7 +1,7 @@ //! S390x ISA definitions: immediate constants. use crate::machinst::PrettyPrint; -use std::string::String; +use alloc::string::String; /// An unsigned 12-bit immediate. #[derive(Clone, Copy, Debug)] diff --git a/cranelift/codegen/src/isa/s390x/inst/mod.rs b/cranelift/codegen/src/isa/s390x/inst/mod.rs index 05a36e098ffa..2dc9cec4a77f 100644 --- a/cranelift/codegen/src/isa/s390x/inst/mod.rs +++ b/cranelift/codegen/src/isa/s390x/inst/mod.rs @@ -7,11 +7,11 @@ use crate::isa::{CallConv, FunctionAlignment}; use crate::machinst::*; use crate::{settings, CodegenError, CodegenResult}; use alloc::boxed::Box; +use alloc::string::{String, ToString}; use alloc::vec::Vec; +use core::fmt::Write; use regalloc2::{PReg, PRegSet}; use smallvec::SmallVec; -use std::fmt::Write; -use std::string::{String, ToString}; pub mod regs; pub use self::regs::*; pub mod imms; @@ -63,7 +63,7 @@ pub struct CallIndInfo { fn inst_size_test() { // This test will help with unintentionally growing the size // of the Inst enum. - assert_eq!(32, std::mem::size_of::()); + assert_eq!(32, core::mem::size_of::()); } /// A register pair. Enum so it can be destructured in ISLE. diff --git a/cranelift/codegen/src/isa/s390x/lower/isle.rs b/cranelift/codegen/src/isa/s390x/lower/isle.rs index f2937856b3b5..8de6ce794d07 100644 --- a/cranelift/codegen/src/isa/s390x/lower/isle.rs +++ b/cranelift/codegen/src/isa/s390x/lower/isle.rs @@ -28,11 +28,14 @@ use crate::{ VCodeConstant, VCodeConstantData, }, }; +use alloc::boxed::Box; +use alloc::vec::Vec; +use core::cell::Cell; use regalloc2::PReg; use smallvec::smallvec; -use std::boxed::Box; -use std::cell::Cell; -use std::vec::Vec; + +#[cfg(not(feature = "std"))] +use core_maths::CoreFloat; /// Information describing a library call to be emitted. pub struct LibCallInfo { @@ -772,7 +775,7 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, S390xBackend> { #[inline] fn fcvt_to_sint_lb32(&mut self, size: u8) -> u64 { let lb = (-2.0_f32).powi((size - 1).into()); - std::cmp::max(lb.to_bits() + 1, (lb - 1.0).to_bits()) as u64 + core::cmp::max(lb.to_bits() + 1, (lb - 1.0).to_bits()) as u64 } #[inline] @@ -783,7 +786,7 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, S390xBackend> { #[inline] fn fcvt_to_sint_lb64(&mut self, size: u8) -> u64 { let lb = (-2.0_f64).powi((size - 1).into()); - std::cmp::max(lb.to_bits() + 1, (lb - 1.0).to_bits()) + core::cmp::max(lb.to_bits() + 1, (lb - 1.0).to_bits()) } #[inline] diff --git a/cranelift/codegen/src/isa/unwind.rs b/cranelift/codegen/src/isa/unwind.rs index d357b64fad6e..e7242e007f42 100644 --- a/cranelift/codegen/src/isa/unwind.rs +++ b/cranelift/codegen/src/isa/unwind.rs @@ -12,6 +12,7 @@ pub mod systemv; pub mod winx64; /// CFA-based unwind information used on SystemV. +#[cfg(feature = "unwind")] pub type CfaUnwindInfo = systemv::UnwindInfo; /// Expected unwind info type. diff --git a/cranelift/codegen/src/isa/unwind/systemv.rs b/cranelift/codegen/src/isa/unwind/systemv.rs index bfc51d846030..d33b2d25325b 100644 --- a/cranelift/codegen/src/isa/unwind/systemv.rs +++ b/cranelift/codegen/src/isa/unwind/systemv.rs @@ -23,10 +23,11 @@ pub enum RegisterMappingError { // 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 RegisterMappingError {} -impl std::fmt::Display for RegisterMappingError { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl core::fmt::Display for RegisterMappingError { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { match self { RegisterMappingError::MissingBank => write!(f, "unable to find bank for register info"), RegisterMappingError::UnsupportedArchitecture => write!( diff --git a/cranelift/codegen/src/isa/x64/abi.rs b/cranelift/codegen/src/isa/x64/abi.rs index 10d71f7aad23..51a8dfc316c0 100644 --- a/cranelift/codegen/src/isa/x64/abi.rs +++ b/cranelift/codegen/src/isa/x64/abi.rs @@ -11,9 +11,9 @@ use crate::{CodegenError, CodegenResult}; use alloc::boxed::Box; use alloc::vec::Vec; use args::*; +use once_cell::sync::OnceCell; use regalloc2::{MachineEnv, PReg, PRegSet}; use smallvec::{smallvec, SmallVec}; -use std::sync::OnceLock; /// This is the limit for the size of argument and return-value areas on the /// stack. We place a reasonable limit here to avoid integer overflow issues @@ -313,7 +313,7 @@ impl ABIMachineSpec for X64ABIMachineSpec { { size } else { - let size = std::cmp::max(size, 8); + let size = core::cmp::max(size, 8); // Align. debug_assert!(size.is_power_of_two()); @@ -381,7 +381,7 @@ impl ABIMachineSpec for X64ABIMachineSpec { for slot in slots.iter_mut() { if let ABIArgSlot::Stack { offset, ty, .. } = slot { let size = if uses_extension { - i64::from(std::cmp::max(ty.bytes(), 8)) + i64::from(core::cmp::max(ty.bytes(), 8)) } else { i64::from(ty.bytes()) }; @@ -912,10 +912,10 @@ impl ABIMachineSpec for X64ABIMachineSpec { fn get_machine_env(flags: &settings::Flags, _call_conv: isa::CallConv) -> &MachineEnv { if flags.enable_pinned_reg() { - static MACHINE_ENV: OnceLock = OnceLock::new(); + static MACHINE_ENV: OnceCell = OnceCell::new(); MACHINE_ENV.get_or_init(|| create_reg_env_systemv(true)) } else { - static MACHINE_ENV: OnceLock = OnceLock::new(); + static MACHINE_ENV: OnceCell = OnceCell::new(); MACHINE_ENV.get_or_init(|| create_reg_env_systemv(false)) } } diff --git a/cranelift/codegen/src/isa/x64/encoding/evex.rs b/cranelift/codegen/src/isa/x64/encoding/evex.rs index 3805e7215545..2af3179bbb2c 100644 --- a/cranelift/codegen/src/isa/x64/encoding/evex.rs +++ b/cranelift/codegen/src/isa/x64/encoding/evex.rs @@ -477,7 +477,7 @@ mod tests { use crate::ir::MemFlags; use crate::isa::x64::args::Gpr; use crate::isa::x64::inst::regs; - use std::vec::Vec; + use alloc::vec::Vec; // As a sanity test, we verify that the output of `xed-asmparse-main 'vpabsq xmm0{k0}, // xmm1'` matches this EVEX encoding machinery. diff --git a/cranelift/codegen/src/isa/x64/encoding/mod.rs b/cranelift/codegen/src/isa/x64/encoding/mod.rs index 9dd269764989..3c1c1607dc6b 100644 --- a/cranelift/codegen/src/isa/x64/encoding/mod.rs +++ b/cranelift/codegen/src/isa/x64/encoding/mod.rs @@ -1,6 +1,6 @@ //! Contains the encoding machinery for the various x64 instruction formats. use crate::{isa::x64, machinst::MachBuffer}; -use std::vec::Vec; +use alloc::vec::Vec; pub mod evex; pub mod rex; diff --git a/cranelift/codegen/src/isa/x64/inst/args.rs b/cranelift/codegen/src/isa/x64/inst/args.rs index 02f45ee640f8..900ff49b1182 100644 --- a/cranelift/codegen/src/isa/x64/inst/args.rs +++ b/cranelift/codegen/src/isa/x64/inst/args.rs @@ -8,9 +8,9 @@ use crate::ir::MemFlags; use crate::isa::x64::inst::regs::pretty_print_reg; use crate::isa::x64::inst::Inst; use crate::machinst::*; +use alloc::string::String; +use core::fmt; use smallvec::{smallvec, SmallVec}; -use std::fmt; -use std::string::String; pub use crate::isa::x64::lower::isle::generated_code::DivSignedness; @@ -77,7 +77,7 @@ macro_rules! newtype_of_reg { // NB: We cannot implement `DerefMut` because that would let people do // nasty stuff like `*my_gpr.deref_mut() = some_xmm_reg`, breaking the // invariants that `Gpr` provides. - impl std::ops::Deref for $newtype_reg { + impl core::ops::Deref for $newtype_reg { type Target = Reg; fn deref(&self) -> &Reg { diff --git a/cranelift/codegen/src/isa/x64/inst/emit.rs b/cranelift/codegen/src/isa/x64/inst/emit.rs index 5c5ea82c1a9e..577184fd803c 100644 --- a/cranelift/codegen/src/isa/x64/inst/emit.rs +++ b/cranelift/codegen/src/isa/x64/inst/emit.rs @@ -1890,7 +1890,7 @@ pub(crate) fn emit( // Emit jump table (table of 32-bit offsets). sink.bind_label(start_of_jumptable, state.ctrl_plane_mut()); let jt_off = sink.cur_offset(); - for &target in targets.iter().chain(std::iter::once(default_target)) { + for &target in targets.iter().chain(core::iter::once(default_target)) { let word_off = sink.cur_offset(); // off_into_table is an addend here embedded in the label to be later patched at // the end of codegen. The offset is initially relative to this jump table entry; diff --git a/cranelift/codegen/src/isa/x64/inst/mod.rs b/cranelift/codegen/src/isa/x64/inst/mod.rs index ee79de792d8e..c6afaf88072e 100644 --- a/cranelift/codegen/src/isa/x64/inst/mod.rs +++ b/cranelift/codegen/src/isa/x64/inst/mod.rs @@ -11,10 +11,10 @@ use crate::isa::{CallConv, FunctionAlignment}; use crate::{machinst::*, trace}; use crate::{settings, CodegenError, CodegenResult}; use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use core::fmt::{self, Write}; use regalloc2::PRegSet; use smallvec::{smallvec, SmallVec}; -use std::fmt::{self, Write}; -use std::string::{String, ToString}; pub mod args; mod emit; @@ -68,7 +68,7 @@ pub struct ReturnCallInfo { fn inst_size_test() { // This test will help with unintentionally growing the size // of the Inst enum. - assert_eq!(40, std::mem::size_of::()); + assert_eq!(40, core::mem::size_of::()); } pub(crate) fn low32_will_sign_extend_to_64(x: u64) -> bool { @@ -2617,7 +2617,7 @@ impl MachInst for Inst { } fn gen_nop(preferred_size: usize) -> Inst { - Inst::nop(std::cmp::min(preferred_size, 15) as u8) + Inst::nop(core::cmp::min(preferred_size, 15) as u8) } fn rc_for_type(ty: Type) -> CodegenResult<(&'static [RegClass], &'static [Type])> { diff --git a/cranelift/codegen/src/isa/x64/inst/regs.rs b/cranelift/codegen/src/isa/x64/inst/regs.rs index 682c2287fb7f..821cc5851854 100644 --- a/cranelift/codegen/src/isa/x64/inst/regs.rs +++ b/cranelift/codegen/src/isa/x64/inst/regs.rs @@ -6,9 +6,9 @@ //! Note also that we make use of pinned VRegs to refer to PRegs. use crate::machinst::{RealReg, Reg}; +use alloc::string::String; use alloc::string::ToString; use regalloc2::{PReg, RegClass, VReg}; -use std::string::String; // Hardware encodings (note the special rax, rcx, rdx, rbx order). diff --git a/cranelift/codegen/src/isa/x64/lower/isle.rs b/cranelift/codegen/src/isa/x64/lower/isle.rs index f5a4f8f616c4..4b8cd926ab39 100644 --- a/cranelift/codegen/src/isa/x64/lower/isle.rs +++ b/cranelift/codegen/src/isa/x64/lower/isle.rs @@ -26,9 +26,9 @@ use crate::{ VCodeConstant, VCodeConstantData, }, }; +use alloc::boxed::Box; use alloc::vec::Vec; use regalloc2::PReg; -use std::boxed::Box; /// Type representing out-of-line data for calls. This type optional because the /// call instruction is also used by Winch to emit calls, but the diff --git a/cranelift/codegen/src/isa/x64/mod.rs b/cranelift/codegen/src/isa/x64/mod.rs index 0b6371582b43..48b7c704ea14 100644 --- a/cranelift/codegen/src/isa/x64/mod.rs +++ b/cranelift/codegen/src/isa/x64/mod.rs @@ -28,6 +28,7 @@ mod lower; mod pcc; pub mod settings; +#[cfg(feature = "unwind")] pub use inst::unwind::systemv::create_cie; /// An X64 backend. @@ -184,6 +185,7 @@ impl TargetIsa for X64Backend { } /// Emit unwind info for an x86 target. +#[cfg(feature = "unwind")] pub fn emit_unwind_info( buffer: &MachBufferFinalized, kind: crate::isa::unwind::UnwindInfoKind, diff --git a/cranelift/codegen/src/isle_prelude.rs b/cranelift/codegen/src/isle_prelude.rs index 530cfb139b37..a4a14f0464fa 100644 --- a/cranelift/codegen/src/isle_prelude.rs +++ b/cranelift/codegen/src/isle_prelude.rs @@ -188,7 +188,7 @@ macro_rules! isle_common_prelude_methods { #[inline] fn i64_sextend_u64(&mut self, ty: Type, x: u64) -> i64 { - let shift_amt = std::cmp::max(0, 64 - ty.bits()); + let shift_amt = core::cmp::max(0, 64 - ty.bits()); ((x as i64) << shift_amt) >> shift_amt } @@ -226,7 +226,7 @@ macro_rules! isle_common_prelude_methods { #[inline] fn ty_bits(&mut self, ty: Type) -> u8 { - use std::convert::TryInto; + use core::convert::TryInto; ty.bits().try_into().unwrap() } diff --git a/cranelift/codegen/src/legalizer/globalvalue.rs b/cranelift/codegen/src/legalizer/globalvalue.rs index 9837dd59278e..98366666ad50 100644 --- a/cranelift/codegen/src/legalizer/globalvalue.rs +++ b/cranelift/codegen/src/legalizer/globalvalue.rs @@ -44,7 +44,7 @@ fn const_vector_scale(inst: ir::Inst, func: &mut ir::Function, ty: ir::Type, isa assert!(ty.bytes() <= 16); // Use a minimum of 128-bits for the base type. - let base_bytes = std::cmp::max(ty.bytes(), 16); + let base_bytes = core::cmp::max(ty.bytes(), 16); let scale = (isa.dynamic_vector_bytes(ty) / base_bytes) as i64; assert!(scale > 0); let pos = FuncCursor::new(func).at_inst(inst); diff --git a/cranelift/codegen/src/lib.rs b/cranelift/codegen/src/lib.rs index a5b8a1051ca1..e0df257262dc 100644 --- a/cranelift/codegen/src/lib.rs +++ b/cranelift/codegen/src/lib.rs @@ -8,6 +8,10 @@ // built for one platform we don't have to worry too much about trimming // everything down. #![cfg_attr(not(feature = "all-arch"), allow(dead_code))] +// Each architecture has several unwind-specific imports that are unused when +// the unwind feature is not selected. This is much cleaner to work with than +// having `use` statements guarded by `#[cfg(feature = "unwind")]`. +#![cfg_attr(not(feature = "unwind"), allow(unused_imports))] #[allow(unused_imports)] // #[macro_use] is required for no_std #[macro_use] @@ -17,10 +21,12 @@ extern crate alloc; #[macro_use] extern crate std; +// Supports compiling ISLE. #[cfg(not(feature = "std"))] +#[macro_use] +extern crate core as std; + use hashbrown::{hash_map, HashMap}; -#[cfg(feature = "std")] -use std::collections::{hash_map, HashMap}; pub use crate::context::Context; pub use crate::value_label::{LabelValueLoc, ValueLabelsRanges, ValueLocRange}; diff --git a/cranelift/codegen/src/loop_analysis.rs b/cranelift/codegen/src/loop_analysis.rs index c4677400b51e..e155c34d9b37 100644 --- a/cranelift/codegen/src/loop_analysis.rs +++ b/cranelift/codegen/src/loop_analysis.rs @@ -62,13 +62,13 @@ impl LoopLevel { /// A clamped loop level from a larger-width (usize) depth. pub fn clamped(level: usize) -> Self { Self( - u8::try_from(std::cmp::min(level, (Self::INVALID as usize) - 1)) + u8::try_from(core::cmp::min(level, (Self::INVALID as usize) - 1)) .expect("Clamped value must always convert"), ) } } -impl std::default::Default for LoopLevel { +impl core::default::Default for LoopLevel { fn default() -> Self { LoopLevel::invalid() } diff --git a/cranelift/codegen/src/machinst/abi.rs b/cranelift/codegen/src/machinst/abi.rs index b5bee22ecfab..8098b8279a9f 100644 --- a/cranelift/codegen/src/machinst/abi.rs +++ b/cranelift/codegen/src/machinst/abi.rs @@ -106,12 +106,11 @@ use crate::settings::ProbestackStrategy; use crate::CodegenError; use crate::{ir, isa}; use crate::{machinst::*, trace}; +use core::marker::PhantomData; +use core::mem; +use hashbrown::HashMap; use regalloc2::{MachineEnv, PReg, PRegSet}; -use rustc_hash::FxHashMap; use smallvec::smallvec; -use std::collections::HashMap; -use std::marker::PhantomData; -use std::mem; /// A small vector of instructions (with some reasonable size); appropriate for /// a small fixed sequence implementing one operation. @@ -684,7 +683,7 @@ impl SigData { /// This type can be indexed by `Sig` to access its associated `SigData`. pub struct SigSet { /// Interned `ir::Signature`s that we already have an ABI signature for. - ir_signature_to_abi_sig: FxHashMap, + ir_signature_to_abi_sig: HashMap, /// Interned `ir::SigRef`s that we already have an ABI signature for. ir_sig_ref_to_abi_sig: SecondaryMap>, @@ -708,7 +707,7 @@ impl SigSet { let arg_estimate = func.dfg.signatures.len() * 6; let mut sigs = SigSet { - ir_signature_to_abi_sig: FxHashMap::default(), + ir_signature_to_abi_sig: HashMap::default(), ir_sig_ref_to_abi_sig: SecondaryMap::with_capacity(func.dfg.signatures.len()), abi_args: Vec::with_capacity(arg_estimate), sigs: PrimaryMap::with_capacity(1 + func.dfg.signatures.len()), @@ -793,10 +792,10 @@ impl SigSet { sig: &ir::Signature, flags: &settings::Flags, ) -> CodegenResult { - use std::borrow::Cow; + use alloc::borrow::Cow; let returns = if let Some(sret) = missing_struct_return(sig) { - Cow::from_iter(std::iter::once(&sret).chain(&sig.returns).copied()) + Cow::from_iter(core::iter::once(&sret).chain(&sig.returns).copied()) } else { Cow::from(sig.returns.as_slice()) }; @@ -907,7 +906,7 @@ impl SigSet { // NB: we do _not_ implement `IndexMut` because these signatures are // deduplicated and shared! -impl std::ops::Index for SigSet { +impl core::ops::Index for SigSet { type Output = SigData; fn index(&self, sig: Sig) -> &Self::Output { @@ -1098,7 +1097,7 @@ impl Callee { // Always at least machine-word-align slots, but also // satisfy the user's requested alignment. debug_assert!(data.align_shift < 32); - let align = std::cmp::max(M::word_bytes(), 1u32 << data.align_shift); + let align = core::cmp::max(M::word_bytes(), 1u32 << data.align_shift); let mask = align - 1; sized_stack_offset = checked_round_up(sized_stack_offset, mask) .ok_or(CodegenError::ImplLimitExceeded)?; @@ -1643,7 +1642,7 @@ impl Callee { // establishes live-ranges for in-register arguments and // constrains them at the start of the function to the // locations defined by the ABI. - Some(M::gen_args(std::mem::take(&mut self.reg_args))) + Some(M::gen_args(core::mem::take(&mut self.reg_args))) } else { None } @@ -1674,7 +1673,7 @@ impl Callee { let map_size = outgoing_args_size + clobbers_and_slots; let bytes = M::word_bytes(); let map_words = (map_size + bytes - 1) / bytes; - let mut bits = std::iter::repeat(false) + let mut bits = core::iter::repeat(false) .take(map_words as usize) .collect::>(); @@ -2401,6 +2400,6 @@ mod tests { fn sig_data_size() { // The size of `SigData` is performance sensitive, so make sure // we don't regress it unintentionally. - assert_eq!(std::mem::size_of::(), 24); + assert_eq!(core::mem::size_of::(), 24); } } diff --git a/cranelift/codegen/src/machinst/blockorder.rs b/cranelift/codegen/src/machinst/blockorder.rs index fb4d5676011f..5713df7cd9ff 100644 --- a/cranelift/codegen/src/machinst/blockorder.rs +++ b/cranelift/codegen/src/machinst/blockorder.rs @@ -65,7 +65,7 @@ use crate::entity::SecondaryMap; use crate::inst_predicates::visit_block_succs; use crate::ir::{Block, Function, Inst, Opcode}; use crate::{machinst::*, trace}; -use rustc_hash::{FxHashMap, FxHashSet}; +use hashbrown::{HashMap, HashSet}; /// Mapping from CLIF BBs to VCode BBs. #[derive(Debug)] @@ -78,16 +78,16 @@ pub struct BlockLoweringOrder { lowered_succ_indices: Vec, /// Ranges in `lowered_succ_indices` giving the successor lists for each lowered /// block. Indexed by lowering-order index (`BlockIndex`). - lowered_succ_ranges: Vec<(Option, std::ops::Range)>, + lowered_succ_ranges: Vec<(Option, core::ops::Range)>, /// Cold blocks. These blocks are not reordered in the /// `lowered_order` above; the lowered order must respect RPO /// (uses after defs) in order for lowering to be /// correct. Instead, this set is used to provide `is_cold()`, /// which is used by VCode emission to sink the blocks at the last /// moment (when we actually emit bytes into the MachBuffer). - cold_blocks: FxHashSet, + cold_blocks: HashSet, /// Lowered blocks that are indirect branch targets. - indirect_branch_targets: FxHashSet, + indirect_branch_targets: HashSet, } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] @@ -160,7 +160,7 @@ impl BlockLoweringOrder { let mut block_succs: SmallVec<[LoweredBlock; 128]> = SmallVec::new(); let mut block_succ_range = SecondaryMap::with_default(0..0); - let mut indirect_branch_target_clif_blocks = FxHashSet::default(); + let mut indirect_branch_target_clif_blocks = HashSet::::default(); for block in f.layout.blocks() { let start = block_succs.len(); @@ -221,7 +221,7 @@ impl BlockLoweringOrder { } } - let lb_to_bindex = FxHashMap::from_iter( + let lb_to_bindex = HashMap::::from_iter( lowered_order .iter() .enumerate() @@ -232,8 +232,8 @@ impl BlockLoweringOrder { // during the creation of `lowering_order`, as we need `lb_to_bindex` to be fully populated // first. let mut lowered_succ_indices = Vec::new(); - let mut cold_blocks = FxHashSet::default(); - let mut indirect_branch_targets = FxHashSet::default(); + let mut cold_blocks = HashSet::default(); + let mut indirect_branch_targets = HashSet::default(); let lowered_succ_ranges = Vec::from_iter(lowered_order.iter().enumerate().map(|(ix, lb)| { let bindex = BlockIndex::new(ix); diff --git a/cranelift/codegen/src/machinst/buffer.rs b/cranelift/codegen/src/machinst/buffer.rs index 5b631334b593..2e81faee8768 100644 --- a/cranelift/codegen/src/machinst/buffer.rs +++ b/cranelift/codegen/src/machinst/buffer.rs @@ -180,14 +180,14 @@ use crate::machinst::{ use crate::trace; use crate::{ir, MachInstEmitState}; use crate::{timing, VCodeConstantData}; +use alloc::collections::BinaryHeap; +use alloc::string::String; +use alloc::vec::Vec; +use core::cmp::Ordering; +use core::mem; use cranelift_control::ControlPlane; use cranelift_entity::{entity_impl, PrimaryMap}; use smallvec::SmallVec; -use std::cmp::Ordering; -use std::collections::BinaryHeap; -use std::mem; -use std::string::String; -use std::vec::Vec; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; @@ -438,7 +438,7 @@ pub struct OpenPatchRegion(usize); /// the [`PatchRegion::patch`] function can be used to get a mutable buffer to the instruction /// bytes, and the constants uses can be updated directly. pub struct PatchRegion { - range: std::ops::Range, + range: core::ops::Range, } impl PatchRegion { @@ -1722,7 +1722,7 @@ impl MachBufferFinalized { /// Return the code in this mach buffer as a hex string for testing purposes. pub fn stringify_code_bytes(&self) -> String { // This is pretty lame, but whatever .. - use std::fmt::Write; + use core::fmt::Write; let mut s = String::with_capacity(self.data.len() * 2); for b in &self.data { write!(&mut s, "{:02X}", b).unwrap(); diff --git a/cranelift/codegen/src/machinst/helpers.rs b/cranelift/codegen/src/machinst/helpers.rs index 411af0cdc7f9..01f397c8c67f 100644 --- a/cranelift/codegen/src/machinst/helpers.rs +++ b/cranelift/codegen/src/machinst/helpers.rs @@ -1,7 +1,7 @@ //! Miscellaneous helpers for machine backends. use crate::ir::Type; -use std::ops::{Add, BitAnd, Not, Sub}; +use core::ops::{Add, BitAnd, Not, Sub}; /// Returns the size (in bits) of a given type. pub fn ty_bits(ty: Type) -> usize { diff --git a/cranelift/codegen/src/machinst/isle.rs b/cranelift/codegen/src/machinst/isle.rs index dcc208f0fa69..a97b216ac109 100644 --- a/cranelift/codegen/src/machinst/isle.rs +++ b/cranelift/codegen/src/machinst/isle.rs @@ -1,8 +1,8 @@ use crate::ir::{BlockCall, Value, ValueList}; use alloc::boxed::Box; use alloc::vec::Vec; +use core::cell::Cell; use smallvec::SmallVec; -use std::cell::Cell; pub use super::MachLabel; use super::RetPair; @@ -94,7 +94,7 @@ macro_rules! isle_lower_prelude_methods { #[inline] fn output_builder_new(&mut self) -> InstOutputBuilder { - std::cell::Cell::new(InstOutput::new()) + core::cell::Cell::new(InstOutput::new()) } #[inline] @@ -231,7 +231,7 @@ macro_rules! isle_lower_prelude_methods { _ => return None, }; let ty = self.lower_ctx.output_ty(inst, 0); - let shift_amt = std::cmp::max(0, 64 - self.ty_bits(ty)); + let shift_amt = core::cmp::max(0, 64 - self.ty_bits(ty)); Some((constant << shift_amt) >> shift_amt) } @@ -693,7 +693,7 @@ macro_rules! isle_lower_prelude_methods { &mut self, targets: &MachLabelSlice, ) -> Option<(MachLabel, BoxVecMachLabel)> { - use std::boxed::Box; + use alloc::boxed::Box; if targets.is_empty() { return None; } diff --git a/cranelift/codegen/src/machinst/lower.rs b/cranelift/codegen/src/machinst/lower.rs index 32db947a259e..4b5c0c14efcc 100644 --- a/cranelift/codegen/src/machinst/lower.rs +++ b/cranelift/codegen/src/machinst/lower.rs @@ -21,10 +21,10 @@ use crate::machinst::{ use crate::settings::Flags; use crate::{trace, CodegenResult}; use alloc::vec::Vec; +use core::fmt::Debug; use cranelift_control::ControlPlane; -use rustc_hash::{FxHashMap, FxHashSet}; +use hashbrown::{HashMap, HashSet}; use smallvec::{smallvec, SmallVec}; -use std::fmt::Debug; use super::{VCodeBuildDirection, VRegAllocator}; @@ -192,7 +192,7 @@ pub struct Lower<'func, I: VCodeInst> { /// i.e., the version of global state that exists before an instruction /// executes. For each side-effecting instruction, the *exit* color is its /// entry color plus one. - side_effect_inst_entry_colors: FxHashMap, + side_effect_inst_entry_colors: HashMap, /// Current color as we scan during lowering. While we are lowering an /// instruction, this is equal to the color *at entry to* the instruction. @@ -202,7 +202,7 @@ pub struct Lower<'func, I: VCodeInst> { cur_inst: Option, /// Instruction constant values, if known. - inst_constants: FxHashMap, + inst_constants: HashMap, /// Use-counts per SSA value, as counted in the input IR. These /// are "coarsened", in the abstract-interpretation sense: we only @@ -217,7 +217,7 @@ pub struct Lower<'func, I: VCodeInst> { /// Effectful instructions that have been sunk; they are not codegen'd at /// their original locations. - inst_sunk: FxHashSet, + inst_sunk: HashSet, /// Instructions collected for the CLIF inst in progress, in forward order. ir_insts: Vec, @@ -428,8 +428,8 @@ impl<'func, I: VCodeInst> Lower<'func, I> { // side-effects, in one combined pass. let mut cur_color = 0; let mut block_end_colors = SecondaryMap::with_default(InstColor::new(0)); - let mut side_effect_inst_entry_colors = FxHashMap::default(); - let mut inst_constants = FxHashMap::default(); + let mut side_effect_inst_entry_colors = HashMap::default(); + let mut inst_constants = HashMap::default(); for bb in f.layout.blocks() { cur_color += 1; for inst in f.layout.block_insts(bb) { @@ -465,7 +465,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> { inst_constants, value_ir_uses, value_lowered_uses: SecondaryMap::default(), - inst_sunk: FxHashSet::default(), + inst_sunk: HashSet::default(), cur_scan_entry_color: None, cur_inst: None, ir_insts: vec![], @@ -906,7 +906,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> { let labels = label_starts .iter() .map(|&ValueLabelStart { label, .. }| label) - .collect::>(); + .collect::>(); for label in labels { trace!( "value labeling: defines val {:?} -> reg {:?} -> label {:?}", diff --git a/cranelift/codegen/src/machinst/mod.rs b/cranelift/codegen/src/machinst/mod.rs index af87c3053a6b..dcac7ce69ea7 100644 --- a/cranelift/codegen/src/machinst/mod.rs +++ b/cranelift/codegen/src/machinst/mod.rs @@ -53,13 +53,13 @@ use crate::result::CodegenResult; use crate::settings; use crate::settings::Flags; use crate::value_label::ValueLabelsRanges; +use alloc::string::String; use alloc::vec::Vec; use core::fmt::Debug; use cranelift_control::ControlPlane; use cranelift_entity::PrimaryMap; use regalloc2::VReg; use smallvec::{smallvec, SmallVec}; -use std::string::String; #[cfg(feature = "enable-serde")] use serde_derive::{Deserialize, Serialize}; @@ -395,7 +395,7 @@ impl CompiledCodeBase { params: Option<&crate::ir::function::FunctionParameters>, cs: &capstone::Capstone, ) -> Result { - use std::fmt::Write; + use core::fmt::Write; let mut buf = String::new(); diff --git a/cranelift/codegen/src/machinst/reg.rs b/cranelift/codegen/src/machinst/reg.rs index b197951affe0..069d4e6575e1 100644 --- a/cranelift/codegen/src/machinst/reg.rs +++ b/cranelift/codegen/src/machinst/reg.rs @@ -80,8 +80,8 @@ impl Reg { } } -impl std::fmt::Debug for Reg { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl core::fmt::Debug for Reg { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { if let Some(rreg) = self.to_real_reg() { let preg: PReg = rreg.into(); write!(f, "{}", preg) @@ -118,8 +118,8 @@ impl RealReg { } } -impl std::fmt::Debug for RealReg { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl core::fmt::Debug for RealReg { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { Reg::from(*self).fmt(f) } } @@ -144,8 +144,8 @@ impl VirtualReg { } } -impl std::fmt::Debug for VirtualReg { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl core::fmt::Debug for VirtualReg { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { Reg::from(*self).fmt(f) } } @@ -188,20 +188,20 @@ impl Writable { // Conversions between regalloc2 types (VReg, PReg) and our types // (VirtualReg, RealReg, Reg). -impl std::convert::From for Reg { +impl core::convert::From for Reg { fn from(vreg: regalloc2::VReg) -> Reg { Reg(vreg) } } -impl std::convert::From for VirtualReg { +impl core::convert::From for VirtualReg { fn from(vreg: regalloc2::VReg) -> VirtualReg { debug_assert!(pinned_vreg_to_preg(vreg).is_none()); VirtualReg(vreg) } } -impl std::convert::From for regalloc2::VReg { +impl core::convert::From for regalloc2::VReg { /// Extract the underlying `regalloc2::VReg`. Note that physical /// registers also map to particular (special) VRegs, so this /// method can be used either on virtual or physical `Reg`s. @@ -209,19 +209,19 @@ impl std::convert::From for regalloc2::VReg { reg.0 } } -impl std::convert::From<&Reg> for regalloc2::VReg { +impl core::convert::From<&Reg> for regalloc2::VReg { fn from(reg: &Reg) -> regalloc2::VReg { reg.0 } } -impl std::convert::From for regalloc2::VReg { +impl core::convert::From for regalloc2::VReg { fn from(reg: VirtualReg) -> regalloc2::VReg { reg.0 } } -impl std::convert::From for regalloc2::VReg { +impl core::convert::From for regalloc2::VReg { fn from(reg: RealReg) -> regalloc2::VReg { // This representation is redundant: the class is implied in the vreg // index as well as being in the vreg class field. @@ -229,31 +229,31 @@ impl std::convert::From for regalloc2::VReg { } } -impl std::convert::From for regalloc2::PReg { +impl core::convert::From for regalloc2::PReg { fn from(reg: RealReg) -> regalloc2::PReg { reg.0 } } -impl std::convert::From for RealReg { +impl core::convert::From for RealReg { fn from(preg: regalloc2::PReg) -> RealReg { RealReg(preg) } } -impl std::convert::From for Reg { +impl core::convert::From for Reg { fn from(preg: regalloc2::PReg) -> Reg { RealReg(preg).into() } } -impl std::convert::From for Reg { +impl core::convert::From for Reg { fn from(reg: RealReg) -> Reg { Reg(reg.into()) } } -impl std::convert::From for Reg { +impl core::convert::From for Reg { fn from(reg: VirtualReg) -> Reg { Reg(reg.0) } diff --git a/cranelift/codegen/src/machinst/valueregs.rs b/cranelift/codegen/src/machinst/valueregs.rs index fbbb365c3d79..49fda9ba1de7 100644 --- a/cranelift/codegen/src/machinst/valueregs.rs +++ b/cranelift/codegen/src/machinst/valueregs.rs @@ -4,7 +4,7 @@ use regalloc2::{PReg, VReg}; use super::{RealReg, Reg, VirtualReg, Writable}; -use std::fmt::Debug; +use core::fmt::Debug; const VALUE_REGS_PARTS: usize = 2; diff --git a/cranelift/codegen/src/machinst/vcode.rs b/cranelift/codegen/src/machinst/vcode.rs index b723c96213fc..f9f12d3ec437 100644 --- a/cranelift/codegen/src/machinst/vcode.rs +++ b/cranelift/codegen/src/machinst/vcode.rs @@ -25,17 +25,14 @@ use crate::timing; use crate::trace; use crate::CodegenError; use crate::{LabelValueLoc, ValueLocRange}; +use core::fmt; +use core::mem::take; +use cranelift_entity::{entity_impl, Keys}; +use hashbrown::{hash_map::Entry, HashMap}; use regalloc2::{ Edit, Function as RegallocFunction, InstOrEdit, InstRange, MachineEnv, Operand, OperandConstraint, OperandKind, PRegSet, RegClass, }; -use rustc_hash::FxHashMap; - -use core::mem::take; -use cranelift_entity::{entity_impl, Keys}; -use std::collections::hash_map::Entry; -use std::collections::HashMap; -use std::fmt; /// Index referring to an instruction in VCode. pub type InsnIndex = regalloc2::Inst; @@ -100,7 +97,7 @@ pub struct VCode { /// This is a sparse side table that only has entries for instructions that /// are safepoints, and only for a subset of those that have an associated /// user stack map. - user_stack_maps: FxHashMap, + user_stack_maps: HashMap, /// Operands: pre-regalloc references to virtual registers with /// constraints, in one flattened array. This allows the regalloc @@ -114,7 +111,7 @@ pub struct VCode { operand_ranges: Ranges, /// Clobbers: a sparse map from instruction indices to clobber masks. - clobbers: FxHashMap, + clobbers: HashMap, /// Source locations for each instruction. (`SourceLoc` is a `u32`, so it is /// reasonable to keep one of these per instruction.) @@ -265,7 +262,7 @@ pub struct VCodeBuilder { /// Debug-value label in-progress map, keyed by label. For each /// label, we keep disjoint ranges mapping to vregs. We'll flatten /// this into (vreg, range, label) tuples when done. - debug_info: FxHashMap>, + debug_info: HashMap>, } /// Direction in which a VCodeBuilder builds VCode. @@ -292,7 +289,7 @@ impl VCodeBuilder { VCodeBuilder { vcode, direction, - debug_info: FxHashMap::default(), + debug_info: HashMap::default(), } } @@ -634,10 +631,10 @@ impl VCode { sigs, vreg_types: vec![], insts: Vec::with_capacity(10 * n_blocks), - user_stack_maps: FxHashMap::default(), + user_stack_maps: HashMap::default(), operands: Vec::with_capacity(30 * n_blocks), operand_ranges: Ranges::with_capacity(10 * n_blocks), - clobbers: FxHashMap::default(), + clobbers: HashMap::default(), srclocs: Vec::with_capacity(10 * n_blocks), entry: BlockIndex::new(0), block_ranges: Ranges::with_capacity(n_blocks), @@ -780,7 +777,7 @@ impl VCode { let mut cur_srcloc = None; let mut last_offset = None; let mut inst_offsets = vec![]; - let mut state = I::State::new(&self.abi, std::mem::take(ctrl_plane)); + let mut state = I::State::new(&self.abi, core::mem::take(ctrl_plane)); let mut disasm = String::new(); @@ -921,9 +918,9 @@ impl VCode { .safepoint_slots .binary_search_by(|(progpoint, _alloc)| { if progpoint.inst() >= iix { - std::cmp::Ordering::Greater + core::cmp::Ordering::Greater } else { - std::cmp::Ordering::Less + core::cmp::Ordering::Less } }) .unwrap_err(); @@ -1216,15 +1213,21 @@ impl VCode { let loc = if let Some(preg) = alloc.as_reg() { LabelValueLoc::Reg(Reg::from(preg)) } else { - let slot = alloc.as_stack().unwrap(); - let slot_offset = self.abi.get_spillslot_offset(slot); - let slot_base_to_caller_sp_offset = self.abi.slot_base_to_caller_sp_offset(); - let caller_sp_to_cfa_offset = - crate::isa::unwind::systemv::caller_sp_to_cfa_offset(); - // NOTE: this is a negative offset because it's relative to the caller's SP - let cfa_to_sp_offset = - -((slot_base_to_caller_sp_offset + caller_sp_to_cfa_offset) as i64); - LabelValueLoc::CFAOffset(cfa_to_sp_offset + slot_offset) + #[cfg(feature = "unwind")] + { + let slot = alloc.as_stack().unwrap(); + let slot_offset = self.abi.get_spillslot_offset(slot); + let slot_base_to_caller_sp_offset = self.abi.slot_base_to_caller_sp_offset(); + let caller_sp_to_cfa_offset = + crate::isa::unwind::systemv::caller_sp_to_cfa_offset(); + // NOTE: this is a negative offset because it's relative to the caller's SP + let cfa_to_sp_offset = + -((slot_base_to_caller_sp_offset + caller_sp_to_cfa_offset) as i64); + LabelValueLoc::CFAOffset(cfa_to_sp_offset + slot_offset) + } + + #[cfg(not(feature = "unwind"))] + todo!("I don't know how to deal with this"); }; // ValueLocRanges are recorded by *instruction-end @@ -1312,7 +1315,7 @@ impl VCode { } } -impl std::ops::Index for VCode { +impl core::ops::Index for VCode { type Output = I; fn index(&self, idx: InsnIndex) -> &Self::Output { &self.insts[idx.index()] @@ -1508,7 +1511,7 @@ pub struct VRegAllocator { /// We use these aliases to rename an instruction's expected /// result vregs to the returned vregs from lowering, which are /// usually freshly-allocated temps. - vreg_aliases: FxHashMap, + vreg_aliases: HashMap, /// A deferred error, to be bubbled up to the top level of the /// lowering algorithm. We take this approach because we cannot @@ -1532,7 +1535,7 @@ impl VRegAllocator { Self { vreg_types, reftyped_vregs: vec![], - vreg_aliases: FxHashMap::with_capacity_and_hasher(capacity, Default::default()), + vreg_aliases: HashMap::with_capacity_and_hasher(capacity, Default::default()), deferred_error: None, facts: Vec::with_capacity(capacity), _inst: core::marker::PhantomData::default(), @@ -1821,7 +1824,7 @@ impl VCodeConstantData { #[cfg(test)] mod test { use super::*; - use std::mem::size_of; + use core::mem::size_of; #[test] fn size_of_constant_structs() { diff --git a/cranelift/codegen/src/opts.rs b/cranelift/codegen/src/opts.rs index 44ef9e6b5200..14cc1e6b7e05 100644 --- a/cranelift/codegen/src/opts.rs +++ b/cranelift/codegen/src/opts.rs @@ -13,9 +13,9 @@ pub use crate::ir::{ use crate::isle_common_prelude_methods; use crate::machinst::isle::*; use crate::trace; +use core::marker::PhantomData; use cranelift_entity::packed_option::ReservedValue; use smallvec::{smallvec, SmallVec}; -use std::marker::PhantomData; #[allow(dead_code)] pub type Unit = (); diff --git a/cranelift/codegen/src/remove_constant_phis.rs b/cranelift/codegen/src/remove_constant_phis.rs index 483788e278d6..09191c2dc40d 100644 --- a/cranelift/codegen/src/remove_constant_phis.rs +++ b/cranelift/codegen/src/remove_constant_phis.rs @@ -7,7 +7,7 @@ use crate::ir::{Block, BlockCall, Inst, Value}; use crate::timing; use bumpalo::Bump; use cranelift_entity::SecondaryMap; -use rustc_hash::{FxHashMap, FxHashSet}; +use hashbrown::{HashMap, HashSet}; use smallvec::SmallVec; // A note on notation. For the sake of clarity, this file uses the phrase @@ -153,7 +153,7 @@ impl<'a> OutEdge<'a> { } /// For some block, a useful bundle of info. The `Block` itself is not stored -/// here since it will be the key in the associated `FxHashMap` -- see +/// here since it will be the key in the associated `HashMap` -- see /// `summaries` below. For the `SmallVec` tuning params: most blocks have /// few parameters, hence `4`. And almost all blocks have either one or two /// successors, hence `2`. @@ -189,13 +189,13 @@ impl<'a> BlockSummary<'a> { /// Solver state. This holds a AbstractValue for each formal parameter, except /// for those from the entry block. struct SolverState { - absvals: FxHashMap, + absvals: HashMap, } impl SolverState { fn new() -> Self { Self { - absvals: FxHashMap::default(), + absvals: HashMap::default(), } } @@ -229,7 +229,7 @@ pub fn do_remove_constant_phis(func: &mut Function, domtree: &mut DominatorTree) // info. The solver will iterate over the summaries, rather than having // to inspect each instruction in each block. let bump = - Bump::with_capacity(domtree.cfg_postorder().len() * 4 * std::mem::size_of::()); + Bump::with_capacity(domtree.cfg_postorder().len() * 4 * core::mem::size_of::()); let mut summaries = SecondaryMap::::with_capacity(domtree.cfg_postorder().len()); @@ -337,7 +337,7 @@ pub fn do_remove_constant_phis(func: &mut Function, domtree: &mut DominatorTree) // summaries and the final solver state as a guide. // Make up a set of blocks that need editing. - let mut need_editing = FxHashSet::::default(); + let mut need_editing = HashSet::::default(); for (block, summary) in summaries.iter() { if block == entry_block { continue; diff --git a/cranelift/codegen/src/result.rs b/cranelift/codegen/src/result.rs index 9d73bd0f6264..c8a204f633d9 100644 --- a/cranelift/codegen/src/result.rs +++ b/cranelift/codegen/src/result.rs @@ -4,7 +4,7 @@ use regalloc2::checker::CheckerErrors; use crate::ir::pcc::PccError; use crate::{ir::Function, verifier::VerifierErrors}; -use std::string::String; +use alloc::string::String; /// A compilation error. /// @@ -52,6 +52,7 @@ pub type CodegenResult = Result; // 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 CodegenError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { @@ -67,8 +68,8 @@ impl std::error::Error for CodegenError { } } -impl std::fmt::Display for CodegenError { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl core::fmt::Display for CodegenError { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { match self { CodegenError::Verifier(_) => write!(f, "Verifier errors"), CodegenError::ImplLimitExceeded => write!(f, "Implementation limit exceeded"), diff --git a/cranelift/codegen/src/scoped_hash_map.rs b/cranelift/codegen/src/scoped_hash_map.rs index 170a6140d259..f7ca91d87c42 100644 --- a/cranelift/codegen/src/scoped_hash_map.rs +++ b/cranelift/codegen/src/scoped_hash_map.rs @@ -1,18 +1,13 @@ //! `ScopedHashMap` //! -//! This module defines a struct `ScopedHashMap` which defines a `FxHashMap`-like +//! This module defines a struct `ScopedHashMap` which defines a `HashMap`-like //! container that has a concept of scopes that can be entered and exited, such that //! values inserted while inside a scope aren't visible outside the scope. use core::hash::Hash; -use rustc_hash::FxHashMap; +use hashbrown::HashMap; use smallvec::{smallvec, SmallVec}; -#[cfg(not(feature = "std"))] -use crate::fx::FxHasher; -#[cfg(not(feature = "std"))] -type Hasher = core::hash::BuildHasherDefault; - struct Val { value: V, level: u32, @@ -45,7 +40,7 @@ enum InsertLoc<'a, K: 'a, V: 'a> { Occupied(super::hash_map::OccupiedEntry<'a, K, Val>), } -impl<'a, K, V> VacantEntry<'a, K, V> { +impl<'a, K: Hash, V> VacantEntry<'a, K, V> { /// Sets the value of the entry with the `VacantEntry`'s key. pub fn insert(self, value: V) { let val = Val { @@ -72,13 +67,13 @@ pub enum Entry<'a, K: 'a, V: 'a> { Vacant(VacantEntry<'a, K, V>), } -/// A wrapper around a `FxHashMap` which adds the concept of scopes. Items inserted +/// A wrapper around a `HashMap` which adds the concept of scopes. Items inserted /// within a scope are removed when the scope is exited. /// /// Shadowing, where one scope has entries with the same keys as a containing scope, /// is not supported in this implementation. pub struct ScopedHashMap { - map: FxHashMap>, + map: HashMap>, generation_by_depth: SmallVec<[u32; 8]>, generation: u32, } @@ -90,7 +85,7 @@ where /// Creates an empty `ScopedHashMap`. pub fn new() -> Self { Self { - map: FxHashMap::default(), + map: HashMap::default(), generation: 0, generation_by_depth: smallvec![0], } @@ -98,7 +93,7 @@ where /// Creates an empty `ScopedHashMap` with some pre-allocated capacity. pub fn with_capacity(cap: usize) -> Self { - let mut map = FxHashMap::default(); + let mut map = HashMap::default(); map.reserve(cap); Self { map, @@ -107,7 +102,7 @@ where } } - /// Similar to `FxHashMap::entry`, gets the given key's corresponding entry in the map for + /// Similar to `HashMap::entry`, gets the given key's corresponding entry in the map for /// in-place manipulation. pub fn entry<'a>(&'a mut self, key: K) -> Entry<'a, K, V> { self.entry_with_depth(key, self.depth()) diff --git a/cranelift/codegen/src/settings.rs b/cranelift/codegen/src/settings.rs index 0672cb093120..1440412bcbc7 100644 --- a/cranelift/codegen/src/settings.rs +++ b/cranelift/codegen/src/settings.rs @@ -290,6 +290,7 @@ pub enum SetError { BadValue(String), } +#[cfg(feature = "std")] impl std::error::Error for SetError {} impl fmt::Display for SetError { diff --git a/cranelift/codegen/src/souper_harvest.rs b/cranelift/codegen/src/souper_harvest.rs index 02958ed56a71..a1e17519638b 100644 --- a/cranelift/codegen/src/souper_harvest.rs +++ b/cranelift/codegen/src/souper_harvest.rs @@ -25,11 +25,11 @@ //! candidate. use crate::ir; +use alloc::string::String; +use alloc::vec::Vec; +use hashbrown::{HashMap, HashSet}; use souper_ir::ast; -use std::collections::{HashMap, HashSet}; -use std::string::String; use std::sync::mpsc; -use std::vec::Vec; /// Harvest Souper left-hand side candidates from the given function. /// diff --git a/cranelift/codegen/src/timing.rs b/cranelift/codegen/src/timing.rs index 2aaf5c3db8d0..a5afd81fd6f1 100644 --- a/cranelift/codegen/src/timing.rs +++ b/cranelift/codegen/src/timing.rs @@ -2,12 +2,13 @@ //! //! This modules provides facilities for timing the execution of individual compilation passes. -use core::fmt; -use std::any::Any; -use std::boxed::Box; -use std::cell::RefCell; -use std::mem; -use std::time::Duration; +use alloc::boxed::Box; +use alloc::fmt; +use core::any::Any; +use core::time::Duration; + +#[cfg(feature = "timing")] +use core::cell::RefCell; // Each pass that can be timed is predefined with the `define_passes!` macro. Each pass has a // snake_case name and a plain text description used when printing out the timing report. @@ -111,6 +112,7 @@ pub trait Profiler { } // Information about passes in a single thread. +#[cfg(feature = "timing")] thread_local! { static PROFILER: RefCell> = RefCell::new(Box::new(DefaultProfiler)); } @@ -118,15 +120,24 @@ thread_local! { /// Set the profiler for the current thread. /// /// Returns the old profiler. +#[cfg(feature = "timing")] pub fn set_thread_profiler(new_profiler: Box) -> Box { - PROFILER.with(|profiler| std::mem::replace(&mut *profiler.borrow_mut(), new_profiler)) + PROFILER.with(|profiler| core::mem::replace(&mut *profiler.borrow_mut(), new_profiler)) } /// Start timing `pass` as a child of the currently running pass, if any. /// /// This function is called by the publicly exposed pass functions. +#[allow(unused_variables)] fn start_pass(pass: Pass) -> Box { - PROFILER.with(|profiler| profiler.borrow().start_pass(pass)) + #[cfg(feature = "timing")] + { + PROFILER.with(|profiler| profiler.borrow().start_pass(pass)) + } + #[cfg(not(feature = "timing"))] + { + Box::new(()) + } } /// Accumulated timing information for a single pass. @@ -197,6 +208,7 @@ impl fmt::Display for PassTimes { } // Information about passes in a single thread. +#[cfg(feature = "timing")] thread_local! { static PASS_TIME: RefCell = RefCell::new(Default::default()); } @@ -208,15 +220,22 @@ pub struct DefaultProfiler; /// /// Only applies when [`DefaultProfiler`] is used. pub fn take_current() -> PassTimes { - PASS_TIME.with(|rc| mem::take(&mut *rc.borrow_mut())) + #[cfg(feature = "timing")] + { + PASS_TIME.with(|rc| core::mem::take(&mut *rc.borrow_mut())) + } + #[cfg(not(feature = "timing"))] + { + PassTimes::default() + } } #[cfg(feature = "timing")] mod enabled { use super::{DefaultProfiler, Pass, Profiler, PASS_TIME}; - use std::any::Any; - use std::boxed::Box; - use std::cell::Cell; + use alloc::boxed::Box; + use core::any::Any; + use core::cell::Cell; use std::time::Instant; // Information about passes in a single thread. @@ -273,8 +292,8 @@ mod enabled { #[cfg(not(feature = "timing"))] mod disabled { use super::{DefaultProfiler, Pass, Profiler}; - use std::any::Any; - use std::boxed::Box; + use alloc::boxed::Box; + use core::any::Any; impl Profiler for DefaultProfiler { fn start_pass(&self, _pass: Pass) -> Box { diff --git a/cranelift/codegen/src/unionfind.rs b/cranelift/codegen/src/unionfind.rs index da96611ec366..92d32fbd1353 100644 --- a/cranelift/codegen/src/unionfind.rs +++ b/cranelift/codegen/src/unionfind.rs @@ -1,9 +1,9 @@ //! Simple union-find data structure. use crate::trace; +use core::hash::Hash; +use core::mem::swap; use cranelift_entity::{packed_option::ReservedValue, EntityRef, SecondaryMap}; -use std::hash::Hash; -use std::mem::swap; /// A union-find data structure. The data structure can allocate /// `Idx`s, indicating eclasses, and can merge eclasses together. @@ -51,7 +51,7 @@ impl Default for Val { } } -impl UnionFind { +impl UnionFind { /// Create a new `UnionFind` with the given capacity. pub fn with_capacity(cap: usize) -> Self { UnionFind { diff --git a/cranelift/codegen/src/verifier/mod.rs b/cranelift/codegen/src/verifier/mod.rs index 457c9e3a9268..ccea6b90def8 100644 --- a/cranelift/codegen/src/verifier/mod.rs +++ b/cranelift/codegen/src/verifier/mod.rs @@ -100,6 +100,7 @@ pub struct VerifierError { // 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 VerifierError {} impl Display for VerifierError { @@ -179,6 +180,7 @@ pub struct VerifierErrors(pub Vec); // 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 VerifierErrors {} impl VerifierErrors { diff --git a/cranelift/isle/isle/src/codegen.rs b/cranelift/isle/isle/src/codegen.rs index 7deb391b12fa..320583886d9b 100644 --- a/cranelift/isle/isle/src/codegen.rs +++ b/cranelift/isle/isle/src/codegen.rs @@ -13,6 +13,9 @@ pub struct CodegenOptions { /// Do not include the `#![allow(...)]` pragmas in the generated /// source. Useful if it must be include!()'d elsewhere. pub exclude_global_allow_pragmas: bool, + + /// Use `core` and `alloc` instead of `std`, for `no_std`-compatible code. + pub no_std: bool, } /// Emit Rust source code for the given type and term environments. @@ -144,7 +147,13 @@ impl<'a> Codegen<'a> { } writeln!(code, "\nuse super::*; // Pulls in all external types.").unwrap(); - writeln!(code, "use std::marker::PhantomData;").unwrap(); + + if options.no_std { + writeln!(code, "use alloc::vec::Vec;").unwrap(); + writeln!(code, "use core::{{marker::PhantomData, ops}};").unwrap(); + } else { + writeln!(code, "use std::{{marker::PhantomData, ops}};").unwrap(); + } } fn generate_trait_sig(&self, code: &mut String, indent: &str, sig: &ExternalSig) { @@ -249,38 +258,38 @@ pub trait Length {{ fn len(&self) -> usize; }} -impl Length for std::vec::Vec {{ +impl Length for Vec {{ fn len(&self) -> usize {{ - std::vec::Vec::len(self) + Vec::len(self) }} }} pub struct ContextIterWrapper {{ iter: I, - _ctx: std::marker::PhantomData, + _ctx: PhantomData, }} impl Default for ContextIterWrapper {{ fn default() -> Self {{ ContextIterWrapper {{ iter: I::default(), - _ctx: std::marker::PhantomData + _ctx: PhantomData }} }} }} -impl std::ops::Deref for ContextIterWrapper {{ +impl ops::Deref for ContextIterWrapper {{ type Target = I; fn deref(&self) -> &I {{ &self.iter }} }} -impl std::ops::DerefMut for ContextIterWrapper {{ +impl ops::DerefMut for ContextIterWrapper {{ fn deref_mut(&mut self) -> &mut I {{ &mut self.iter }} }} impl From for ContextIterWrapper {{ fn from(iter: I) -> Self {{ - Self {{ iter, _ctx: std::marker::PhantomData }} + Self {{ iter, _ctx: PhantomData }} }} }} impl ContextIter for ContextIterWrapper {{ @@ -300,7 +309,7 @@ impl IntoContextIter for ContextIterWrapper { fn into_context_iter(self) -> Self::IntoIter {{ ContextIterWrapper {{ iter: self.iter.into_iter(), - _ctx: std::marker::PhantomData + _ctx: PhantomData }} }} }} diff --git a/crates/cranelift/src/debug/transform/expression.rs b/crates/cranelift/src/debug/transform/expression.rs index 19015ea1ef42..16802512c0cd 100644 --- a/crates/cranelift/src/debug/transform/expression.rs +++ b/crates/cranelift/src/debug/transform/expression.rs @@ -1179,8 +1179,7 @@ mod tests { fn create_mock_value_ranges() -> (ValueLabelsRanges, (ValueLabel, ValueLabel, ValueLabel)) { use cranelift_codegen::{LabelValueLoc, ValueLocRange}; use cranelift_entity::EntityRef; - use std::collections::HashMap; - let mut value_ranges = HashMap::new(); + let mut value_ranges = ValueLabelsRanges::new(); let value_0 = ValueLabel::new(0); let value_1 = ValueLabel::new(1); let value_2 = ValueLabel::new(2); diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index bba9c038352b..ab7f91144e5b 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -21,7 +21,7 @@ cranelift-filetests = { workspace = true } cranelift-interpreter = { workspace = true } cranelift-fuzzgen = { workspace = true } cranelift-native = { workspace = true } -cranelift-control = { workspace = true } +cranelift-control = { workspace = true, features = ["fuzz"] } libfuzzer-sys = { workspace = true, features = ["arbitrary-derive"] } target-lexicon = { workspace = true } smallvec = { workspace = true }