Split EntityMap into entity::PrimaryMap and entity::EntityMap.
The new PrimaryMap replaces the primary EntityMap and the PrimaryEntityData marker trait which was causing some confusion. We now have a clear division between the two types of maps: - PrimaryMap is used to assign entity numbers to the primary data for an entity. - EntityMap is a secondary mapping adding additional info. The split also means that the secondary EntityMap can now behave as if all keys have a default value. This means that we can get rid of the annoying ensure() and get_or_default() methods ther were used everywhere instead of indexing. Just use normal indexing now; non-existent keys will return the default value.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
//! Data flow graph tracking Instructions, Values, and EBBs.
|
||||
|
||||
use entity_map::{EntityMap, PrimaryEntityData};
|
||||
use entity::{PrimaryMap, EntityMap};
|
||||
use isa::TargetIsa;
|
||||
use ir::builder::{InsertBuilder, ReplaceBuilder};
|
||||
use ir::extfunc::ExtFuncData;
|
||||
@@ -27,7 +27,7 @@ pub struct DataFlowGraph {
|
||||
/// Data about all of the instructions in the function, including opcodes and operands.
|
||||
/// The instructions in this map are not in program order. That is tracked by `Layout`, along
|
||||
/// with the EBB containing each instruction.
|
||||
insts: EntityMap<Inst, InstructionData>,
|
||||
insts: PrimaryMap<Inst, InstructionData>,
|
||||
|
||||
/// List of result values for each instruction.
|
||||
///
|
||||
@@ -38,7 +38,7 @@ pub struct DataFlowGraph {
|
||||
/// Extended basic blocks in the function and their arguments.
|
||||
/// This map is not in program order. That is handled by `Layout`, and so is the sequence of
|
||||
/// instructions contained in each EBB.
|
||||
ebbs: EntityMap<Ebb, EbbData>,
|
||||
ebbs: PrimaryMap<Ebb, EbbData>,
|
||||
|
||||
/// Memory pool of value lists.
|
||||
///
|
||||
@@ -50,33 +50,27 @@ pub struct DataFlowGraph {
|
||||
pub value_lists: ValueListPool,
|
||||
|
||||
/// Primary value table with entries for all values.
|
||||
values: EntityMap<Value, ValueData>,
|
||||
values: PrimaryMap<Value, ValueData>,
|
||||
|
||||
/// Function signature table. These signatures are referenced by indirect call instructions as
|
||||
/// well as the external function references.
|
||||
pub signatures: EntityMap<SigRef, Signature>,
|
||||
pub signatures: PrimaryMap<SigRef, Signature>,
|
||||
|
||||
/// External function references. These are functions that can be called directly.
|
||||
pub ext_funcs: EntityMap<FuncRef, ExtFuncData>,
|
||||
pub ext_funcs: PrimaryMap<FuncRef, ExtFuncData>,
|
||||
}
|
||||
|
||||
impl PrimaryEntityData for InstructionData {}
|
||||
impl PrimaryEntityData for EbbData {}
|
||||
impl PrimaryEntityData for ValueData {}
|
||||
impl PrimaryEntityData for Signature {}
|
||||
impl PrimaryEntityData for ExtFuncData {}
|
||||
|
||||
impl DataFlowGraph {
|
||||
/// Create a new empty `DataFlowGraph`.
|
||||
pub fn new() -> DataFlowGraph {
|
||||
DataFlowGraph {
|
||||
insts: EntityMap::new(),
|
||||
insts: PrimaryMap::new(),
|
||||
results: EntityMap::new(),
|
||||
ebbs: EntityMap::new(),
|
||||
ebbs: PrimaryMap::new(),
|
||||
value_lists: ValueListPool::new(),
|
||||
values: EntityMap::new(),
|
||||
signatures: EntityMap::new(),
|
||||
ext_funcs: EntityMap::new(),
|
||||
values: PrimaryMap::new(),
|
||||
signatures: PrimaryMap::new(),
|
||||
ext_funcs: PrimaryMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +109,7 @@ impl DataFlowGraph {
|
||||
/// Resolve value aliases.
|
||||
///
|
||||
/// Find the original SSA value that `value` aliases.
|
||||
fn resolve_aliases(values: &EntityMap<Value, ValueData>, value: Value) -> Value {
|
||||
fn resolve_aliases(values: &PrimaryMap<Value, ValueData>, value: Value) -> Value {
|
||||
let mut v = value;
|
||||
|
||||
// Note that values may be empty here.
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
//! The `Function` struct defined in this module owns all of its extended basic blocks and
|
||||
//! instructions.
|
||||
|
||||
use entity_map::{EntityMap, PrimaryEntityData};
|
||||
use ir::{FunctionName, CallConv, Signature, JumpTableData, GlobalVarData, DataFlowGraph, Layout};
|
||||
use ir::{JumpTables, InstEncodings, ValueLocations, StackSlots, GlobalVars, EbbOffsets};
|
||||
use entity::{PrimaryMap, EntityMap};
|
||||
use ir;
|
||||
use ir::{FunctionName, CallConv, Signature, DataFlowGraph, Layout};
|
||||
use ir::{InstEncodings, ValueLocations, JumpTables, StackSlots, EbbOffsets};
|
||||
use isa::TargetIsa;
|
||||
use std::fmt;
|
||||
use write::write_function;
|
||||
@@ -26,7 +27,7 @@ pub struct Function {
|
||||
pub stack_slots: StackSlots,
|
||||
|
||||
/// Global variables referenced.
|
||||
pub global_vars: GlobalVars,
|
||||
pub global_vars: PrimaryMap<ir::GlobalVar, ir::GlobalVarData>,
|
||||
|
||||
/// Jump tables used in this function.
|
||||
pub jump_tables: JumpTables,
|
||||
@@ -52,9 +53,6 @@ pub struct Function {
|
||||
pub offsets: EbbOffsets,
|
||||
}
|
||||
|
||||
impl PrimaryEntityData for JumpTableData {}
|
||||
impl PrimaryEntityData for GlobalVarData {}
|
||||
|
||||
impl Function {
|
||||
/// Create a function with the given name and signature.
|
||||
pub fn with_name_signature(name: FunctionName, sig: Signature) -> Function {
|
||||
@@ -62,8 +60,8 @@ impl Function {
|
||||
name,
|
||||
signature: sig,
|
||||
stack_slots: StackSlots::new(),
|
||||
global_vars: GlobalVars::new(),
|
||||
jump_tables: EntityMap::new(),
|
||||
global_vars: PrimaryMap::new(),
|
||||
jump_tables: PrimaryMap::new(),
|
||||
dfg: DataFlowGraph::new(),
|
||||
layout: Layout::new(),
|
||||
encodings: EntityMap::new(),
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
use std::cmp;
|
||||
use std::iter::{Iterator, IntoIterator};
|
||||
use entity_map::EntityMap;
|
||||
use entity::EntityMap;
|
||||
use packed_option::PackedOption;
|
||||
use ir::{Ebb, Inst, Type, DataFlowGraph};
|
||||
use ir::builder::InstInserterBase;
|
||||
@@ -278,7 +278,7 @@ impl Layout {
|
||||
impl Layout {
|
||||
/// Is `ebb` currently part of the layout?
|
||||
pub fn is_ebb_inserted(&self, ebb: Ebb) -> bool {
|
||||
Some(ebb) == self.first_ebb || (self.ebbs.is_valid(ebb) && self.ebbs[ebb].prev.is_some())
|
||||
Some(ebb) == self.first_ebb || self.ebbs[ebb].prev.is_some()
|
||||
}
|
||||
|
||||
/// Insert `ebb` as the last EBB in the layout.
|
||||
@@ -286,7 +286,7 @@ impl Layout {
|
||||
assert!(!self.is_ebb_inserted(ebb),
|
||||
"Cannot append EBB that is already in the layout");
|
||||
{
|
||||
let node = self.ebbs.ensure(ebb);
|
||||
let node = &mut self.ebbs[ebb];
|
||||
assert!(node.first_inst.is_none() && node.last_inst.is_none());
|
||||
node.prev = self.last_ebb.into();
|
||||
node.next = None.into();
|
||||
@@ -308,7 +308,7 @@ impl Layout {
|
||||
"EBB Insertion point not in the layout");
|
||||
let after = self.ebbs[before].prev;
|
||||
{
|
||||
let node = self.ebbs.ensure(ebb);
|
||||
let node = &mut self.ebbs[ebb];
|
||||
node.next = before.into();
|
||||
node.prev = after;
|
||||
}
|
||||
@@ -328,7 +328,7 @@ impl Layout {
|
||||
"EBB Insertion point not in the layout");
|
||||
let before = self.ebbs[after].next;
|
||||
{
|
||||
let node = self.ebbs.ensure(ebb);
|
||||
let node = &mut self.ebbs[ebb];
|
||||
node.next = before;
|
||||
node.prev = after.into();
|
||||
}
|
||||
@@ -406,11 +406,7 @@ impl<'f> IntoIterator for &'f Layout {
|
||||
impl Layout {
|
||||
/// Get the EBB containing `inst`, or `None` if `inst` is not inserted in the layout.
|
||||
pub fn inst_ebb(&self, inst: Inst) -> Option<Ebb> {
|
||||
if self.insts.is_valid(inst) {
|
||||
self.insts[inst].ebb.into()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
self.insts[inst].ebb.into()
|
||||
}
|
||||
|
||||
/// Get the EBB containing the program point `pp`. Panic if `pp` is not in the layout.
|
||||
@@ -433,7 +429,7 @@ impl Layout {
|
||||
{
|
||||
let ebb_node = &mut self.ebbs[ebb];
|
||||
{
|
||||
let inst_node = self.insts.ensure(inst);
|
||||
let inst_node = &mut self.insts[inst];
|
||||
inst_node.ebb = ebb.into();
|
||||
inst_node.prev = ebb_node.last_inst;
|
||||
assert!(inst_node.next.is_none());
|
||||
@@ -465,7 +461,7 @@ impl Layout {
|
||||
.expect("Instruction before insertion point not in the layout");
|
||||
let after = self.insts[before].prev;
|
||||
{
|
||||
let inst_node = self.insts.ensure(inst);
|
||||
let inst_node = &mut self.insts[inst];
|
||||
inst_node.ebb = ebb.into();
|
||||
inst_node.next = before.into();
|
||||
inst_node.prev = after;
|
||||
@@ -543,7 +539,7 @@ impl Layout {
|
||||
let next_ebb = self.ebbs[old_ebb].next;
|
||||
let last_inst = self.ebbs[old_ebb].last_inst;
|
||||
{
|
||||
let node = self.ebbs.ensure(new_ebb);
|
||||
let node = &mut self.ebbs[new_ebb];
|
||||
node.prev = old_ebb.into();
|
||||
node.next = next_ebb;
|
||||
node.first_inst = before.into();
|
||||
|
||||
@@ -36,20 +36,17 @@ pub use ir::types::Type;
|
||||
pub use ir::valueloc::{ValueLoc, ArgumentLoc};
|
||||
|
||||
use binemit;
|
||||
use entity_map::EntityMap;
|
||||
use entity::{PrimaryMap, EntityMap};
|
||||
use isa;
|
||||
|
||||
/// Map of value locations.
|
||||
pub type ValueLocations = EntityMap<Value, ValueLoc>;
|
||||
|
||||
/// Map of jump tables.
|
||||
pub type JumpTables = EntityMap<JumpTable, JumpTableData>;
|
||||
pub type JumpTables = PrimaryMap<JumpTable, JumpTableData>;
|
||||
|
||||
/// Map of instruction encodings.
|
||||
pub type InstEncodings = EntityMap<Inst, isa::Encoding>;
|
||||
|
||||
/// Code offsets for EBBs.
|
||||
pub type EbbOffsets = EntityMap<Ebb, binemit::CodeOffset>;
|
||||
|
||||
/// Map of global variables.
|
||||
pub type GlobalVars = EntityMap<GlobalVar, GlobalVarData>;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//! The `StackSlotData` struct keeps track of a single stack slot in a function.
|
||||
//!
|
||||
|
||||
use entity_map::{EntityMap, PrimaryEntityData, Keys};
|
||||
use entity::{PrimaryMap, Keys};
|
||||
use ir::{Type, StackSlot};
|
||||
use std::fmt;
|
||||
use std::ops::Index;
|
||||
@@ -124,15 +124,13 @@ impl fmt::Display for StackSlotData {
|
||||
}
|
||||
}
|
||||
|
||||
impl PrimaryEntityData for StackSlotData {}
|
||||
|
||||
/// Stack frame manager.
|
||||
///
|
||||
/// Keep track of all the stack slots used by a function.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct StackSlots {
|
||||
/// All allocated stack slots.
|
||||
slots: EntityMap<StackSlot, StackSlotData>,
|
||||
slots: PrimaryMap<StackSlot, StackSlotData>,
|
||||
|
||||
/// All the outgoing stack slots, ordered by offset.
|
||||
outgoing: Vec<StackSlot>,
|
||||
@@ -152,7 +150,7 @@ impl StackSlots {
|
||||
/// Create an empty stack slot manager.
|
||||
pub fn new() -> StackSlots {
|
||||
StackSlots {
|
||||
slots: EntityMap::new(),
|
||||
slots: PrimaryMap::new(),
|
||||
outgoing: Vec::new(),
|
||||
frame_size: None,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user