diff --git a/src/libcretonne/ir/mod.rs b/src/libcretonne/ir/mod.rs index 30fb4d9323..806466a90b 100644 --- a/src/libcretonne/ir/mod.rs +++ b/src/libcretonne/ir/mod.rs @@ -1,10 +1,11 @@ //! Representation of Cretonne IL functions. -pub mod entities; pub mod types; +pub mod entities; pub mod condcodes; pub mod immediates; pub mod instructions; +pub mod stackslot; pub mod jumptable; pub mod dfg; pub mod layout; @@ -12,13 +13,13 @@ pub mod layout; pub use ir::types::{Type, FunctionName, Signature}; pub use ir::entities::{Ebb, Inst, Value, StackSlot, JumpTable}; pub use ir::instructions::{Opcode, InstructionData}; +pub use ir::stackslot::StackSlotData; +pub use ir::jumptable::JumpTableData; pub use ir::dfg::DataFlowGraph; pub use ir::layout::Layout; -use ir::jumptable::JumpTableData; -use std::fmt::{self, Debug, Display, Formatter}; -use std::ops::Index; -use entity_map::{EntityRef, EntityMap, PrimaryEntityData}; +use std::fmt::{self, Debug, Formatter}; +use entity_map::{EntityMap, PrimaryEntityData}; /// A function. pub struct Function { @@ -29,7 +30,7 @@ pub struct Function { signature: Signature, /// Stack slots allocated in this function. - stack_slots: Vec, + pub stack_slots: EntityMap, /// Jump tables used in this function. pub jump_tables: EntityMap, @@ -41,7 +42,7 @@ pub struct Function { pub layout: Layout, } -// Tag JumpTableData as a primary entity so jump_tables above . +impl PrimaryEntityData for StackSlotData {} impl PrimaryEntityData for JumpTableData {} impl Function { @@ -50,7 +51,7 @@ impl Function { Function { name: name, signature: sig, - stack_slots: Vec::new(), + stack_slots: EntityMap::new(), jump_tables: EntityMap::new(), dfg: DataFlowGraph::new(), layout: Layout::new(), @@ -66,23 +67,6 @@ impl Function { pub fn own_signature(&self) -> &Signature { &self.signature } - - // Stack slots. - - /// Allocate a new stack slot. - pub fn make_stack_slot(&mut self, data: StackSlotData) -> StackSlot { - let ss = StackSlot::new(self.stack_slots.len()); - self.stack_slots.push(data); - ss - } - - /// Iterate over all stack slots in function. - pub fn stack_slot_iter(&self) -> StackSlotIter { - StackSlotIter { - cur: 0, - end: self.stack_slots.len(), - } - } } impl Debug for Function { @@ -91,76 +75,3 @@ impl Debug for Function { fmt.write_str(&function_to_string(self)) } } - -// ====--------------------------------------------------------------------------------------====// -// -// Stack slot implementation. -// -// ====--------------------------------------------------------------------------------------====// - -/// Contents of a stack slot. -#[derive(Debug)] -pub struct StackSlotData { - /// Size of stack slot in bytes. - pub size: u32, -} - -impl StackSlotData { - /// Create a stack slot with the specified byte size. - pub fn new(size: u32) -> StackSlotData { - StackSlotData { size: size } - } -} - -impl Display for StackSlotData { - fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { - write!(fmt, "stack_slot {}", self.size) - } -} - -/// Allow immutable access to stack slots via function indexing. -impl Index for Function { - type Output = StackSlotData; - - fn index<'a>(&'a self, ss: StackSlot) -> &'a StackSlotData { - &self.stack_slots[ss.index()] - } -} - -/// Stack slot iterator visits all stack slots in a function, returning `StackSlot` references. -pub struct StackSlotIter { - cur: usize, - end: usize, -} - -impl Iterator for StackSlotIter { - type Item = StackSlot; - - fn next(&mut self) -> Option { - if self.cur < self.end { - let ss = StackSlot::new(self.cur); - self.cur += 1; - Some(ss) - } else { - None - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn stack_slot() { - let mut func = Function::new(); - - let ss0 = func.make_stack_slot(StackSlotData::new(4)); - let ss1 = func.make_stack_slot(StackSlotData::new(8)); - assert_eq!(ss0.to_string(), "ss0"); - assert_eq!(ss1.to_string(), "ss1"); - - assert_eq!(func[ss0].size, 4); - assert_eq!(func[ss1].size, 8); - } -} diff --git a/src/libcretonne/ir/stackslot.rs b/src/libcretonne/ir/stackslot.rs new file mode 100644 index 0000000000..31bee66eda --- /dev/null +++ b/src/libcretonne/ir/stackslot.rs @@ -0,0 +1,45 @@ +//! Stack slots. +//! +//! The `StackSlotData` struct keeps track of a single stack slot in a function. +//! + +use std::fmt::{self, Display, Formatter}; + +/// Contents of a stack slot. +#[derive(Debug)] +pub struct StackSlotData { + /// Size of stack slot in bytes. + pub size: u32, +} + +impl StackSlotData { + /// Create a stack slot with the specified byte size. + pub fn new(size: u32) -> StackSlotData { + StackSlotData { size: size } + } +} + +impl Display for StackSlotData { + fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { + write!(fmt, "stack_slot {}", self.size) + } +} + +#[cfg(test)] +mod tests { + use ir::Function; + use super::StackSlotData; + + #[test] + fn stack_slot() { + let mut func = Function::new(); + + let ss0 = func.stack_slots.push(StackSlotData::new(4)); + let ss1 = func.stack_slots.push(StackSlotData::new(8)); + assert_eq!(ss0.to_string(), "ss0"); + assert_eq!(ss1.to_string(), "ss1"); + + assert_eq!(func.stack_slots[ss0].size, 4); + assert_eq!(func.stack_slots[ss1].size, 8); + } +} diff --git a/src/libcretonne/write.rs b/src/libcretonne/write.rs index e21c93c554..a20007ed05 100644 --- a/src/libcretonne/write.rs +++ b/src/libcretonne/write.rs @@ -68,9 +68,9 @@ fn write_spec(w: &mut Write, func: &Function) -> Result { fn write_preamble(w: &mut Write, func: &Function) -> io::Result { let mut any = false; - for ss in func.stack_slot_iter() { + for ss in func.stack_slots.keys() { any = true; - try!(writeln!(w, " {} = {}", ss, func[ss])); + try!(writeln!(w, " {} = {}", ss, func.stack_slots[ss])); } for jt in func.jump_tables.keys() { @@ -249,7 +249,7 @@ mod tests { f.name.push_str("foo"); assert_eq!(function_to_string(&f), "function foo() {\n}\n"); - f.make_stack_slot(StackSlotData::new(4)); + f.stack_slots.push(StackSlotData::new(4)); assert_eq!(function_to_string(&f), "function foo() {\n ss0 = stack_slot 4\n}\n"); diff --git a/src/libreader/parser.rs b/src/libreader/parser.rs index 0fc0ff6ab4..87c336906a 100644 --- a/src/libreader/parser.rs +++ b/src/libreader/parser.rs @@ -11,14 +11,13 @@ use std::fmt::{self, Display, Formatter}; use std::str::FromStr; use std::u32; use lexer::{self, Lexer, Token}; -use cretonne::ir::{Function, Ebb, Inst, Opcode, Value, Type, FunctionName, StackSlotData, - JumpTable, StackSlot}; +use cretonne::ir::{Function, Ebb, Inst, Opcode, Value, Type, FunctionName, StackSlot, + StackSlotData, JumpTable, JumpTableData}; use cretonne::ir::types::{VOID, Signature, ArgumentType, ArgumentExtension}; use cretonne::ir::immediates::{Imm64, Ieee32, Ieee64}; use cretonne::ir::entities::{NO_EBB, NO_VALUE}; use cretonne::ir::instructions::{InstructionFormat, InstructionData, VariableArgs, JumpData, BranchData, ReturnData}; -use cretonne::ir::jumptable::JumpTableData; pub use lexer::Location; @@ -95,7 +94,7 @@ impl Context { // Allocate a new stack slot and add a mapping number -> StackSlot. fn add_ss(&mut self, number: u32, data: StackSlotData, loc: &Location) -> Result<()> { - if self.stack_slots.insert(number, self.function.make_stack_slot(data)).is_some() { + if self.stack_slots.insert(number, self.function.stack_slots.push(data)).is_some() { err!(loc, "duplicate stack slot: ss{}", number) } else { Ok(()) @@ -1173,13 +1172,13 @@ mod tests { .parse_function() .unwrap(); assert_eq!(func.name, "foo"); - let mut iter = func.stack_slot_iter(); + let mut iter = func.stack_slots.keys(); let ss0 = iter.next().unwrap(); assert_eq!(ss0.to_string(), "ss0"); - assert_eq!(func[ss0].size, 13); + assert_eq!(func.stack_slots[ss0].size, 13); let ss1 = iter.next().unwrap(); assert_eq!(ss1.to_string(), "ss1"); - assert_eq!(func[ss1].size, 1); + assert_eq!(func.stack_slots[ss1].size, 1); assert_eq!(iter.next(), None); // Catch duplicate definitions.