Most of the way to no_std support
This commit is contained in:
committed by
Dan Gohman
parent
2a26b70854
commit
7375088c3e
@@ -17,3 +17,11 @@ name = "cretonne"
|
|||||||
# Please don't add any unless they are essential to the task of creating binary
|
# 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
|
# machine code. Integration tests that need external dependencies can be
|
||||||
# accomodated in `tests`.
|
# accomodated in `tests`.
|
||||||
|
[dependencies.hashmap_core]
|
||||||
|
version = "0.1.1"
|
||||||
|
optional = true
|
||||||
|
|
||||||
|
[features]
|
||||||
|
# Currently, the only feature is the `no_std` feature.
|
||||||
|
# Enabling this disables use of `stdlib`.
|
||||||
|
no_std = ["hashmap_core"]
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
use ir::{ArgumentLoc, AbiParam, ArgumentExtension, Type};
|
use ir::{ArgumentLoc, AbiParam, ArgumentExtension, Type};
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// Legalization action to perform on a single argument or return value when converting a
|
/// Legalization action to perform on a single argument or return value when converting a
|
||||||
/// signature.
|
/// signature.
|
||||||
|
|||||||
@@ -10,12 +10,17 @@
|
|||||||
/// thread doing the logging.
|
/// thread doing the logging.
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
use std::env;
|
use std::env;
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
use std::sync::atomic;
|
use std::sync::atomic;
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
static STATE: atomic::AtomicIsize = atomic::ATOMIC_ISIZE_INIT;
|
static STATE: atomic::AtomicIsize = atomic::ATOMIC_ISIZE_INIT;
|
||||||
@@ -26,6 +31,7 @@ static STATE: atomic::AtomicIsize = atomic::ATOMIC_ISIZE_INIT;
|
|||||||
/// other than `0`.
|
/// other than `0`.
|
||||||
///
|
///
|
||||||
/// This inline function turns into a constant `false` when debug assertions are disabled.
|
/// This inline function turns into a constant `false` when debug assertions are disabled.
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn enabled() -> bool {
|
pub fn enabled() -> bool {
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
@@ -38,7 +44,15 @@ pub fn enabled() -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Does nothing
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
#[inline]
|
||||||
|
pub fn enabled() -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
/// Initialize `STATE` from the environment variable.
|
/// Initialize `STATE` from the environment variable.
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
fn initialize() -> bool {
|
fn initialize() -> bool {
|
||||||
let enable = match env::var_os("CRETONNE_DBG") {
|
let enable = match env::var_os("CRETONNE_DBG") {
|
||||||
Some(s) => s != OsStr::new("0"),
|
Some(s) => s != OsStr::new("0"),
|
||||||
@@ -54,6 +68,7 @@ fn initialize() -> bool {
|
|||||||
enable
|
enable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
thread_local! {
|
thread_local! {
|
||||||
static WRITER : RefCell<io::BufWriter<File>> = RefCell::new(open_file());
|
static WRITER : RefCell<io::BufWriter<File>> = RefCell::new(open_file());
|
||||||
}
|
}
|
||||||
@@ -61,6 +76,7 @@ thread_local! {
|
|||||||
/// Write a line with the given format arguments.
|
/// Write a line with the given format arguments.
|
||||||
///
|
///
|
||||||
/// This is for use by the `dbg!` macro.
|
/// This is for use by the `dbg!` macro.
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
pub fn writeln_with_format_args(args: fmt::Arguments) -> io::Result<()> {
|
pub fn writeln_with_format_args(args: fmt::Arguments) -> io::Result<()> {
|
||||||
WRITER.with(|rc| {
|
WRITER.with(|rc| {
|
||||||
let mut w = rc.borrow_mut();
|
let mut w = rc.borrow_mut();
|
||||||
@@ -70,6 +86,7 @@ pub fn writeln_with_format_args(args: fmt::Arguments) -> io::Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Open the tracing file for the current thread.
|
/// Open the tracing file for the current thread.
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
fn open_file() -> io::BufWriter<File> {
|
fn open_file() -> io::BufWriter<File> {
|
||||||
let curthread = thread::current();
|
let curthread = thread::current();
|
||||||
let tmpstr;
|
let tmpstr;
|
||||||
@@ -97,6 +114,7 @@ macro_rules! dbg {
|
|||||||
if $crate::dbg::enabled() {
|
if $crate::dbg::enabled() {
|
||||||
// Drop the error result so we don't get compiler errors for ignoring it.
|
// Drop the error result so we don't get compiler errors for ignoring it.
|
||||||
// What are you going to do, log the error?
|
// What are you going to do, log the error?
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
$crate::dbg::writeln_with_format_args(format_args!($($arg)+)).ok();
|
$crate::dbg::writeln_with_format_args(format_args!($($arg)+)).ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use std::mem;
|
|||||||
use timing;
|
use timing;
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
// RPO numbers are not first assigned in a contiguous way but as multiples of STRIDE, to leave
|
// RPO numbers are not first assigned in a contiguous way but as multiples of STRIDE, to leave
|
||||||
// room for modifications of the dominator tree.
|
// room for modifications of the dominator tree.
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use entity::EntityRef;
|
|||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// A small list of entity references allocated from a pool.
|
/// A small list of entity references allocated from a pool.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
use entity::{EntityRef, Keys};
|
use entity::{EntityRef, Keys};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ops::{Index, IndexMut};
|
use std::ops::{Index, IndexMut};
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// A mapping `K -> V` for densely indexed entity references.
|
/// A mapping `K -> V` for densely indexed entity references.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
use entity::{EntityRef, Keys};
|
use entity::{EntityRef, Keys};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ops::{Index, IndexMut};
|
use std::ops::{Index, IndexMut};
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// A primary mapping `K -> V` allocating dense entity references.
|
/// A primary mapping `K -> V` allocating dense entity references.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
use entity::{EntityRef, Keys};
|
use entity::{EntityRef, Keys};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// A set of `K` for densely indexed entity references.
|
/// A set of `K` for densely indexed entity references.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use entity::{EntityRef, EntityMap};
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::u32;
|
use std::u32;
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// Trait for extracting keys from values stored in a `SparseMap`.
|
/// Trait for extracting keys from values stored in a `SparseMap`.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use isa::{RegInfo, RegUnit};
|
|||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// Function signature.
|
/// Function signature.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
use ir;
|
use ir;
|
||||||
use ir::{Value, Type, Ebb, JumpTable, SigRef, FuncRef, StackSlot, MemFlags};
|
use ir::{Value, Type, Ebb, JumpTable, SigRef, FuncRef, StackSlot, MemFlags};
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use ir::entities::Ebb;
|
|||||||
use std::iter;
|
use std::iter;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// Contents of a jump table.
|
/// Contents of a jump table.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use std::cmp;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::{Index, IndexMut};
|
use std::ops::{Index, IndexMut};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// The size of an object on the stack, or the size of a stack frame.
|
/// The size of an object on the stack, or the size of a stack frame.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ use ir;
|
|||||||
use regalloc;
|
use regalloc;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use std::boxed::Box;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
struct Isa {
|
struct Isa {
|
||||||
shared_flags: shared_settings::Flags,
|
shared_flags: shared_settings::Flags,
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ use ir;
|
|||||||
use regalloc;
|
use regalloc;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use std::boxed::Box;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
struct Isa {
|
struct Isa {
|
||||||
shared_flags: shared_settings::Flags,
|
shared_flags: shared_settings::Flags,
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ use result;
|
|||||||
use timing;
|
use timing;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use std::boxed::Box;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
struct Isa {
|
struct Isa {
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ use timing;
|
|||||||
use isa::enc_tables::Encodings;
|
use isa::enc_tables::Encodings;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use std::boxed::Box;
|
||||||
|
|
||||||
#[cfg(build_riscv)]
|
#[cfg(build_riscv)]
|
||||||
mod riscv;
|
mod riscv;
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ use ir;
|
|||||||
use regalloc;
|
use regalloc;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use std::boxed::Box;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
struct Isa {
|
struct Isa {
|
||||||
shared_flags: shared_settings::Flags,
|
shared_flags: shared_settings::Flags,
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ use ir::{Function, DataFlowGraph, Inst, InstBuilder, Ebb, Type, Value, Signature
|
|||||||
use ir::instructions::CallInfo;
|
use ir::instructions::CallInfo;
|
||||||
use isa::TargetIsa;
|
use isa::TargetIsa;
|
||||||
use legalizer::split::{isplit, vsplit};
|
use legalizer::split::{isplit, vsplit};
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// Legalize all the function signatures in `func`.
|
/// Legalize all the function signatures in `func`.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub fn expand_as_libcall(inst: ir::Inst, func: &mut ir::Function) -> bool {
|
|||||||
let funcref = find_funcref(libcall, func).unwrap_or_else(|| make_funcref(libcall, inst, func));
|
let funcref = find_funcref(libcall, func).unwrap_or_else(|| make_funcref(libcall, inst, func));
|
||||||
|
|
||||||
// Now we convert `inst` to a call. First save the arguments.
|
// Now we convert `inst` to a call. First save the arguments.
|
||||||
let mut args = Vec::new();
|
let mut args = vec![];
|
||||||
args.extend_from_slice(func.dfg.inst_args(inst));
|
args.extend_from_slice(func.dfg.inst_args(inst));
|
||||||
// The replace builder will preserve the instruction result values.
|
// The replace builder will preserve the instruction result values.
|
||||||
func.dfg.replace(inst).call(funcref, &args);
|
func.dfg.replace(inst).call(funcref, &args);
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ use cursor::{Cursor, CursorPosition, FuncCursor};
|
|||||||
use flowgraph::ControlFlowGraph;
|
use flowgraph::ControlFlowGraph;
|
||||||
use ir::{self, Ebb, Inst, Value, Type, Opcode, ValueDef, InstructionData, InstBuilder};
|
use ir::{self, Ebb, Inst, Value, Type, Opcode, ValueDef, InstructionData, InstBuilder};
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// Split `value` into two values using the `isplit` semantics. Do this by reusing existing values
|
/// Split `value` into two values using the `isplit` semantics. Do this by reusing existing values
|
||||||
/// if possible.
|
/// if possible.
|
||||||
|
|||||||
@@ -1,7 +1,17 @@
|
|||||||
//! Cretonne code generation library.
|
//! Cretonne code generation library.
|
||||||
|
#![cfg_attr(feature = "no_std", no_std)]
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
|
// Turns on alloc feature if no_std
|
||||||
|
#![cfg_attr(feature = "no_std", feature(alloc))]
|
||||||
|
|
||||||
|
// Include the `hashmap_core` crate if no_std
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
extern crate hashmap_core;
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
pub use context::Context;
|
pub use context::Context;
|
||||||
pub use legalizer::legalize_function;
|
pub use legalizer::legalize_function;
|
||||||
pub use verifier::verify_function;
|
pub use verifier::verify_function;
|
||||||
@@ -46,3 +56,25 @@ mod stack_layout;
|
|||||||
mod topo_order;
|
mod topo_order;
|
||||||
mod unreachable_code;
|
mod unreachable_code;
|
||||||
mod write;
|
mod write;
|
||||||
|
|
||||||
|
/// This replaces `std` in builds with no_std.
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
mod std {
|
||||||
|
pub use core::*;
|
||||||
|
#[macro_use]
|
||||||
|
pub use alloc::{boxed, vec, string};
|
||||||
|
pub mod prelude {
|
||||||
|
pub use core::prelude as v1;
|
||||||
|
}
|
||||||
|
pub mod collections {
|
||||||
|
pub use hashmap_core::{HashMap, HashSet};
|
||||||
|
pub use hashmap_core::map as hash_map;
|
||||||
|
pub use alloc::BTreeSet;
|
||||||
|
}
|
||||||
|
pub mod error {
|
||||||
|
pub trait Error {
|
||||||
|
fn description(&self) -> &str;
|
||||||
|
fn cause(&self) -> Option<&Error> { None }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ use dominator_tree::DominatorTree;
|
|||||||
use entity::{EntityList, ListPool};
|
use entity::{EntityList, ListPool};
|
||||||
use loop_analysis::{Loop, LoopAnalysis};
|
use loop_analysis::{Loop, LoopAnalysis};
|
||||||
use timing;
|
use timing;
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// Performs the LICM pass by detecting loops within the CFG and moving
|
/// Performs the LICM pass by detecting loops within the CFG and moving
|
||||||
/// loop-invariant instructions out of them.
|
/// loop-invariant instructions out of them.
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use flowgraph::ControlFlowGraph;
|
|||||||
use ir::{Function, Ebb, Layout};
|
use ir::{Function, Ebb, Layout};
|
||||||
use packed_option::PackedOption;
|
use packed_option::PackedOption;
|
||||||
use timing;
|
use timing;
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// A opaque reference to a code loop.
|
/// A opaque reference to a code loop.
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ use std::cmp;
|
|||||||
use std::iter;
|
use std::iter;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
use std::iter::Peekable;
|
||||||
|
use std::mem;
|
||||||
|
use std::vec::Vec;
|
||||||
use isa::{TargetIsa, EncInfo};
|
use isa::{TargetIsa, EncInfo};
|
||||||
use timing;
|
use timing;
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use ir::{Value, ValueLoc, ValueLocations, StackSlot};
|
|||||||
use ir::{InstructionData, Opcode};
|
use ir::{InstructionData, Opcode};
|
||||||
use isa::{RegUnit, RegInfo};
|
use isa::{RegUnit, RegInfo};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// A diversion of a value from its original location to a new register or stack location.
|
/// A diversion of a value from its original location to a new register or stack location.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ use regalloc::affinity::Affinity;
|
|||||||
use regalloc::liveness::Liveness;
|
use regalloc::liveness::Liveness;
|
||||||
use regalloc::liverange::LiveRange;
|
use regalloc::liverange::LiveRange;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
type ValueList = EntityList<Value>;
|
type ValueList = EntityList<Value>;
|
||||||
|
|
||||||
|
|||||||
@@ -184,6 +184,7 @@ use regalloc::affinity::Affinity;
|
|||||||
use regalloc::liverange::{LiveRange, LiveRangeForest, LiveRangeContext};
|
use regalloc::liverange::{LiveRange, LiveRangeForest, LiveRangeContext};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::Index;
|
use std::ops::Index;
|
||||||
|
use std::vec::Vec;
|
||||||
use timing;
|
use timing;
|
||||||
|
|
||||||
/// A set of live ranges, indexed by value number.
|
/// A set of live ranges, indexed by value number.
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ use regalloc::live_value_tracker::{LiveValue, LiveValueTracker};
|
|||||||
use regalloc::liveness::Liveness;
|
use regalloc::liveness::Liveness;
|
||||||
use timing;
|
use timing;
|
||||||
use topo_order::TopoOrder;
|
use topo_order::TopoOrder;
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// Reusable data structures for the reload pass.
|
/// Reusable data structures for the reload pass.
|
||||||
pub struct Reload {
|
pub struct Reload {
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ use std::fmt;
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use super::AllocatableSet;
|
use super::AllocatableSet;
|
||||||
use std::u16;
|
use std::u16;
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// A variable in the constraint problem.
|
/// A variable in the constraint problem.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ use regalloc::liveness::Liveness;
|
|||||||
use regalloc::pressure::Pressure;
|
use regalloc::pressure::Pressure;
|
||||||
use regalloc::virtregs::VirtRegs;
|
use regalloc::virtregs::VirtRegs;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::vec::Vec;
|
||||||
use timing;
|
use timing;
|
||||||
use topo_order::TopoOrder;
|
use topo_order::TopoOrder;
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ use constant_hash::{probe, simple_hash};
|
|||||||
use isa::TargetIsa;
|
use isa::TargetIsa;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::result;
|
use std::result;
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// A string-based configurator for settings groups.
|
/// A string-based configurator for settings groups.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ use ir::{InstructionData, Function, Inst, Opcode, Type};
|
|||||||
use scoped_hash_map::ScopedHashMap;
|
use scoped_hash_map::ScopedHashMap;
|
||||||
use timing;
|
use timing;
|
||||||
|
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use alloc::Vec;
|
||||||
|
|
||||||
/// Test whether the given opcode is unsafe to even consider for GVN.
|
/// Test whether the given opcode is unsafe to even consider for GVN.
|
||||||
fn trivially_unsafe_for_gvn(opcode: Opcode) -> bool {
|
fn trivially_unsafe_for_gvn(opcode: Opcode) -> bool {
|
||||||
opcode.is_call() || opcode.is_branch() || opcode.is_terminator() ||
|
opcode.is_call() || opcode.is_branch() || opcode.is_terminator() ||
|
||||||
|
|||||||
@@ -87,12 +87,12 @@ impl fmt::Display for Pass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Implementation details.
|
/// Implementation details.
|
||||||
///
|
///
|
||||||
/// This whole module can be gated on a `cfg` feature to provide a dummy implementation for
|
/// This whole module can be gated on a `cfg` feature to provide a dummy implementation for
|
||||||
/// performance-sensitive builds or restricted environments. The dummy implementation must provide
|
/// performance-sensitive builds or restricted environments. The dummy implementation must provide
|
||||||
/// `TimingToken` and `PassTimings` types and a `take_current` function.
|
/// `TimingToken` and `PassTimes` types and `take_current`, `add_to_current`, and `start_pass` functions.
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
mod details {
|
mod details {
|
||||||
use super::{Pass, NUM_PASSES, DESCRIPTIONS};
|
use super::{Pass, NUM_PASSES, DESCRIPTIONS};
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
@@ -214,6 +214,27 @@ mod details {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Dummy `debug` implementation
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
mod details {
|
||||||
|
use super::Pass;
|
||||||
|
/// Dummy `TimingToken`
|
||||||
|
pub struct TimingToken;
|
||||||
|
/// Dummy `PassTimes`
|
||||||
|
pub struct PassTimes;
|
||||||
|
/// Returns dummy `PassTimes`
|
||||||
|
pub fn take_current() -> PassTimes {
|
||||||
|
PassTimes
|
||||||
|
}
|
||||||
|
/// does nothing
|
||||||
|
pub fn add_to_current(_times: PassTimes) { }
|
||||||
|
|
||||||
|
/// does nothing
|
||||||
|
pub(super) fn start_pass(_pass: Pass) -> TimingToken {
|
||||||
|
TimingToken
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ use entity::SparseSet;
|
|||||||
use dominator_tree::DominatorTree;
|
use dominator_tree::DominatorTree;
|
||||||
use ir::{Ebb, Layout};
|
use ir::{Ebb, Layout};
|
||||||
|
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use alloc::Vec;
|
||||||
|
|
||||||
/// Present EBBs in a topological order such that all dominating EBBs are guaranteed to be visited
|
/// Present EBBs in a topological order such that all dominating EBBs are guaranteed to be visited
|
||||||
/// before the current EBB.
|
/// before the current EBB.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ use std::collections::BTreeSet;
|
|||||||
use std::error as std_error;
|
use std::error as std_error;
|
||||||
use std::fmt::{self, Display, Formatter, Write};
|
use std::fmt::{self, Display, Formatter, Write};
|
||||||
use std::result;
|
use std::result;
|
||||||
|
use std::vec::Vec;
|
||||||
|
use std::string::String;
|
||||||
use timing;
|
use timing;
|
||||||
|
|
||||||
pub use self::cssa::verify_cssa;
|
pub use self::cssa::verify_cssa;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use isa::{TargetIsa, RegInfo};
|
|||||||
use std::fmt::{self, Result, Error, Write};
|
use std::fmt::{self, Result, Error, Write};
|
||||||
use std::result;
|
use std::result;
|
||||||
use packed_option::ReservedValue;
|
use packed_option::ReservedValue;
|
||||||
|
use std::string::String;
|
||||||
|
|
||||||
/// Write `func` to `w` as equivalent text.
|
/// Write `func` to `w` as equivalent text.
|
||||||
/// Use `isa` to emit ISA-dependent annotations.
|
/// Use `isa` to emit ISA-dependent annotations.
|
||||||
|
|||||||
@@ -13,3 +13,6 @@ name = "cton_frontend"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cretonne = { path = "../cretonne", version = "0.1.0" }
|
cretonne = { path = "../cretonne", version = "0.1.0" }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
no_std = ["cretonne/no_std"]
|
||||||
|
|||||||
@@ -142,11 +142,23 @@
|
|||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
|
#![cfg_attr(feature = "no_std", no_std)]
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
|
#![cfg_attr(feature = "no_std", feature(alloc))]
|
||||||
|
|
||||||
extern crate cretonne;
|
extern crate cretonne;
|
||||||
|
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
pub use frontend::{ILBuilder, FunctionBuilder};
|
pub use frontend::{ILBuilder, FunctionBuilder};
|
||||||
|
|
||||||
mod frontend;
|
mod frontend;
|
||||||
mod ssa;
|
mod ssa;
|
||||||
|
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
mod std {
|
||||||
|
pub use alloc::vec;
|
||||||
|
pub use core::*;
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@ use std::u32;
|
|||||||
use cretonne::ir::types::{F32, F64};
|
use cretonne::ir::types::{F32, F64};
|
||||||
use cretonne::ir::immediates::{Ieee32, Ieee64};
|
use cretonne::ir::immediates::{Ieee32, Ieee64};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// Structure containing the data relevant the construction of SSA for a given function.
|
/// Structure containing the data relevant the construction of SSA for a given function.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -15,3 +15,6 @@ cretonne = { path = "../cretonne", version = "0.1.0" }
|
|||||||
|
|
||||||
[target.'cfg(any(target_arch = "x86", target_arch = "x86_64"))'.dependencies]
|
[target.'cfg(any(target_arch = "x86", target_arch = "x86_64"))'.dependencies]
|
||||||
raw-cpuid = "3.0.0"
|
raw-cpuid = "3.0.0"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
no_std = ["cretonne/no_std"]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! Performs autodetection of the host for the purposes of running
|
//! Performs autodetection of the host for the purposes of running
|
||||||
//! Cretonne to generate code to run on the same machine.
|
//! Cretonne to generate code to run on the same machine.
|
||||||
|
#![cfg_attr(feature = "no_std", no_std)]
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
extern crate cretonne;
|
extern crate cretonne;
|
||||||
|
|||||||
Reference in New Issue
Block a user