Add typedefs for the common entity maps.

The various entity maps in a function end up being referenced in
multiple places, so create typedefs for them.
This commit is contained in:
Jakob Stoklund Olesen
2017-06-16 13:08:13 -07:00
parent a4cc66cb4a
commit bae37e523f
5 changed files with 45 additions and 32 deletions

View File

@@ -28,9 +28,8 @@
//! ``` //! ```
use binemit::CodeOffset; use binemit::CodeOffset;
use entity_map::EntityMap; use ir::{Function, DataFlowGraph, Cursor, InstructionData, Opcode, InstEncodings};
use ir::{Function, DataFlowGraph, Cursor, Inst, InstructionData, Opcode}; use isa::{TargetIsa, EncInfo};
use isa::{TargetIsa, EncInfo, Encoding};
use iterators::IteratorExtras; use iterators::IteratorExtras;
/// Relax branches and compute the final layout of EBB headers in `func`. /// Relax branches and compute the final layout of EBB headers in `func`.
@@ -127,7 +126,7 @@ fn fallthroughs(func: &mut Function) {
/// Return the size of the replacement instructions up to and including the location where `pos` is /// Return the size of the replacement instructions up to and including the location where `pos` is
/// left. /// left.
fn relax_branch(dfg: &mut DataFlowGraph, fn relax_branch(dfg: &mut DataFlowGraph,
encodings: &mut EntityMap<Inst, Encoding>, encodings: &mut InstEncodings,
encinfo: &EncInfo, encinfo: &EncInfo,
pos: &mut Cursor, pos: &mut Cursor,
offset: CodeOffset, offset: CodeOffset,

View File

@@ -3,12 +3,11 @@
//! The `Function` struct defined in this module owns all of its extended basic blocks and //! The `Function` struct defined in this module owns all of its extended basic blocks and
//! instructions. //! instructions.
use binemit::CodeOffset;
use entity_map::{EntityMap, PrimaryEntityData}; use entity_map::{EntityMap, PrimaryEntityData};
use ir::{FunctionName, Signature, Value, Inst, Ebb, StackSlots, JumpTable, JumpTableData, use ir::{FunctionName, Signature, JumpTableData, DataFlowGraph, Layout};
ValueLoc, DataFlowGraph, Layout}; use ir::{JumpTables, InstEncodings, ValueLocations, StackSlots, EbbOffsets};
use isa::{TargetIsa, Encoding}; use isa::TargetIsa;
use std::fmt::{self, Display, Debug, Formatter}; use std::fmt;
use write::write_function; use write::write_function;
/// A function. /// A function.
@@ -27,7 +26,7 @@ pub struct Function {
pub stack_slots: StackSlots, pub stack_slots: StackSlots,
/// Jump tables used in this function. /// Jump tables used in this function.
pub jump_tables: EntityMap<JumpTable, JumpTableData>, pub jump_tables: JumpTables,
/// Data flow graph containing the primary definition of all instructions, EBBs and values. /// Data flow graph containing the primary definition of all instructions, EBBs and values.
pub dfg: DataFlowGraph, pub dfg: DataFlowGraph,
@@ -37,17 +36,17 @@ pub struct Function {
/// Encoding recipe and bits for the legal instructions. /// Encoding recipe and bits for the legal instructions.
/// Illegal instructions have the `Encoding::default()` value. /// Illegal instructions have the `Encoding::default()` value.
pub encodings: EntityMap<Inst, Encoding>, pub encodings: InstEncodings,
/// Location assigned to every value. /// Location assigned to every value.
pub locations: EntityMap<Value, ValueLoc>, pub locations: ValueLocations,
/// Code offsets of the EBB headers. /// Code offsets of the EBB headers.
/// ///
/// This information is only transiently available after the `binemit::relax_branches` function /// This information is only transiently available after the `binemit::relax_branches` function
/// computes it, and it can easily be recomputed by calling that function. It is not included /// computes it, and it can easily be recomputed by calling that function. It is not included
/// in the textual IL format. /// in the textual IL format.
pub offsets: EntityMap<Ebb, CodeOffset>, pub offsets: EbbOffsets,
} }
impl PrimaryEntityData for JumpTableData {} impl PrimaryEntityData for JumpTableData {}
@@ -82,20 +81,20 @@ impl Function {
/// Wrapper type capable of displaying a `Function` with correct ISA annotations. /// Wrapper type capable of displaying a `Function` with correct ISA annotations.
pub struct DisplayFunction<'a>(&'a Function, Option<&'a TargetIsa>); pub struct DisplayFunction<'a>(&'a Function, Option<&'a TargetIsa>);
impl<'a> Display for DisplayFunction<'a> { impl<'a> fmt::Display for DisplayFunction<'a> {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write_function(fmt, self.0, self.1) write_function(fmt, self.0, self.1)
} }
} }
impl Display for Function { impl fmt::Display for Function {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write_function(fmt, self, None) write_function(fmt, self, None)
} }
} }
impl Debug for Function { impl fmt::Debug for Function {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write_function(fmt, self, None) write_function(fmt, self, None)
} }
} }

