diff --git a/cranelift/src/libcretonne/cfg.rs b/cranelift/src/libcretonne/cfg.rs index 4fc2f1b292..8c423c23ac 100644 --- a/cranelift/src/libcretonne/cfg.rs +++ b/cranelift/src/libcretonne/cfg.rs @@ -95,6 +95,7 @@ impl ControlFlowGraph { #[cfg(test)] mod tests { use instructions::*; + use entity_map::EntityRef; use entities::{Ebb, Inst, NO_VALUE}; use repr::Function; use super::*; diff --git a/cranelift/src/libcretonne/entities.rs b/cranelift/src/libcretonne/entities.rs index c87ed6a818..33b41e5273 100644 --- a/cranelift/src/libcretonne/entities.rs +++ b/cranelift/src/libcretonne/entities.rs @@ -19,6 +19,7 @@ //! The entity references all implement the `Display` trait in a way that matches the textual IL //! format. +use entity_map::EntityRef; use std::default::Default; use std::fmt::{self, Display, Formatter}; use std::u32; @@ -27,12 +28,18 @@ use std::u32; #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)] pub struct Ebb(u32); -impl Ebb { - pub fn new(index: usize) -> Ebb { +impl EntityRef for Ebb { + fn new(index: usize) -> Self { assert!(index < (u32::MAX as usize)); Ebb(index as u32) } + fn index(self) -> usize { + self.0 as usize + } +} + +impl Ebb { /// Create a new EBB reference from its number. This corresponds to the ebbNN representation. pub fn with_number(n: u32) -> Option { if n < u32::MAX { @@ -41,10 +48,6 @@ impl Ebb { None } } - - pub fn index(&self) -> usize { - self.0 as usize - } } /// Display an `Ebb` reference as "ebb12". @@ -67,13 +70,13 @@ impl Default for Ebb { #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)] pub struct Inst(u32); -impl Inst { - pub fn new(index: usize) -> Inst { +impl EntityRef for Inst { + fn new(index: usize) -> Self { assert!(index < (u32::MAX as usize)); Inst(index as u32) } - pub fn index(&self) -> usize { + fn index(self) -> usize { self.0 as usize } } @@ -188,13 +191,13 @@ impl Default for Value { #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct StackSlot(u32); -impl StackSlot { - pub fn new(index: usize) -> StackSlot { +impl EntityRef for StackSlot { + fn new(index: usize) -> StackSlot { assert!(index < (u32::MAX as usize)); StackSlot(index as u32) } - pub fn index(&self) -> usize { + fn index(self) -> usize { self.0 as usize } } @@ -219,13 +222,13 @@ impl Default for StackSlot { #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct JumpTable(u32); -impl JumpTable { - pub fn new(index: usize) -> JumpTable { +impl EntityRef for JumpTable { + fn new(index: usize) -> JumpTable { assert!(index < (u32::MAX as usize)); JumpTable(index as u32) } - pub fn index(&self) -> usize { + fn index(self) -> usize { self.0 as usize } } @@ -250,6 +253,7 @@ impl Default for JumpTable { mod tests { use super::*; use std::u32; + use entity_map::EntityRef; #[test] fn value_with_number() { diff --git a/cranelift/src/libcretonne/entity_map.rs b/cranelift/src/libcretonne/entity_map.rs index 3e1f16a595..fbf8109d9f 100644 --- a/cranelift/src/libcretonne/entity_map.rs +++ b/cranelift/src/libcretonne/entity_map.rs @@ -41,11 +41,15 @@ impl EntityMap } } + /// Check if `k` is a valid key in the map. + pub fn is_valid(&self, k: K) -> bool { + k.index() < self.elems.len() + } + /// Ensure that `k` is a valid key but adding default entries if necesssary. pub fn ensure(&mut self, k: K) { - let idx = k.index(); - if idx >= self.elems.len() { - self.elems.resize(idx + 1, V::default()) + if !self.is_valid(k) { + self.elems.resize(k.index() + 1, V::default()) } } @@ -106,7 +110,9 @@ mod tests { let r2 = E(2); let mut m = EntityMap::new(); + assert!(!m.is_valid(r0)); m[r2] = 3; + assert!(m.is_valid(r1)); m[r1] = 5; assert_eq!(m[r1], 5); diff --git a/cranelift/src/libcretonne/repr.rs b/cranelift/src/libcretonne/repr.rs index 5a36115fbd..27de00ea66 100644 --- a/cranelift/src/libcretonne/repr.rs +++ b/cranelift/src/libcretonne/repr.rs @@ -1,6 +1,7 @@ //! Representation of Cretonne IL functions. use types::{Type, FunctionName, Signature, VOID}; +use entity_map::EntityRef; use entities::{Ebb, NO_EBB, Inst, NO_INST, Value, NO_VALUE, ExpandedValue, StackSlot}; use instructions::*; use std::fmt::{self, Display, Formatter};