From d8b840d2f5ea565dbf378faf938e6886dfef2466 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Tue, 29 Oct 2019 16:57:11 +0100 Subject: [PATCH] [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. --- cranelift/codegen/meta/src/cdsl/formats.rs | 1 + .../codegen/meta/src/cdsl/instructions.rs | 4 +- cranelift/codegen/meta/src/cdsl/operands.rs | 77 ++++------------ cranelift/codegen/meta/src/shared/entities.rs | 40 ++++----- .../codegen/meta/src/shared/immediates.rs | 90 ++++++++----------- 5 files changed, 78 insertions(+), 134 deletions(-) diff --git a/cranelift/codegen/meta/src/cdsl/formats.rs b/cranelift/codegen/meta/src/cdsl/formats.rs index 0978d61faf..e713a8bccb 100644 --- a/cranelift/codegen/meta/src/cdsl/formats.rs +++ b/cranelift/codegen/meta/src/cdsl/formats.rs @@ -49,6 +49,7 @@ pub(crate) struct InstructionFormat { pub(crate) struct FormatStructure { pub num_value_operands: usize, 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)>, } diff --git a/cranelift/codegen/meta/src/cdsl/instructions.rs b/cranelift/codegen/meta/src/cdsl/instructions.rs index 6b21bfaf10..86ef1e2a8a 100644 --- a/cranelift/codegen/meta/src/cdsl/instructions.rs +++ b/cranelift/codegen/meta/src/cdsl/instructions.rs @@ -1296,7 +1296,7 @@ impl Into for BoundInstruction { mod test { use super::*; use crate::cdsl::formats::InstructionFormatBuilder; - use crate::cdsl::operands::{OperandKindBuilder, OperandKindFields}; + use crate::cdsl::operands::{OperandKind, OperandKindFields}; use crate::cdsl::typevar::TypeSetBuilder; use crate::shared::types::Int::{I32, I64}; @@ -1304,7 +1304,7 @@ mod test { // Pretend the index string is &'static. let name = Box::leak(index.to_string().into_boxed_str()); // 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); operand } diff --git a/cranelift/codegen/meta/src/cdsl/operands.rs b/cranelift/codegen/meta/src/cdsl/operands.rs index d4c1a334c7..605df24862 100644 --- a/cranelift/codegen/meta/src/cdsl/operands.rs +++ b/cranelift/codegen/meta/src/cdsl/operands.rs @@ -100,7 +100,7 @@ impl Operand { } } -type EnumValues = HashMap<&'static str, &'static str>; +pub type EnumValues = HashMap<&'static str, &'static str>; #[derive(Clone, Debug)] pub(crate) enum OperandKindFields { @@ -126,6 +126,23 @@ pub(crate) struct 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> { if let Some(doc) = &self.doc { return Some(doc); @@ -142,12 +159,11 @@ impl OperandKind { impl Into for &TypeVar { fn into(self) -> OperandKind { - OperandKindBuilder::new( + OperandKind::new( "value", "ir::Value", OperandKindFields::TypeVar(self.into()), ) - .build() } } impl Into for &OperandKind { @@ -155,58 +171,3 @@ impl Into for &OperandKind { 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, - } - } -} diff --git a/cranelift/codegen/meta/src/shared/entities.rs b/cranelift/codegen/meta/src/shared/entities.rs index d4c6d6bfd7..068987c344 100644 --- a/cranelift/codegen/meta/src/shared/entities.rs +++ b/cranelift/codegen/meta/src/shared/entities.rs @@ -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 { /// A reference to an extended basic block in the same function. @@ -35,43 +40,34 @@ pub(crate) struct EntityRefs { impl EntityRefs { pub fn new() -> Self { Self { - ebb: create( + ebb: new( "destination", "ir::Ebb", "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: Builder::new("", "&[Value]", OperandKindFields::VariableArgs) - .with_doc( - r#" + varargs: OperandKind::new("", "&[Value]", OperandKindFields::VariableArgs).with_doc( + r#" A variable size list of `value` operands. Use this to represent arguments passed to a function call, arguments passed to an extended basic block, or a variable number of results 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) -} diff --git a/cranelift/codegen/meta/src/shared/immediates.rs b/cranelift/codegen/meta/src/shared/immediates.rs index 71e24beed8..d8382e4067 100644 --- a/cranelift/codegen/meta/src/shared/immediates.rs +++ b/cranelift/codegen/meta/src/shared/immediates.rs @@ -1,4 +1,4 @@ -use crate::cdsl::operands::{OperandKind, OperandKindBuilder as Builder}; +use crate::cdsl::operands::{EnumValues, OperandKind, OperandKindFields}; use std::collections::HashMap; @@ -73,45 +73,40 @@ pub(crate) struct Immediates { 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 { pub fn new() -> Self { Self { - imm64: Builder::new_imm("imm", "ir::immediates::Imm64") - .with_doc("A 64-bit immediate integer.") - .build(), - - uimm8: Builder::new_imm("imm", "ir::immediates::Uimm8") - .with_doc("An 8-bit immediate unsigned integer.") - .build(), - - uimm32: Builder::new_imm("imm", "ir::immediates::Uimm32") - .with_doc("A 32-bit immediate unsigned integer.") - .build(), - - uimm128: Builder::new_imm("imm", "ir::Immediate") - .with_doc("A 128-bit immediate unsigned integer.") - .build(), - - 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(), - + imm64: new_imm("imm", "ir::immediates::Imm64").with_doc("A 64-bit immediate integer."), + uimm8: new_imm("imm", "ir::immediates::Uimm8") + .with_doc("An 8-bit immediate unsigned integer."), + uimm32: new_imm("imm", "ir::immediates::Uimm32") + .with_doc("A 32-bit immediate unsigned integer."), + uimm128: new_imm("imm", "ir::Immediate") + .with_doc("A 128-bit immediate unsigned integer."), + pool_constant: new_imm("constant_handle", "ir::Constant") + .with_doc("A constant stored in the constant pool."), + offset32: new_imm("offset", "ir::immediates::Offset32") + .with_doc("A 32-bit immediate signed offset."), + ieee32: new_imm("imm", "ir::immediates::Ieee32") + .with_doc("A 32-bit immediate floating point number."), + ieee64: new_imm("imm", "ir::immediates::Ieee64") + .with_doc("A 64-bit immediate floating point number."), + boolean: new_imm("imm", "bool").with_doc("An immediate boolean."), intcc: { let mut intcc_values = HashMap::new(); intcc_values.insert("eq", "Equal"); @@ -126,9 +121,8 @@ impl Immediates { intcc_values.insert("ult", "UnsignedLessThan"); intcc_values.insert("of", "Overflow"); 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.") - .build() }, floatcc: { @@ -147,28 +141,20 @@ impl Immediates { floatcc_values.insert("ule", "UnorderedOrLessThanOrEqual"); floatcc_values.insert("ugt", "UnorderedOrGreaterThan"); 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") - .build() }, - memflags: Builder::new_imm("flags", "ir::MemFlags") - .with_doc("Memory operation flags") - .build(), - - regunit: Builder::new_imm("regunit", "isa::RegUnit") - .with_doc("A register unit in the target ISA") - .build(), - + memflags: new_imm("flags", "ir::MemFlags").with_doc("Memory operation flags"), + regunit: new_imm("regunit", "isa::RegUnit") + .with_doc("A register unit in the target ISA"), trapcode: { let mut trapcode_values = HashMap::new(); trapcode_values.insert("stk_ovf", "StackOverflow"); trapcode_values.insert("heap_oob", "HeapOutOfBounds"); trapcode_values.insert("int_ovf", "IntegerOverflow"); trapcode_values.insert("int_divz", "IntegerDivisionByZero"); - Builder::new_enum("code", "ir::TrapCode", trapcode_values) - .with_doc("A trap reason code.") - .build() + new_enum("code", "ir::TrapCode", trapcode_values).with_doc("A trap reason code.") }, } }