View File

@@ -31,3 +31,19 @@ pub use ir::function::Function;
pub use ir::builder::InstBuilder; pub use ir::builder::InstBuilder;
pub use ir::progpoint::{ProgramPoint, ProgramOrder, ExpandedProgramPoint}; pub use ir::progpoint::{ProgramPoint, ProgramOrder, ExpandedProgramPoint};
pub use ir::memflags::MemFlags; pub use ir::memflags::MemFlags;
use binemit;
use entity_map::EntityMap;
use isa;
/// Map of value locations.
pub type ValueLocations = EntityMap<Value, ValueLoc>;
/// Map of jump tables.
pub type JumpTables = EntityMap<JumpTable, JumpTableData>;
/// Map of instruction encodings.
pub type InstEncodings = EntityMap<Inst, isa::Encoding>;
/// Code offsets for EBBs.
pub type EbbOffsets = EntityMap<Ebb, binemit::CodeOffset>;

View File

@@ -33,7 +33,7 @@
use entity_map::EntityMap; use entity_map::EntityMap;
use dominator_tree::DominatorTree; use dominator_tree::DominatorTree;
use ir::{Ebb, Inst, Value, Function, Cursor, ValueLoc, DataFlowGraph}; use ir::{Ebb, Inst, Value, Function, Cursor, ValueLoc, DataFlowGraph, ValueLocations};
use ir::{InstBuilder, Signature, ArgumentType, ArgumentLoc}; use ir::{InstBuilder, Signature, ArgumentType, ArgumentLoc};
use isa::{TargetIsa, Encoding, EncInfo, OperandConstraint, ConstraintKind}; use isa::{TargetIsa, Encoding, EncInfo, OperandConstraint, ConstraintKind};
use isa::{RegUnit, RegClass, RegInfo, regs_overlap}; use isa::{RegUnit, RegClass, RegInfo, regs_overlap};
@@ -218,7 +218,7 @@ impl<'a> Context<'a> {
fn color_entry_args(&self, fn color_entry_args(&self,
sig: &Signature, sig: &Signature,
args: &[LiveValue], args: &[LiveValue],
locations: &mut EntityMap<Value, ValueLoc>) locations: &mut ValueLocations)
-> AllocatableSet { -> AllocatableSet {
assert_eq!(sig.argument_types.len(), args.len()); assert_eq!(sig.argument_types.len(), args.len());
@@ -271,7 +271,7 @@ impl<'a> Context<'a> {
fn color_args(&self, fn color_args(&self,
args: &[LiveValue], args: &[LiveValue],
mut regs: AllocatableSet, mut regs: AllocatableSet,
locations: &mut EntityMap<Value, ValueLoc>) locations: &mut ValueLocations)
-> AllocatableSet { -> AllocatableSet {
// Available registers *after* filtering out the dead arguments. // Available registers *after* filtering out the dead arguments.
let mut live_regs = regs.clone(); let mut live_regs = regs.clone();
@@ -309,7 +309,7 @@ impl<'a> Context<'a> {
dfg: &mut DataFlowGraph, dfg: &mut DataFlowGraph,
tracker: &mut LiveValueTracker, tracker: &mut LiveValueTracker,
regs: &mut AllocatableSet, regs: &mut AllocatableSet,
locations: &mut EntityMap<Value, ValueLoc>, locations: &mut ValueLocations,
func_signature: &Signature) { func_signature: &Signature) {
dbg!("Coloring [{}] {}", dbg!("Coloring [{}] {}",
self.encinfo.display(encoding), self.encinfo.display(encoding),
@@ -449,7 +449,7 @@ impl<'a> Context<'a> {
// into the constraint solver. Convert them to solver variables so they can be diverted. // into the constraint solver. Convert them to solver variables so they can be diverted.
fn divert_fixed_input_conflicts(&mut self, fn divert_fixed_input_conflicts(&mut self,
live: &[LiveValue], live: &[LiveValue],
locations: &mut EntityMap<Value, ValueLoc>) { locations: &mut ValueLocations) {
for lv in live { for lv in live {
if let Affinity::Reg(rci) = lv.affinity { if let Affinity::Reg(rci) = lv.affinity {
let rc = self.reginfo.rc(rci); let rc = self.reginfo.rc(rci);
@@ -468,7 +468,7 @@ impl<'a> Context<'a> {
constraints: &[OperandConstraint], constraints: &[OperandConstraint],
defs: &[LiveValue], defs: &[LiveValue],
throughs: &[LiveValue], throughs: &[LiveValue],
locations: &mut EntityMap<Value, ValueLoc>) { locations: &mut ValueLocations) {
for (op, lv) in constraints.iter().zip(defs) { for (op, lv) in constraints.iter().zip(defs) {
if let ConstraintKind::FixedReg(reg) = op.kind { if let ConstraintKind::FixedReg(reg) = op.kind {
self.add_fixed_output(lv.value, op.regclass, reg, throughs, locations); self.add_fixed_output(lv.value, op.regclass, reg, throughs, locations);
@@ -483,7 +483,7 @@ impl<'a> Context<'a> {
abi_types: &[ArgumentType], abi_types: &[ArgumentType],
defs: &[LiveValue], defs: &[LiveValue],
throughs: &[LiveValue], throughs: &[LiveValue],
locations: &mut EntityMap<Value, ValueLoc>) { locations: &mut ValueLocations) {
// It's technically possible for a call instruction to have fixed results before the // It's technically possible for a call instruction to have fixed results before the
// variable list of results, but we have no known instances of that. // variable list of results, but we have no known instances of that.
// Just assume all results are variable return values. // Just assume all results are variable return values.
@@ -506,7 +506,7 @@ impl<'a> Context<'a> {
rc: RegClass, rc: RegClass,
reg: RegUnit, reg: RegUnit,
throughs: &[LiveValue], throughs: &[LiveValue],
locations: &mut EntityMap<Value, ValueLoc>) { locations: &mut ValueLocations) {
if !self.solver.add_fixed_output(rc, reg) { if !self.solver.add_fixed_output(rc, reg) {
// The fixed output conflicts with some of the live-through registers. // The fixed output conflicts with some of the live-through registers.
for lv in throughs { for lv in throughs {
@@ -538,7 +538,7 @@ impl<'a> Context<'a> {
constraints: &[OperandConstraint], constraints: &[OperandConstraint],
defs: &[LiveValue], defs: &[LiveValue],
_dfg: &mut DataFlowGraph, _dfg: &mut DataFlowGraph,
_locations: &mut EntityMap<Value, ValueLoc>) { _locations: &mut ValueLocations) {
for (op, lv) in constraints.iter().zip(defs) { for (op, lv) in constraints.iter().zip(defs) {
match op.kind { match op.kind {
ConstraintKind::FixedReg(_) | ConstraintKind::FixedReg(_) |

View File

@@ -10,8 +10,7 @@
//! pressure limits to be exceeded. //! pressure limits to be exceeded.
use dominator_tree::DominatorTree; use dominator_tree::DominatorTree;
use entity_map::EntityMap; use ir::{Ebb, Inst, Value, Function, Signature, DataFlowGraph, InstEncodings};
use ir::{Ebb, Inst, Value, Function, Signature, DataFlowGraph};
use ir::layout::{Cursor, CursorPosition}; use ir::layout::{Cursor, CursorPosition};
use ir::{InstBuilder, Opcode, ArgumentType, ArgumentLoc}; use ir::{InstBuilder, Opcode, ArgumentType, ArgumentLoc};
use isa::RegClass; use isa::RegClass;
@@ -201,7 +200,7 @@ impl<'a> Context<'a> {
encoding: Encoding, encoding: Encoding,
pos: &mut Cursor, pos: &mut Cursor,
dfg: &mut DataFlowGraph, dfg: &mut DataFlowGraph,
encodings: &mut EntityMap<Inst, Encoding>, encodings: &mut InstEncodings,
func_signature: &Signature, func_signature: &Signature,
tracker: &mut LiveValueTracker) { tracker: &mut LiveValueTracker) {
// Get the operand constraints for `inst` that we are trying to satisfy. // Get the operand constraints for `inst` that we are trying to satisfy.
@@ -341,7 +340,7 @@ impl<'a> Context<'a> {
stack: Value, stack: Value,
reg: Value, reg: Value,
pos: &mut Cursor, pos: &mut Cursor,
encodings: &mut EntityMap<Inst, Encoding>, encodings: &mut InstEncodings,
dfg: &mut DataFlowGraph) { dfg: &mut DataFlowGraph) {
let ty = dfg.value_type(reg); let ty = dfg.value_type(reg);