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
|
||||
//! reserved for the empty list which isn't allocated in the vector.
|
||||
|
||||
use entity_ref::EntityRef;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
|
||||
use entity_map::EntityRef;
|
||||
|
||||
/// 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
|
||||
@@ -484,7 +483,7 @@ mod tests {
|
||||
use super::*;
|
||||
use super::{sclass_size, sclass_for_length};
|
||||
use ir::Inst;
|
||||
use entity_map::EntityRef;
|
||||
use entity_ref::EntityRef;
|
||||
|
||||
#[test]
|
||||
fn size_classes() {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
//! 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. The `EntityMap` data structure uses the dense index space to implement a
|
||||
//! map with a vector. There are primary and secondary entity maps:
|
||||
//! The `EntityMap` data structure uses the dense index space to implement a 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
|
||||
//! 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
|
||||
//! values need to implement `Clone + Default` traits so the map can be grown with `ensure`.
|
||||
|
||||
use std::vec::Vec;
|
||||
use std::default::Default;
|
||||
use entity_ref::EntityRef;
|
||||
use std::marker::PhantomData;
|
||||
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.
|
||||
#[derive(Debug, Clone)]
|
||||
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
|
||||
//! format.
|
||||
|
||||
use entity_map::EntityRef;
|
||||
use packed_option::ReservedValue;
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
use std::fmt;
|
||||
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.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
|
||||
pub struct Ebb(u32);
|
||||
@@ -138,17 +101,17 @@ pub enum AnyEntity {
|
||||
SigRef(SigRef),
|
||||
}
|
||||
|
||||
impl Display for AnyEntity {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
|
||||
impl fmt::Display for AnyEntity {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
AnyEntity::Function => write!(fmt, "function"),
|
||||
AnyEntity::Ebb(r) => r.fmt(fmt),
|
||||
AnyEntity::Inst(r) => r.fmt(fmt),
|
||||
AnyEntity::Value(r) => r.fmt(fmt),
|
||||
AnyEntity::StackSlot(r) => r.fmt(fmt),
|
||||
AnyEntity::JumpTable(r) => r.fmt(fmt),
|
||||
AnyEntity::FuncRef(r) => r.fmt(fmt),
|
||||
AnyEntity::SigRef(r) => r.fmt(fmt),
|
||||
AnyEntity::Function => write!(f, "function"),
|
||||
AnyEntity::Ebb(r) => r.fmt(f),
|
||||
AnyEntity::Inst(r) => r.fmt(f),
|
||||
AnyEntity::Value(r) => r.fmt(f),
|
||||
AnyEntity::StackSlot(r) => r.fmt(f),
|
||||
AnyEntity::JumpTable(r) => r.fmt(f),
|
||||
AnyEntity::FuncRef(r) => r.fmt(f),
|
||||
AnyEntity::SigRef(r) => r.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ impl Display for JumpTableData {
|
||||
mod tests {
|
||||
use super::JumpTableData;
|
||||
use ir::Ebb;
|
||||
use entity_map::EntityRef;
|
||||
use entity_ref::EntityRef;
|
||||
|
||||
#[test]
|
||||
fn empty() {
|
||||
|
||||
@@ -982,7 +982,7 @@ impl<'f> Cursor<'f> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{Layout, Cursor, CursorPosition};
|
||||
use entity_map::EntityRef;
|
||||
use entity_ref::EntityRef;
|
||||
use ir::{Ebb, Inst, ProgramOrder};
|
||||
use std::cmp::Ordering;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Program points.
|
||||
|
||||
use entity_map::EntityRef;
|
||||
use entity_ref::EntityRef;
|
||||
use ir::{Ebb, Inst, ValueDef};
|
||||
use std::fmt;
|
||||
use std::u32;
|
||||
@@ -122,7 +122,7 @@ pub trait ProgramOrder {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use entity_map::EntityRef;
|
||||
use entity_ref::EntityRef;
|
||||
use ir::{Inst, Ebb};
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Data structures describing the registers in an ISA.
|
||||
|
||||
use entity_map::EntityRef;
|
||||
use entity_ref::EntityRef;
|
||||
use std::fmt;
|
||||
|
||||
/// Register units are the smallest units of register allocation.
|
||||
|
||||
@@ -12,6 +12,8 @@ pub const VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
#[macro_use]
|
||||
pub mod dbg;
|
||||
#[macro_use]
|
||||
pub mod entity_ref;
|
||||
|
||||
pub mod binemit;
|
||||
pub mod dominator_tree;
|
||||
|
||||
@@ -1,34 +1,16 @@
|
||||
//! A loop analysis represented as mappings of loops to their header Ebb
|
||||
//! and parent in the loop tree.
|
||||
|
||||
use ir::{Function, Ebb, Layout};
|
||||
use flowgraph::ControlFlowGraph;
|
||||
use dominator_tree::DominatorTree;
|
||||
use entity_map::{EntityMap, PrimaryEntityData};
|
||||
use packed_option::{PackedOption, ReservedValue};
|
||||
use entity_map::{EntityRef, Keys};
|
||||
use std::u32;
|
||||
use entity_map::{EntityMap, PrimaryEntityData, Keys};
|
||||
use flowgraph::ControlFlowGraph;
|
||||
use ir::{Function, Ebb, Layout};
|
||||
use packed_option::PackedOption;
|
||||
|
||||
/// A opaque reference to a code loop.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub struct Loop(u32);
|
||||
impl EntityRef for 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)
|
||||
}
|
||||
}
|
||||
|
||||
entity_impl!(Loop, "loop");
|
||||
|
||||
/// Loop tree information for a single function.
|
||||
///
|
||||
|
||||
@@ -89,7 +89,7 @@ impl RegDiversions {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use ir::Value;
|
||||
use entity_map::EntityRef;
|
||||
use entity_ref::EntityRef;
|
||||
|
||||
#[test]
|
||||
fn inserts() {
|
||||
|
||||
@@ -394,7 +394,7 @@ impl SparseMapValue<Value> for LiveRange {
|
||||
mod tests {
|
||||
use super::LiveRange;
|
||||
use ir::{Inst, Ebb, Value};
|
||||
use entity_map::EntityRef;
|
||||
use entity_ref::EntityRef;
|
||||
use ir::{ProgramOrder, ExpandedProgramPoint};
|
||||
use std::cmp::Ordering;
|
||||
|
||||
|
||||
@@ -675,7 +675,7 @@ impl Solver {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use entity_map::EntityRef;
|
||||
use entity_ref::EntityRef;
|
||||
use ir::Value;
|
||||
use isa::{TargetIsa, RegClass, RegUnit};
|
||||
use regalloc::AllocatableSet;
|
||||
|
||||
@@ -35,7 +35,8 @@
|
||||
//! - `SparseMap` requires the values to implement `SparseMapValue<K>` which means that they must
|
||||
//! contain their own key.
|
||||
|
||||
use entity_map::{EntityRef, EntityMap};
|
||||
use entity_map::EntityMap;
|
||||
use entity_ref::EntityRef;
|
||||
use std::mem;
|
||||
use std::slice;
|
||||
use std::u32;
|
||||
@@ -215,7 +216,7 @@ pub type SparseSet<T> = SparseMap<T, T>;
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use entity_map::EntityRef;
|
||||
use entity_ref::EntityRef;
|
||||
use ir::Inst;
|
||||
|
||||
// Mock key-value object for testing.
|
||||
|
||||
Reference in New Issue
Block a user