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:
Amanieu d'Antras
2023-03-09 20:25:59 +01:00
committed by GitHub
parent 7354cfedde
commit 2bd03256b3
23 changed files with 176 additions and 115 deletions

View File

@@ -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.