diff --git a/lib/cretonne/Cargo.toml b/lib/cretonne/Cargo.toml index cf12060989..4540a783a6 100644 --- a/lib/cretonne/Cargo.toml +++ b/lib/cretonne/Cargo.toml @@ -14,6 +14,7 @@ build = "build.rs" name = "cretonne" [dependencies] +cretonne-entity = { path = "../entity" } # It is a goal of the cretonne 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 diff --git a/lib/cretonne/src/lib.rs b/lib/cretonne/src/lib.rs index 99246defe3..996bb865bd 100644 --- a/lib/cretonne/src/lib.rs +++ b/lib/cretonne/src/lib.rs @@ -39,9 +39,10 @@ pub use write::write_function; pub const VERSION: &str = env!("CARGO_PKG_VERSION"); #[macro_use] -pub mod dbg; +pub extern crate cton_entity as entity; + #[macro_use] -pub mod entity; +pub mod dbg; pub mod bforest; pub mod binemit; @@ -52,13 +53,14 @@ pub mod flowgraph; pub mod ir; pub mod isa; pub mod loop_analysis; -pub mod packed_option; pub mod print_errors; pub mod result; pub mod settings; pub mod timing; pub mod verifier; +pub use entity::packed_option; + mod abi; mod bitset; mod constant_hash; diff --git a/lib/entity/Cargo.toml b/lib/entity/Cargo.toml new file mode 100644 index 0000000000..c86962c809 --- /dev/null +++ b/lib/entity/Cargo.toml @@ -0,0 +1,21 @@ +[package] +authors = ["The Cretonne Project Developers"] +name = "cretonne-entity" +version = "0.4.2" +description = "Data structures using entity references as mapping keys" +license = "Apache-2.0" +documentation = "https://cretonne.readthedocs.io/" +repository = "https://github.com/Cretonne/cretonne" +readme = "README.md" +keywords = ["entity", "set", "map"] + +[lib] +name = "cton_entity" + +[features] +default = ["std"] +std = [] + +[badges] +maintenance = { status = "experimental" } +travis-ci = { repository = "Cretonne/cretonne" } diff --git a/lib/entity/README.md b/lib/entity/README.md new file mode 100644 index 0000000000..abe3b6210c --- /dev/null +++ b/lib/entity/README.md @@ -0,0 +1,2 @@ +This crate contains array-based data structures used by the core Cretonne code +generator which use densely numbered entity references as mapping keys. diff --git a/lib/cretonne/src/entity/iter.rs b/lib/entity/src/iter.rs similarity index 99% rename from lib/cretonne/src/entity/iter.rs rename to lib/entity/src/iter.rs index 156021ee86..9eeba6c7a6 100644 --- a/lib/cretonne/src/entity/iter.rs +++ b/lib/entity/src/iter.rs @@ -1,6 +1,6 @@ //! A double-ended iterator over entity references and entities. -use entity::EntityRef; +use EntityRef; use std::marker::PhantomData; use std::slice; diff --git a/lib/cretonne/src/entity/keys.rs b/lib/entity/src/keys.rs similarity index 98% rename from lib/cretonne/src/entity/keys.rs rename to lib/entity/src/keys.rs index 3ad5b660b6..52481097cb 100644 --- a/lib/cretonne/src/entity/keys.rs +++ b/lib/entity/src/keys.rs @@ -1,6 +1,6 @@ //! A double-ended iterator over entity references. -use entity::EntityRef; +use EntityRef; use std::marker::PhantomData; /// Iterate over all keys in order. diff --git a/lib/cretonne/src/entity/mod.rs b/lib/entity/src/lib.rs similarity index 71% rename from lib/cretonne/src/entity/mod.rs rename to lib/entity/src/lib.rs index 88c0977cf2..00b6412c0d 100644 --- a/lib/cretonne/src/entity/mod.rs +++ b/lib/entity/src/lib.rs @@ -1,6 +1,6 @@ //! Array-based data structures using densely numbered entity references as mapping keys. //! -//! This module defines a number of data structures based on arrays. The arrays are not indexed by +//! This crate defines a number of data structures based on arrays. The arrays are not indexed by //! `usize` as usual, but by *entity references* which are integers wrapped in new-types. This has //! a couple advantages: //! @@ -29,21 +29,26 @@ //! references allocated from an associated memory pool. It has a much smaller footprint than //! `Vec`. -mod iter; -mod keys; -mod list; -mod map; -mod primary; -mod set; -mod sparse; +#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)] +#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))] +#![cfg_attr(feature = "cargo-clippy", + allow(new_without_default, new_without_default_derive, redundant_field_names))] -pub use self::iter::{Iter, IterMut}; -pub use self::keys::Keys; -pub use self::list::{EntityList, ListPool}; -pub use self::map::EntityMap; -pub use self::primary::PrimaryMap; -pub use self::set::EntitySet; -pub use self::sparse::{SparseMap, SparseMapValue, SparseSet}; +// Turns on no_std and alloc features if std is not available. +#![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(not(feature = "std"), feature(alloc))] + +/// This replaces `std` in builds with `core`. +#[cfg(not(feature = "std"))] +mod std { + extern crate alloc; + pub use self::alloc::{boxed, string, vec}; + pub use core::*; +} + +// Re-export core so that the macros works with both std and no_std crates +#[doc(hidden)] +pub extern crate core as __core; /// A type wrapping a small integer index should implement `EntityRef` so it can be used as the key /// of an `EntityMap` or `SparseMap`. @@ -61,9 +66,9 @@ pub trait EntityRef: Copy + Eq { macro_rules! entity_impl { // Basic traits. ($entity:ident) => { - impl $crate::entity::EntityRef for $entity { + impl $crate::EntityRef for $entity { fn new(index: usize) -> Self { - debug_assert!(index < (::std::u32::MAX as usize)); + debug_assert!(index < ($crate::__core::u32::MAX as usize)); $entity(index as u32) } @@ -74,7 +79,7 @@ macro_rules! entity_impl { impl $crate::packed_option::ReservedValue for $entity { fn reserved_value() -> $entity { - $entity(::std::u32::MAX) + $entity($crate::__core::u32::MAX) } } }; @@ -84,16 +89,34 @@ macro_rules! entity_impl { ($entity:ident, $display_prefix:expr) => { entity_impl!($entity); - impl ::std::fmt::Display for $entity { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + impl $crate::__core::fmt::Display for $entity { + fn fmt(&self, f: &mut $crate::__core::fmt::Formatter) -> $crate::__core::fmt::Result { write!(f, "{}{}", $display_prefix, self.0) } } - impl ::std::fmt::Debug for $entity { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - (self as &::std::fmt::Display).fmt(f) + impl $crate::__core::fmt::Debug for $entity { + fn fmt(&self, f: &mut $crate::__core::fmt::Formatter) -> $crate::__core::fmt::Result { + (self as &$crate::__core::fmt::Display).fmt(f) } } }; } + +pub mod packed_option; + +mod iter; +mod keys; +mod list; +mod map; +mod primary; +mod set; +mod sparse; + +pub use self::iter::{Iter, IterMut}; +pub use self::keys::Keys; +pub use self::list::{EntityList, ListPool}; +pub use self::map::EntityMap; +pub use self::primary::PrimaryMap; +pub use self::set::EntitySet; +pub use self::sparse::{SparseMap, SparseMapValue, SparseSet}; diff --git a/lib/cretonne/src/entity/list.rs b/lib/entity/src/list.rs similarity index 99% rename from lib/cretonne/src/entity/list.rs rename to lib/entity/src/list.rs index 545b1e146b..803504bc76 100644 --- a/lib/cretonne/src/entity/list.rs +++ b/lib/entity/src/list.rs @@ -1,5 +1,5 @@ //! Small lists of entity references. -use entity::EntityRef; +use EntityRef; use std::hash::{Hash, Hasher}; use std::marker::PhantomData; use std::mem; @@ -481,8 +481,12 @@ impl EntityList { mod tests { use super::*; use super::{sclass_for_length, sclass_size}; - use entity::EntityRef; - use ir::Inst; + use EntityRef; + + /// An opaque reference to an instruction in a function. + #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] + pub struct Inst(u32); + entity_impl!(Inst, "inst"); #[test] fn size_classes() { diff --git a/lib/cretonne/src/entity/map.rs b/lib/entity/src/map.rs similarity index 98% rename from lib/cretonne/src/entity/map.rs rename to lib/entity/src/map.rs index ff402b104f..8256ba9c90 100644 --- a/lib/cretonne/src/entity/map.rs +++ b/lib/entity/src/map.rs @@ -1,6 +1,6 @@ //! Densely numbered entity references as mapping keys. -use entity::{EntityRef, Iter, IterMut, Keys}; +use {EntityRef, Iter, IterMut, Keys}; use std::marker::PhantomData; use std::ops::{Index, IndexMut}; use std::slice; diff --git a/lib/cretonne/src/packed_option.rs b/lib/entity/src/packed_option.rs similarity index 100% rename from lib/cretonne/src/packed_option.rs rename to lib/entity/src/packed_option.rs diff --git a/lib/cretonne/src/entity/primary.rs b/lib/entity/src/primary.rs similarity index 99% rename from lib/cretonne/src/entity/primary.rs rename to lib/entity/src/primary.rs index 5d690a7553..805ccc6866 100644 --- a/lib/cretonne/src/entity/primary.rs +++ b/lib/entity/src/primary.rs @@ -1,5 +1,5 @@ //! Densely numbered entity references as mapping keys. -use entity::{EntityRef, Iter, IterMut, Keys}; +use {EntityRef, Iter, IterMut, Keys}; use std::marker::PhantomData; use std::ops::{Index, IndexMut}; use std::slice; diff --git a/lib/cretonne/src/entity/set.rs b/lib/entity/src/set.rs similarity index 99% rename from lib/cretonne/src/entity/set.rs rename to lib/entity/src/set.rs index e4acf47723..392813401c 100644 --- a/lib/cretonne/src/entity/set.rs +++ b/lib/entity/src/set.rs @@ -1,6 +1,6 @@ //! Densely numbered entity references as set keys. -use entity::{EntityRef, Keys}; +use {EntityRef, Keys}; use std::marker::PhantomData; use std::vec::Vec; diff --git a/lib/cretonne/src/entity/sparse.rs b/lib/entity/src/sparse.rs similarity index 98% rename from lib/cretonne/src/entity/sparse.rs rename to lib/entity/src/sparse.rs index 6894c89498..95d0bba41b 100644 --- a/lib/cretonne/src/entity/sparse.rs +++ b/lib/entity/src/sparse.rs @@ -7,7 +7,7 @@ //! > Briggs, Torczon, *An efficient representation for sparse sets*, //! ACM Letters on Programming Languages and Systems, Volume 2, Issue 1-4, March-Dec. 1993. -use entity::{EntityMap, EntityRef}; +use {EntityMap, EntityRef}; use std::mem; use std::slice; use std::u32; @@ -229,8 +229,12 @@ pub type SparseSet = SparseMap; #[cfg(test)] mod tests { use super::*; - use entity::EntityRef; - use ir::Inst; + use EntityRef; + + /// An opaque reference to an instruction in a function. + #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] + pub struct Inst(u32); + entity_impl!(Inst, "inst"); // Mock key-value object for testing. #[derive(PartialEq, Eq, Debug)]