[meta] Remove the OperandKindBuilder;

And replace it by constructors in OperandKind. There's a single optional
parameter function `set_doc` that remains, and didn't justify the whole
OperandKindBuilder concept to exist.
This commit is contained in:
Benjamin Bouvier
2019-10-29 16:57:11 +01:00
parent d5e990220e
commit d8b840d2f5
5 changed files with 78 additions and 134 deletions

View File

@@ -49,6 +49,7 @@ pub(crate) struct InstructionFormat {
pub(crate) struct FormatStructure { pub(crate) struct FormatStructure {
pub num_value_operands: usize, pub num_value_operands: usize,
pub has_value_list: bool, pub has_value_list: bool,
/// Tuples of (Rust field name / Rust type) for each immediate field.
pub imm_field_names: Vec<(&'static str, &'static str)>, pub imm_field_names: Vec<(&'static str, &'static str)>,
} }

View File

@@ -1296,7 +1296,7 @@ impl Into<InstSpec> for BoundInstruction {
mod test { mod test {
use super::*; use super::*;
use crate::cdsl::formats::InstructionFormatBuilder; use crate::cdsl::formats::InstructionFormatBuilder;
use crate::cdsl::operands::{OperandKindBuilder, OperandKindFields}; use crate::cdsl::operands::{OperandKind, OperandKindFields};
use crate::cdsl::typevar::TypeSetBuilder; use crate::cdsl::typevar::TypeSetBuilder;
use crate::shared::types::Int::{I32, I64}; use crate::shared::types::Int::{I32, I64};
@@ -1304,7 +1304,7 @@ mod test {
// Pretend the index string is &'static. // Pretend the index string is &'static.
let name = Box::leak(index.to_string().into_boxed_str()); let name = Box::leak(index.to_string().into_boxed_str());
// Format's name / rust_type don't matter here. // Format's name / rust_type don't matter here.
let kind = OperandKindBuilder::new(name, name, field).build(); let kind = OperandKind::new(name, name, field);
let operand = Operand::new(name, kind); let operand = Operand::new(name, kind);
operand operand
} }

View File

@@ -100,7 +100,7 @@ impl Operand {
} }
} }
type EnumValues = HashMap<&'static str, &'static str>; pub type EnumValues = HashMap<&'static str, &'static str>;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub(crate) enum OperandKindFields { pub(crate) enum OperandKindFields {
@@ -126,6 +126,23 @@ pub(crate) struct OperandKind {
} }
impl OperandKind { impl OperandKind {
pub fn new(
rust_field_name: &'static str,
rust_type: &'static str,
fields: OperandKindFields,
) -> Self {
Self {
rust_field_name,
rust_type,
fields,
doc: None,
}
}
pub fn with_doc(mut self, doc: &'static str) -> Self {
assert!(self.doc.is_none());
self.doc = Some(doc);
self
}
fn doc(&self) -> Option<&str> { fn doc(&self) -> Option<&str> {
if let Some(doc) = &self.doc { if let Some(doc) = &self.doc {
return Some(doc); return Some(doc);
@@ -142,12 +159,11 @@ impl OperandKind {
impl Into<OperandKind> for &TypeVar { impl Into<OperandKind> for &TypeVar {
fn into(self) -> OperandKind { fn into(self) -> OperandKind {
OperandKindBuilder::new( OperandKind::new(
"value", "value",
"ir::Value", "ir::Value",
OperandKindFields::TypeVar(self.into()), OperandKindFields::TypeVar(self.into()),
) )
.build()
} }
} }
impl Into<OperandKind> for &OperandKind { impl Into<OperandKind> for &OperandKind {
@@ -155,58 +171,3 @@ impl Into<OperandKind> for &OperandKind {
self.clone() self.clone()
} }
} }
pub(crate) struct OperandKindBuilder {
rust_field_name: &'static str,
rust_type: &'static str,
fields: OperandKindFields,
doc: Option<&'static str>,
}
impl OperandKindBuilder {
pub fn new(
rust_field_name: &'static str,
rust_type: &'static str,
fields: OperandKindFields,
) -> Self {
Self {
rust_field_name,
rust_type,
fields,
doc: None,
}
}
pub fn new_imm(rust_field_name: &'static str, rust_type: &'static str) -> Self {
Self {
rust_field_name,
rust_type,
fields: OperandKindFields::ImmValue,
doc: None,
}
}
pub fn new_enum(
rust_field_name: &'static str,
rust_type: &'static str,
values: EnumValues,
) -> Self {
Self {
rust_field_name,
rust_type,
fields: OperandKindFields::ImmEnum(values),
doc: None,
}
}
pub fn with_doc(mut self, doc: &'static str) -> Self {
assert!(self.doc.is_none());
self.doc = Some(doc);
self
}
pub fn build(self) -> OperandKind {
OperandKind {
rust_type: self.rust_type,
fields: self.fields,
rust_field_name: self.rust_field_name,
doc: self.doc,
}
}
}

View File

@@ -1,4 +1,9 @@
use crate::cdsl::operands::{OperandKind, OperandKindBuilder as Builder, OperandKindFields}; use crate::cdsl::operands::{OperandKind, OperandKindFields};
/// Small helper to initialize an OperandBuilder with the right kind, for a given name and doc.
fn new(format_field_name: &'static str, rust_type: &'static str, doc: &'static str) -> OperandKind {
OperandKind::new(format_field_name, rust_type, OperandKindFields::EntityRef).with_doc(doc)
}
pub(crate) struct EntityRefs { pub(crate) struct EntityRefs {
/// A reference to an extended basic block in the same function. /// A reference to an extended basic block in the same function.
@@ -35,43 +40,34 @@ pub(crate) struct EntityRefs {
impl EntityRefs { impl EntityRefs {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
ebb: create( ebb: new(
"destination", "destination",
"ir::Ebb", "ir::Ebb",
"An extended basic block in the same function.", "An extended basic block in the same function.",
) ),
.build(), stack_slot: new("stack_slot", "ir::StackSlot", "A stack slot"),
stack_slot: create("stack_slot", "ir::StackSlot", "A stack slot").build(), global_value: new("global_value", "ir::GlobalValue", "A global value."),
global_value: create("global_value", "ir::GlobalValue", "A global value.").build(), sig_ref: new("sig_ref", "ir::SigRef", "A function signature."),
sig_ref: create("sig_ref", "ir::SigRef", "A function signature.").build(), func_ref: new("func_ref", "ir::FuncRef", "An external function."),
func_ref: create("func_ref", "ir::FuncRef", "An external function.").build(), jump_table: new("table", "ir::JumpTable", "A jump table."),
jump_table: create("table", "ir::JumpTable", "A jump table.").build(), heap: new("heap", "ir::Heap", "A heap."),
heap: create("heap", "ir::Heap", "A heap.").build(), table: new("table", "ir::Table", "A table."),
table: create("table", "ir::Table", "A table.").build(), varargs: OperandKind::new("", "&[Value]", OperandKindFields::VariableArgs).with_doc(
r#"
varargs: Builder::new("", "&[Value]", OperandKindFields::VariableArgs)
.with_doc(
r#"
A variable size list of `value` operands. A variable size list of `value` operands.
Use this to represent arguments passed to a function call, arguments Use this to represent arguments passed to a function call, arguments
passed to an extended basic block, or a variable number of results passed to an extended basic block, or a variable number of results
returned from an instruction. returned from an instruction.
"#, "#,
) ),
.build(),
} }
} }
} }
/// Small helper to initialize an OperandBuilder with the right kind, for a given name and doc.
fn create(format_field_name: &'static str, rust_type: &'static str, doc: &'static str) -> Builder {
Builder::new(format_field_name, rust_type, OperandKindFields::EntityRef).with_doc(doc)
}

View File

@@ -1,4 +1,4 @@
use crate::cdsl::operands::{OperandKind, OperandKindBuilder as Builder}; use crate::cdsl::operands::{EnumValues, OperandKind, OperandKindFields};
use std::collections::HashMap; use std::collections::HashMap;
@@ -73,45 +73,40 @@ pub(crate) struct Immediates {
pub trapcode: OperandKind, pub trapcode: OperandKind,
} }
fn new_imm(format_field_name: &'static str, rust_type: &'static str) -> OperandKind {
OperandKind::new(format_field_name, rust_type, OperandKindFields::ImmValue)
}
fn new_enum(
format_field_name: &'static str,
rust_type: &'static str,
values: EnumValues,
) -> OperandKind {
OperandKind::new(
format_field_name,
rust_type,
OperandKindFields::ImmEnum(values),
)
}
impl Immediates { impl Immediates {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
imm64: Builder::new_imm("imm", "ir::immediates::Imm64") imm64: new_imm("imm", "ir::immediates::Imm64").with_doc("A 64-bit immediate integer."),
.with_doc("A 64-bit immediate integer.") uimm8: new_imm("imm", "ir::immediates::Uimm8")
.build(), .with_doc("An 8-bit immediate unsigned integer."),
uimm32: new_imm("imm", "ir::immediates::Uimm32")
uimm8: Builder::new_imm("imm", "ir::immediates::Uimm8") .with_doc("A 32-bit immediate unsigned integer."),
.with_doc("An 8-bit immediate unsigned integer.") uimm128: new_imm("imm", "ir::Immediate")
.build(), .with_doc("A 128-bit immediate unsigned integer."),
pool_constant: new_imm("constant_handle", "ir::Constant")
uimm32: Builder::new_imm("imm", "ir::immediates::Uimm32") .with_doc("A constant stored in the constant pool."),
.with_doc("A 32-bit immediate unsigned integer.") offset32: new_imm("offset", "ir::immediates::Offset32")
.build(), .with_doc("A 32-bit immediate signed offset."),
ieee32: new_imm("imm", "ir::immediates::Ieee32")
uimm128: Builder::new_imm("imm", "ir::Immediate") .with_doc("A 32-bit immediate floating point number."),
.with_doc("A 128-bit immediate unsigned integer.") ieee64: new_imm("imm", "ir::immediates::Ieee64")
.build(), .with_doc("A 64-bit immediate floating point number."),
boolean: new_imm("imm", "bool").with_doc("An immediate boolean."),
pool_constant: Builder::new_imm("constant_handle", "ir::Constant")
.with_doc("A constant stored in the constant pool.")
.build(),
offset32: Builder::new_imm("offset", "ir::immediates::Offset32")
.with_doc("A 32-bit immediate signed offset.")
.build(),
ieee32: Builder::new_imm("imm", "ir::immediates::Ieee32")
.with_doc("A 32-bit immediate floating point number.")
.build(),
ieee64: Builder::new_imm("imm", "ir::immediates::Ieee64")
.with_doc("A 64-bit immediate floating point number.")
.build(),
boolean: Builder::new_imm("imm", "bool")
.with_doc("An immediate boolean.")
.build(),
intcc: { intcc: {
let mut intcc_values = HashMap::new(); let mut intcc_values = HashMap::new();
intcc_values.insert("eq", "Equal"); intcc_values.insert("eq", "Equal");
@@ -126,9 +121,8 @@ impl Immediates {
intcc_values.insert("ult", "UnsignedLessThan"); intcc_values.insert("ult", "UnsignedLessThan");
intcc_values.insert("of", "Overflow"); intcc_values.insert("of", "Overflow");
intcc_values.insert("nof", "NotOverflow"); intcc_values.insert("nof", "NotOverflow");
Builder::new_enum("cond", "ir::condcodes::IntCC", intcc_values) new_enum("cond", "ir::condcodes::IntCC", intcc_values)
.with_doc("An integer comparison condition code.") .with_doc("An integer comparison condition code.")
.build()
}, },
floatcc: { floatcc: {
@@ -147,28 +141,20 @@ impl Immediates {
floatcc_values.insert("ule", "UnorderedOrLessThanOrEqual"); floatcc_values.insert("ule", "UnorderedOrLessThanOrEqual");
floatcc_values.insert("ugt", "UnorderedOrGreaterThan"); floatcc_values.insert("ugt", "UnorderedOrGreaterThan");
floatcc_values.insert("uge", "UnorderedOrGreaterThanOrEqual"); floatcc_values.insert("uge", "UnorderedOrGreaterThanOrEqual");
Builder::new_enum("cond", "ir::condcodes::FloatCC", floatcc_values) new_enum("cond", "ir::condcodes::FloatCC", floatcc_values)
.with_doc("A floating point comparison condition code") .with_doc("A floating point comparison condition code")
.build()
}, },
memflags: Builder::new_imm("flags", "ir::MemFlags") memflags: new_imm("flags", "ir::MemFlags").with_doc("Memory operation flags"),
.with_doc("Memory operation flags") regunit: new_imm("regunit", "isa::RegUnit")
.build(), .with_doc("A register unit in the target ISA"),
regunit: Builder::new_imm("regunit", "isa::RegUnit")
.with_doc("A register unit in the target ISA")
.build(),
trapcode: { trapcode: {
let mut trapcode_values = HashMap::new(); let mut trapcode_values = HashMap::new();
trapcode_values.insert("stk_ovf", "StackOverflow"); trapcode_values.insert("stk_ovf", "StackOverflow");
trapcode_values.insert("heap_oob", "HeapOutOfBounds"); trapcode_values.insert("heap_oob", "HeapOutOfBounds");
trapcode_values.insert("int_ovf", "IntegerOverflow"); trapcode_values.insert("int_ovf", "IntegerOverflow");
trapcode_values.insert("int_divz", "IntegerDivisionByZero"); trapcode_values.insert("int_divz", "IntegerDivisionByZero");
Builder::new_enum("code", "ir::TrapCode", trapcode_values) new_enum("code", "ir::TrapCode", trapcode_values).with_doc("A trap reason code.")
.with_doc("A trap reason code.")
.build()
}, },
} }
} }