Make regalloc2 #![no_std] (#119)
* Make regalloc2 `#![no_std]` This crate doesn't require any features from the standard library, so it can be made `no_std` to allow it to be used in environments that can't use the Rust standard library. This PR mainly performs the following mechanical changes: - `std::collections` is replaced with `alloc::collections`. - `std::*` is replaced with `core::*`. - `Vec`, `vec!`, `format!` and `ToString` are imported when needed since they are no longer in the prelude. - `HashSet` and `HashMap` are taken from the `hashbrown` crate, which is the same implementation that the standard library uses. - `FxHashSet` and `FxHashMap` are typedefs in `lib.rs` that are based on the `hashbrown` types. The only functional change is that `RegAllocError` no longer implements the `Error` trait since that is not available in `core`. Dependencies were adjusted to not require `std` and this is tested in CI by building against the `thumbv6m-none-eabi` target that doesn't have `std`. * Add the Error trait impl back under a "std" feature
This commit is contained in:
70
src/lib.rs
70
src/lib.rs
@@ -11,6 +11,12 @@
|
||||
*/
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![no_std]
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
extern crate std;
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
// Even when trace logging is disabled, the trace macro has a significant
|
||||
// performance cost so we disable it in release builds.
|
||||
@@ -28,6 +34,11 @@ macro_rules! trace_enabled {
|
||||
};
|
||||
}
|
||||
|
||||
use core::hash::BuildHasherDefault;
|
||||
use rustc_hash::FxHasher;
|
||||
type FxHashMap<K, V> = hashbrown::HashMap<K, V, BuildHasherDefault<FxHasher>>;
|
||||
type FxHashSet<V> = hashbrown::HashSet<V, BuildHasherDefault<FxHasher>>;
|
||||
|
||||
pub(crate) mod cfg;
|
||||
pub(crate) mod domtree;
|
||||
pub mod indexset;
|
||||
@@ -38,6 +49,8 @@ pub mod ssa;
|
||||
|
||||
#[macro_use]
|
||||
mod index;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
pub use index::{Block, Inst, InstRange, InstRangeIter};
|
||||
|
||||
pub mod checker;
|
||||
@@ -142,8 +155,8 @@ impl PReg {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for PReg {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
impl core::fmt::Debug for PReg {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"PReg(hw = {}, class = {:?}, index = {})",
|
||||
@@ -154,8 +167,8 @@ impl std::fmt::Debug for PReg {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for PReg {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
impl core::fmt::Display for PReg {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
let class = match self.class() {
|
||||
RegClass::Int => "i",
|
||||
RegClass::Float => "f",
|
||||
@@ -311,8 +324,8 @@ impl VReg {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for VReg {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
impl core::fmt::Debug for VReg {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"VReg(vreg = {}, class = {:?})",
|
||||
@@ -322,8 +335,8 @@ impl std::fmt::Debug for VReg {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for VReg {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
impl core::fmt::Display for VReg {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
write!(f, "v{}", self.vreg())
|
||||
}
|
||||
}
|
||||
@@ -382,8 +395,8 @@ impl SpillSlot {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for SpillSlot {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
impl core::fmt::Display for SpillSlot {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
write!(f, "stack{}", self.index())
|
||||
}
|
||||
}
|
||||
@@ -413,8 +426,8 @@ pub enum OperandConstraint {
|
||||
Reuse(usize),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for OperandConstraint {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
impl core::fmt::Display for OperandConstraint {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
match self {
|
||||
Self::Any => write!(f, "any"),
|
||||
Self::Reg => write!(f, "reg"),
|
||||
@@ -796,14 +809,14 @@ impl Operand {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Operand {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self, f)
|
||||
impl core::fmt::Debug for Operand {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
core::fmt::Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Operand {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
impl core::fmt::Display for Operand {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
match (self.kind(), self.pos()) {
|
||||
(OperandKind::Def, OperandPos::Late) | (OperandKind::Use, OperandPos::Early) => {
|
||||
write!(f, "{:?}", self.kind())?;
|
||||
@@ -836,14 +849,14 @@ pub struct Allocation {
|
||||
bits: u32,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Allocation {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self, f)
|
||||
impl core::fmt::Debug for Allocation {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
core::fmt::Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Allocation {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
impl core::fmt::Display for Allocation {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
match self.kind() {
|
||||
AllocationKind::None => write!(f, "none"),
|
||||
AllocationKind::Reg => write!(f, "{}", self.as_reg().unwrap()),
|
||||
@@ -1173,8 +1186,8 @@ pub struct ProgPoint {
|
||||
bits: u32,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for ProgPoint {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
impl core::fmt::Debug for ProgPoint {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"progpoint{}{}",
|
||||
@@ -1422,9 +1435,9 @@ impl Output {
|
||||
// binary_search_by returns the index of where it would have
|
||||
// been inserted in Err.
|
||||
if pos < ProgPoint::before(inst_range.first()) {
|
||||
std::cmp::Ordering::Less
|
||||
core::cmp::Ordering::Less
|
||||
} else {
|
||||
std::cmp::Ordering::Greater
|
||||
core::cmp::Ordering::Greater
|
||||
}
|
||||
})
|
||||
.unwrap_err();
|
||||
@@ -1463,12 +1476,13 @@ pub enum RegAllocError {
|
||||
TooManyLiveRegs,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for RegAllocError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
impl core::fmt::Display for RegAllocError {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
write!(f, "{:?}", self)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl std::error::Error for RegAllocError {}
|
||||
|
||||
/// Run the allocator.
|
||||
|
||||
Reference in New Issue
Block a user