Move EntityRef and entity_impl! into a new module.
The EntityRef trait is used by more than just the EntityMap now, so it should live in its own module. Also move the entity_impl! macro into the new module so it can be used for defining new entity references anywhere.
This commit is contained in:
@@ -46,12 +46,11 @@
|
|||||||
//! The index stored in an `EntityList` points to part 2, the list elements. The value 0 is
|
//! The index stored in an `EntityList` points to part 2, the list elements. The value 0 is
|
||||||
//! reserved for the empty list which isn't allocated in the vector.
|
//! reserved for the empty list which isn't allocated in the vector.
|
||||||
|
|
||||||
|
use entity_ref::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 entity_map::EntityRef;
|
|
||||||
|
|
||||||
/// A small list of entity references allocated from a pool.
|
/// A small list of entity references allocated from a pool.
|
||||||
///
|
///
|
||||||
/// All of the list methods that take a pool reference must be given the same pool reference every
|
/// All of the list methods that take a pool reference must be given the same pool reference every
|
||||||
@@ -484,7 +483,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use super::{sclass_size, sclass_for_length};
|
use super::{sclass_size, sclass_for_length};
|
||||||
use ir::Inst;
|
use ir::Inst;
|
||||||
use entity_map::EntityRef;
|
use entity_ref::EntityRef;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn size_classes() {
|
fn size_classes() {
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
//! Densely numbered entity references as mapping keys.
|
//! Densely numbered entity references as mapping keys.
|
||||||
//!
|
//!
|
||||||
//! This module defines an `EntityRef` trait that should be implemented by reference types wrapping
|
//! The `EntityMap` data structure uses the dense index space to implement a map with a vector.
|
||||||
//! a small integer index. The `EntityMap` data structure uses the dense index space to implement a
|
//! There are primary and secondary entity maps:
|
||||||
//! map with a vector. There are primary and secondary entity maps:
|
|
||||||
//!
|
//!
|
||||||
//! - A *primary* `EntityMap` contains the main definition of an entity, and it can be used to
|
//! - A *primary* `EntityMap` contains the main definition of an entity, and it can be used to
|
||||||
//! allocate new entity references with the `push` method. The values stores in a primary map
|
//! allocate new entity references with the `push` method. The values stores in a primary map
|
||||||
@@ -10,22 +9,10 @@
|
|||||||
//! - A *secondary* `EntityMap` contains additional data about entities kept in a primary map. The
|
//! - A *secondary* `EntityMap` contains additional data about entities kept in a primary map. The
|
||||||
//! values need to implement `Clone + Default` traits so the map can be grown with `ensure`.
|
//! values need to implement `Clone + Default` traits so the map can be grown with `ensure`.
|
||||||
|
|
||||||
use std::vec::Vec;
|
use entity_ref::EntityRef;
|
||||||
use std::default::Default;
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ops::{Index, IndexMut};
|
use std::ops::{Index, IndexMut};
|
||||||
|
|
||||||
/// A type wrapping a small integer index should implement `EntityRef` so it can be used as the key
|
|
||||||
/// of an `EntityMap`.
|
|
||||||
pub trait EntityRef: Copy + Eq {
|
|
||||||
/// Create a new entity reference from a small integer.
|
|
||||||
/// This should crash if the requested index is not representable.
|
|
||||||
fn new(usize) -> Self;
|
|
||||||
|
|
||||||
/// Get the index that was used to create this entity reference.
|
|
||||||
fn index(self) -> usize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A mapping `K -> V` for densely indexed entity references.
|
/// A mapping `K -> V` for densely indexed entity references.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct EntityMap<K, V>
|
pub struct EntityMap<K, V>
|
||||||
|
|||||||
51
lib/cretonne/src/entity_ref.rs
Normal file
51
lib/cretonne/src/entity_ref.rs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
//! Densely numbered entity references as mapping keys.
|
||||||
|
//!
|
||||||
|
//! This module defines an `EntityRef` trait that should be implemented by reference types wrapping
|
||||||
|
//! a small integer index.
|
||||||
|
|
||||||
|
/// A type wrapping a small integer index should implement `EntityRef` so it can be used as the key
|
||||||
|
/// of an `EntityMap` or `SparseMap`.
|
||||||
|
pub trait EntityRef: Copy + Eq {
|
||||||
|
/// Create a new entity reference from a small integer.
|
||||||
|
/// This should crash if the requested index is not representable.
|
||||||
|
fn new(usize) -> Self;
|
||||||
|
|
||||||
|
/// Get the index that was used to create this entity reference.
|
||||||
|
fn index(self) -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Macro which provides the common implementation of a 32-bit entity reference.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! entity_impl {
|
||||||
|
// Basic traits.
|
||||||
|
($entity:ident) => {
|
||||||
|
impl $crate::entity_ref::EntityRef for $entity {
|
||||||
|
fn new(index: usize) -> Self {
|
||||||
|
assert!(index < (::std::u32::MAX as usize));
|
||||||
|
$entity(index as u32)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn index(self) -> usize {
|
||||||
|
self.0 as usize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl $crate::packed_option::ReservedValue for $entity {
|
||||||
|
fn reserved_value() -> $entity {
|
||||||
|
$entity(::std::u32::MAX)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Include basic `Display` impl using the given display prefix.
|
||||||
|
// Display an `Ebb` reference as "ebb12".
|
||||||
|
($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 {
|
||||||
|
write!(f, "{}{}", $display_prefix, self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,46 +19,9 @@
|
|||||||
//! The entity references all implement the `Display` trait in a way that matches the textual IL
|
//! The entity references all implement the `Display` trait in a way that matches the textual IL
|
||||||
//! format.
|
//! format.
|
||||||
|
|
||||||
use entity_map::EntityRef;
|
use std::fmt;
|
||||||
use packed_option::ReservedValue;
|
|
||||||
use std::fmt::{self, Display, Formatter};
|
|
||||||
use std::u32;
|
use std::u32;
|
||||||
|
|
||||||
// Implement the common traits for a 32-bit entity reference.
|
|
||||||
macro_rules! entity_impl {
|
|
||||||
// Basic traits.
|
|
||||||
($entity:ident) => {
|
|
||||||
impl EntityRef for $entity {
|
|
||||||
fn new(index: usize) -> Self {
|
|
||||||
assert!(index < (u32::MAX as usize));
|
|
||||||
$entity(index as u32)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn index(self) -> usize {
|
|
||||||
self.0 as usize
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ReservedValue for $entity {
|
|
||||||
fn reserved_value() -> $entity {
|
|
||||||
$entity(u32::MAX)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Include basic `Display` impl using the given display prefix.
|
|
||||||
// Display an `Ebb` reference as "ebb12".
|
|
||||||
($entity:ident, $display_prefix:expr) => {
|
|
||||||
entity_impl!($entity);
|
|
||||||
|
|
||||||
impl Display for $entity {
|
|
||||||
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
|
|
||||||
write!(fmt, "{}{}", $display_prefix, self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An opaque reference to an extended basic block in a function.
|
/// An opaque reference to an extended basic block in a function.
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
|
||||||
pub struct Ebb(u32);
|
pub struct Ebb(u32);
|
||||||
@@ -138,17 +101,17 @@ pub enum AnyEntity {
|
|||||||
SigRef(SigRef),
|
SigRef(SigRef),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for AnyEntity {
|
impl fmt::Display for AnyEntity {
|
||||||
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
AnyEntity::Function => write!(fmt, "function"),
|
AnyEntity::Function => write!(f, "function"),
|
||||||
AnyEntity::Ebb(r) => r.fmt(fmt),
|
AnyEntity::Ebb(r) => r.fmt(f),
|
||||||
AnyEntity::Inst(r) => r.fmt(fmt),
|
AnyEntity::Inst(r) => r.fmt(f),
|
||||||
AnyEntity::Value(r) => r.fmt(fmt),
|
AnyEntity::Value(r) => r.fmt(f),
|
||||||
AnyEntity::StackSlot(r) => r.fmt(fmt),
|
AnyEntity::StackSlot(r) => r.fmt(f),
|
||||||
AnyEntity::JumpTable(r) => r.fmt(fmt),
|
AnyEntity::JumpTable(r) => r.fmt(f),
|
||||||
AnyEntity::FuncRef(r) => r.fmt(fmt),
|
AnyEntity::FuncRef(r) => r.fmt(f),
|
||||||
AnyEntity::SigRef(r) => r.fmt(fmt),
|
AnyEntity::SigRef(r) => r.fmt(f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ impl Display for JumpTableData {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::JumpTableData;
|
use super::JumpTableData;
|
||||||
use ir::Ebb;
|
use ir::Ebb;
|
||||||
use entity_map::EntityRef;
|
use entity_ref::EntityRef;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn empty() {
|
fn empty() {
|
||||||
|
|||||||
@@ -982,7 +982,7 @@ impl<'f> Cursor<'f> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{Layout, Cursor, CursorPosition};
|
use super::{Layout, Cursor, CursorPosition};
|
||||||
use entity_map::EntityRef;
|
use entity_ref::EntityRef;
|
||||||
use ir::{Ebb, Inst, ProgramOrder};
|
use ir::{Ebb, Inst, ProgramOrder};
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! Program points.
|
//! Program points.
|
||||||
|
|
||||||
use entity_map::EntityRef;
|
use entity_ref::EntityRef;
|
||||||
use ir::{Ebb, Inst, ValueDef};
|
use ir::{Ebb, Inst, ValueDef};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::u32;
|
use std::u32;
|
||||||
@@ -122,7 +122,7 @@ pub trait ProgramOrder {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use entity_map::EntityRef;
|
use entity_ref::EntityRef;
|
||||||
use ir::{Inst, Ebb};
|
use ir::{Inst, Ebb};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! Data structures describing the registers in an ISA.
|
//! Data structures describing the registers in an ISA.
|
||||||
|
|
||||||
use entity_map::EntityRef;
|
use entity_ref::EntityRef;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
/// Register units are the smallest units of register allocation.
|
/// Register units are the smallest units of register allocation.
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ pub const VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
|||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod dbg;
|
pub mod dbg;
|
||||||
|
#[macro_use]
|
||||||
|
pub mod entity_ref;
|
||||||
|
|
||||||
pub mod binemit;
|
pub mod binemit;
|
||||||
pub mod dominator_tree;
|
pub mod dominator_tree;
|
||||||
|
|||||||
@@ -1,34 +1,16 @@
|
|||||||
//! A loop analysis represented as mappings of loops to their header Ebb
|
//! A loop analysis represented as mappings of loops to their header Ebb
|
||||||
//! and parent in the loop tree.
|
//! and parent in the loop tree.
|
||||||
|
|
||||||
use ir::{Function, Ebb, Layout};
|
|
||||||
use flowgraph::ControlFlowGraph;
|
|
||||||
use dominator_tree::DominatorTree;
|
use dominator_tree::DominatorTree;
|
||||||
use entity_map::{EntityMap, PrimaryEntityData};
|
use entity_map::{EntityMap, PrimaryEntityData, Keys};
|
||||||
use packed_option::{PackedOption, ReservedValue};
|
use flowgraph::ControlFlowGraph;
|
||||||
use entity_map::{EntityRef, Keys};
|
use ir::{Function, Ebb, Layout};
|
||||||
use std::u32;
|
use packed_option::PackedOption;
|
||||||
|
|
||||||
/// A opaque reference to a code loop.
|
/// A opaque reference to a code loop.
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
pub struct Loop(u32);
|
pub struct Loop(u32);
|
||||||
impl EntityRef for Loop {
|
entity_impl!(Loop, "loop");
|
||||||
fn new(index: usize) -> Self {
|
|
||||||
assert!(index < (u32::MAX as usize));
|
|
||||||
Loop(index as u32)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn index(self) -> usize {
|
|
||||||
self.0 as usize
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ReservedValue for Loop {
|
|
||||||
fn reserved_value() -> Loop {
|
|
||||||
Loop(u32::MAX)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Loop tree information for a single function.
|
/// Loop tree information for a single function.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ impl RegDiversions {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use ir::Value;
|
use ir::Value;
|
||||||
use entity_map::EntityRef;
|
use entity_ref::EntityRef;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn inserts() {
|
fn inserts() {
|
||||||
|
|||||||
@@ -394,7 +394,7 @@ impl SparseMapValue<Value> for LiveRange {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::LiveRange;
|
use super::LiveRange;
|
||||||
use ir::{Inst, Ebb, Value};
|
use ir::{Inst, Ebb, Value};
|
||||||
use entity_map::EntityRef;
|
use entity_ref::EntityRef;
|
||||||
use ir::{ProgramOrder, ExpandedProgramPoint};
|
use ir::{ProgramOrder, ExpandedProgramPoint};
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
|
|||||||
@@ -675,7 +675,7 @@ impl Solver {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use entity_map::EntityRef;
|
use entity_ref::EntityRef;
|
||||||
use ir::Value;
|
use ir::Value;
|
||||||
use isa::{TargetIsa, RegClass, RegUnit};
|
use isa::{TargetIsa, RegClass, RegUnit};
|
||||||
use regalloc::AllocatableSet;
|
use regalloc::AllocatableSet;
|
||||||
|
|||||||
@@ -35,7 +35,8 @@
|
|||||||
//! - `SparseMap` requires the values to implement `SparseMapValue<K>` which means that they must
|
//! - `SparseMap` requires the values to implement `SparseMapValue<K>` which means that they must
|
||||||
//! contain their own key.
|
//! contain their own key.
|
||||||
|
|
||||||
use entity_map::{EntityRef, EntityMap};
|
use entity_map::EntityMap;
|
||||||
|
use entity_ref::EntityRef;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::u32;
|
use std::u32;
|
||||||
@@ -215,7 +216,7 @@ pub type SparseSet<T> = SparseMap<T, T>;
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use entity_map::EntityRef;
|
use entity_ref::EntityRef;
|
||||||
use ir::Inst;
|
use ir::Inst;
|
||||||
|
|
||||||
// Mock key-value object for testing.
|
// Mock key-value object for testing.
|
||||||
|
|||||||
Reference in New Issue
Block a user