From b6e64324e3484526c0856290c38f044713582b3b Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 21:47:57 +0900 Subject: [PATCH 01/20] Refactor --- macro/src/dialect.rs | 2 +- macro/src/dialect/operation.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/macro/src/dialect.rs b/macro/src/dialect.rs index ad24b8d49a..31bffe6d67 100644 --- a/macro/src/dialect.rs +++ b/macro/src/dialect.rs @@ -56,7 +56,7 @@ fn generate_dialect_module( ) -> Result { let operations = record_keeper .all_derived_definitions("Op") - .map(Operation::from_def) + .map(Operation::from_definition) .collect::, _>>()? .into_iter() .filter(|operation| operation.dialect.name() == dialect.name()) diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 2b6ce9073c..a173100ca4 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -521,7 +521,7 @@ impl<'a> Operation<'a> { .collect() } - pub fn from_def(def: Record<'a>) -> Result { + pub fn from_definition(def: Record<'a>) -> Result { let dialect = def.def_value("opDialect")?; let traits = Self::collect_traits(def)?; let has_trait = |name: &str| traits.iter().any(|r#trait| r#trait.has_name(name)); From 39dfa356b3dc0d22220adf48dafbe872ad89aff2 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 21:49:21 +0900 Subject: [PATCH 02/20] Rename --- macro/src/dialect/operation.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index a173100ca4..67574a7436 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -521,20 +521,20 @@ impl<'a> Operation<'a> { .collect() } - pub fn from_definition(def: Record<'a>) -> Result { - let dialect = def.def_value("opDialect")?; - let traits = Self::collect_traits(def)?; + pub fn from_definition(definition: Record<'a>) -> Result { + let dialect = definition.def_value("opDialect")?; + let traits = Self::collect_traits(definition)?; let has_trait = |name: &str| traits.iter().any(|r#trait| r#trait.has_name(name)); - let arguments = Self::dag_constraints(def, "arguments")?; - let regions = Self::collect_regions(def)?; + let arguments = Self::dag_constraints(definition, "arguments")?; + let regions = Self::collect_regions(definition)?; let (results, num_variable_length_results) = Self::collect_results( - def, + definition, has_trait("::mlir::OpTrait::SameVariadicResultSize"), has_trait("::mlir::OpTrait::AttrSizedResultSegments"), )?; - let name = def.name()?; + let name = definition.name()?; let class_name = if name.starts_with('_') { name } else if let Some(name) = name.split('_').nth(1) { @@ -543,7 +543,7 @@ impl<'a> Operation<'a> { } else { name }; - let short_name = def.str_value("opName")?; + let short_name = definition.str_value("opName")?; Ok(Self { dialect, @@ -558,7 +558,7 @@ impl<'a> Operation<'a> { } }, class_name, - successors: Self::collect_successors(def)?, + successors: Self::collect_successors(definition)?, operands: Self::collect_operands( &arguments, has_trait("::mlir::OpTrait::SameVariadicOperandSize"), @@ -566,7 +566,7 @@ impl<'a> Operation<'a> { )?, results, attributes: Self::collect_attributes(&arguments)?, - derived_attributes: Self::collect_derived_attributes(def)?, + derived_attributes: Self::collect_derived_attributes(definition)?, can_infer_type: traits.iter().any(|r#trait| { (r#trait.has_name("::mlir::OpTrait::FirstAttrDerivedResultType") || r#trait.has_name("::mlir::OpTrait::SameOperandsAndResultType")) @@ -574,7 +574,7 @@ impl<'a> Operation<'a> { || r#trait.has_name("::mlir::InferTypeOpInterface::Trait") && regions.is_empty() }), summary: { - let summary = def.str_value("summary")?; + let summary = definition.str_value("summary")?; if summary.is_empty() { format!("[`{short_name}`]({class_name}) operation") @@ -585,7 +585,7 @@ impl<'a> Operation<'a> { ) } }, - description: unindent::unindent(def.str_value("description")?), + description: unindent::unindent(definition.str_value("description")?), regions, }) } From 1623cc0088e04b7b1bb706d54ca1d12908aaf01c Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 21:52:27 +0900 Subject: [PATCH 03/20] Fix quoting --- macro/src/dialect/operation.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 67574a7436..73affdbf61 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -577,10 +577,10 @@ impl<'a> Operation<'a> { let summary = definition.str_value("summary")?; if summary.is_empty() { - format!("[`{short_name}`]({class_name}) operation") + format!("[`{short_name}`]({class_name}) operation.") } else { format!( - "[`{short_name}`]({class_name}) operation: {}", + "[`{short_name}`]({class_name}) operation. {}.", summary[0..1].to_uppercase() + &summary[1..] ) } From 904fd470e29ad88de36f79fe6bdc31db0d3aaa55 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 21:55:03 +0900 Subject: [PATCH 04/20] Refactor --- macro/src/dialect/operation.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 73affdbf61..ec96804430 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -576,14 +576,15 @@ impl<'a> Operation<'a> { summary: { let summary = definition.str_value("summary")?; - if summary.is_empty() { - format!("[`{short_name}`]({class_name}) operation.") - } else { - format!( - "[`{short_name}`]({class_name}) operation. {}.", - summary[0..1].to_uppercase() + &summary[1..] - ) - } + [ + format!("[`{short_name}`]({class_name}) operation."), + if summary.is_empty() { + Default::default() + } else { + summary[0..1].to_uppercase() + &summary[1..] + "." + }, + ] + .join(" ") }, description: unindent::unindent(definition.str_value("description")?), regions, From 115a3274fe48a357cd2b3d6f94256e9c4993895d Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 21:56:54 +0900 Subject: [PATCH 05/20] Refactor --- macro/src/dialect.rs | 4 +--- macro/src/dialect/operation.rs | 2 +- macro/src/dialect/utility.rs | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/macro/src/dialect.rs b/macro/src/dialect.rs index 31bffe6d67..61c1bae059 100644 --- a/macro/src/dialect.rs +++ b/macro/src/dialect.rs @@ -64,9 +64,7 @@ fn generate_dialect_module( let doc = format!( "`{name}` dialect.\n\n{}", - sanitize_documentation(&unindent::unindent( - dialect.str_value("description").unwrap_or(""), - ))? + sanitize_documentation(dialect.str_value("description").unwrap_or(""),)? ); let name = sanitize_snake_case_name(name)?; diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index ec96804430..f0ade14124 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -586,7 +586,7 @@ impl<'a> Operation<'a> { ] .join(" ") }, - description: unindent::unindent(definition.str_value("description")?), + description: sanitize_documentation(definition.str_value("description")?)?, regions, }) } diff --git a/macro/src/dialect/utility.rs b/macro/src/dialect/utility.rs index bc43fae820..a13cf22235 100644 --- a/macro/src/dialect/utility.rs +++ b/macro/src/dialect/utility.rs @@ -32,7 +32,7 @@ fn sanitize_name(name: &str) -> Result { pub fn sanitize_documentation(string: &str) -> Result { let arena = Arena::new(); - let node = parse_document(&arena, string, &Default::default()); + let node = parse_document(&arena, &unindent::unindent(string), &Default::default()); for node in node.traverse() { let NodeEdge::Start(node) = node else { From 8732b7be5b78372aa251014109318230343cfc74 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 21:58:15 +0900 Subject: [PATCH 06/20] Refactor --- macro/src/dialect/operation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index f0ade14124..d514b552e1 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -524,7 +524,7 @@ impl<'a> Operation<'a> { pub fn from_definition(definition: Record<'a>) -> Result { let dialect = definition.def_value("opDialect")?; let traits = Self::collect_traits(definition)?; - let has_trait = |name: &str| traits.iter().any(|r#trait| r#trait.has_name(name)); + let has_trait = |name| traits.iter().any(|r#trait| r#trait.has_name(name)); let arguments = Self::dag_constraints(definition, "arguments")?; let regions = Self::collect_regions(definition)?; From 5834d8aa7d7ebf86a12b4d1919243da423281f0a Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 22:00:36 +0900 Subject: [PATCH 07/20] Refactor --- macro/src/dialect.rs | 2 +- macro/src/dialect/operation.rs | 21 ++++++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/macro/src/dialect.rs b/macro/src/dialect.rs index 61c1bae059..21571b43c8 100644 --- a/macro/src/dialect.rs +++ b/macro/src/dialect.rs @@ -59,7 +59,7 @@ fn generate_dialect_module( .map(Operation::from_definition) .collect::, _>>()? .into_iter() - .filter(|operation| operation.dialect.name() == dialect.name()) + .filter(|operation| operation.dialect_name() == dialect.name()) .collect::>(); let doc = format!( diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index d514b552e1..9b1c6f0303 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -10,7 +10,10 @@ use crate::dialect::{ use proc_macro2::{Ident, TokenStream}; use quote::{format_ident, quote, ToTokens, TokenStreamExt}; use syn::{parse_quote, Type}; -use tblgen::{error::WithLocation, record::Record}; +use tblgen::{ + error::{SourceError, TableGenError, WithLocation}, + record::Record, +}; #[derive(Debug, Clone, Copy)] pub enum ElementKind { @@ -291,12 +294,12 @@ impl<'a> OperationField<'a> { #[derive(Debug, Clone)] pub struct Operation<'a> { - pub(crate) dialect: Record<'a>, - pub(crate) short_name: &'a str, - pub(crate) full_name: String, - pub(crate) class_name: &'a str, - pub(crate) summary: String, - pub(crate) can_infer_type: bool, + dialect: Record<'a>, + short_name: &'a str, + full_name: String, + class_name: &'a str, + summary: String, + can_infer_type: bool, description: String, regions: Vec>, successors: Vec>, @@ -307,6 +310,10 @@ pub struct Operation<'a> { } impl<'a> Operation<'a> { + pub fn dialect_name(&self) -> Result<&str, SourceError> { + self.dialect.name() + } + pub fn fields(&self) -> impl Iterator> + Clone { self.results .iter() From 10e534f3e78654e53dfea56793d9a20c5ba0f391 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 22:18:29 +0900 Subject: [PATCH 08/20] Fix --- macro/src/dialect.rs | 3 +- macro/src/dialect/operation.rs | 265 +----------------- macro/src/dialect/operation/element_kind.rs | 14 + macro/src/dialect/operation/field_kind.rs | 163 +++++++++++ .../src/dialect/operation/operation_field.rs | 77 +++++ 5 files changed, 270 insertions(+), 252 deletions(-) create mode 100644 macro/src/dialect/operation/element_kind.rs create mode 100644 macro/src/dialect/operation/field_kind.rs create mode 100644 macro/src/dialect/operation/operation_field.rs diff --git a/macro/src/dialect.rs b/macro/src/dialect.rs index 21571b43c8..5f5c7e83bb 100644 --- a/macro/src/dialect.rs +++ b/macro/src/dialect.rs @@ -54,12 +54,13 @@ fn generate_dialect_module( dialect: Record, record_keeper: &RecordKeeper, ) -> Result { + let dialect_name = dialect.name()?; let operations = record_keeper .all_derived_definitions("Op") .map(Operation::from_definition) .collect::, _>>()? .into_iter() - .filter(|operation| operation.dialect_name() == dialect.name()) + .filter(|operation| operation.dialect_name() == dialect_name) .collect::>(); let doc = format!( diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 9b1c6f0303..e3958ce5e3 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -1,190 +1,20 @@ mod accessors; mod builder; - -use self::builder::OperationBuilder; -use super::utility::{sanitize_documentation, sanitize_snake_case_name}; +mod element_kind; +mod field_kind; +mod operation_field; + +use self::element_kind::ElementKind; +use self::operation_field::OperationField; +use self::{builder::OperationBuilder, field_kind::FieldKind}; +use super::utility::sanitize_documentation; use crate::dialect::{ error::{Error, OdsError}, types::{AttributeConstraint, RegionConstraint, SuccessorConstraint, Trait, TypeConstraint}, }; -use proc_macro2::{Ident, TokenStream}; +use proc_macro2::TokenStream; use quote::{format_ident, quote, ToTokens, TokenStreamExt}; -use syn::{parse_quote, Type}; -use tblgen::{ - error::{SourceError, TableGenError, WithLocation}, - record::Record, -}; - -#[derive(Debug, Clone, Copy)] -pub enum ElementKind { - Operand, - Result, -} - -impl ElementKind { - pub fn as_str(&self) -> &'static str { - match self { - Self::Operand => "operand", - Self::Result => "result", - } - } -} - -#[derive(Debug, Clone)] -pub enum FieldKind<'a> { - Element { - kind: ElementKind, - constraint: TypeConstraint<'a>, - sequence_info: SequenceInfo, - variadic_kind: VariadicKind, - }, - Attribute { - constraint: AttributeConstraint<'a>, - }, - Successor { - constraint: SuccessorConstraint<'a>, - sequence_info: SequenceInfo, - }, - Region { - constraint: RegionConstraint<'a>, - sequence_info: SequenceInfo, - }, -} - -impl<'a> FieldKind<'a> { - pub fn as_str(&self) -> &'static str { - match self { - Self::Element { kind, .. } => kind.as_str(), - Self::Attribute { .. } => "attribute", - Self::Successor { .. } => "successor", - Self::Region { .. } => "region", - } - } - - pub fn is_optional(&self) -> Result { - Ok(match self { - Self::Element { constraint, .. } => constraint.is_optional(), - Self::Attribute { constraint, .. } => { - constraint.is_optional()? || constraint.has_default_value()? - } - Self::Successor { .. } | Self::Region { .. } => false, - }) - } - - pub fn is_result(&self) -> bool { - matches!( - self, - Self::Element { - kind: ElementKind::Result, - .. - } - ) - } - - pub fn parameter_type(&self) -> Result { - Ok(match self { - Self::Element { - kind, constraint, .. - } => { - let base_type: Type = match kind { - ElementKind::Operand => { - parse_quote!(::melior::ir::Value<'c, '_>) - } - ElementKind::Result => { - parse_quote!(::melior::ir::Type<'c>) - } - }; - if constraint.is_variadic() { - parse_quote! { &[#base_type] } - } else { - base_type - } - } - Self::Attribute { constraint } => { - if constraint.is_unit()? { - parse_quote!(bool) - } else { - let r#type: Type = syn::parse_str(constraint.storage_type()?)?; - parse_quote!(#r#type<'c>) - } - } - Self::Successor { constraint, .. } => { - let r#type: Type = parse_quote!(&::melior::ir::Block<'c>); - if constraint.is_variadic() { - parse_quote!(&[#r#type]) - } else { - r#type - } - } - Self::Region { constraint, .. } => { - let r#type: Type = parse_quote!(::melior::ir::Region<'c>); - if constraint.is_variadic() { - parse_quote!(Vec<#r#type>) - } else { - r#type - } - } - }) - } - - fn create_result_type(r#type: Type) -> Type { - parse_quote!(Result<#r#type, ::melior::Error>) - } - - fn create_iterator_type(r#type: Type) -> Type { - parse_quote!(impl Iterator) - } - - pub fn return_type(&self) -> Result { - Ok(match self { - Self::Element { - kind, - constraint, - variadic_kind, - .. - } => { - let base_type: Type = match kind { - ElementKind::Operand => { - parse_quote!(::melior::ir::Value<'c, '_>) - } - ElementKind::Result => { - parse_quote!(::melior::ir::operation::OperationResult<'c, '_>) - } - }; - if !constraint.is_variadic() { - Self::create_result_type(base_type) - } else if let VariadicKind::AttrSized {} = variadic_kind { - Self::create_result_type(Self::create_iterator_type(base_type)) - } else { - Self::create_iterator_type(base_type) - } - } - Self::Attribute { constraint } => { - if constraint.is_unit()? { - parse_quote!(bool) - } else { - Self::create_result_type(self.parameter_type()?) - } - } - Self::Successor { constraint, .. } => { - let r#type: Type = parse_quote!(::melior::ir::BlockRef<'c, '_>); - if constraint.is_variadic() { - Self::create_iterator_type(r#type) - } else { - Self::create_result_type(r#type) - } - } - Self::Region { constraint, .. } => { - let r#type: Type = parse_quote!(::melior::ir::RegionRef<'c, '_>); - if constraint.is_variadic() { - Self::create_iterator_type(r#type) - } else { - Self::create_result_type(r#type) - } - } - }) - } -} +use tblgen::{error::WithLocation, record::Record}; #[derive(Debug, Clone)] pub struct SequenceInfo { @@ -225,76 +55,9 @@ impl VariadicKind { } } -#[derive(Debug, Clone)] -pub struct OperationField<'a> { - pub(crate) name: &'a str, - pub(crate) sanitized_name: Ident, - pub(crate) kind: FieldKind<'a>, -} - -impl<'a> OperationField<'a> { - fn new(name: &'a str, kind: FieldKind<'a>) -> Result { - Ok(Self { - name, - sanitized_name: sanitize_snake_case_name(name)?, - kind, - }) - } - - fn new_attribute(name: &'a str, constraint: AttributeConstraint<'a>) -> Result { - Self::new(name, FieldKind::Attribute { constraint }) - } - - fn new_region( - name: &'a str, - constraint: RegionConstraint<'a>, - sequence_info: SequenceInfo, - ) -> Result { - Self::new( - name, - FieldKind::Region { - constraint, - sequence_info, - }, - ) - } - - fn new_successor( - name: &'a str, - constraint: SuccessorConstraint<'a>, - sequence_info: SequenceInfo, - ) -> Result { - Self::new( - name, - FieldKind::Successor { - constraint, - sequence_info, - }, - ) - } - - fn new_element( - name: &'a str, - constraint: TypeConstraint<'a>, - kind: ElementKind, - sequence_info: SequenceInfo, - variadic_kind: VariadicKind, - ) -> Result { - Self::new( - name, - FieldKind::Element { - kind, - constraint, - sequence_info, - variadic_kind, - }, - ) - } -} - #[derive(Debug, Clone)] pub struct Operation<'a> { - dialect: Record<'a>, + dialect_name: &'a str, short_name: &'a str, full_name: String, class_name: &'a str, @@ -310,8 +73,8 @@ pub struct Operation<'a> { } impl<'a> Operation<'a> { - pub fn dialect_name(&self) -> Result<&str, SourceError> { - self.dialect.name() + pub fn dialect_name(&self) -> &str { + &self.dialect_name } pub fn fields(&self) -> impl Iterator> + Clone { @@ -553,7 +316,7 @@ impl<'a> Operation<'a> { let short_name = definition.str_value("opName")?; Ok(Self { - dialect, + dialect_name: dialect.name()?.into(), short_name, full_name: { let dialect_name = dialect.string_value("name")?; diff --git a/macro/src/dialect/operation/element_kind.rs b/macro/src/dialect/operation/element_kind.rs new file mode 100644 index 0000000000..6f1de942ef --- /dev/null +++ b/macro/src/dialect/operation/element_kind.rs @@ -0,0 +1,14 @@ +#[derive(Debug, Clone, Copy)] +pub enum ElementKind { + Operand, + Result, +} + +impl ElementKind { + pub fn as_str(&self) -> &'static str { + match self { + Self::Operand => "operand", + Self::Result => "result", + } + } +} diff --git a/macro/src/dialect/operation/field_kind.rs b/macro/src/dialect/operation/field_kind.rs new file mode 100644 index 0000000000..39c8323b86 --- /dev/null +++ b/macro/src/dialect/operation/field_kind.rs @@ -0,0 +1,163 @@ +use super::{element_kind::ElementKind, SequenceInfo, VariadicKind}; +use crate::dialect::{ + error::Error, + types::{AttributeConstraint, RegionConstraint, SuccessorConstraint, TypeConstraint}, +}; +use syn::parse_quote; +use syn::Type; + +#[derive(Debug, Clone)] +pub enum FieldKind<'a> { + Element { + kind: ElementKind, + constraint: TypeConstraint<'a>, + sequence_info: SequenceInfo, + variadic_kind: VariadicKind, + }, + Attribute { + constraint: AttributeConstraint<'a>, + }, + Successor { + constraint: SuccessorConstraint<'a>, + sequence_info: SequenceInfo, + }, + Region { + constraint: RegionConstraint<'a>, + sequence_info: SequenceInfo, + }, +} + +impl<'a> FieldKind<'a> { + pub fn as_str(&self) -> &'static str { + match self { + Self::Element { kind, .. } => kind.as_str(), + Self::Attribute { .. } => "attribute", + Self::Successor { .. } => "successor", + Self::Region { .. } => "region", + } + } + + pub fn is_optional(&self) -> Result { + Ok(match self { + Self::Element { constraint, .. } => constraint.is_optional(), + Self::Attribute { constraint, .. } => { + constraint.is_optional()? || constraint.has_default_value()? + } + Self::Successor { .. } | Self::Region { .. } => false, + }) + } + + pub fn is_result(&self) -> bool { + matches!( + self, + Self::Element { + kind: ElementKind::Result, + .. + } + ) + } + + pub fn parameter_type(&self) -> Result { + Ok(match self { + Self::Element { + kind, constraint, .. + } => { + let base_type: Type = match kind { + ElementKind::Operand => { + parse_quote!(::melior::ir::Value<'c, '_>) + } + ElementKind::Result => { + parse_quote!(::melior::ir::Type<'c>) + } + }; + if constraint.is_variadic() { + parse_quote! { &[#base_type] } + } else { + base_type + } + } + Self::Attribute { constraint } => { + if constraint.is_unit()? { + parse_quote!(bool) + } else { + let r#type: Type = syn::parse_str(constraint.storage_type()?)?; + parse_quote!(#r#type<'c>) + } + } + Self::Successor { constraint, .. } => { + let r#type: Type = parse_quote!(&::melior::ir::Block<'c>); + if constraint.is_variadic() { + parse_quote!(&[#r#type]) + } else { + r#type + } + } + Self::Region { constraint, .. } => { + let r#type: Type = parse_quote!(::melior::ir::Region<'c>); + if constraint.is_variadic() { + parse_quote!(Vec<#r#type>) + } else { + r#type + } + } + }) + } + + fn create_result_type(r#type: Type) -> Type { + parse_quote!(Result<#r#type, ::melior::Error>) + } + + fn create_iterator_type(r#type: Type) -> Type { + parse_quote!(impl Iterator) + } + + pub fn return_type(&self) -> Result { + Ok(match self { + Self::Element { + kind, + constraint, + variadic_kind, + .. + } => { + let base_type: Type = match kind { + ElementKind::Operand => { + parse_quote!(::melior::ir::Value<'c, '_>) + } + ElementKind::Result => { + parse_quote!(::melior::ir::operation::OperationResult<'c, '_>) + } + }; + if !constraint.is_variadic() { + Self::create_result_type(base_type) + } else if let VariadicKind::AttrSized {} = variadic_kind { + Self::create_result_type(Self::create_iterator_type(base_type)) + } else { + Self::create_iterator_type(base_type) + } + } + Self::Attribute { constraint } => { + if constraint.is_unit()? { + parse_quote!(bool) + } else { + Self::create_result_type(self.parameter_type()?) + } + } + Self::Successor { constraint, .. } => { + let r#type: Type = parse_quote!(::melior::ir::BlockRef<'c, '_>); + if constraint.is_variadic() { + Self::create_iterator_type(r#type) + } else { + Self::create_result_type(r#type) + } + } + Self::Region { constraint, .. } => { + let r#type: Type = parse_quote!(::melior::ir::RegionRef<'c, '_>); + if constraint.is_variadic() { + Self::create_iterator_type(r#type) + } else { + Self::create_result_type(r#type) + } + } + }) + } +} diff --git a/macro/src/dialect/operation/operation_field.rs b/macro/src/dialect/operation/operation_field.rs new file mode 100644 index 0000000000..1977823b79 --- /dev/null +++ b/macro/src/dialect/operation/operation_field.rs @@ -0,0 +1,77 @@ +use super::{element_kind::ElementKind, field_kind::FieldKind, SequenceInfo, VariadicKind}; +use crate::dialect::{ + error::Error, + types::{AttributeConstraint, RegionConstraint, SuccessorConstraint, TypeConstraint}, + utility::sanitize_snake_case_name, +}; +use proc_macro2::Ident; + +#[derive(Debug, Clone)] +pub struct OperationField<'a> { + pub(crate) name: &'a str, + pub(crate) sanitized_name: Ident, + pub(crate) kind: FieldKind<'a>, +} + +impl<'a> OperationField<'a> { + fn new(name: &'a str, kind: FieldKind<'a>) -> Result { + Ok(Self { + name, + sanitized_name: sanitize_snake_case_name(name)?, + kind, + }) + } + + pub fn new_attribute( + name: &'a str, + constraint: AttributeConstraint<'a>, + ) -> Result { + Self::new(name, FieldKind::Attribute { constraint }) + } + + pub fn new_region( + name: &'a str, + constraint: RegionConstraint<'a>, + sequence_info: SequenceInfo, + ) -> Result { + Self::new( + name, + FieldKind::Region { + constraint, + sequence_info, + }, + ) + } + + pub fn new_successor( + name: &'a str, + constraint: SuccessorConstraint<'a>, + sequence_info: SequenceInfo, + ) -> Result { + Self::new( + name, + FieldKind::Successor { + constraint, + sequence_info, + }, + ) + } + + pub fn new_element( + name: &'a str, + constraint: TypeConstraint<'a>, + kind: ElementKind, + sequence_info: SequenceInfo, + variadic_kind: VariadicKind, + ) -> Result { + Self::new( + name, + FieldKind::Element { + kind, + constraint, + sequence_info, + variadic_kind, + }, + ) + } +} From a8c7d6781491ec5b041f13ec178976f53ddbb767 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 22:19:18 +0900 Subject: [PATCH 09/20] Refactor --- macro/src/dialect/operation.rs | 8 ++------ macro/src/dialect/operation/sequence_info.rs | 5 +++++ 2 files changed, 7 insertions(+), 6 deletions(-) create mode 100644 macro/src/dialect/operation/sequence_info.rs diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index e3958ce5e3..e15397b399 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -3,9 +3,11 @@ mod builder; mod element_kind; mod field_kind; mod operation_field; +mod sequence_info; use self::element_kind::ElementKind; use self::operation_field::OperationField; +use self::sequence_info::SequenceInfo; use self::{builder::OperationBuilder, field_kind::FieldKind}; use super::utility::sanitize_documentation; use crate::dialect::{ @@ -16,12 +18,6 @@ use proc_macro2::TokenStream; use quote::{format_ident, quote, ToTokens, TokenStreamExt}; use tblgen::{error::WithLocation, record::Record}; -#[derive(Debug, Clone)] -pub struct SequenceInfo { - index: usize, - len: usize, -} - #[derive(Clone, Debug)] pub enum VariadicKind { Simple { diff --git a/macro/src/dialect/operation/sequence_info.rs b/macro/src/dialect/operation/sequence_info.rs new file mode 100644 index 0000000000..1dd7f85553 --- /dev/null +++ b/macro/src/dialect/operation/sequence_info.rs @@ -0,0 +1,5 @@ +#[derive(Debug, Clone)] +pub struct SequenceInfo { + pub index: usize, + pub len: usize, +} From 75ef57091e92621a0546573d3ff0eab34b963817 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 22:22:32 +0900 Subject: [PATCH 10/20] Refactor --- macro/src/dialect/operation.rs | 46 ++++++++++++------------ macro/src/dialect/operation/accessors.rs | 12 +++---- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index e15397b399..4480c6f7fe 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -24,24 +24,24 @@ pub enum VariadicKind { seen_variable_length: bool, }, SameSize { - num_variable_length: usize, - num_preceding_simple: usize, - num_preceding_variadic: usize, + variable_length_count: usize, + preceding_simple_count: usize, + preceding_variadic_count: usize, }, AttrSized {}, } impl VariadicKind { - pub fn new(num_variable_length: usize, same_size: bool, attr_sized: bool) -> Self { - if num_variable_length <= 1 { + pub fn new(variable_length_count: usize, same_size: bool, attr_sized: bool) -> Self { + if variable_length_count <= 1 { VariadicKind::Simple { seen_variable_length: false, } } else if same_size { VariadicKind::SameSize { - num_variable_length, - num_preceding_simple: 0, - num_preceding_variadic: 0, + variable_length_count, + preceding_simple_count: 0, + preceding_variadic_count: 0, } } else if attr_sized { VariadicKind::AttrSized {} @@ -83,8 +83,8 @@ impl<'a> Operation<'a> { .chain(self.derived_attributes.iter()) } - fn collect_successors(def: Record<'a>) -> Result, Error> { - let successors_dag = def.dag_value("successors")?; + fn collect_successors(definition: Record<'a>) -> Result, Error> { + let successors_dag = definition.dag_value("successors")?; let len = successors_dag.num_args(); successors_dag .args() @@ -95,7 +95,7 @@ impl<'a> Operation<'a> { SuccessorConstraint::new( value .try_into() - .map_err(|error: tblgen::Error| error.set_location(def))?, + .map_err(|error: tblgen::Error| error.set_location(definition))?, ), SequenceInfo { index, len }, ) @@ -103,8 +103,8 @@ impl<'a> Operation<'a> { .collect() } - fn collect_regions(def: Record<'a>) -> Result, Error> { - let regions_dag = def.dag_value("regions")?; + fn collect_regions(definition: Record<'a>) -> Result, Error> { + let regions_dag = definition.dag_value("regions")?; let len = regions_dag.num_args(); regions_dag .args() @@ -115,7 +115,7 @@ impl<'a> Operation<'a> { RegionConstraint::new( value .try_into() - .map_err(|error: tblgen::Error| error.set_location(def))?, + .map_err(|error: tblgen::Error| error.set_location(definition))?, ), SequenceInfo { index, len }, ) @@ -207,11 +207,11 @@ impl<'a> Operation<'a> { same_size: bool, attr_sized: bool, ) -> Result<(Vec>, usize), Error> { - let num_variable_length = elements + let variable_length_count = elements .iter() .filter(|(_, constraint)| constraint.has_variable_length()) .count(); - let mut variadic_kind = VariadicKind::new(num_variable_length, same_size, attr_sized); + let mut variadic_kind = VariadicKind::new(variable_length_count, same_size, attr_sized); let mut fields = vec![]; for (index, (name, constraint)) in elements.iter().enumerate() { @@ -235,21 +235,21 @@ impl<'a> Operation<'a> { } } VariadicKind::SameSize { - num_preceding_simple, - num_preceding_variadic, + preceding_simple_count, + preceding_variadic_count, .. } => { if constraint.has_variable_length() { - *num_preceding_variadic += 1; + *preceding_variadic_count += 1; } else { - *num_preceding_simple += 1; + *preceding_simple_count += 1; } } VariadicKind::AttrSized {} => {} } } - Ok((fields, num_variable_length)) + Ok((fields, variable_length_count)) } fn collect_attributes( @@ -294,7 +294,7 @@ impl<'a> Operation<'a> { let arguments = Self::dag_constraints(definition, "arguments")?; let regions = Self::collect_regions(definition)?; - let (results, num_variable_length_results) = Self::collect_results( + let (results, variable_length_results_count) = Self::collect_results( definition, has_trait("::mlir::OpTrait::SameVariadicResultSize"), has_trait("::mlir::OpTrait::AttrSizedResultSegments"), @@ -336,7 +336,7 @@ impl<'a> Operation<'a> { can_infer_type: traits.iter().any(|r#trait| { (r#trait.has_name("::mlir::OpTrait::FirstAttrDerivedResultType") || r#trait.has_name("::mlir::OpTrait::SameOperandsAndResultType")) - && num_variable_length_results == 0 + && variable_length_results_count == 0 || r#trait.has_name("::mlir::InferTypeOpInterface::Trait") && regions.is_empty() }), summary: { diff --git a/macro/src/dialect/operation/accessors.rs b/macro/src/dialect/operation/accessors.rs index b2f87ff374..90ef4c65dc 100644 --- a/macro/src/dialect/operation/accessors.rs +++ b/macro/src/dialect/operation/accessors.rs @@ -62,14 +62,14 @@ impl<'a> OperationField<'a> { } } VariadicKind::SameSize { - num_variable_length, - num_preceding_simple, - num_preceding_variadic, + variable_length_count, + preceding_simple_count, + preceding_variadic_count, } => { let compute_start_length = quote! { - let total_var_len = self.operation.#count() - #num_variable_length + 1; - let group_len = total_var_len / #num_variable_length; - let start = #num_preceding_simple + #num_preceding_variadic * group_len; + let total_var_len = self.operation.#count() - #variable_length_count + 1; + let group_len = total_var_len / #variable_length_count; + let start = #preceding_simple_count + #preceding_variadic_count * group_len; }; let get_elements = if constraint.has_variable_length() { quote! { From 9c7ca5c221d6ce2ca890614f8d7c6636369c623c Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 22:23:33 +0900 Subject: [PATCH 11/20] Add todo --- macro/src/dialect/operation.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 4480c6f7fe..d7c68b9c04 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -359,6 +359,7 @@ impl<'a> Operation<'a> { } impl<'a> ToTokens for Operation<'a> { + // TODO Compile values for proper error handling and remove `Result::expect()`. fn to_tokens(&self, tokens: &mut TokenStream) { let class_name = format_ident!("{}", &self.class_name); let name = &self.full_name; From 984c7221b53c34745ef14cf5cf46fb41352407c9 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 22:25:16 +0900 Subject: [PATCH 12/20] Refactor --- macro/src/dialect/operation.rs | 35 ++------------------ macro/src/dialect/operation/variadic_kind.rs | 32 ++++++++++++++++++ 2 files changed, 34 insertions(+), 33 deletions(-) create mode 100644 macro/src/dialect/operation/variadic_kind.rs diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index d7c68b9c04..a7e948d7b6 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -4,10 +4,12 @@ mod element_kind; mod field_kind; mod operation_field; mod sequence_info; +mod variadic_kind; use self::element_kind::ElementKind; use self::operation_field::OperationField; use self::sequence_info::SequenceInfo; +use self::variadic_kind::VariadicKind; use self::{builder::OperationBuilder, field_kind::FieldKind}; use super::utility::sanitize_documentation; use crate::dialect::{ @@ -19,39 +21,6 @@ use quote::{format_ident, quote, ToTokens, TokenStreamExt}; use tblgen::{error::WithLocation, record::Record}; #[derive(Clone, Debug)] -pub enum VariadicKind { - Simple { - seen_variable_length: bool, - }, - SameSize { - variable_length_count: usize, - preceding_simple_count: usize, - preceding_variadic_count: usize, - }, - AttrSized {}, -} - -impl VariadicKind { - pub fn new(variable_length_count: usize, same_size: bool, attr_sized: bool) -> Self { - if variable_length_count <= 1 { - VariadicKind::Simple { - seen_variable_length: false, - } - } else if same_size { - VariadicKind::SameSize { - variable_length_count, - preceding_simple_count: 0, - preceding_variadic_count: 0, - } - } else if attr_sized { - VariadicKind::AttrSized {} - } else { - unimplemented!() - } - } -} - -#[derive(Debug, Clone)] pub struct Operation<'a> { dialect_name: &'a str, short_name: &'a str, diff --git a/macro/src/dialect/operation/variadic_kind.rs b/macro/src/dialect/operation/variadic_kind.rs new file mode 100644 index 0000000000..4d5a5aa995 --- /dev/null +++ b/macro/src/dialect/operation/variadic_kind.rs @@ -0,0 +1,32 @@ +#[derive(Clone, Debug)] +pub enum VariadicKind { + Simple { + seen_variable_length: bool, + }, + SameSize { + variable_length_count: usize, + preceding_simple_count: usize, + preceding_variadic_count: usize, + }, + AttrSized {}, +} + +impl VariadicKind { + pub fn new(variable_length_count: usize, same_size: bool, attr_sized: bool) -> Self { + if variable_length_count <= 1 { + VariadicKind::Simple { + seen_variable_length: false, + } + } else if same_size { + VariadicKind::SameSize { + variable_length_count, + preceding_simple_count: 0, + preceding_variadic_count: 0, + } + } else if attr_sized { + VariadicKind::AttrSized {} + } else { + unimplemented!() + } + } +} From 08ea7002c9fb2d9f0755a1d3134d86f1ef6738dc Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 22:26:42 +0900 Subject: [PATCH 13/20] Refactor --- macro/src/dialect/operation.rs | 2 +- macro/src/dialect/operation/accessors.rs | 2 +- macro/src/dialect/operation/variadic_kind.rs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index a7e948d7b6..f731652f22 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -197,7 +197,7 @@ impl<'a> Operation<'a> { match &mut variadic_kind { VariadicKind::Simple { - seen_variable_length, + variable_length_seen: seen_variable_length, } => { if constraint.has_variable_length() { *seen_variable_length = true; diff --git a/macro/src/dialect/operation/accessors.rs b/macro/src/dialect/operation/accessors.rs index 90ef4c65dc..ee08465c89 100644 --- a/macro/src/dialect/operation/accessors.rs +++ b/macro/src/dialect/operation/accessors.rs @@ -26,7 +26,7 @@ impl<'a> OperationField<'a> { Some(match variadic_kind { VariadicKind::Simple { - seen_variable_length, + variable_length_seen: seen_variable_length, } => { if constraint.is_optional() { // Optional element, and some singular elements. diff --git a/macro/src/dialect/operation/variadic_kind.rs b/macro/src/dialect/operation/variadic_kind.rs index 4d5a5aa995..68531d4b5e 100644 --- a/macro/src/dialect/operation/variadic_kind.rs +++ b/macro/src/dialect/operation/variadic_kind.rs @@ -1,7 +1,7 @@ #[derive(Clone, Debug)] pub enum VariadicKind { Simple { - seen_variable_length: bool, + variable_length_seen: bool, }, SameSize { variable_length_count: usize, @@ -15,7 +15,7 @@ impl VariadicKind { pub fn new(variable_length_count: usize, same_size: bool, attr_sized: bool) -> Self { if variable_length_count <= 1 { VariadicKind::Simple { - seen_variable_length: false, + variable_length_seen: false, } } else if same_size { VariadicKind::SameSize { From 69ae00adb47425b910d89496fc7b3629f28812ce Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 22:28:07 +0900 Subject: [PATCH 14/20] Add period --- macro/src/dialect/operation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index f731652f22..41896e84dd 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -273,7 +273,7 @@ impl<'a> Operation<'a> { let class_name = if name.starts_with('_') { name } else if let Some(name) = name.split('_').nth(1) { - // Trim dialect prefix from name + // Trim dialect prefix from name. name } else { name From f317925c49f9a54ffd6b8718c82b93d15f564f52 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 22:33:44 +0900 Subject: [PATCH 15/20] Refactor --- macro/src/dialect/operation.rs | 7 +++---- macro/src/dialect/operation/field_kind.rs | 3 +-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 41896e84dd..ba44e2b0e1 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -39,7 +39,7 @@ pub struct Operation<'a> { impl<'a> Operation<'a> { pub fn dialect_name(&self) -> &str { - &self.dialect_name + self.dialect_name } pub fn fields(&self) -> impl Iterator> + Clone { @@ -281,7 +281,7 @@ impl<'a> Operation<'a> { let short_name = definition.str_value("opName")?; Ok(Self { - dialect_name: dialect.name()?.into(), + dialect_name: dialect.name()?, short_name, full_name: { let dialect_name = dialect.string_value("name")?; @@ -342,8 +342,7 @@ impl<'a> ToTokens for Operation<'a> { .create_default_constructor() .expect("valid constructor"); let summary = &self.summary; - let description = - sanitize_documentation(&self.description).expect("valid Markdown documentation"); + let description = &self.description; tokens.append_all(quote! { #[doc = #summary] diff --git a/macro/src/dialect/operation/field_kind.rs b/macro/src/dialect/operation/field_kind.rs index 39c8323b86..944d3b2495 100644 --- a/macro/src/dialect/operation/field_kind.rs +++ b/macro/src/dialect/operation/field_kind.rs @@ -3,8 +3,7 @@ use crate::dialect::{ error::Error, types::{AttributeConstraint, RegionConstraint, SuccessorConstraint, TypeConstraint}, }; -use syn::parse_quote; -use syn::Type; +use syn::{parse_quote, Type}; #[derive(Debug, Clone)] pub enum FieldKind<'a> { From 0fccd260ec5b0b495f2ac4012f4f251cf2149447 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 22:34:22 +0900 Subject: [PATCH 16/20] Format files --- macro/src/dialect/operation.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index ba44e2b0e1..480f7a4255 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -6,11 +6,10 @@ mod operation_field; mod sequence_info; mod variadic_kind; -use self::element_kind::ElementKind; -use self::operation_field::OperationField; -use self::sequence_info::SequenceInfo; -use self::variadic_kind::VariadicKind; -use self::{builder::OperationBuilder, field_kind::FieldKind}; +use self::{ + builder::OperationBuilder, element_kind::ElementKind, field_kind::FieldKind, + operation_field::OperationField, sequence_info::SequenceInfo, variadic_kind::VariadicKind, +}; use super::utility::sanitize_documentation; use crate::dialect::{ error::{Error, OdsError}, From 8aaed8e7a526d14de39b230ab92c2a115e8d4f33 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 22:35:44 +0900 Subject: [PATCH 17/20] Rename --- macro/src/dialect/dialect.rs | 104 ++++++++++++++++++++++++ macro/src/dialect/operation.rs | 140 ++++++++++++++++----------------- 2 files changed, 174 insertions(+), 70 deletions(-) create mode 100644 macro/src/dialect/dialect.rs diff --git a/macro/src/dialect/dialect.rs b/macro/src/dialect/dialect.rs new file mode 100644 index 0000000000..67833e57fd --- /dev/null +++ b/macro/src/dialect/dialect.rs @@ -0,0 +1,104 @@ +mod error; +mod input; +mod operation; +mod types; +mod utility; + +use self::{ + error::Error, + utility::{sanitize_documentation, sanitize_snake_case_name}, +}; +pub use input::DialectInput; +use operation::Operation; +use proc_macro::TokenStream; +use proc_macro2::Span; +use quote::quote; +use std::{env, fmt::Display, path::Path, process::Command, str}; +use tblgen::{record::Record, record_keeper::RecordKeeper, TableGenParser}; + +const LLVM_MAJOR_VERSION: usize = 17; + +pub fn generate_dialect(input: DialectInput) -> Result> { + let mut parser = TableGenParser::new(); + + if let Some(source) = input.table_gen() { + parser = parser.add_source(source).map_err(create_syn_error)?; + } + + if let Some(file) = input.td_file() { + parser = parser.add_source_file(file).map_err(create_syn_error)?; + } + + // spell-checker: disable-next-line + for path in input.includes().chain([&*llvm_config("--includedir")?]) { + parser = parser.add_include_path(path); + } + + let keeper = parser.parse().map_err(Error::Parse)?; + + let dialect = generate_dialect_module( + input.name(), + keeper + .all_derived_definitions("Dialect") + .find(|definition| definition.str_value("name") == Ok(input.name())) + .ok_or_else(|| create_syn_error("dialect not found"))?, + &keeper, + ) + .map_err(|error| error.add_source_info(keeper.source_info()))?; + + Ok(quote! { #dialect }.into()) +} + +fn generate_dialect_module( + name: &str, + dialect: Record, + record_keeper: &RecordKeeper, +) -> Result { + let dialect_name = dialect.name()?; + let operations = record_keeper + .all_derived_definitions("Op") + .map(Operation::new) + .collect::, _>>()? + .into_iter() + .filter(|operation| operation.dialect_name() == dialect_name) + .collect::>(); + + let doc = format!( + "`{name}` dialect.\n\n{}", + sanitize_documentation(dialect.str_value("description").unwrap_or(""),)? + ); + let name = sanitize_snake_case_name(name)?; + + Ok(quote! { + #[doc = #doc] + pub mod #name { + #(#operations)* + } + }) +} + +fn llvm_config(argument: &str) -> Result> { + let prefix = env::var(format!("MLIR_SYS_{}0_PREFIX", LLVM_MAJOR_VERSION)) + .map(|path| Path::new(&path).join("bin")) + .unwrap_or_default(); + let call = format!( + "{} --link-static {}", + prefix.join("llvm-config").display(), + argument + ); + + Ok(str::from_utf8( + &if cfg!(target_os = "windows") { + Command::new("cmd").args(["/C", &call]).output()? + } else { + Command::new("sh").arg("-c").arg(&call).output()? + } + .stdout, + )? + .trim() + .to_string()) +} + +fn create_syn_error(error: impl Display) -> syn::Error { + syn::Error::new(Span::call_site(), format!("{}", error)) +} diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 480f7a4255..35b9f33285 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -37,6 +37,76 @@ pub struct Operation<'a> { } impl<'a> Operation<'a> { + pub fn new(definition: Record<'a>) -> Result { + let dialect = definition.def_value("opDialect")?; + let traits = Self::collect_traits(definition)?; + let has_trait = |name| traits.iter().any(|r#trait| r#trait.has_name(name)); + + let arguments = Self::dag_constraints(definition, "arguments")?; + let regions = Self::collect_regions(definition)?; + let (results, variable_length_results_count) = Self::collect_results( + definition, + has_trait("::mlir::OpTrait::SameVariadicResultSize"), + has_trait("::mlir::OpTrait::AttrSizedResultSegments"), + )?; + + let name = definition.name()?; + let class_name = if name.starts_with('_') { + name + } else if let Some(name) = name.split('_').nth(1) { + // Trim dialect prefix from name. + name + } else { + name + }; + let short_name = definition.str_value("opName")?; + + Ok(Self { + dialect_name: dialect.name()?, + short_name, + full_name: { + let dialect_name = dialect.string_value("name")?; + + if dialect_name.is_empty() { + short_name.into() + } else { + format!("{dialect_name}.{short_name}") + } + }, + class_name, + successors: Self::collect_successors(definition)?, + operands: Self::collect_operands( + &arguments, + has_trait("::mlir::OpTrait::SameVariadicOperandSize"), + has_trait("::mlir::OpTrait::AttrSizedOperandSegments"), + )?, + results, + attributes: Self::collect_attributes(&arguments)?, + derived_attributes: Self::collect_derived_attributes(definition)?, + can_infer_type: traits.iter().any(|r#trait| { + (r#trait.has_name("::mlir::OpTrait::FirstAttrDerivedResultType") + || r#trait.has_name("::mlir::OpTrait::SameOperandsAndResultType")) + && variable_length_results_count == 0 + || r#trait.has_name("::mlir::InferTypeOpInterface::Trait") && regions.is_empty() + }), + summary: { + let summary = definition.str_value("summary")?; + + [ + format!("[`{short_name}`]({class_name}) operation."), + if summary.is_empty() { + Default::default() + } else { + summary[0..1].to_uppercase() + &summary[1..] + "." + }, + ] + .join(" ") + }, + description: sanitize_documentation(definition.str_value("description")?)?, + regions, + }) + } + pub fn dialect_name(&self) -> &str { self.dialect_name } @@ -254,76 +324,6 @@ impl<'a> Operation<'a> { }) .collect() } - - pub fn from_definition(definition: Record<'a>) -> Result { - let dialect = definition.def_value("opDialect")?; - let traits = Self::collect_traits(definition)?; - let has_trait = |name| traits.iter().any(|r#trait| r#trait.has_name(name)); - - let arguments = Self::dag_constraints(definition, "arguments")?; - let regions = Self::collect_regions(definition)?; - let (results, variable_length_results_count) = Self::collect_results( - definition, - has_trait("::mlir::OpTrait::SameVariadicResultSize"), - has_trait("::mlir::OpTrait::AttrSizedResultSegments"), - )?; - - let name = definition.name()?; - let class_name = if name.starts_with('_') { - name - } else if let Some(name) = name.split('_').nth(1) { - // Trim dialect prefix from name. - name - } else { - name - }; - let short_name = definition.str_value("opName")?; - - Ok(Self { - dialect_name: dialect.name()?, - short_name, - full_name: { - let dialect_name = dialect.string_value("name")?; - - if dialect_name.is_empty() { - short_name.into() - } else { - format!("{dialect_name}.{short_name}") - } - }, - class_name, - successors: Self::collect_successors(definition)?, - operands: Self::collect_operands( - &arguments, - has_trait("::mlir::OpTrait::SameVariadicOperandSize"), - has_trait("::mlir::OpTrait::AttrSizedOperandSegments"), - )?, - results, - attributes: Self::collect_attributes(&arguments)?, - derived_attributes: Self::collect_derived_attributes(definition)?, - can_infer_type: traits.iter().any(|r#trait| { - (r#trait.has_name("::mlir::OpTrait::FirstAttrDerivedResultType") - || r#trait.has_name("::mlir::OpTrait::SameOperandsAndResultType")) - && variable_length_results_count == 0 - || r#trait.has_name("::mlir::InferTypeOpInterface::Trait") && regions.is_empty() - }), - summary: { - let summary = definition.str_value("summary")?; - - [ - format!("[`{short_name}`]({class_name}) operation."), - if summary.is_empty() { - Default::default() - } else { - summary[0..1].to_uppercase() + &summary[1..] + "." - }, - ] - .join(" ") - }, - description: sanitize_documentation(definition.str_value("description")?)?, - regions, - }) - } } impl<'a> ToTokens for Operation<'a> { From 03c16cc5d1ae2a64de63ccba29f883162191a98a Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 22:37:45 +0900 Subject: [PATCH 18/20] Fix --- macro/src/dialect.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/macro/src/dialect.rs b/macro/src/dialect.rs index 5f5c7e83bb..67833e57fd 100644 --- a/macro/src/dialect.rs +++ b/macro/src/dialect.rs @@ -57,7 +57,7 @@ fn generate_dialect_module( let dialect_name = dialect.name()?; let operations = record_keeper .all_derived_definitions("Op") - .map(Operation::from_definition) + .map(Operation::new) .collect::, _>>()? .into_iter() .filter(|operation| operation.dialect_name() == dialect_name) From 11fa14544afe5b75d7fd14f69e2c76bbc2acd015 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 22:38:27 +0900 Subject: [PATCH 19/20] Fix --- macro/src/dialect/operation.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 35b9f33285..c3dfb50c1a 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -161,15 +161,15 @@ impl<'a> Operation<'a> { .collect() } - fn collect_traits(def: Record<'a>) -> Result, Error> { - let mut work_list = vec![def.list_value("traits")?]; + fn collect_traits(definition: Record<'a>) -> Result, Error> { + let mut work_list = vec![definition.list_value("traits")?]; let mut traits = Vec::new(); while let Some(trait_def) = work_list.pop() { for value in trait_def.iter() { let trait_def: Record = value .try_into() - .map_err(|error: tblgen::Error| error.set_location(def))?; + .map_err(|error: tblgen::Error| error.set_location(definition))?; if trait_def.subclass_of("TraitList") { work_list.push(trait_def.list_value("traits")?); @@ -186,15 +186,16 @@ impl<'a> Operation<'a> { } fn dag_constraints( - def: Record<'a>, + definition: Record<'a>, dag_field_name: &str, ) -> Result)>, Error> { - def.dag_value(dag_field_name)? + definition + .dag_value(dag_field_name)? .args() .map(|(name, arg)| { let mut arg_def: Record = arg .try_into() - .map_err(|error: tblgen::Error| error.set_location(def))?; + .map_err(|error: tblgen::Error| error.set_location(definition))?; if arg_def.subclass_of("OpVariable") { arg_def = arg_def.def_value("constraint")?; From 68f121658c5397cafb8cfeedcb6da80e004577ef Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 22:39:28 +0900 Subject: [PATCH 20/20] Rename --- macro/src/dialect/operation.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index c3dfb50c1a..106426fb0b 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -165,8 +165,8 @@ impl<'a> Operation<'a> { let mut work_list = vec![definition.list_value("traits")?]; let mut traits = Vec::new(); - while let Some(trait_def) = work_list.pop() { - for value in trait_def.iter() { + while let Some(trait_definition) = work_list.pop() { + for value in trait_definition.iter() { let trait_def: Record = value .try_into() .map_err(|error: tblgen::Error| error.set_location(definition))?; @@ -192,16 +192,16 @@ impl<'a> Operation<'a> { definition .dag_value(dag_field_name)? .args() - .map(|(name, arg)| { - let mut arg_def: Record = arg + .map(|(name, argument)| { + let mut argument_definition: Record = argument .try_into() .map_err(|error: tblgen::Error| error.set_location(definition))?; - if arg_def.subclass_of("OpVariable") { - arg_def = arg_def.def_value("constraint")?; + if argument_definition.subclass_of("OpVariable") { + argument_definition = argument_definition.def_value("constraint")?; } - Ok((name, arg_def)) + Ok((name, argument_definition)) }) .collect() }