Use an EntityMap for stack slots.
Delete the StackSlots iterator and move the remaining StackSlotData into its own module.
This commit is contained in:
@@ -1,10 +1,11 @@
|
|||||||
//! Representation of Cretonne IL functions.
|
//! Representation of Cretonne IL functions.
|
||||||
|
|
||||||
pub mod entities;
|
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
pub mod entities;
|
||||||
pub mod condcodes;
|
pub mod condcodes;
|
||||||
pub mod immediates;
|
pub mod immediates;
|
||||||
pub mod instructions;
|
pub mod instructions;
|
||||||
|
pub mod stackslot;
|
||||||
pub mod jumptable;
|
pub mod jumptable;
|
||||||
pub mod dfg;
|
pub mod dfg;
|
||||||
pub mod layout;
|
pub mod layout;
|
||||||
@@ -12,13 +13,13 @@ pub mod layout;
|
|||||||
pub use ir::types::{Type, FunctionName, Signature};
|
pub use ir::types::{Type, FunctionName, Signature};
|
||||||
pub use ir::entities::{Ebb, Inst, Value, StackSlot, JumpTable};
|
pub use ir::entities::{Ebb, Inst, Value, StackSlot, JumpTable};
|
||||||
pub use ir::instructions::{Opcode, InstructionData};
|
pub use ir::instructions::{Opcode, InstructionData};
|
||||||
|
pub use ir::stackslot::StackSlotData;
|
||||||
|
pub use ir::jumptable::JumpTableData;
|
||||||
pub use ir::dfg::DataFlowGraph;
|
pub use ir::dfg::DataFlowGraph;
|
||||||
pub use ir::layout::Layout;
|
pub use ir::layout::Layout;
|
||||||
|
|
||||||
use ir::jumptable::JumpTableData;
|
use std::fmt::{self, Debug, Formatter};
|
||||||
use std::fmt::{self, Debug, Display, Formatter};
|
use entity_map::{EntityMap, PrimaryEntityData};
|
||||||
use std::ops::Index;
|
|
||||||
use entity_map::{EntityRef, EntityMap, PrimaryEntityData};
|
|
||||||
|
|
||||||
/// A function.
|
/// A function.
|
||||||
pub struct Function {
|
pub struct Function {
|
||||||
@@ -29,7 +30,7 @@ pub struct Function {
|
|||||||
signature: Signature,
|
signature: Signature,
|
||||||
|
|
||||||
/// Stack slots allocated in this function.
|
/// Stack slots allocated in this function.
|
||||||
stack_slots: Vec<StackSlotData>,
|
pub stack_slots: EntityMap<StackSlot, StackSlotData>,
|
||||||
|
|
||||||
/// Jump tables used in this function.
|
/// Jump tables used in this function.
|
||||||
pub jump_tables: EntityMap<JumpTable, JumpTableData>,
|
pub jump_tables: EntityMap<JumpTable, JumpTableData>,
|
||||||
@@ -41,7 +42,7 @@ pub struct Function {
|
|||||||
pub layout: Layout,
|
pub layout: Layout,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tag JumpTableData as a primary entity so jump_tables above .
|
impl PrimaryEntityData for StackSlotData {}
|
||||||
impl PrimaryEntityData for JumpTableData {}
|
impl PrimaryEntityData for JumpTableData {}
|
||||||
|
|
||||||
impl Function {
|
impl Function {
|
||||||
@@ -50,7 +51,7 @@ impl Function {
|
|||||||
Function {
|
Function {
|
||||||
name: name,
|
name: name,
|
||||||
signature: sig,
|
signature: sig,
|
||||||
stack_slots: Vec::new(),
|
stack_slots: EntityMap::new(),
|
||||||
jump_tables: EntityMap::new(),
|
jump_tables: EntityMap::new(),
|
||||||
dfg: DataFlowGraph::new(),
|
dfg: DataFlowGraph::new(),
|
||||||
layout: Layout::new(),
|
layout: Layout::new(),
|
||||||
@@ -66,23 +67,6 @@ impl Function {
|
|||||||
pub fn own_signature(&self) -> &Signature {
|
pub fn own_signature(&self) -> &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 {
|
impl Debug for Function {
|
||||||
@@ -91,76 +75,3 @@ impl Debug for Function {
|
|||||||
fmt.write_str(&function_to_string(self))
|
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<StackSlot> 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<Self::Item> {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
45
cranelift/src/libcretonne/ir/stackslot.rs
Normal file
45
cranelift/src/libcretonne/ir/stackslot.rs
Normal file
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -68,9 +68,9 @@ fn write_spec(w: &mut Write, func: &Function) -> Result {
|
|||||||
fn write_preamble(w: &mut Write, func: &Function) -> io::Result<bool> {
|
fn write_preamble(w: &mut Write, func: &Function) -> io::Result<bool> {
|
||||||
let mut any = false;
|
let mut any = false;
|
||||||
|
|
||||||
for ss in func.stack_slot_iter() {
|
for ss in func.stack_slots.keys() {
|
||||||
any = true;
|
any = true;
|
||||||
try!(writeln!(w, " {} = {}", ss, func[ss]));
|
try!(writeln!(w, " {} = {}", ss, func.stack_slots[ss]));
|
||||||
}
|
}
|
||||||
|
|
||||||
for jt in func.jump_tables.keys() {
|
for jt in func.jump_tables.keys() {
|
||||||
@@ -249,7 +249,7 @@ mod tests {
|
|||||||
f.name.push_str("foo");
|
f.name.push_str("foo");
|
||||||
assert_eq!(function_to_string(&f), "function foo() {\n}\n");
|
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),
|
assert_eq!(function_to_string(&f),
|
||||||
"function foo() {\n ss0 = stack_slot 4\n}\n");
|
"function foo() {\n ss0 = stack_slot 4\n}\n");
|
||||||
|
|
||||||
|
|||||||
@@ -11,14 +11,13 @@ use std::fmt::{self, Display, Formatter};
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::u32;
|
use std::u32;
|
||||||
use lexer::{self, Lexer, Token};
|
use lexer::{self, Lexer, Token};
|
||||||
use cretonne::ir::{Function, Ebb, Inst, Opcode, Value, Type, FunctionName, StackSlotData,
|
use cretonne::ir::{Function, Ebb, Inst, Opcode, Value, Type, FunctionName, StackSlot,
|
||||||
JumpTable, StackSlot};
|
StackSlotData, JumpTable, JumpTableData};
|
||||||
use cretonne::ir::types::{VOID, Signature, ArgumentType, ArgumentExtension};
|
use cretonne::ir::types::{VOID, Signature, ArgumentType, ArgumentExtension};
|
||||||
use cretonne::ir::immediates::{Imm64, Ieee32, Ieee64};
|
use cretonne::ir::immediates::{Imm64, Ieee32, Ieee64};
|
||||||
use cretonne::ir::entities::{NO_EBB, NO_VALUE};
|
use cretonne::ir::entities::{NO_EBB, NO_VALUE};
|
||||||
use cretonne::ir::instructions::{InstructionFormat, InstructionData, VariableArgs, JumpData,
|
use cretonne::ir::instructions::{InstructionFormat, InstructionData, VariableArgs, JumpData,
|
||||||
BranchData, ReturnData};
|
BranchData, ReturnData};
|
||||||
use cretonne::ir::jumptable::JumpTableData;
|
|
||||||
|
|
||||||
pub use lexer::Location;
|
pub use lexer::Location;
|
||||||
|
|
||||||
@@ -95,7 +94,7 @@ impl Context {
|
|||||||
|
|
||||||
// Allocate a new stack slot and add a mapping number -> StackSlot.
|
// Allocate a new stack slot and add a mapping number -> StackSlot.
|
||||||
fn add_ss(&mut self, number: u32, data: StackSlotData, loc: &Location) -> Result<()> {
|
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)
|
err!(loc, "duplicate stack slot: ss{}", number)
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -1173,13 +1172,13 @@ mod tests {
|
|||||||
.parse_function()
|
.parse_function()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(func.name, "foo");
|
assert_eq!(func.name, "foo");
|
||||||
let mut iter = func.stack_slot_iter();
|
let mut iter = func.stack_slots.keys();
|
||||||
let ss0 = iter.next().unwrap();
|
let ss0 = iter.next().unwrap();
|
||||||
assert_eq!(ss0.to_string(), "ss0");
|
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();
|
let ss1 = iter.next().unwrap();
|
||||||
assert_eq!(ss1.to_string(), "ss1");
|
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);
|
assert_eq!(iter.next(), None);
|
||||||
|
|
||||||
// Catch duplicate definitions.
|
// Catch duplicate definitions.
|
||||||
|
|||||||
Reference in New Issue
Block a user