Fix all dead-code warnings in cranelift-codegen-meta

This commit is contained in:
bjorn3
2021-06-21 12:06:24 +02:00
parent 59e18b7d1b
commit d8818c967e
10 changed files with 14 additions and 748 deletions

View File

@@ -456,7 +456,7 @@ impl Apply {
// Apply should only operate on concrete value types, not "any". // Apply should only operate on concrete value types, not "any".
let value_types = value_types let value_types = value_types
.into_iter() .into_iter()
.map(|vt| vt.expect("shouldn't be Any")) .map(|vt| vt.expect())
.collect(); .collect();
// Basic check on number of arguments. // Basic check on number of arguments.
@@ -635,10 +635,6 @@ impl Into<DummyExpr> for Literal {
#[derive(Clone)] #[derive(Clone)]
pub(crate) struct DummyConstant(pub(crate) Vec<u8>); pub(crate) struct DummyConstant(pub(crate) Vec<u8>);
pub(crate) fn constant(data: Vec<u8>) -> DummyConstant {
DummyConstant(data)
}
impl Into<DummyExpr> for DummyConstant { impl Into<DummyExpr> for DummyConstant {
fn into(self) -> DummyExpr { fn into(self) -> DummyExpr {
DummyExpr::Constant(self) DummyExpr::Constant(self)

View File

@@ -2,8 +2,8 @@ use std::collections::{hash_map, HashMap, HashSet};
use std::iter::FromIterator; use std::iter::FromIterator;
use crate::cdsl::encodings::Encoding; use crate::cdsl::encodings::Encoding;
use crate::cdsl::types::{LaneType, ValueType}; use crate::cdsl::types::ValueType;
use crate::cdsl::xform::{TransformGroup, TransformGroupIndex}; use crate::cdsl::xform::TransformGroupIndex;
pub(crate) struct CpuMode { pub(crate) struct CpuMode {
pub name: &'static str, pub name: &'static str,
@@ -14,42 +14,6 @@ pub(crate) struct CpuMode {
} }
impl CpuMode { impl CpuMode {
pub fn new(name: &'static str) -> Self {
Self {
name,
default_legalize: None,
monomorphic_legalize: None,
typed_legalize: HashMap::new(),
encodings: Vec::new(),
}
}
pub fn set_encodings(&mut self, encodings: Vec<Encoding>) {
assert!(self.encodings.is_empty(), "clobbering encodings");
self.encodings = encodings;
}
pub fn legalize_monomorphic(&mut self, group: &TransformGroup) {
assert!(self.monomorphic_legalize.is_none());
self.monomorphic_legalize = Some(group.id);
}
pub fn legalize_default(&mut self, group: &TransformGroup) {
assert!(self.default_legalize.is_none());
self.default_legalize = Some(group.id);
}
pub fn legalize_value_type(&mut self, lane_type: impl Into<ValueType>, group: &TransformGroup) {
assert!(self
.typed_legalize
.insert(lane_type.into(), group.id)
.is_none());
}
pub fn legalize_type(&mut self, lane_type: impl Into<LaneType>, group: &TransformGroup) {
assert!(self
.typed_legalize
.insert(lane_type.into().into(), group.id)
.is_none());
}
pub fn get_default_legalize_code(&self) -> TransformGroupIndex { pub fn get_default_legalize_code(&self) -> TransformGroupIndex {
self.default_legalize self.default_legalize
.expect("a finished CpuMode must have a default legalize code") .expect("a finished CpuMode must have a default legalize code")

View File

@@ -1,12 +1,11 @@
use crate::cdsl::instructions::{ use crate::cdsl::instructions::{
InstSpec, Instruction, InstructionPredicate, InstructionPredicateNode, InstSpec, Instruction,
InstructionPredicateNumber, InstructionPredicateRegistry, ValueTypeOrAny, InstructionPredicateNumber
}; };
use crate::cdsl::recipes::{EncodingRecipeNumber, Recipes}; use crate::cdsl::recipes::{EncodingRecipeNumber, Recipes};
use crate::cdsl::settings::SettingPredicateNumber; use crate::cdsl::settings::SettingPredicateNumber;
use crate::cdsl::types::ValueType; use crate::cdsl::types::ValueType;
use std::rc::Rc; use std::rc::Rc;
use std::string::ToString;
/// Encoding for a concrete instruction. /// Encoding for a concrete instruction.
/// ///
@@ -51,128 +50,3 @@ impl EncodingContent {
pub(crate) type Encoding = Rc<EncodingContent>; pub(crate) type Encoding = Rc<EncodingContent>;
pub(crate) struct EncodingBuilder {
inst: InstSpec,
recipe: EncodingRecipeNumber,
encbits: u16,
inst_predicate: Option<InstructionPredicate>,
isa_predicate: Option<SettingPredicateNumber>,
bound_type: Option<ValueType>,
}
impl EncodingBuilder {
pub fn new(inst: InstSpec, recipe: EncodingRecipeNumber, encbits: u16) -> Self {
let (inst_predicate, bound_type) = match &inst {
InstSpec::Bound(inst) => {
let other_typevars = &inst.inst.polymorphic_info.as_ref().unwrap().other_typevars;
assert_eq!(
inst.value_types.len(),
other_typevars.len() + 1,
"partially bound polymorphic instruction"
);
// Add secondary type variables to the instruction predicate.
let value_types = &inst.value_types;
let mut inst_predicate: Option<InstructionPredicate> = None;
for (typevar, value_type) in other_typevars.iter().zip(value_types.iter().skip(1)) {
let value_type = match value_type {
ValueTypeOrAny::Any => continue,
ValueTypeOrAny::ValueType(vt) => vt,
};
let type_predicate =
InstructionPredicate::new_typevar_check(&inst.inst, typevar, value_type);
inst_predicate = Some(type_predicate.into());
}
// Add immediate value predicates
for (immediate_value, immediate_operand) in inst
.immediate_values
.iter()
.zip(inst.inst.operands_in.iter().filter(|o| o.is_immediate()))
{
let immediate_predicate = InstructionPredicate::new_is_field_equal(
&inst.inst.format,
immediate_operand.kind.rust_field_name,
immediate_value.to_string(),
);
inst_predicate = if let Some(type_predicate) = inst_predicate {
Some(type_predicate.and(immediate_predicate))
} else {
Some(immediate_predicate.into())
}
}
let ctrl_type = value_types[0]
.clone()
.expect("Controlling type shouldn't be Any");
(inst_predicate, Some(ctrl_type))
}
InstSpec::Inst(inst) => {
assert!(
inst.polymorphic_info.is_none(),
"unbound polymorphic instruction"
);
(None, None)
}
};
Self {
inst,
recipe,
encbits,
inst_predicate,
isa_predicate: None,
bound_type,
}
}
pub fn inst_predicate(mut self, inst_predicate: InstructionPredicateNode) -> Self {
let inst_predicate = Some(match self.inst_predicate {
Some(node) => node.and(inst_predicate),
None => inst_predicate.into(),
});
self.inst_predicate = inst_predicate;
self
}
pub fn isa_predicate(mut self, isa_predicate: SettingPredicateNumber) -> Self {
assert!(self.isa_predicate.is_none());
self.isa_predicate = Some(isa_predicate);
self
}
pub fn build(
self,
recipes: &Recipes,
inst_pred_reg: &mut InstructionPredicateRegistry,
) -> Encoding {
let inst_predicate = self.inst_predicate.map(|pred| inst_pred_reg.insert(pred));
let inst = self.inst.inst();
assert!(
Rc::ptr_eq(&inst.format, &recipes[self.recipe].format),
"Inst {} and recipe {} must have the same format!",
inst.name,
recipes[self.recipe].name
);
assert_eq!(
inst.is_branch && !inst.is_indirect_branch,
recipes[self.recipe].branch_range.is_some(),
"Inst {}'s is_branch contradicts recipe {} branch_range!",
inst.name,
recipes[self.recipe].name
);
Rc::new(EncodingContent {
inst: self.inst,
recipe: self.recipe,
encbits: self.encbits,
inst_predicate,
isa_predicate: self.isa_predicate,
bound_type: self.bound_type,
})
}
}

View File

@@ -70,18 +70,6 @@ impl fmt::Display for InstructionFormat {
} }
impl InstructionFormat { impl InstructionFormat {
pub fn imm_by_name(&self, name: &'static str) -> &FormatField {
self.imm_fields
.iter()
.find(|&field| field.member == name)
.unwrap_or_else(|| {
panic!(
"unexpected immediate field named {} in instruction format {}",
name, self.name
)
})
}
/// Returns a tuple that uniquely identifies the structure. /// Returns a tuple that uniquely identifies the structure.
pub fn structure(&self) -> FormatStructure { pub fn structure(&self) -> FormatStructure {
FormatStructure { FormatStructure {

View File

@@ -1,7 +1,5 @@
use cranelift_codegen_shared::condcodes::IntCC;
use cranelift_entity::{entity_impl, PrimaryMap}; use cranelift_entity::{entity_impl, PrimaryMap};
use std::collections::HashMap;
use std::fmt; use std::fmt;
use std::fmt::{Display, Error, Formatter}; use std::fmt::{Display, Error, Formatter};
use std::rc::Rc; use std::rc::Rc;
@@ -10,10 +8,9 @@ use crate::cdsl::camel_case;
use crate::cdsl::formats::{FormatField, InstructionFormat}; use crate::cdsl::formats::{FormatField, InstructionFormat};
use crate::cdsl::operands::Operand; use crate::cdsl::operands::Operand;
use crate::cdsl::type_inference::Constraint; use crate::cdsl::type_inference::Constraint;
use crate::cdsl::types::{LaneType, ReferenceType, ValueType, VectorType}; use crate::cdsl::types::{LaneType, ReferenceType, ValueType};
use crate::cdsl::typevar::TypeVar; use crate::cdsl::typevar::TypeVar;
use crate::shared::formats::Formats;
use crate::shared::types::{Bool, Float, Int, Reference}; use crate::shared::types::{Bool, Float, Int, Reference};
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
@@ -317,11 +314,6 @@ impl InstructionBuilder {
self self
} }
pub fn clobbers_all_regs(mut self, val: bool) -> Self {
self.clobbers_all_regs = val;
self
}
fn build(self, opcode_number: OpcodeNumber) -> Instruction { fn build(self, opcode_number: OpcodeNumber) -> Instruction {
let operands_in = self.operands_in.unwrap_or_else(Vec::new); let operands_in = self.operands_in.unwrap_or_else(Vec::new);
let operands_out = self.operands_out.unwrap_or_else(Vec::new); let operands_out = self.operands_out.unwrap_or_else(Vec::new);
@@ -387,33 +379,20 @@ impl InstructionBuilder {
#[derive(Clone)] #[derive(Clone)]
pub(crate) enum ValueTypeOrAny { pub(crate) enum ValueTypeOrAny {
ValueType(ValueType), ValueType(ValueType),
Any,
} }
impl ValueTypeOrAny { impl ValueTypeOrAny {
pub fn expect(self, msg: &str) -> ValueType { pub fn expect(self) -> ValueType {
match self { match self {
ValueTypeOrAny::ValueType(vt) => vt, ValueTypeOrAny::ValueType(vt) => vt,
ValueTypeOrAny::Any => panic!("Unexpected Any: {}", msg),
} }
} }
} }
/// The number of bits in the vector
type VectorBitWidth = u64;
/// An parameter used for binding instructions to specific types or values /// An parameter used for binding instructions to specific types or values
pub(crate) enum BindParameter { pub(crate) enum BindParameter {
Any,
Lane(LaneType), Lane(LaneType),
Vector(LaneType, VectorBitWidth),
Reference(ReferenceType), Reference(ReferenceType),
Immediate(Immediate),
}
/// Constructor for more easily building vector parameters from any lane type
pub(crate) fn vector(parameter: impl Into<LaneType>, vector_size: VectorBitWidth) -> BindParameter {
BindParameter::Vector(parameter.into(), vector_size)
} }
impl From<Int> for BindParameter { impl From<Int> for BindParameter {
@@ -446,22 +425,13 @@ impl From<Reference> for BindParameter {
} }
} }
impl From<Immediate> for BindParameter {
fn from(imm: Immediate) -> Self {
BindParameter::Immediate(imm)
}
}
#[derive(Clone)] #[derive(Clone)]
pub(crate) enum Immediate { pub(crate) enum Immediate {}
// When needed, this enum should be expanded to include other immediate types (e.g. u8, u128).
IntCC(IntCC),
}
impl Display for Immediate { impl Display for Immediate {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { fn fmt(&self, _f: &mut Formatter) -> Result<(), Error> {
match self { match self {
Immediate::IntCC(x) => write!(f, "IntCC::{:?}", x), _ => panic!(),
} }
} }
} }
@@ -530,28 +500,14 @@ impl Bindable for BoundInstruction {
fn bind(&self, parameter: impl Into<BindParameter>) -> BoundInstruction { fn bind(&self, parameter: impl Into<BindParameter>) -> BoundInstruction {
let mut modified = self.clone(); let mut modified = self.clone();
match parameter.into() { match parameter.into() {
BindParameter::Any => modified.value_types.push(ValueTypeOrAny::Any),
BindParameter::Lane(lane_type) => modified BindParameter::Lane(lane_type) => modified
.value_types .value_types
.push(ValueTypeOrAny::ValueType(lane_type.into())), .push(ValueTypeOrAny::ValueType(lane_type.into())),
BindParameter::Vector(lane_type, vector_size_in_bits) => {
let num_lanes = vector_size_in_bits / lane_type.lane_bits();
assert!(
num_lanes >= 2,
"Minimum lane number for bind_vector is 2, found {}.",
num_lanes,
);
let vector_type = ValueType::Vector(VectorType::new(lane_type, num_lanes));
modified
.value_types
.push(ValueTypeOrAny::ValueType(vector_type));
}
BindParameter::Reference(reference_type) => { BindParameter::Reference(reference_type) => {
modified modified
.value_types .value_types
.push(ValueTypeOrAny::ValueType(reference_type.into())); .push(ValueTypeOrAny::ValueType(reference_type.into()));
} }
BindParameter::Immediate(immediate) => modified.immediate_values.push(immediate),
} }
modified.verify_bindings().unwrap(); modified.verify_bindings().unwrap();
modified modified
@@ -767,41 +723,6 @@ fn is_ctrl_typevar_candidate(
pub(crate) enum FormatPredicateKind { pub(crate) enum FormatPredicateKind {
/// Is the field member equal to the expected value (stored here)? /// Is the field member equal to the expected value (stored here)?
IsEqual(String), IsEqual(String),
/// Is the immediate instruction format field representable as an n-bit two's complement
/// integer? (with width: first member, scale: second member).
/// The predicate is true if the field is in the range: `-2^(width-1) -- 2^(width-1)-1` and a
/// multiple of `2^scale`.
IsSignedInt(usize, usize),
/// Is the immediate instruction format field representable as an n-bit unsigned integer? (with
/// width: first member, scale: second member).
/// The predicate is true if the field is in the range: `0 -- 2^width - 1` and a multiple of
/// `2^scale`.
IsUnsignedInt(usize, usize),
/// Is the immediate format field member an integer equal to zero?
IsZeroInt,
/// Is the immediate format field member equal to zero? (float32 version)
IsZero32BitFloat,
/// Is the immediate format field member equal to zero? (float64 version)
IsZero64BitFloat,
/// Is the immediate format field member equal zero in all lanes?
IsAllZeroes,
/// Does the immediate format field member have ones in all bits of all lanes?
IsAllOnes,
/// Has the value list (in member_name) the size specified in parameter?
LengthEquals(usize),
/// Is the referenced function colocated?
IsColocatedFunc,
/// Is the referenced data object colocated?
IsColocatedData,
} }
#[derive(Clone, Hash, PartialEq, Eq)] #[derive(Clone, Hash, PartialEq, Eq)]
@@ -812,19 +733,6 @@ pub(crate) struct FormatPredicateNode {
} }
impl FormatPredicateNode { impl FormatPredicateNode {
fn new(
format: &InstructionFormat,
field_name: &'static str,
kind: FormatPredicateKind,
) -> Self {
let member_name = format.imm_by_name(field_name).member;
Self {
format_name: format.name,
member_name,
kind,
}
}
fn new_raw( fn new_raw(
format: &InstructionFormat, format: &InstructionFormat,
member_name: &'static str, member_name: &'static str,
@@ -839,11 +747,6 @@ impl FormatPredicateNode {
fn destructuring_member_name(&self) -> &'static str { fn destructuring_member_name(&self) -> &'static str {
match &self.kind { match &self.kind {
FormatPredicateKind::LengthEquals(_) => {
// Length operates on the argument value list.
assert!(self.member_name == "args");
"ref args"
}
_ => self.member_name, _ => self.member_name,
} }
} }
@@ -853,41 +756,6 @@ impl FormatPredicateNode {
FormatPredicateKind::IsEqual(arg) => { FormatPredicateKind::IsEqual(arg) => {
format!("predicates::is_equal({}, {})", self.member_name, arg) format!("predicates::is_equal({}, {})", self.member_name, arg)
} }
FormatPredicateKind::IsSignedInt(width, scale) => format!(
"predicates::is_signed_int({}, {}, {})",
self.member_name, width, scale
),
FormatPredicateKind::IsUnsignedInt(width, scale) => format!(
"predicates::is_unsigned_int({}, {}, {})",
self.member_name, width, scale
),
FormatPredicateKind::IsZeroInt => {
format!("predicates::is_zero_int({})", self.member_name)
}
FormatPredicateKind::IsZero32BitFloat => {
format!("predicates::is_zero_32_bit_float({})", self.member_name)
}
FormatPredicateKind::IsZero64BitFloat => {
format!("predicates::is_zero_64_bit_float({})", self.member_name)
}
FormatPredicateKind::IsAllZeroes => format!(
"predicates::is_all_zeroes(func.dfg.constants.get({}))",
self.member_name
),
FormatPredicateKind::IsAllOnes => format!(
"predicates::is_all_ones(func.dfg.constants.get({}))",
self.member_name
),
FormatPredicateKind::LengthEquals(num) => format!(
"predicates::has_length_of({}, {}, func)",
self.member_name, num
),
FormatPredicateKind::IsColocatedFunc => {
format!("predicates::is_colocated_func({}, func)", self.member_name,)
}
FormatPredicateKind::IsColocatedData => {
format!("predicates::is_colocated_data({}, func)", self.member_name)
}
} }
} }
} }
@@ -926,9 +794,6 @@ pub(crate) enum InstructionPredicateNode {
/// An AND-combination of two or more other predicates. /// An AND-combination of two or more other predicates.
And(Vec<InstructionPredicateNode>), And(Vec<InstructionPredicateNode>),
/// An OR-combination of two or more other predicates.
Or(Vec<InstructionPredicateNode>),
} }
impl InstructionPredicateNode { impl InstructionPredicateNode {
@@ -941,11 +806,6 @@ impl InstructionPredicateNode {
.map(|x| x.rust_predicate(func_str)) .map(|x| x.rust_predicate(func_str))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(" && "), .join(" && "),
InstructionPredicateNode::Or(nodes) => nodes
.iter()
.map(|x| x.rust_predicate(func_str))
.collect::<Vec<_>>()
.join(" || "),
} }
} }
@@ -967,9 +827,9 @@ impl InstructionPredicateNode {
pub fn is_type_predicate(&self) -> bool { pub fn is_type_predicate(&self) -> bool {
match self { match self {
InstructionPredicateNode::FormatPredicate(_) InstructionPredicateNode::FormatPredicate(_) | InstructionPredicateNode::And(_) => {
| InstructionPredicateNode::And(_) false
| InstructionPredicateNode::Or(_) => false, }
InstructionPredicateNode::TypePredicate(_) => true, InstructionPredicateNode::TypePredicate(_) => true,
} }
} }
@@ -977,7 +837,7 @@ impl InstructionPredicateNode {
fn collect_leaves(&self) -> Vec<&InstructionPredicateNode> { fn collect_leaves(&self) -> Vec<&InstructionPredicateNode> {
let mut ret = Vec::new(); let mut ret = Vec::new();
match self { match self {
InstructionPredicateNode::And(nodes) | InstructionPredicateNode::Or(nodes) => { InstructionPredicateNode::And(nodes) => {
for node in nodes { for node in nodes {
ret.extend(node.collect_leaves()); ret.extend(node.collect_leaves());
} }
@@ -1004,10 +864,6 @@ impl InstructionPredicate {
Self { node: None } Self { node: None }
} }
pub fn unwrap(self) -> InstructionPredicateNode {
self.node.unwrap()
}
pub fn new_typevar_check( pub fn new_typevar_check(
inst: &Instruction, inst: &Instruction,
type_var: &TypeVar, type_var: &TypeVar,
@@ -1032,18 +888,6 @@ impl InstructionPredicate {
)) ))
} }
pub fn new_is_field_equal(
format: &InstructionFormat,
field_name: &'static str,
imm_value: String,
) -> InstructionPredicateNode {
InstructionPredicateNode::FormatPredicate(FormatPredicateNode::new(
format,
field_name,
FormatPredicateKind::IsEqual(imm_value),
))
}
/// Used only for the AST module, which directly passes in the format field. /// Used only for the AST module, which directly passes in the format field.
pub fn new_is_field_equal_ast( pub fn new_is_field_equal_ast(
format: &InstructionFormat, format: &InstructionFormat,
@@ -1057,127 +901,11 @@ impl InstructionPredicate {
)) ))
} }
pub fn new_is_signed_int(
format: &InstructionFormat,
field_name: &'static str,
width: usize,
scale: usize,
) -> InstructionPredicateNode {
InstructionPredicateNode::FormatPredicate(FormatPredicateNode::new(
format,
field_name,
FormatPredicateKind::IsSignedInt(width, scale),
))
}
pub fn new_is_unsigned_int(
format: &InstructionFormat,
field_name: &'static str,
width: usize,
scale: usize,
) -> InstructionPredicateNode {
InstructionPredicateNode::FormatPredicate(FormatPredicateNode::new(
format,
field_name,
FormatPredicateKind::IsUnsignedInt(width, scale),
))
}
pub fn new_is_zero_int(
format: &InstructionFormat,
field_name: &'static str,
) -> InstructionPredicateNode {
InstructionPredicateNode::FormatPredicate(FormatPredicateNode::new(
format,
field_name,
FormatPredicateKind::IsZeroInt,
))
}
pub fn new_is_zero_32bit_float(
format: &InstructionFormat,
field_name: &'static str,
) -> InstructionPredicateNode {
InstructionPredicateNode::FormatPredicate(FormatPredicateNode::new(
format,
field_name,
FormatPredicateKind::IsZero32BitFloat,
))
}
pub fn new_is_zero_64bit_float(
format: &InstructionFormat,
field_name: &'static str,
) -> InstructionPredicateNode {
InstructionPredicateNode::FormatPredicate(FormatPredicateNode::new(
format,
field_name,
FormatPredicateKind::IsZero64BitFloat,
))
}
pub fn new_is_all_zeroes(
format: &InstructionFormat,
field_name: &'static str,
) -> InstructionPredicateNode {
InstructionPredicateNode::FormatPredicate(FormatPredicateNode::new(
format,
field_name,
FormatPredicateKind::IsAllZeroes,
))
}
pub fn new_is_all_ones(
format: &InstructionFormat,
field_name: &'static str,
) -> InstructionPredicateNode {
InstructionPredicateNode::FormatPredicate(FormatPredicateNode::new(
format,
field_name,
FormatPredicateKind::IsAllOnes,
))
}
pub fn new_length_equals(format: &InstructionFormat, size: usize) -> InstructionPredicateNode {
assert!(
format.has_value_list,
"the format must be variadic in number of arguments"
);
InstructionPredicateNode::FormatPredicate(FormatPredicateNode::new_raw(
format,
"args",
FormatPredicateKind::LengthEquals(size),
))
}
pub fn new_is_colocated_func(
format: &InstructionFormat,
field_name: &'static str,
) -> InstructionPredicateNode {
InstructionPredicateNode::FormatPredicate(FormatPredicateNode::new(
format,
field_name,
FormatPredicateKind::IsColocatedFunc,
))
}
pub fn new_is_colocated_data(formats: &Formats) -> InstructionPredicateNode {
let format = &formats.unary_global_value;
InstructionPredicateNode::FormatPredicate(FormatPredicateNode::new(
&*format,
"global_value",
FormatPredicateKind::IsColocatedData,
))
}
pub fn and(mut self, new_node: InstructionPredicateNode) -> Self { pub fn and(mut self, new_node: InstructionPredicateNode) -> Self {
let node = self.node; let node = self.node;
let mut and_nodes = match node { let mut and_nodes = match node {
Some(node) => match node { Some(node) => match node {
InstructionPredicateNode::And(nodes) => nodes, InstructionPredicateNode::And(nodes) => nodes,
InstructionPredicateNode::Or(_) => {
panic!("Can't mix and/or without implementing operator precedence!")
}
_ => vec![node], _ => vec![node],
}, },
_ => Vec::new(), _ => Vec::new(),
@@ -1187,23 +915,6 @@ impl InstructionPredicate {
self self
} }
pub fn or(mut self, new_node: InstructionPredicateNode) -> Self {
let node = self.node;
let mut or_nodes = match node {
Some(node) => match node {
InstructionPredicateNode::Or(nodes) => nodes,
InstructionPredicateNode::And(_) => {
panic!("Can't mix and/or without implementing operator precedence!")
}
_ => vec![node],
},
_ => Vec::new(),
};
or_nodes.push(new_node);
self.node = Some(InstructionPredicateNode::Or(or_nodes));
self
}
pub fn rust_predicate(&self, func_str: &str) -> Option<String> { pub fn rust_predicate(&self, func_str: &str) -> Option<String> {
self.node.as_ref().map(|root| root.rust_predicate(func_str)) self.node.as_ref().map(|root| root.rust_predicate(func_str))
} }
@@ -1232,40 +943,6 @@ entity_impl!(InstructionPredicateNumber);
pub(crate) type InstructionPredicateMap = pub(crate) type InstructionPredicateMap =
PrimaryMap<InstructionPredicateNumber, InstructionPredicate>; PrimaryMap<InstructionPredicateNumber, InstructionPredicate>;
/// A registry of predicates to help deduplicating them, during Encodings construction. When the
/// construction process is over, it needs to be extracted with `extract` and associated to the
/// TargetIsa.
pub(crate) struct InstructionPredicateRegistry {
/// Maps a predicate number to its actual predicate.
map: InstructionPredicateMap,
/// Inverse map: maps a predicate to its predicate number. This is used before inserting a
/// predicate, to check whether it already exists.
inverted_map: HashMap<InstructionPredicate, InstructionPredicateNumber>,
}
impl InstructionPredicateRegistry {
pub fn new() -> Self {
Self {
map: PrimaryMap::new(),
inverted_map: HashMap::new(),
}
}
pub fn insert(&mut self, predicate: InstructionPredicate) -> InstructionPredicateNumber {
match self.inverted_map.get(&predicate) {
Some(&found) => found,
None => {
let key = self.map.push(predicate.clone());
self.inverted_map.insert(predicate, key);
key
}
}
}
pub fn extract(self) -> InstructionPredicateMap {
self.map
}
}
/// An instruction specification, containing an instruction that has bound types or not. /// An instruction specification, containing an instruction that has bound types or not.
pub(crate) enum InstSpec { pub(crate) enum InstSpec {
Inst(Instruction), Inst(Instruction),

View File

@@ -23,12 +23,6 @@ pub(crate) struct Register {
pub unit: u8, pub unit: u8,
} }
impl Register {
pub fn new(regclass: RegClassIndex, unit: u8) -> Self {
Self { regclass, unit }
}
}
/// An operand that must be in a stack slot. /// An operand that must be in a stack slot.
/// ///
/// A `Stack` object can be used to indicate an operand constraint for a value /// A `Stack` object can be used to indicate an operand constraint for a value
@@ -39,9 +33,6 @@ pub(crate) struct Stack {
} }
impl Stack { impl Stack {
pub fn new(regclass: RegClassIndex) -> Self {
Self { regclass }
}
pub fn stack_base_mask(self) -> &'static str { pub fn stack_base_mask(self) -> &'static str {
// TODO: Make this configurable instead of just using the SP. // TODO: Make this configurable instead of just using the SP.
"StackBaseMask(1)" "StackBaseMask(1)"
@@ -179,119 +170,3 @@ pub(crate) struct EncodingRecipeBuilder {
inst_predicate: Option<InstructionPredicate>, inst_predicate: Option<InstructionPredicate>,
isa_predicate: Option<SettingPredicateNumber>, isa_predicate: Option<SettingPredicateNumber>,
} }
impl EncodingRecipeBuilder {
pub fn new(name: impl Into<String>, format: &Rc<InstructionFormat>, base_size: u64) -> Self {
Self {
name: name.into(),
format: format.clone(),
base_size,
operands_in: None,
operands_out: None,
compute_size: None,
branch_range: None,
emit: None,
clobbers_flags: None,
inst_predicate: None,
isa_predicate: None,
}
}
// Setters.
pub fn operands_in(mut self, constraints: Vec<impl Into<OperandConstraint>>) -> Self {
assert!(self.operands_in.is_none());
self.operands_in = Some(
constraints
.into_iter()
.map(|constr| constr.into())
.collect(),
);
self
}
pub fn operands_out(mut self, constraints: Vec<impl Into<OperandConstraint>>) -> Self {
assert!(self.operands_out.is_none());
self.operands_out = Some(
constraints
.into_iter()
.map(|constr| constr.into())
.collect(),
);
self
}
pub fn clobbers_flags(mut self, flag: bool) -> Self {
assert!(self.clobbers_flags.is_none());
self.clobbers_flags = Some(flag);
self
}
pub fn emit(mut self, code: impl Into<String>) -> Self {
assert!(self.emit.is_none());
self.emit = Some(code.into());
self
}
pub fn branch_range(mut self, range: (u64, u64)) -> Self {
assert!(self.branch_range.is_none());
self.branch_range = Some(BranchRange {
inst_size: range.0,
range: range.1,
});
self
}
pub fn isa_predicate(mut self, pred: SettingPredicateNumber) -> Self {
assert!(self.isa_predicate.is_none());
self.isa_predicate = Some(pred);
self
}
pub fn inst_predicate(mut self, inst_predicate: impl Into<InstructionPredicate>) -> Self {
assert!(self.inst_predicate.is_none());
self.inst_predicate = Some(inst_predicate.into());
self
}
pub fn compute_size(mut self, compute_size: &'static str) -> Self {
assert!(self.compute_size.is_none());
self.compute_size = Some(compute_size);
self
}
pub fn build(self) -> EncodingRecipe {
let operands_in = self.operands_in.unwrap_or_default();
let operands_out = self.operands_out.unwrap_or_default();
// The number of input constraints must match the number of format input operands.
if !self.format.has_value_list {
assert!(
operands_in.len() == self.format.num_value_operands,
"missing operand constraints for recipe {} (format {})",
self.name,
self.format.name
);
}
// Ensure tied inputs actually refer to existing inputs.
for constraint in operands_in.iter().chain(operands_out.iter()) {
if let OperandConstraint::TiedInput(n) = *constraint {
assert!(n < operands_in.len());
}
}
let compute_size = match self.compute_size {
Some(compute_size) => compute_size,
None => "base_size",
};
let clobbers_flags = self.clobbers_flags.unwrap_or(true);
EncodingRecipe {
name: self.name,
format: self.format,
base_size: self.base_size,
operands_in,
operands_out,
compute_size,
branch_range: self.branch_range,
clobbers_flags,
inst_predicate: self.inst_predicate,
isa_predicate: self.isa_predicate,
emit: self.emit,
}
}
}

View File

@@ -39,37 +39,6 @@ impl RegBank {
classes: Vec::new(), classes: Vec::new(),
} }
} }
fn unit_by_name(&self, name: &'static str) -> u8 {
let unit = if let Some(found) = self.names.iter().position(|&reg_name| reg_name == name) {
found
} else {
// Try to match without the bank prefix.
assert!(name.starts_with(self.prefix));
let name_without_prefix = &name[self.prefix.len()..];
if let Some(found) = self
.names
.iter()
.position(|&reg_name| reg_name == name_without_prefix)
{
found
} else {
// Ultimate try: try to parse a number and use this in the array, eg r15 on x86.
if let Ok(as_num) = name_without_prefix.parse::<u8>() {
assert!(
as_num < self.units,
"trying to get {}, but bank only has {} registers!",
name,
self.units
);
as_num as usize
} else {
panic!("invalid register name {}", name);
}
}
};
self.first_unit + (unit as u8)
}
} }
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
@@ -132,7 +101,6 @@ impl RegClass {
pub(crate) enum RegClassProto { pub(crate) enum RegClassProto {
TopLevel(RegBankIndex), TopLevel(RegBankIndex),
SubClass(RegClassIndex),
} }
pub(crate) struct RegClassBuilder { pub(crate) struct RegClassBuilder {
@@ -153,21 +121,6 @@ impl RegClassBuilder {
proto: RegClassProto::TopLevel(bank), proto: RegClassProto::TopLevel(bank),
} }
} }
pub fn subclass_of(
name: &'static str,
parent_index: RegClassIndex,
start: u8,
stop: u8,
) -> Self {
assert!(stop >= start);
Self {
name,
width: 0,
count: stop - start,
start,
proto: RegClassProto::SubClass(parent_index),
}
}
pub fn count(mut self, count: u8) -> Self { pub fn count(mut self, count: u8) -> Self {
self.count = count; self.count = count;
self self
@@ -175,7 +128,6 @@ impl RegClassBuilder {
pub fn width(mut self, width: u8) -> Self { pub fn width(mut self, width: u8) -> Self {
match self.proto { match self.proto {
RegClassProto::TopLevel(_) => self.width = width, RegClassProto::TopLevel(_) => self.width = width,
RegClassProto::SubClass(_) => panic!("Subclasses inherit their parent's width."),
} }
self self
} }
@@ -213,11 +165,6 @@ impl RegBankBuilder {
self.pressure_tracking = Some(track); self.pressure_tracking = Some(track);
self self
} }
pub fn pinned_reg(mut self, unit: u16) -> Self {
assert!(unit < u16::from(self.units));
self.pinned_reg = Some(unit);
self
}
} }
pub(crate) struct IsaRegsBuilder { pub(crate) struct IsaRegsBuilder {
@@ -274,20 +221,6 @@ impl IsaRegsBuilder {
.push(class_index); .push(class_index);
(bank_index, class_index, builder.start, builder.width) (bank_index, class_index, builder.start, builder.width)
} }
RegClassProto::SubClass(parent_class_index) => {
assert!(builder.width == 0);
let (bank, toprc, start, width) = {
let parent = self.classes.get(parent_class_index).unwrap();
(parent.bank, parent.toprc, parent.start, parent.width)
};
for reg_class in self.classes.values_mut() {
if reg_class.toprc == toprc {
reg_class.subclasses.push(class_index);
}
}
let subclass_start = start + builder.start * width;
(bank, toprc, subclass_start, width)
}
}; };
let reg_bank_units = self.banks.get(bank).unwrap().units; let reg_bank_units = self.banks.get(bank).unwrap().units;
@@ -396,17 +329,4 @@ impl IsaRegs {
) -> Self { ) -> Self {
Self { banks, classes } Self { banks, classes }
} }
pub fn class_by_name(&self, name: &str) -> RegClassIndex {
self.classes
.values()
.find(|&class| class.name == name)
.unwrap_or_else(|| panic!("register class {} not found", name))
.index
}
pub fn regunit_by_name(&self, class_index: RegClassIndex, name: &'static str) -> u8 {
let bank_index = self.classes.get(class_index).unwrap().bank;
self.banks.get(bank_index).unwrap().unit_by_name(name)
}
} }

View File

@@ -150,14 +150,6 @@ impl SettingGroup {
} }
panic!("Should have found bool setting by name."); panic!("Should have found bool setting by name.");
} }
pub fn predicate_by_name(&self, name: &'static str) -> SettingPredicateNumber {
self.predicates
.iter()
.find(|pred| pred.name == name)
.unwrap_or_else(|| panic!("unknown predicate {}", name))
.number
}
} }
/// This is the basic information needed to track the specific parts of a setting when building /// This is the basic information needed to track the specific parts of a setting when building

View File

@@ -237,20 +237,6 @@ impl LaneType {
ValueType::Vector(VectorType::new(self, lanes.into())) ValueType::Vector(VectorType::new(self, lanes.into()))
} }
} }
pub fn is_float(self) -> bool {
match self {
LaneType::Float(_) => true,
_ => false,
}
}
pub fn is_int(self) -> bool {
match self {
LaneType::Int(_) => true,
_ => false,
}
}
} }
impl fmt::Display for LaneType { impl fmt::Display for LaneType {

View File

@@ -384,12 +384,6 @@ impl TransformGroupBuilder {
self self
} }
pub fn isa(mut self, isa_name: &'static str) -> Self {
assert!(self.isa_name.is_none());
self.isa_name = Some(isa_name);
self
}
/// Add a custom legalization action for `inst`. /// Add a custom legalization action for `inst`.
/// ///
/// The `func_name` parameter is the fully qualified name of a Rust function which takes the /// The `func_name` parameter is the fully qualified name of a Rust function which takes the