From 3eb199d1c05583fa88e5cd6787c49f488b8fcdf5 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Fri, 20 Oct 2023 10:40:26 +1100 Subject: [PATCH 001/108] Rename dependabot workflow (#361) --- .github/workflows/{merge.yaml => dependabot.yaml} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename .github/workflows/{merge.yaml => dependabot.yaml} (92%) diff --git a/.github/workflows/merge.yaml b/.github/workflows/dependabot.yaml similarity index 92% rename from .github/workflows/merge.yaml rename to .github/workflows/dependabot.yaml index b071d74f6f..b4e087b30f 100644 --- a/.github/workflows/merge.yaml +++ b/.github/workflows/dependabot.yaml @@ -1,10 +1,10 @@ -name: merge +name: dependabot on: pull_request permissions: contents: write pull-requests: write jobs: - dependabot: + merge: runs-on: ubuntu-latest if: github.actor == 'dependabot[bot]' steps: From 8f806b064ed21b35abeaed19eded75497aaed26e Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Fri, 20 Oct 2023 19:36:03 +1100 Subject: [PATCH 002/108] chore: Release --- Cargo.lock | 4 ++-- macro/Cargo.toml | 2 +- melior/Cargo.toml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2cb11dba0d..684cd7d17a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -750,7 +750,7 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "melior" -version = "0.12.2" +version = "0.13.0" dependencies = [ "criterion", "dashmap", @@ -764,7 +764,7 @@ dependencies = [ [[package]] name = "melior-macro" -version = "0.6.1" +version = "0.7.0" dependencies = [ "comrak", "convert_case", diff --git a/macro/Cargo.toml b/macro/Cargo.toml index 9cb3399875..a5690241db 100644 --- a/macro/Cargo.toml +++ b/macro/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "melior-macro" description = "Internal macros for Melior" -version = "0.6.1" +version = "0.7.0" edition = "2021" license = "Apache-2.0" repository = "https://github.com/raviqqe/melior" diff --git a/melior/Cargo.toml b/melior/Cargo.toml index 6dbe016ddd..4aa1c4969d 100644 --- a/melior/Cargo.toml +++ b/melior/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "melior" description = "The rustic MLIR bindings in Rust" -version = "0.12.2" +version = "0.13.0" edition = "2021" license = "Apache-2.0" repository = "https://github.com/raviqqe/melior" @@ -14,7 +14,7 @@ ods-dialects = [] [dependencies] dashmap = "5.5.3" -melior-macro = { version = "0.6", path = "../macro" } +melior-macro = { version = "0.7", path = "../macro" } mlir-sys = "0.2" once_cell = "1" From bed0011fe048f78e709b3add840ff4a4b2cdeb27 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 16:49:14 +0000 Subject: [PATCH 003/108] build(deps): Bump syn from 2.0.38 to 2.0.39 (#363) Bumps [syn](https://github.com/dtolnay/syn) from 2.0.38 to 2.0.39.
Release notes

Sourced from syn's releases.

2.0.39

  • Fix parsing of return expression in match guards (#1528)
  • Improve error message on labeled loop as value expression for break (#1531)
Commits
  • 924217c Release 2.0.39
  • 95aeeb5 Merge pull request #1531 from dtolnay/breaklabel
  • b88f86f Ignore single_element_loop clippy lint in test
  • a876185 Improve error on break followed by labeled loop
  • 32ab979 Add test of ambiguous label parsing in break
  • 6f658f8 Merge pull request #1530 from dtolnay/canbeginexpr
  • 20497e1 More precise decision to parse expression after return keyword
  • c6a651a Update name of ExprReturn parse function to match variant name
  • c274590 Indicate that peek argument refers to syn::Ident
  • 3e67cb0 Merge pull request #1529 from dtolnay/up
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=syn&package-manager=cargo&previous-version=2.0.38&new-version=2.0.39)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 684cd7d17a..c61eab5859 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,7 +111,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.38", + "syn 2.0.39", "which", ] @@ -134,7 +134,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.38", + "syn 2.0.39", "which", ] @@ -271,7 +271,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -775,7 +775,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.38", + "syn 2.0.39", "tblgen", "unindent", ] @@ -968,7 +968,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -1125,7 +1125,7 @@ checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -1191,9 +1191,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -1261,7 +1261,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -1370,7 +1370,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", "wasm-bindgen-shared", ] @@ -1392,7 +1392,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] From 4c7600273f1ec0f7fc5ec9c6058ba54e198eed68 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Wed, 8 Nov 2023 11:46:30 +1100 Subject: [PATCH 004/108] Remove string cache (#364) - Remove string cache - Fix - Fix --- melior/src/context.rs | 11 +---------- melior/src/string_ref.rs | 17 ----------------- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/melior/src/context.rs b/melior/src/context.rs index 8e5407f7f5..7315cd85ce 100644 --- a/melior/src/context.rs +++ b/melior/src/context.rs @@ -4,7 +4,6 @@ use crate::{ logical_result::LogicalResult, string_ref::StringRef, }; -use dashmap::DashMap; use mlir_sys::{ mlirContextAppendDialectRegistry, mlirContextAttachDiagnosticHandler, mlirContextCreate, mlirContextDestroy, mlirContextDetachDiagnosticHandler, mlirContextEnableMultithreading, @@ -13,7 +12,7 @@ use mlir_sys::{ mlirContextIsRegisteredOperation, mlirContextLoadAllAvailableDialects, mlirContextSetAllowUnregisteredDialects, MlirContext, MlirDiagnostic, MlirLogicalResult, }; -use std::{ffi::c_void, marker::PhantomData, pin::Pin}; +use std::{ffi::c_void, marker::PhantomData}; /// A context of IR, dialects, and passes. /// @@ -22,9 +21,6 @@ use std::{ffi::c_void, marker::PhantomData, pin::Pin}; #[derive(Debug)] pub struct Context { raw: MlirContext, - // We need to pass null-terminated strings to functions in the MLIR API although - // Rust's strings are not. - string_cache: DashMap, ()>, } impl Context { @@ -32,7 +28,6 @@ impl Context { pub fn new() -> Self { Self { raw: unsafe { mlirContextCreate() }, - string_cache: Default::default(), } } @@ -124,10 +119,6 @@ impl Context { pub(crate) fn to_ref(&self) -> ContextRef { unsafe { ContextRef::from_raw(self.to_raw()) } } - - pub(crate) fn string_cache(&self) -> &DashMap, ()> { - &self.string_cache - } } impl Drop for Context { diff --git a/melior/src/string_ref.rs b/melior/src/string_ref.rs index 36e0170505..159ca3db7f 100644 --- a/melior/src/string_ref.rs +++ b/melior/src/string_ref.rs @@ -1,9 +1,7 @@ -use crate::Context; use mlir_sys::{mlirStringRefEqual, MlirStringRef}; use std::{ ffi::CStr, marker::PhantomData, - pin::Pin, slice, str::{self, Utf8Error}, }; @@ -40,21 +38,6 @@ impl<'a> StringRef<'a> { unsafe { Self::from_raw(string) } } - /// Converts a string into a null-terminated string reference. - #[deprecated] - pub fn from_str(context: &'a Context, string: &str) -> Self { - let entry = context - .string_cache() - .entry(Pin::new(string.into())) - .or_default(); - let string = MlirStringRef { - data: entry.key().as_bytes().as_ptr() as *const i8, - length: entry.key().len(), - }; - - unsafe { Self::from_raw(string) } - } - /// Converts a string reference into a `str`. pub fn as_str(&self) -> Result<&'a str, Utf8Error> { unsafe { From 73baa63f766c4a2fc5609367993dc6469ca392a7 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Mon, 27 Nov 2023 22:18:42 +0900 Subject: [PATCH 005/108] Remove unused benchmark (#366) - Remove unused benchmark - Uninstall criterion --- melior/Cargo.toml | 5 ----- melior/benches/main.rs | 41 ----------------------------------------- 2 files changed, 46 deletions(-) delete mode 100644 melior/benches/main.rs diff --git a/melior/Cargo.toml b/melior/Cargo.toml index 4aa1c4969d..96233848f9 100644 --- a/melior/Cargo.toml +++ b/melior/Cargo.toml @@ -19,11 +19,6 @@ mlir-sys = "0.2" once_cell = "1" [dev-dependencies] -criterion = "0.5.1" indoc = "2.0.4" insta = "1.34.0" pretty_assertions = "1.4.0" - -[[bench]] -name = "main" -harness = false diff --git a/melior/benches/main.rs b/melior/benches/main.rs deleted file mode 100644 index 485cb214d4..0000000000 --- a/melior/benches/main.rs +++ /dev/null @@ -1,41 +0,0 @@ -use criterion::{criterion_group, criterion_main, Bencher, Criterion}; -use melior::{Context, StringRef}; - -const ITERATION_COUNT: usize = 1000000; - -fn generate_strings() -> Vec { - (0..ITERATION_COUNT) - .map(|number| number.to_string()) - .collect() -} - -fn string_ref_create(bencher: &mut Bencher) { - let context = Context::new(); - let strings = generate_strings(); - - bencher.iter(|| { - for string in &strings { - #[allow(deprecated)] - let _ = StringRef::from_str(&context, string.as_str()); - } - }); -} - -fn string_ref_create_cached(bencher: &mut Bencher) { - let context = Context::new(); - - bencher.iter(|| { - for _ in 0..ITERATION_COUNT { - #[allow(deprecated)] - let _ = StringRef::from_str(&context, "foo"); - } - }); -} - -fn benchmark(criterion: &mut Criterion) { - criterion.bench_function("string ref create", string_ref_create); - criterion.bench_function("string ref create cached", string_ref_create_cached); -} - -criterion_group!(benchmark_group, benchmark); -criterion_main!(benchmark_group); From 2d063edc0f74f6831ec67b4c578c4c293be21c3e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 16:41:54 +0000 Subject: [PATCH 006/108] build(deps): Bump proc-macro2 from 1.0.69 to 1.0.70 (#367) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.69 to 1.0.70.
Release notes

Sourced from proc-macro2's releases.

1.0.70

  • Add #[track_caller] on Ident::new so that panics on invalid input are attributed to the caller (#423)
Commits
  • cd31a69 Release 1.0.70
  • 4482662 Merge pull request #423 from dtolnay/trackcaller
  • 690ab11 Track caller for Ident validation panics
  • f15383f Merge pull request #422 from dtolnay/newchecked
  • ea2cd7f Rename internal Ident::new -> Ident::new_checked
  • 8059195 Merge pull request #421 from dtolnay/identunchecked
  • 805a6ad Bypass Ident validation on identifiers created by parser
  • c513462 Merge pull request #420 from dtolnay/newraw
  • bd778e1 Delete Ident::_new_raw
  • 0cb3649 Ignore checked_conversions pedantic clippy lint
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=proc-macro2&package-manager=cargo&previous-version=1.0.69&new-version=1.0.70)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 306 +---------------------------------------------------- 1 file changed, 2 insertions(+), 304 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c61eab5859..eb4e4b554c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,12 +17,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "anes" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" - [[package]] name = "anstream" version = "0.6.4" @@ -165,18 +159,6 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" -[[package]] -name = "bumpalo" -version = "3.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" - -[[package]] -name = "cast" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" - [[package]] name = "cc" version = "1.0.83" @@ -201,33 +183,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "ciborium" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" -dependencies = [ - "ciborium-io", - "ciborium-ll", - "serde", -] - -[[package]] -name = "ciborium-io" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" - -[[package]] -name = "ciborium-ll" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" -dependencies = [ - "ciborium-io", - "half", -] - [[package]] name = "clang-sys" version = "1.6.1" @@ -336,75 +291,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "criterion" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" -dependencies = [ - "anes", - "cast", - "ciborium", - "clap", - "criterion-plot", - "is-terminal", - "itertools", - "num-traits", - "once_cell", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_derive", - "serde_json", - "tinytemplate", - "walkdir", -] - -[[package]] -name = "criterion-plot" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" -dependencies = [ - "cast", - "itertools", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] - [[package]] name = "darling" version = "0.14.4" @@ -574,12 +460,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" -[[package]] -name = "half" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" - [[package]] name = "hashbrown" version = "0.12.3" @@ -598,12 +478,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -[[package]] -name = "hermit-abi" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" - [[package]] name = "home" version = "0.5.5" @@ -648,41 +522,12 @@ dependencies = [ "yaml-rust", ] -[[package]] -name = "is-terminal" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys 0.48.0", -] - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" -[[package]] -name = "js-sys" -version = "0.3.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" -dependencies = [ - "wasm-bindgen", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -752,7 +597,6 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" name = "melior" version = "0.13.0" dependencies = [ - "criterion", "dashmap", "indoc", "insta", @@ -786,15 +630,6 @@ version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -829,15 +664,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "num-traits" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" -dependencies = [ - "autocfg", -] - [[package]] name = "once_cell" version = "1.18.0" @@ -866,12 +692,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "oorandom" -version = "11.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" - [[package]] name = "parking_lot_core" version = "0.9.9" @@ -917,34 +737,6 @@ dependencies = [ "time", ] -[[package]] -name = "plotters" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" - -[[package]] -name = "plotters-svg" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" -dependencies = [ - "plotters-backend", -] - [[package]] name = "powerfmt" version = "0.2.0" @@ -973,9 +765,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -998,26 +790,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rayon" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -1293,16 +1065,6 @@ dependencies = [ "time-core", ] -[[package]] -name = "tinytemplate" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "typed-arena" version = "2.0.2" @@ -1349,70 +1111,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasm-bindgen" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.39", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.39", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" - -[[package]] -name = "web-sys" -version = "0.3.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - [[package]] name = "which" version = "4.4.2" From 3f05035307c2562cd8083552b23e33dff9dd5b36 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Nov 2023 16:28:55 +0000 Subject: [PATCH 007/108] build(deps): Bump comrak from 0.19.0 to 0.20.0 (#369) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [comrak](https://github.com/kivikakk/comrak) from 0.19.0 to 0.20.0.
Release notes

Sourced from comrak's releases.

0.20.0

What's Changed

New Contributors

Full Changelog: https://github.com/kivikakk/comrak/compare/0.19.0...0.20.0

Changelog

Sourced from comrak's changelog.

0.20.0

Commits
  • 4c909b6 0.20.0
  • 769b4e5 Merge pull request #347 from kivikakk/use-css-if-you-like
  • 4b9d838 syntect: minor cleanups.
  • 985e49a Allow for Syntect to simply generate CSS classes
  • a21d42c [clippy] remove outdated include
  • 0679810 Merge pull request #338 from kivikakk/nix
  • 270c6ee flake.nix, workflows: use Nix for clippy/fmt to start.
  • 840f14d Merge pull request #346 from kivikakk/dependabot/cargo/fuzz/rustix-0.36.16
  • c7f9d47 build(deps): bump rustix from 0.36.11 to 0.36.16 in /fuzz
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=comrak&package-manager=cargo&previous-version=0.19.0&new-version=0.20.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- macro/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eb4e4b554c..dfa274e716 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -243,9 +243,9 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "comrak" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82c995deda3bfdebd07d0e2af79e9da13e4b1be652b21a746f3f5b24bf0a49ef" +checksum = "9f18e72341e6cdc7489cffb76f993812a14a906db54dedb020044ccc211dcaae" dependencies = [ "clap", "derive_builder", diff --git a/macro/Cargo.toml b/macro/Cargo.toml index a5690241db..3b0afb88b2 100644 --- a/macro/Cargo.toml +++ b/macro/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["mlir", "llvm"] proc-macro = true [dependencies] -comrak = "0.19.0" +comrak = "0.20.0" convert_case = "0.6.0" once_cell = "1.18.0" proc-macro2 = "1" From 524425ff2965d28041c300a874ae99412aa7f7f5 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Mon, 4 Dec 2023 20:41:57 +0800 Subject: [PATCH 008/108] Remove readme field (#372) --- melior/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/melior/Cargo.toml b/melior/Cargo.toml index 96233848f9..b9fd098dcd 100644 --- a/melior/Cargo.toml +++ b/melior/Cargo.toml @@ -6,7 +6,6 @@ edition = "2021" license = "Apache-2.0" repository = "https://github.com/raviqqe/melior" documentation = "https://raviqqe.github.io/melior/melior/" -readme = "../README.md" keywords = ["mlir", "llvm"] [features] From db45fe9b94336d7bdf5551b41dbd0897b2fff148 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Mon, 4 Dec 2023 21:45:12 +0900 Subject: [PATCH 009/108] chore: Release --- Cargo.lock | 4 ++-- macro/Cargo.toml | 2 +- melior/Cargo.toml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dfa274e716..960a6e5de7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -595,7 +595,7 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "melior" -version = "0.13.0" +version = "0.14.0" dependencies = [ "dashmap", "indoc", @@ -608,7 +608,7 @@ dependencies = [ [[package]] name = "melior-macro" -version = "0.7.0" +version = "0.8.0" dependencies = [ "comrak", "convert_case", diff --git a/macro/Cargo.toml b/macro/Cargo.toml index 3b0afb88b2..fe758089ef 100644 --- a/macro/Cargo.toml +++ b/macro/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "melior-macro" description = "Internal macros for Melior" -version = "0.7.0" +version = "0.8.0" edition = "2021" license = "Apache-2.0" repository = "https://github.com/raviqqe/melior" diff --git a/melior/Cargo.toml b/melior/Cargo.toml index b9fd098dcd..c0df35f672 100644 --- a/melior/Cargo.toml +++ b/melior/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "melior" description = "The rustic MLIR bindings in Rust" -version = "0.13.0" +version = "0.14.0" edition = "2021" license = "Apache-2.0" repository = "https://github.com/raviqqe/melior" @@ -13,7 +13,7 @@ ods-dialects = [] [dependencies] dashmap = "5.5.3" -melior-macro = { version = "0.7", path = "../macro" } +melior-macro = { version = "0.8", path = "../macro" } mlir-sys = "0.2" once_cell = "1" From 86f261ca82b382991285a8904c73fb65cd91b56c Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Mon, 4 Dec 2023 21:25:17 +0800 Subject: [PATCH 010/108] Refactor pass macros (#373) --- macro/src/lib.rs | 46 ++++---------------------------- macro/src/parse.rs | 33 ++++++++++++++++++++++- melior/src/pass/async.rs | 17 +++++++----- melior/src/pass/gpu.rs | 15 ++++++----- melior/src/pass/linalg.rs | 27 ++++++++++--------- melior/src/pass/sparse_tensor.rs | 21 ++++++++------- melior/src/pass/transform.rs | 33 ++++++++++++----------- 7 files changed, 101 insertions(+), 91 deletions(-) diff --git a/macro/src/lib.rs b/macro/src/lib.rs index fb8fb39339..64e01cf6e0 100644 --- a/macro/src/lib.rs +++ b/macro/src/lib.rs @@ -7,7 +7,7 @@ mod r#type; mod utility; use dialect::DialectInput; -use parse::{DialectOperationSet, IdentifierList}; +use parse::{DialectOperationSet, IdentifierList, PassSet}; use proc_macro::TokenStream; use quote::quote; use std::error::Error; @@ -68,15 +68,6 @@ pub fn attribute_check_functions(stream: TokenStream) -> TokenStream { convert_result(attribute::generate(identifiers.identifiers())) } -#[proc_macro] -pub fn async_passes(stream: TokenStream) -> TokenStream { - let identifiers = parse_macro_input!(stream as IdentifierList); - - convert_result(pass::generate(identifiers.identifiers(), |name| { - name.strip_prefix("Async").unwrap().into() - })) -} - #[proc_macro] pub fn conversion_passes(stream: TokenStream) -> TokenStream { let identifiers = parse_macro_input!(stream as IdentifierList); @@ -90,38 +81,11 @@ pub fn conversion_passes(stream: TokenStream) -> TokenStream { } #[proc_macro] -pub fn gpu_passes(stream: TokenStream) -> TokenStream { - let identifiers = parse_macro_input!(stream as IdentifierList); - - convert_result(pass::generate(identifiers.identifiers(), |name| { - name.strip_prefix("GPU").unwrap().into() - })) -} - -#[proc_macro] -pub fn transform_passes(stream: TokenStream) -> TokenStream { - let identifiers = parse_macro_input!(stream as IdentifierList); - - convert_result(pass::generate(identifiers.identifiers(), |name| { - name.strip_prefix("Transforms").unwrap().into() - })) -} - -#[proc_macro] -pub fn linalg_passes(stream: TokenStream) -> TokenStream { - let identifiers = parse_macro_input!(stream as IdentifierList); - - convert_result(pass::generate(identifiers.identifiers(), |name| { - name.strip_prefix("Linalg").unwrap().into() - })) -} - -#[proc_macro] -pub fn sparse_tensor_passes(stream: TokenStream) -> TokenStream { - let identifiers = parse_macro_input!(stream as IdentifierList); +pub fn passes(stream: TokenStream) -> TokenStream { + let set = parse_macro_input!(stream as PassSet); - convert_result(pass::generate(identifiers.identifiers(), |name| { - name.strip_prefix("SparseTensor").unwrap().into() + convert_result(pass::generate(set.identifiers(), |name| { + name.strip_prefix(&set.prefix().value()).unwrap().into() })) } diff --git a/macro/src/parse.rs b/macro/src/parse.rs index d484f5bd80..0f8cdbae1d 100644 --- a/macro/src/parse.rs +++ b/macro/src/parse.rs @@ -3,7 +3,7 @@ use syn::{ bracketed, parse::{Parse, ParseStream}, punctuated::Punctuated, - Result, Token, + LitStr, Result, Token, }; pub struct IdentifierList { @@ -56,3 +56,34 @@ impl Parse for DialectOperationSet { }) } } + +pub struct PassSet { + prefix: LitStr, + identifiers: IdentifierList, +} + +impl PassSet { + pub const fn prefix(&self) -> &LitStr { + &self.prefix + } + + pub fn identifiers(&self) -> &[Ident] { + self.identifiers.identifiers() + } +} + +impl Parse for PassSet { + fn parse(input: ParseStream) -> Result { + let prefix = input.parse()?; + ::parse(input)?; + + Ok(Self { + prefix, + identifiers: { + let content; + bracketed!(content in input); + content.parse::()? + }, + }) + } +} diff --git a/melior/src/pass/async.rs b/melior/src/pass/async.rs index 53effd3f71..30ea238c7d 100644 --- a/melior/src/pass/async.rs +++ b/melior/src/pass/async.rs @@ -1,10 +1,13 @@ //! Async passes. -melior_macro::async_passes!( - mlirCreateAsyncAsyncFuncToAsyncRuntime, - mlirCreateAsyncAsyncParallelFor, - mlirCreateAsyncAsyncRuntimePolicyBasedRefCounting, - mlirCreateAsyncAsyncRuntimeRefCounting, - mlirCreateAsyncAsyncRuntimeRefCountingOpt, - mlirCreateAsyncAsyncToAsyncRuntime, +melior_macro::passes!( + "Async", + [ + mlirCreateAsyncAsyncFuncToAsyncRuntime, + mlirCreateAsyncAsyncParallelFor, + mlirCreateAsyncAsyncRuntimePolicyBasedRefCounting, + mlirCreateAsyncAsyncRuntimeRefCounting, + mlirCreateAsyncAsyncRuntimeRefCountingOpt, + mlirCreateAsyncAsyncToAsyncRuntime, + ] ); diff --git a/melior/src/pass/gpu.rs b/melior/src/pass/gpu.rs index d89bc36e87..daa2a3aea1 100644 --- a/melior/src/pass/gpu.rs +++ b/melior/src/pass/gpu.rs @@ -1,9 +1,12 @@ //! GPU passes. -melior_macro::gpu_passes!( - // spell-checker: disable-next-line - mlirCreateGPUGpuAsyncRegionPass, - mlirCreateGPUGpuKernelOutlining, - mlirCreateGPUGpuLaunchSinkIndexComputations, - mlirCreateGPUGpuMapParallelLoopsPass, +melior_macro::passes!( + "GPU", + [ + // spell-checker: disable-next-line + mlirCreateGPUGpuAsyncRegionPass, + mlirCreateGPUGpuKernelOutlining, + mlirCreateGPUGpuLaunchSinkIndexComputations, + mlirCreateGPUGpuMapParallelLoopsPass, + ] ); diff --git a/melior/src/pass/linalg.rs b/melior/src/pass/linalg.rs index 067127264d..00b091d6d1 100644 --- a/melior/src/pass/linalg.rs +++ b/melior/src/pass/linalg.rs @@ -1,15 +1,18 @@ //! Linalg passes. -melior_macro::linalg_passes!( - mlirCreateLinalgConvertElementwiseToLinalg, - mlirCreateLinalgLinalgBufferize, - mlirCreateLinalgLinalgDetensorize, - mlirCreateLinalgLinalgElementwiseOpFusion, - mlirCreateLinalgLinalgFoldUnitExtentDims, - mlirCreateLinalgLinalgGeneralization, - mlirCreateLinalgLinalgInlineScalarOperands, - mlirCreateLinalgLinalgLowerToAffineLoops, - mlirCreateLinalgLinalgLowerToLoops, - mlirCreateLinalgLinalgLowerToParallelLoops, - mlirCreateLinalgLinalgNamedOpConversion, +melior_macro::passes!( + "Linalg", + [ + mlirCreateLinalgConvertElementwiseToLinalg, + mlirCreateLinalgLinalgBufferize, + mlirCreateLinalgLinalgDetensorize, + mlirCreateLinalgLinalgElementwiseOpFusion, + mlirCreateLinalgLinalgFoldUnitExtentDims, + mlirCreateLinalgLinalgGeneralization, + mlirCreateLinalgLinalgInlineScalarOperands, + mlirCreateLinalgLinalgLowerToAffineLoops, + mlirCreateLinalgLinalgLowerToLoops, + mlirCreateLinalgLinalgLowerToParallelLoops, + mlirCreateLinalgLinalgNamedOpConversion, + ] ); diff --git a/melior/src/pass/sparse_tensor.rs b/melior/src/pass/sparse_tensor.rs index 60ef80b232..c8544bc46d 100644 --- a/melior/src/pass/sparse_tensor.rs +++ b/melior/src/pass/sparse_tensor.rs @@ -1,12 +1,15 @@ //! Sparse tensor passes. -melior_macro::sparse_tensor_passes!( - mlirCreateSparseTensorPostSparsificationRewrite, - mlirCreateSparseTensorPreSparsificationRewrite, - mlirCreateSparseTensorSparseBufferRewrite, - mlirCreateSparseTensorSparseTensorCodegen, - mlirCreateSparseTensorSparseTensorConversionPass, - mlirCreateSparseTensorSparseVectorization, - mlirCreateSparseTensorSparsificationPass, - mlirCreateSparseTensorStorageSpecifierToLLVM, +melior_macro::passes!( + "SparseTensor", + [ + mlirCreateSparseTensorPostSparsificationRewrite, + mlirCreateSparseTensorPreSparsificationRewrite, + mlirCreateSparseTensorSparseBufferRewrite, + mlirCreateSparseTensorSparseTensorCodegen, + mlirCreateSparseTensorSparseTensorConversionPass, + mlirCreateSparseTensorSparseVectorization, + mlirCreateSparseTensorSparsificationPass, + mlirCreateSparseTensorStorageSpecifierToLLVM, + ] ); diff --git a/melior/src/pass/transform.rs b/melior/src/pass/transform.rs index aaa09c6660..657e9f554a 100644 --- a/melior/src/pass/transform.rs +++ b/melior/src/pass/transform.rs @@ -1,18 +1,21 @@ //! Transform passes. -melior_macro::transform_passes!( - mlirCreateTransformsCSE, - mlirCreateTransformsCanonicalizer, - mlirCreateTransformsControlFlowSink, - mlirCreateTransformsGenerateRuntimeVerification, - mlirCreateTransformsInliner, - mlirCreateTransformsLocationSnapshot, - mlirCreateTransformsLoopInvariantCodeMotion, - mlirCreateTransformsPrintOpStats, - mlirCreateTransformsSCCP, - mlirCreateTransformsStripDebugInfo, - mlirCreateTransformsSymbolDCE, - mlirCreateTransformsSymbolPrivatize, - mlirCreateTransformsTopologicalSort, - mlirCreateTransformsViewOpGraph, +melior_macro::passes!( + "Transforms", + [ + mlirCreateTransformsCSE, + mlirCreateTransformsCanonicalizer, + mlirCreateTransformsControlFlowSink, + mlirCreateTransformsGenerateRuntimeVerification, + mlirCreateTransformsInliner, + mlirCreateTransformsLocationSnapshot, + mlirCreateTransformsLoopInvariantCodeMotion, + mlirCreateTransformsPrintOpStats, + mlirCreateTransformsSCCP, + mlirCreateTransformsStripDebugInfo, + mlirCreateTransformsSymbolDCE, + mlirCreateTransformsSymbolPrivatize, + mlirCreateTransformsTopologicalSort, + mlirCreateTransformsViewOpGraph, + ] ); From 7b5ab0b9e6d22560f418dcd1fc5e76c19ad55234 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Mon, 4 Dec 2023 21:34:16 +0800 Subject: [PATCH 011/108] Refactor parse module in macro crate (#374) --- macro/src/parse.rs | 94 ++---------------------- macro/src/parse/dialect_operation_set.rs | 38 ++++++++++ macro/src/parse/identifier_list.rs | 26 +++++++ macro/src/parse/pass_set.rs | 38 ++++++++++ 4 files changed, 108 insertions(+), 88 deletions(-) create mode 100644 macro/src/parse/dialect_operation_set.rs create mode 100644 macro/src/parse/identifier_list.rs create mode 100644 macro/src/parse/pass_set.rs diff --git a/macro/src/parse.rs b/macro/src/parse.rs index 0f8cdbae1d..ddf099919a 100644 --- a/macro/src/parse.rs +++ b/macro/src/parse.rs @@ -1,89 +1,7 @@ -use proc_macro2::Ident; -use syn::{ - bracketed, - parse::{Parse, ParseStream}, - punctuated::Punctuated, - LitStr, Result, Token, -}; +mod dialect_operation_set; +mod identifier_list; +mod pass_set; -pub struct IdentifierList { - identifiers: Vec, -} - -impl IdentifierList { - pub fn identifiers(&self) -> &[Ident] { - &self.identifiers - } -} - -impl Parse for IdentifierList { - fn parse(input: ParseStream) -> Result { - Ok(Self { - identifiers: Punctuated::::parse_terminated(input)? - .into_iter() - .collect(), - }) - } -} - -pub struct DialectOperationSet { - dialect: Ident, - identifiers: IdentifierList, -} - -impl DialectOperationSet { - pub const fn dialect(&self) -> &Ident { - &self.dialect - } - - pub fn identifiers(&self) -> &[Ident] { - self.identifiers.identifiers() - } -} - -impl Parse for DialectOperationSet { - fn parse(input: ParseStream) -> Result { - let dialect = Ident::parse(input)?; - ::parse(input)?; - - Ok(Self { - dialect, - identifiers: { - let content; - bracketed!(content in input); - content.parse::()? - }, - }) - } -} - -pub struct PassSet { - prefix: LitStr, - identifiers: IdentifierList, -} - -impl PassSet { - pub const fn prefix(&self) -> &LitStr { - &self.prefix - } - - pub fn identifiers(&self) -> &[Ident] { - self.identifiers.identifiers() - } -} - -impl Parse for PassSet { - fn parse(input: ParseStream) -> Result { - let prefix = input.parse()?; - ::parse(input)?; - - Ok(Self { - prefix, - identifiers: { - let content; - bracketed!(content in input); - content.parse::()? - }, - }) - } -} +pub use dialect_operation_set::DialectOperationSet; +pub use identifier_list::IdentifierList; +pub use pass_set::PassSet; diff --git a/macro/src/parse/dialect_operation_set.rs b/macro/src/parse/dialect_operation_set.rs new file mode 100644 index 0000000000..1c9022f508 --- /dev/null +++ b/macro/src/parse/dialect_operation_set.rs @@ -0,0 +1,38 @@ +use super::IdentifierList; +use proc_macro2::Ident; +use syn::{ + bracketed, + parse::{Parse, ParseStream}, + Result, Token, +}; + +pub struct DialectOperationSet { + dialect: Ident, + identifiers: IdentifierList, +} + +impl DialectOperationSet { + pub const fn dialect(&self) -> &Ident { + &self.dialect + } + + pub fn identifiers(&self) -> &[Ident] { + self.identifiers.identifiers() + } +} + +impl Parse for DialectOperationSet { + fn parse(input: ParseStream) -> Result { + let dialect = Ident::parse(input)?; + ::parse(input)?; + + Ok(Self { + dialect, + identifiers: { + let content; + bracketed!(content in input); + content.parse::()? + }, + }) + } +} diff --git a/macro/src/parse/identifier_list.rs b/macro/src/parse/identifier_list.rs new file mode 100644 index 0000000000..af5a5a0742 --- /dev/null +++ b/macro/src/parse/identifier_list.rs @@ -0,0 +1,26 @@ +use proc_macro2::Ident; +use syn::{ + parse::{Parse, ParseStream}, + punctuated::Punctuated, + Result, Token, +}; + +pub struct IdentifierList { + identifiers: Vec, +} + +impl IdentifierList { + pub fn identifiers(&self) -> &[Ident] { + &self.identifiers + } +} + +impl Parse for IdentifierList { + fn parse(input: ParseStream) -> Result { + Ok(Self { + identifiers: Punctuated::::parse_terminated(input)? + .into_iter() + .collect(), + }) + } +} diff --git a/macro/src/parse/pass_set.rs b/macro/src/parse/pass_set.rs new file mode 100644 index 0000000000..1c646d055f --- /dev/null +++ b/macro/src/parse/pass_set.rs @@ -0,0 +1,38 @@ +use super::IdentifierList; +use proc_macro2::Ident; +use syn::{ + bracketed, + parse::{Parse, ParseStream}, + LitStr, Result, Token, +}; + +pub struct PassSet { + prefix: LitStr, + identifiers: IdentifierList, +} + +impl PassSet { + pub const fn prefix(&self) -> &LitStr { + &self.prefix + } + + pub fn identifiers(&self) -> &[Ident] { + self.identifiers.identifiers() + } +} + +impl Parse for PassSet { + fn parse(input: ParseStream) -> Result { + let prefix = input.parse()?; + ::parse(input)?; + + Ok(Self { + prefix, + identifiers: { + let content; + bracketed!(content in input); + content.parse::()? + }, + }) + } +} From eb075e7acf6bb839d1165b468489c0f690feb46a Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Mon, 4 Dec 2023 21:58:11 +0800 Subject: [PATCH 012/108] Refactor dialect macros (#375) --- macro/src/dialect.rs | 20 +++++++-------- macro/src/dialect/input.rs | 14 +++++----- macro/src/dialect/utility.rs | 5 ++-- macro/src/lib.rs | 2 +- melior/src/dialect/ods.rs | 50 ++++++++++++++++++------------------ 5 files changed, 46 insertions(+), 45 deletions(-) diff --git a/macro/src/dialect.rs b/macro/src/dialect.rs index a0a5517515..ad24b8d49a 100644 --- a/macro/src/dialect.rs +++ b/macro/src/dialect.rs @@ -19,28 +19,28 @@ use tblgen::{record::Record, record_keeper::RecordKeeper, TableGenParser}; const LLVM_MAJOR_VERSION: usize = 17; pub fn generate_dialect(input: DialectInput) -> Result> { - let mut td_parser = TableGenParser::new(); + let mut parser = TableGenParser::new(); - if let Some(source) = input.tablegen() { - td_parser = td_parser.add_source(source).map_err(create_syn_error)?; + if let Some(source) = input.table_gen() { + parser = parser.add_source(source).map_err(create_syn_error)?; } if let Some(file) = input.td_file() { - td_parser = td_parser.add_source_file(file).map_err(create_syn_error)?; + parser = parser.add_source_file(file).map_err(create_syn_error)?; } // spell-checker: disable-next-line - for include in input.includes().chain([&*llvm_config("--includedir")?]) { - td_parser = td_parser.add_include_path(include); + for path in input.includes().chain([&*llvm_config("--includedir")?]) { + parser = parser.add_include_path(path); } - let keeper = td_parser.parse().map_err(Error::Parse)?; + let keeper = parser.parse().map_err(Error::Parse)?; - let dialect = dialect_module( + let dialect = generate_dialect_module( input.name(), keeper .all_derived_definitions("Dialect") - .find(|def| def.str_value("name") == Ok(input.name())) + .find(|definition| definition.str_value("name") == Ok(input.name())) .ok_or_else(|| create_syn_error("dialect not found"))?, &keeper, ) @@ -49,7 +49,7 @@ pub fn generate_dialect(input: DialectInput) -> Result, + table_gen: Option, td_file: Option, includes: Vec, } @@ -15,8 +15,8 @@ impl DialectInput { &self.name } - pub fn tablegen(&self) -> Option<&str> { - self.tablegen.as_deref() + pub fn table_gen(&self) -> Option<&str> { + self.table_gen.as_deref() } pub fn td_file(&self) -> Option<&str> { @@ -31,14 +31,14 @@ impl DialectInput { impl Parse for DialectInput { fn parse(input: syn::parse::ParseStream) -> syn::Result { let mut name = None; - let mut tablegen = None; + let mut table_gen = None; let mut td_file = None; let mut includes = vec![]; for item in Punctuated::::parse_terminated(input)? { match item { InputField::Name(field) => name = Some(field.value()), - InputField::TableGen(td) => tablegen = Some(td.value()), + InputField::TableGen(td) => table_gen = Some(td.value()), InputField::TdFile(file) => td_file = Some(file.value()), InputField::Includes(field) => { includes = field.into_iter().map(|literal| literal.value()).collect() @@ -48,7 +48,7 @@ impl Parse for DialectInput { Ok(Self { name: name.ok_or(input.error("dialect name required"))?, - tablegen, + table_gen, td_file, includes, }) @@ -70,7 +70,7 @@ impl Parse for InputField { if ident == format_ident!("name") { Ok(Self::Name(input.parse()?)) - } else if ident == format_ident!("tablegen") { + } else if ident == format_ident!("table_gen") { Ok(Self::TableGen(input.parse()?)) } else if ident == format_ident!("td_file") { Ok(Self::TdFile(input.parse()?)) diff --git a/macro/src/dialect/utility.rs b/macro/src/dialect/utility.rs index 86e7a4c908..bc43fae820 100644 --- a/macro/src/dialect/utility.rs +++ b/macro/src/dialect/utility.rs @@ -11,10 +11,10 @@ pub fn sanitize_snake_case_name(name: &str) -> Result { } fn sanitize_name(name: &str) -> Result { - // Replace any "." with "_" + // Replace any "." with "_". let mut name = name.replace('.', "_"); - // Add "_" suffix to avoid conflicts with existing methods + // Add "_" suffix to avoid conflicts with existing methods. if RESERVED_NAMES.contains(&name.as_str()) || name .chars() @@ -44,6 +44,7 @@ pub fn sanitize_documentation(string: &str) -> Result { }; if block.info.is_empty() { + // Mark them not in Rust to prevent documentation tests. block.info = "text".into(); } } diff --git a/macro/src/lib.rs b/macro/src/lib.rs index 64e01cf6e0..db11c8a20e 100644 --- a/macro/src/lib.rs +++ b/macro/src/lib.rs @@ -20,7 +20,7 @@ use syn::parse_macro_input; /// ```rust /// melior::dialect! { /// name: "func", -/// tablegen: r#"include "mlir/Dialect/Func/IR/FuncOps.td""# +/// table_gen: r#"include "mlir/Dialect/Func/IR/FuncOps.td""# /// } /// ``` #[proc_macro] diff --git a/melior/src/dialect/ods.rs b/melior/src/dialect/ods.rs index 1ff3d515ce..43322430c0 100644 --- a/melior/src/dialect/ods.rs +++ b/melior/src/dialect/ods.rs @@ -9,104 +9,104 @@ pub mod __private { melior_macro::dialect! { name: "affine", - tablegen: r#"include "mlir/Dialect/Affine/IR/AffineOps.td""# + table_gen: r#"include "mlir/Dialect/Affine/IR/AffineOps.td""# } melior_macro::dialect! { name: "amdgpu", - tablegen: r#"include "mlir/Dialect/AMDGPU/IR/AMDGPU.td""# + table_gen: r#"include "mlir/Dialect/AMDGPU/IR/AMDGPU.td""# } melior_macro::dialect! { name: "arith", - tablegen: r#"include "mlir/Dialect/Arith/IR/ArithOps.td""# + table_gen: r#"include "mlir/Dialect/Arith/IR/ArithOps.td""# } melior_macro::dialect! { name: "arm_neon", - tablegen: r#"include "mlir/Dialect/ArmNeon/ArmNeon.td""# + table_gen: r#"include "mlir/Dialect/ArmNeon/ArmNeon.td""# } melior_macro::dialect! { name: "arm_sve", - tablegen: r#"include "mlir/Dialect/ArmSVE/ArmSVE.td""# + table_gen: r#"include "mlir/Dialect/ArmSVE/ArmSVE.td""# } melior_macro::dialect! { name: "async", - tablegen: r#"include "mlir/Dialect/Async/IR/AsyncOps.td""# + table_gen: r#"include "mlir/Dialect/Async/IR/AsyncOps.td""# } melior_macro::dialect! { name: "bufferization", - tablegen: r#"include "mlir/Dialect/Bufferization/IR/BufferizationOps.td""# + table_gen: r#"include "mlir/Dialect/Bufferization/IR/BufferizationOps.td""# } melior_macro::dialect! { name: "cf", - tablegen: r#"include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.td""# + table_gen: r#"include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.td""# } melior_macro::dialect! { name: "func", - tablegen: r#"include "mlir/Dialect/Func/IR/FuncOps.td""# + table_gen: r#"include "mlir/Dialect/Func/IR/FuncOps.td""# } melior_macro::dialect! { name: "index", - tablegen: r#"include "mlir/Dialect/Index/IR/IndexOps.td""# + table_gen: r#"include "mlir/Dialect/Index/IR/IndexOps.td""# } melior_macro::dialect! { name: "llvm", // spell-checker: disable-next-line - tablegen: r#"include "mlir/Dialect/LLVMIR/LLVMOps.td""# + table_gen: r#"include "mlir/Dialect/LLVMIR/LLVMOps.td""# } melior_macro::dialect! { name: "memref", - tablegen: r#"include "mlir/Dialect/MemRef/IR/MemRefOps.td""# + table_gen: r#"include "mlir/Dialect/MemRef/IR/MemRefOps.td""# } melior_macro::dialect! { name: "scf", - tablegen: r#"include "mlir/Dialect/SCF/IR/SCFOps.td""# + table_gen: r#"include "mlir/Dialect/SCF/IR/SCFOps.td""# } melior_macro::dialect! { name: "pdl", - tablegen: r#"include "mlir/Dialect/PDL/IR/PDLOps.td""# + table_gen: r#"include "mlir/Dialect/PDL/IR/PDLOps.td""# } melior_macro::dialect! { name: "pdl_interp", - tablegen: r#"include "mlir/Dialect/PDLInterp/IR/PDLInterpOps.td""# + table_gen: r#"include "mlir/Dialect/PDLInterp/IR/PDLInterpOps.td""# } melior_macro::dialect! { name: "math", - tablegen: r#"include "mlir/Dialect/Math/IR/MathOps.td""# + table_gen: r#"include "mlir/Dialect/Math/IR/MathOps.td""# } melior_macro::dialect! { name: "gpu", - tablegen: r#"include "mlir/Dialect/GPU/IR/GPUOps.td""# + table_gen: r#"include "mlir/Dialect/GPU/IR/GPUOps.td""# } melior_macro::dialect! { name: "linalg", - tablegen: r#"include "mlir/Dialect/Linalg/IR/LinalgOps.td""# + table_gen: r#"include "mlir/Dialect/Linalg/IR/LinalgOps.td""# } melior_macro::dialect! { name: "quant", - tablegen: r#"include "mlir/Dialect/Quant/QuantOps.td""# + table_gen: r#"include "mlir/Dialect/Quant/QuantOps.td""# } melior_macro::dialect! { name: "shape", - tablegen: r#"include "mlir/Dialect/Shape/IR/ShapeOps.td""# + table_gen: r#"include "mlir/Dialect/Shape/IR/ShapeOps.td""# } melior_macro::dialect! { name: "sparse_tensor", - tablegen: r#"include "mlir/Dialect/SparseTensor/IR/SparseTensorOps.td""# + table_gen: r#"include "mlir/Dialect/SparseTensor/IR/SparseTensorOps.td""# } melior_macro::dialect! { name: "tensor", - tablegen: r#"include "mlir/Dialect/Tensor/IR/TensorOps.td""# + table_gen: r#"include "mlir/Dialect/Tensor/IR/TensorOps.td""# } melior_macro::dialect! { name: "tosa", - tablegen: r#"include "mlir/Dialect/Tosa/IR/TosaOps.td""# + table_gen: r#"include "mlir/Dialect/Tosa/IR/TosaOps.td""# } melior_macro::dialect! { name: "transform", - tablegen: r#"include "mlir/Dialect/Transform/IR/TransformOps.td""# + table_gen: r#"include "mlir/Dialect/Transform/IR/TransformOps.td""# } melior_macro::dialect! { name: "vector", - tablegen: r#"include "mlir/Dialect/Vector/IR/VectorOps.td""# + table_gen: r#"include "mlir/Dialect/Vector/IR/VectorOps.td""# } #[cfg(test)] From f85bca88e5de1ef5ed5e07c7bda1019366aa5f40 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 21:43:01 +0800 Subject: [PATCH 013/108] Refactor dialect macros (#376) --- macro/src/dialect.rs | 9 +- macro/src/dialect/dialect.rs | 104 ++++ macro/src/dialect/operation.rs | 504 +++++------------- macro/src/dialect/operation/accessors.rs | 14 +- macro/src/dialect/operation/element_kind.rs | 14 + macro/src/dialect/operation/field_kind.rs | 162 ++++++ .../src/dialect/operation/operation_field.rs | 77 +++ macro/src/dialect/operation/sequence_info.rs | 5 + macro/src/dialect/operation/variadic_kind.rs | 32 ++ macro/src/dialect/utility.rs | 2 +- 10 files changed, 526 insertions(+), 397 deletions(-) create mode 100644 macro/src/dialect/dialect.rs 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 create mode 100644 macro/src/dialect/operation/sequence_info.rs create mode 100644 macro/src/dialect/operation/variadic_kind.rs diff --git a/macro/src/dialect.rs b/macro/src/dialect.rs index ad24b8d49a..67833e57fd 100644 --- a/macro/src/dialect.rs +++ b/macro/src/dialect.rs @@ -54,19 +54,18 @@ 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_def) + .map(Operation::new) .collect::, _>>()? .into_iter() - .filter(|operation| operation.dialect.name() == dialect.name()) + .filter(|operation| operation.dialect_name() == dialect_name) .collect::>(); 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/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 2b6ce9073c..106426fb0b 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -1,312 +1,116 @@ 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; +mod sequence_info; +mod variadic_kind; + +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}, 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::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) - } - } - }) - } -} - -#[derive(Debug, Clone)] -pub struct SequenceInfo { - index: usize, - len: usize, -} - #[derive(Clone, Debug)] -pub enum VariadicKind { - Simple { - seen_variable_length: bool, - }, - SameSize { - num_variable_length: usize, - num_preceding_simple: usize, - num_preceding_variadic: usize, - }, - AttrSized {}, +pub struct Operation<'a> { + dialect_name: &'a str, + short_name: &'a str, + full_name: String, + class_name: &'a str, + summary: String, + can_infer_type: bool, + description: String, + regions: Vec>, + successors: Vec>, + results: Vec>, + operands: Vec>, + attributes: Vec>, + derived_attributes: Vec>, } -impl VariadicKind { - pub fn new(num_variable_length: usize, same_size: bool, attr_sized: bool) -> Self { - if num_variable_length <= 1 { - VariadicKind::Simple { - seen_variable_length: false, - } - } else if same_size { - VariadicKind::SameSize { - num_variable_length, - num_preceding_simple: 0, - num_preceding_variadic: 0, - } - } else if attr_sized { - VariadicKind::AttrSized {} - } else { - unimplemented!() - } - } -} +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"), + )?; -#[derive(Debug, Clone)] -pub struct OperationField<'a> { - pub(crate) name: &'a str, - pub(crate) sanitized_name: Ident, - pub(crate) kind: FieldKind<'a>, -} + 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")?; -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 }) - } + dialect_name: dialect.name()?, + short_name, + full_name: { + let dialect_name = dialect.string_value("name")?; - fn new_region( - name: &'a str, - constraint: RegionConstraint<'a>, - sequence_info: SequenceInfo, - ) -> Result { - Self::new( - name, - FieldKind::Region { - constraint, - sequence_info, + 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")?; - fn new_successor( - name: &'a str, - constraint: SuccessorConstraint<'a>, - sequence_info: SequenceInfo, - ) -> Result { - Self::new( - name, - FieldKind::Successor { - constraint, - sequence_info, + [ + 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, + }) } - 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, - }, - ) + pub fn dialect_name(&self) -> &str { + self.dialect_name } -} -#[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, - description: String, - regions: Vec>, - successors: Vec>, - results: Vec>, - operands: Vec>, - attributes: Vec>, - derived_attributes: Vec>, -} - -impl<'a> Operation<'a> { pub fn fields(&self) -> impl Iterator> + Clone { self.results .iter() @@ -317,8 +121,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() @@ -329,7 +133,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 }, ) @@ -337,8 +141,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() @@ -349,7 +153,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 }, ) @@ -357,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() { + 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(def))?; + .map_err(|error: tblgen::Error| error.set_location(definition))?; if trait_def.subclass_of("TraitList") { work_list.push(trait_def.list_value("traits")?); @@ -382,21 +186,22 @@ 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 + .map(|(name, argument)| { + let mut argument_definition: Record = argument .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")?; + if argument_definition.subclass_of("OpVariable") { + argument_definition = argument_definition.def_value("constraint")?; } - Ok((name, arg_def)) + Ok((name, argument_definition)) }) .collect() } @@ -441,11 +246,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() { @@ -462,28 +267,28 @@ 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; } } 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( @@ -520,78 +325,10 @@ impl<'a> Operation<'a> { }) .collect() } - - pub fn from_def(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)); - - let arguments = Self::dag_constraints(def, "arguments")?; - let regions = Self::collect_regions(def)?; - let (results, num_variable_length_results) = Self::collect_results( - def, - has_trait("::mlir::OpTrait::SameVariadicResultSize"), - has_trait("::mlir::OpTrait::AttrSizedResultSegments"), - )?; - - let name = def.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 = def.str_value("opName")?; - - Ok(Self { - dialect, - 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(def)?, - 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(def)?, - 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 - || r#trait.has_name("::mlir::InferTypeOpInterface::Trait") && regions.is_empty() - }), - summary: { - let summary = def.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..] - ) - } - }, - description: unindent::unindent(def.str_value("description")?), - regions, - }) - } } 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; @@ -605,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/accessors.rs b/macro/src/dialect/operation/accessors.rs index b2f87ff374..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. @@ -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! { 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..944d3b2495 --- /dev/null +++ b/macro/src/dialect/operation/field_kind.rs @@ -0,0 +1,162 @@ +use super::{element_kind::ElementKind, SequenceInfo, VariadicKind}; +use crate::dialect::{ + error::Error, + types::{AttributeConstraint, RegionConstraint, SuccessorConstraint, TypeConstraint}, +}; +use syn::{parse_quote, 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, + }, + ) + } +} 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, +} diff --git a/macro/src/dialect/operation/variadic_kind.rs b/macro/src/dialect/operation/variadic_kind.rs new file mode 100644 index 0000000000..68531d4b5e --- /dev/null +++ b/macro/src/dialect/operation/variadic_kind.rs @@ -0,0 +1,32 @@ +#[derive(Clone, Debug)] +pub enum VariadicKind { + Simple { + variable_length_seen: 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 { + variable_length_seen: 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!() + } + } +} 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 0b64220db80377644b4b435c8e89018032e6bd35 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 22:14:33 +0800 Subject: [PATCH 014/108] Refactor operation bulids in dialect macro (#377) --- macro/src/dialect/operation.rs | 74 ++++++++++---------- macro/src/dialect/operation/accessors.rs | 22 +++--- macro/src/dialect/operation/builder.rs | 2 +- macro/src/dialect/operation/field_kind.rs | 2 +- macro/src/dialect/operation/variadic_kind.rs | 22 +++--- macro/src/dialect/types.rs | 2 +- 6 files changed, 60 insertions(+), 64 deletions(-) diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 106426fb0b..90e5005aa5 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -44,7 +44,7 @@ impl<'a> Operation<'a> { let arguments = Self::dag_constraints(definition, "arguments")?; let regions = Self::collect_regions(definition)?; - let (results, variable_length_results_count) = Self::collect_results( + let (results, unfixed_results_count) = Self::collect_results( definition, has_trait("::mlir::OpTrait::SameVariadicResultSize"), has_trait("::mlir::OpTrait::AttrSizedResultSegments"), @@ -86,7 +86,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")) - && variable_length_results_count == 0 + && unfixed_results_count == 0 || r#trait.has_name("::mlir::InferTypeOpInterface::Trait") && regions.is_empty() }), summary: { @@ -162,22 +162,22 @@ impl<'a> Operation<'a> { } fn collect_traits(definition: Record<'a>) -> Result, Error> { - let mut work_list = vec![definition.list_value("traits")?]; - let mut traits = Vec::new(); + let mut trait_lists = vec![definition.list_value("traits")?]; + let mut traits = vec![]; - while let Some(trait_definition) = work_list.pop() { - for value in trait_definition.iter() { - let trait_def: Record = value + while let Some(trait_list) = trait_lists.pop() { + for value in trait_list.iter() { + let definition: Record = value .try_into() .map_err(|error: tblgen::Error| error.set_location(definition))?; - if trait_def.subclass_of("TraitList") { - work_list.push(trait_def.list_value("traits")?); + if definition.subclass_of("TraitList") { + trait_lists.push(definition.list_value("traits")?); } else { - if trait_def.subclass_of("Interface") { - work_list.push(trait_def.list_value("baseInterfaces")?); + if definition.subclass_of("Interface") { + trait_lists.push(definition.list_value("baseInterfaces")?); } - traits.push(Trait::new(trait_def)?) + traits.push(Trait::new(definition)?) } } } @@ -193,15 +193,15 @@ impl<'a> Operation<'a> { .dag_value(dag_field_name)? .args() .map(|(name, argument)| { - let mut argument_definition: Record = argument + let mut definition: Record = argument .try_into() .map_err(|error: tblgen::Error| error.set_location(definition))?; - if argument_definition.subclass_of("OpVariable") { - argument_definition = argument_definition.def_value("constraint")?; + if definition.subclass_of("OpVariable") { + definition = definition.def_value("constraint")?; } - Ok((name, argument_definition)) + Ok((name, definition)) }) .collect() } @@ -209,7 +209,7 @@ impl<'a> Operation<'a> { fn collect_results( def: Record<'a>, same_size: bool, - attr_sized: bool, + attribute_sized: bool, ) -> Result<(Vec, usize), Error> { Self::collect_elements( &Self::dag_constraints(def, "results")? @@ -218,24 +218,24 @@ impl<'a> Operation<'a> { .collect::>(), ElementKind::Result, same_size, - attr_sized, + attribute_sized, ) } fn collect_operands( arguments: &[(&'a str, Record<'a>)], same_size: bool, - attr_sized: bool, + attribute_sized: bool, ) -> Result>, Error> { Ok(Self::collect_elements( &arguments .iter() - .filter(|(_, arg_def)| arg_def.subclass_of("TypeConstraint")) - .map(|(name, arg_def)| (*name, TypeConstraint::new(*arg_def))) + .filter(|(_, definition)| definition.subclass_of("TypeConstraint")) + .map(|(name, definition)| (*name, TypeConstraint::new(*definition))) .collect::>(), ElementKind::Operand, same_size, - attr_sized, + attribute_sized, )? .0) } @@ -244,13 +244,13 @@ impl<'a> Operation<'a> { elements: &[(&'a str, TypeConstraint<'a>)], element_kind: ElementKind, same_size: bool, - attr_sized: bool, + attribute_sized: bool, ) -> Result<(Vec>, usize), Error> { - let variable_length_count = elements + let unfixed_count = elements .iter() - .filter(|(_, constraint)| constraint.has_variable_length()) + .filter(|(_, constraint)| constraint.has_unfixed()) .count(); - let mut variadic_kind = VariadicKind::new(variable_length_count, same_size, attr_sized); + let mut variadic_kind = VariadicKind::new(unfixed_count, same_size, attribute_sized); let mut fields = vec![]; for (index, (name, constraint)) in elements.iter().enumerate() { @@ -266,11 +266,9 @@ impl<'a> Operation<'a> { )?); match &mut variadic_kind { - VariadicKind::Simple { - variable_length_seen: seen_variable_length, - } => { - if constraint.has_variable_length() { - *seen_variable_length = true; + VariadicKind::Simple { unfixed_seen } => { + if constraint.has_unfixed() { + *unfixed_seen = true; } } VariadicKind::SameSize { @@ -278,17 +276,17 @@ impl<'a> Operation<'a> { preceding_variadic_count, .. } => { - if constraint.has_variable_length() { + if constraint.has_unfixed() { *preceding_variadic_count += 1; } else { *preceding_simple_count += 1; } } - VariadicKind::AttrSized {} => {} + VariadicKind::AttributeSized => {} } } - Ok((fields, variable_length_count)) + Ok((fields, unfixed_count)) } fn collect_attributes( @@ -296,12 +294,12 @@ impl<'a> Operation<'a> { ) -> Result>, Error> { arguments .iter() - .filter(|(_, arg_def)| arg_def.subclass_of("Attr")) - .map(|(name, arg_def)| { + .filter(|(_, definition)| definition.subclass_of("Attr")) + .map(|(name, definition)| { // TODO: Replace assert! with Result - assert!(!arg_def.subclass_of("DerivedAttr")); + assert!(!definition.subclass_of("DerivedAttr")); - OperationField::new_attribute(name, AttributeConstraint::new(*arg_def)) + OperationField::new_attribute(name, AttributeConstraint::new(*definition)) }) .collect() } diff --git a/macro/src/dialect/operation/accessors.rs b/macro/src/dialect/operation/accessors.rs index ee08465c89..7ebf4ecd0a 100644 --- a/macro/src/dialect/operation/accessors.rs +++ b/macro/src/dialect/operation/accessors.rs @@ -25,9 +25,7 @@ impl<'a> OperationField<'a> { let name = self.name; Some(match variadic_kind { - VariadicKind::Simple { - variable_length_seen: seen_variable_length, - } => { + VariadicKind::Simple { unfixed_seen } => { if constraint.is_optional() { // Optional element, and some singular elements. // Only present if the amount of groups is at least the number of @@ -40,15 +38,15 @@ impl<'a> OperationField<'a> { } } } else if constraint.is_variadic() { - // A variable length group + // A unfixed group // Length computed by subtracting the amount of other // singular elements from the number of elements. quote! { let group_length = self.operation.#count() - #len + 1; self.operation.#plural().skip(#index).take(group_length) } - } else if *seen_variable_length { - // Single element after variable length group + } else if *unfixed_seen { + // Single element after unfixed group // Compute the length of that variable group and take the next element quote! { let group_length = self.operation.#count() - #len + 1; @@ -62,16 +60,16 @@ impl<'a> OperationField<'a> { } } VariadicKind::SameSize { - variable_length_count, + unfixed_count, preceding_simple_count, preceding_variadic_count, } => { let compute_start_length = quote! { - let total_var_len = self.operation.#count() - #variable_length_count + 1; - let group_len = total_var_len / #variable_length_count; + let total_var_len = self.operation.#count() - #unfixed_count + 1; + let group_len = total_var_len / #unfixed_count; let start = #preceding_simple_count + #preceding_variadic_count * group_len; }; - let get_elements = if constraint.has_variable_length() { + let get_elements = if constraint.has_unfixed() { quote! { self.operation.#plural().skip(start).take(group_len) } @@ -83,7 +81,7 @@ impl<'a> OperationField<'a> { quote! { #compute_start_length #get_elements } } - VariadicKind::AttrSized {} => { + VariadicKind::AttributeSized => { let attribute_name = format!("{}_segment_sizes", kind_str); let compute_start_length = quote! { let attribute = @@ -98,7 +96,7 @@ impl<'a> OperationField<'a> { .sum::() as usize; let group_len = attribute.element(#index)? as usize; }; - let get_elements = if !constraint.has_variable_length() { + let get_elements = if !constraint.has_unfixed() { quote! { self.operation.#kind_ident(start) } diff --git a/macro/src/dialect/operation/builder.rs b/macro/src/dialect/operation/builder.rs index 5ccf057fd5..a7b9efc7f8 100644 --- a/macro/src/dialect/operation/builder.rs +++ b/macro/src/dialect/operation/builder.rs @@ -40,7 +40,7 @@ impl<'o> OperationBuilder<'o> { // arguments let add_arguments = match &field.kind { FieldKind::Element { constraint, .. } => { - if constraint.has_variable_length() && !constraint.is_optional() { + if constraint.has_unfixed() && !constraint.is_optional() { quote! { #name } } else { quote! { &[#name] } diff --git a/macro/src/dialect/operation/field_kind.rs b/macro/src/dialect/operation/field_kind.rs index 944d3b2495..8412d9d0fb 100644 --- a/macro/src/dialect/operation/field_kind.rs +++ b/macro/src/dialect/operation/field_kind.rs @@ -128,7 +128,7 @@ impl<'a> FieldKind<'a> { }; if !constraint.is_variadic() { Self::create_result_type(base_type) - } else if let VariadicKind::AttrSized {} = variadic_kind { + } else if let VariadicKind::AttributeSized = variadic_kind { Self::create_result_type(Self::create_iterator_type(base_type)) } else { Self::create_iterator_type(base_type) diff --git a/macro/src/dialect/operation/variadic_kind.rs b/macro/src/dialect/operation/variadic_kind.rs index 68531d4b5e..3866c98e2d 100644 --- a/macro/src/dialect/operation/variadic_kind.rs +++ b/macro/src/dialect/operation/variadic_kind.rs @@ -1,30 +1,30 @@ #[derive(Clone, Debug)] pub enum VariadicKind { Simple { - variable_length_seen: bool, + unfixed_seen: bool, }, SameSize { - variable_length_count: usize, + unfixed_count: usize, preceding_simple_count: usize, preceding_variadic_count: usize, }, - AttrSized {}, + AttributeSized, } impl VariadicKind { - pub fn new(variable_length_count: usize, same_size: bool, attr_sized: bool) -> Self { - if variable_length_count <= 1 { - VariadicKind::Simple { - variable_length_seen: false, + pub fn new(unfixed_count: usize, same_size: bool, attribute_sized: bool) -> Self { + if unfixed_count <= 1 { + Self::Simple { + unfixed_seen: false, } } else if same_size { - VariadicKind::SameSize { - variable_length_count, + Self::SameSize { + unfixed_count, preceding_simple_count: 0, preceding_variadic_count: 0, } - } else if attr_sized { - VariadicKind::AttrSized {} + } else if attribute_sized { + Self::AttributeSized } else { unimplemented!() } diff --git a/macro/src/dialect/types.rs b/macro/src/dialect/types.rs index 891aab8be1..6b4db80c62 100644 --- a/macro/src/dialect/types.rs +++ b/macro/src/dialect/types.rs @@ -100,7 +100,7 @@ impl<'a> TypeConstraint<'a> { self.0.subclass_of("VariadicOfVariadic") } - pub fn has_variable_length(&self) -> bool { + pub fn has_unfixed(&self) -> bool { self.is_variadic() || self.is_optional() } } From 9f10c9ed69f3d6eecd4f6f4ed82e2ff028783558 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 5 Dec 2023 23:33:05 +0800 Subject: [PATCH 015/108] Refactor dialect macros (#378) --- macro/src/dialect.rs | 10 ++- macro/src/dialect/dialect.rs | 104 ----------------------- macro/src/dialect/error.rs | 11 ++- macro/src/dialect/input.rs | 48 ++--------- macro/src/dialect/input/input_field.rs | 34 ++++++++ macro/src/dialect/operation.rs | 65 +++++++------- macro/src/dialect/operation/accessors.rs | 9 +- macro/src/dialect/operation/builder.rs | 2 +- macro/src/dialect/types.rs | 34 ++++---- 9 files changed, 116 insertions(+), 201 deletions(-) delete mode 100644 macro/src/dialect/dialect.rs create mode 100644 macro/src/dialect/input/input_field.rs diff --git a/macro/src/dialect.rs b/macro/src/dialect.rs index 67833e57fd..9a5563e470 100644 --- a/macro/src/dialect.rs +++ b/macro/src/dialect.rs @@ -30,7 +30,12 @@ pub fn generate_dialect(input: DialectInput) -> Result, _>>()? .into_iter() .filter(|operation| operation.dialect_name() == dialect_name) - .collect::>(); + .map(|operation| operation.to_tokens()) + .collect::, _>>()?; let doc = format!( "`{name}` dialect.\n\n{}", diff --git a/macro/src/dialect/dialect.rs b/macro/src/dialect/dialect.rs deleted file mode 100644 index 67833e57fd..0000000000 --- a/macro/src/dialect/dialect.rs +++ /dev/null @@ -1,104 +0,0 @@ -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/error.rs b/macro/src/dialect/error.rs index 2f7b67f93d..4c4a13b367 100644 --- a/macro/src/dialect/error.rs +++ b/macro/src/dialect/error.rs @@ -83,16 +83,19 @@ impl From for Error { pub enum OdsError { ExpectedSuperClass(&'static str), InvalidTrait, + UnexpectedSuperClass(&'static str), } impl Display for OdsError { fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { match self { - Self::ExpectedSuperClass(class) => write!( - formatter, - "expected this record to be a subclass of {class}", - ), + Self::ExpectedSuperClass(class) => { + write!(formatter, "record should be a sub-class of {class}",) + } Self::InvalidTrait => write!(formatter, "record is not a supported trait"), + Self::UnexpectedSuperClass(class) => { + write!(formatter, "record should not be a sub-class of {class}",) + } } } } diff --git a/macro/src/dialect/input.rs b/macro/src/dialect/input.rs index 0304083fb0..bb11df5fb7 100644 --- a/macro/src/dialect/input.rs +++ b/macro/src/dialect/input.rs @@ -1,13 +1,14 @@ -use proc_macro2::Ident; -use quote::format_ident; +mod input_field; + +use self::input_field::InputField; use std::ops::Deref; -use syn::{bracketed, parse::Parse, punctuated::Punctuated, LitStr, Token}; +use syn::{parse::Parse, punctuated::Punctuated, Token}; pub struct DialectInput { name: String, table_gen: Option, td_file: Option, - includes: Vec, + include_directories: Vec, } impl DialectInput { @@ -23,8 +24,8 @@ impl DialectInput { self.td_file.as_deref() } - pub fn includes(&self) -> impl Iterator { - self.includes.iter().map(Deref::deref) + pub fn include_directories(&self) -> impl Iterator { + self.include_directories.iter().map(Deref::deref) } } @@ -40,7 +41,7 @@ impl Parse for DialectInput { InputField::Name(field) => name = Some(field.value()), InputField::TableGen(td) => table_gen = Some(td.value()), InputField::TdFile(file) => td_file = Some(file.value()), - InputField::Includes(field) => { + InputField::IncludeDirectories(field) => { includes = field.into_iter().map(|literal| literal.value()).collect() } } @@ -50,38 +51,7 @@ impl Parse for DialectInput { name: name.ok_or(input.error("dialect name required"))?, table_gen, td_file, - includes, + include_directories: includes, }) } } - -enum InputField { - Name(LitStr), - TableGen(LitStr), - TdFile(LitStr), - Includes(Punctuated), -} - -impl Parse for InputField { - fn parse(input: syn::parse::ParseStream) -> syn::Result { - let ident = input.parse::()?; - - input.parse::()?; - - if ident == format_ident!("name") { - Ok(Self::Name(input.parse()?)) - } else if ident == format_ident!("table_gen") { - Ok(Self::TableGen(input.parse()?)) - } else if ident == format_ident!("td_file") { - Ok(Self::TdFile(input.parse()?)) - } else if ident == format_ident!("include_dirs") { - let content; - bracketed!(content in input); - Ok(Self::Includes( - Punctuated::::parse_terminated(&content)?, - )) - } else { - Err(input.error(format!("invalid field {}", ident))) - } - } -} diff --git a/macro/src/dialect/input/input_field.rs b/macro/src/dialect/input/input_field.rs new file mode 100644 index 0000000000..61a161fca6 --- /dev/null +++ b/macro/src/dialect/input/input_field.rs @@ -0,0 +1,34 @@ +use proc_macro2::Ident; +use quote::format_ident; +use syn::{bracketed, parse::Parse, punctuated::Punctuated, LitStr, Token}; + +pub enum InputField { + Name(LitStr), + TableGen(LitStr), + TdFile(LitStr), + IncludeDirectories(Punctuated), +} + +impl Parse for InputField { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let ident = input.parse::()?; + + input.parse::()?; + + if ident == format_ident!("name") { + Ok(Self::Name(input.parse()?)) + } else if ident == format_ident!("table_gen") { + Ok(Self::TableGen(input.parse()?)) + } else if ident == format_ident!("td_file") { + Ok(Self::TdFile(input.parse()?)) + } else if ident == format_ident!("include_dirs") { + let content; + bracketed!(content in input); + Ok(Self::IncludeDirectories( + Punctuated::::parse_terminated(&content)?, + )) + } else { + Err(input.error(format!("invalid field {}", ident))) + } + } +} diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 90e5005aa5..fdee4641ad 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -16,7 +16,7 @@ use crate::dialect::{ types::{AttributeConstraint, RegionConstraint, SuccessorConstraint, Trait, TypeConstraint}, }; use proc_macro2::TokenStream; -use quote::{format_ident, quote, ToTokens, TokenStreamExt}; +use quote::{format_ident, quote}; use tblgen::{error::WithLocation, record::Record}; #[derive(Clone, Debug)] @@ -44,7 +44,7 @@ impl<'a> Operation<'a> { let arguments = Self::dag_constraints(definition, "arguments")?; let regions = Self::collect_regions(definition)?; - let (results, unfixed_results_count) = Self::collect_results( + let (results, unfixed_result_count) = Self::collect_results( definition, has_trait("::mlir::OpTrait::SameVariadicResultSize"), has_trait("::mlir::OpTrait::AttrSizedResultSegments"), @@ -86,7 +86,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")) - && unfixed_results_count == 0 + && unfixed_result_count == 0 || r#trait.has_name("::mlir::InferTypeOpInterface::Trait") && regions.is_empty() }), summary: { @@ -114,16 +114,17 @@ impl<'a> Operation<'a> { pub fn fields(&self) -> impl Iterator> + Clone { self.results .iter() - .chain(self.operands.iter()) - .chain(self.regions.iter()) - .chain(self.successors.iter()) - .chain(self.attributes.iter()) - .chain(self.derived_attributes.iter()) + .chain(&self.operands) + .chain(&self.regions) + .chain(&self.successors) + .chain(&self.attributes) + .chain(&self.derived_attributes) } fn collect_successors(definition: Record<'a>) -> Result, Error> { let successors_dag = definition.dag_value("successors")?; let len = successors_dag.num_args(); + successors_dag .args() .enumerate() @@ -144,6 +145,7 @@ impl<'a> Operation<'a> { fn collect_regions(definition: Record<'a>) -> Result, Error> { let regions_dag = definition.dag_value("regions")?; let len = regions_dag.num_args(); + regions_dag .args() .enumerate() @@ -296,53 +298,58 @@ impl<'a> Operation<'a> { .iter() .filter(|(_, definition)| definition.subclass_of("Attr")) .map(|(name, definition)| { - // TODO: Replace assert! with Result - assert!(!definition.subclass_of("DerivedAttr")); - - OperationField::new_attribute(name, AttributeConstraint::new(*definition)) + if definition.subclass_of("DerivedAttr") { + Err(OdsError::UnexpectedSuperClass("DerivedAttr") + .with_location(*definition) + .into()) + } else { + OperationField::new_attribute(name, AttributeConstraint::new(*definition)) + } }) .collect() } - fn collect_derived_attributes(def: Record<'a>) -> Result>, Error> { - def.values() + fn collect_derived_attributes( + definition: Record<'a>, + ) -> Result>, Error> { + definition + .values() .filter_map(|value| { let Ok(def) = Record::try_from(value) else { return None; }; def.subclass_of("Attr").then_some(def) }) - .map(|def| { - if def.subclass_of("DerivedAttr") { - OperationField::new_attribute(def.name()?, AttributeConstraint::new(def)) + .map(|definition| { + if definition.subclass_of("DerivedAttr") { + OperationField::new_attribute( + definition.name()?, + AttributeConstraint::new(definition), + ) } else { Err(OdsError::ExpectedSuperClass("DerivedAttr") - .with_location(def) + .with_location(definition) .into()) } }) .collect() } -} -impl<'a> ToTokens for Operation<'a> { - // TODO Compile values for proper error handling and remove `Result::expect()`. - fn to_tokens(&self, tokens: &mut TokenStream) { + pub fn to_tokens(&self) -> Result { let class_name = format_ident!("{}", &self.class_name); let name = &self.full_name; let accessors = self .fields() - .map(|field| field.accessors().expect("valid accessors")); - let builder = OperationBuilder::new(self).expect("valid builder generator"); - let builder_tokens = builder.builder().expect("valid builder"); + .map(|field| field.accessors()) + .collect::, _>>()?; + let builder = OperationBuilder::new(self)?; + let builder_tokens = builder.to_tokens()?; let builder_fn = builder.create_op_builder_fn(); - let default_constructor = builder - .create_default_constructor() - .expect("valid constructor"); + let default_constructor = builder.create_default_constructor()?; let summary = &self.summary; let description = &self.description; - tokens.append_all(quote! { + Ok(quote! { #[doc = #summary] #[doc = "\n\n"] #[doc = #description] diff --git a/macro/src/dialect/operation/accessors.rs b/macro/src/dialect/operation/accessors.rs index 7ebf4ecd0a..e2f1cd0f62 100644 --- a/macro/src/dialect/operation/accessors.rs +++ b/macro/src/dialect/operation/accessors.rs @@ -14,10 +14,9 @@ impl<'a> OperationField<'a> { sequence_info: SequenceInfo { index, len }, variadic_kind, } => { - let kind_str = kind.as_str(); - let kind_ident = format_ident!("{}", kind_str); - let plural = format_ident!("{}s", kind_str); - let count = format_ident!("{}_count", kind_str); + let kind_ident = format_ident!("{}", kind.as_str()); + let plural = format_ident!("{}s", kind.as_str()); + let count = format_ident!("{}_count", kind.as_str()); let error_variant = match kind { ElementKind::Operand => quote!(OperandNotFound), ElementKind::Result => quote!(ResultNotFound), @@ -82,7 +81,7 @@ impl<'a> OperationField<'a> { quote! { #compute_start_length #get_elements } } VariadicKind::AttributeSized => { - let attribute_name = format!("{}_segment_sizes", kind_str); + let attribute_name = format!("{}_segment_sizes", kind.as_str()); let compute_start_length = quote! { let attribute = ::melior::ir::attribute::DenseI32ArrayAttribute::<'c>::try_from( diff --git a/macro/src/dialect/operation/builder.rs b/macro/src/dialect/operation/builder.rs index a7b9efc7f8..5f5989ccfb 100644 --- a/macro/src/dialect/operation/builder.rs +++ b/macro/src/dialect/operation/builder.rs @@ -105,7 +105,7 @@ impl<'o> OperationBuilder<'o> { }) } - pub fn builder(&self) -> Result { + pub fn to_tokens(&self) -> Result { let field_names = self .type_state .field_names() diff --git a/macro/src/dialect/types.rs b/macro/src/dialect/types.rs index 6b4db80c62..0549503a17 100644 --- a/macro/src/dialect/types.rs +++ b/macro/src/dialect/types.rs @@ -173,7 +173,7 @@ enum TraitKind { #[allow(unused)] structural: bool, }, - Pred {}, + Predicate, Internal { name: String, }, @@ -188,25 +188,25 @@ pub struct Trait { } impl Trait { - pub fn new(def: Record) -> Result { + pub fn new(definition: Record) -> Result { Ok(Self { - kind: if def.subclass_of("PredTrait") { - TraitKind::Pred {} - } else if def.subclass_of("InterfaceTrait") { + kind: if definition.subclass_of("PredTrait") { + TraitKind::Predicate + } else if definition.subclass_of("InterfaceTrait") { TraitKind::Interface { - name: Self::name(def)?, + name: Self::name(definition)?, } - } else if def.subclass_of("NativeTrait") { + } else if definition.subclass_of("NativeTrait") { TraitKind::Native { - name: Self::name(def)?, - structural: def.subclass_of("StructuralOpTrait"), + name: Self::name(definition)?, + structural: definition.subclass_of("StructuralOpTrait"), } - } else if def.subclass_of("GenInternalTrait") { + } else if definition.subclass_of("GenInternalTrait") { TraitKind::Internal { - name: def.string_value("trait")?, + name: definition.string_value("trait")?, } } else { - return Err(OdsError::InvalidTrait.with_location(def).into()); + return Err(OdsError::InvalidTrait.with_location(definition).into()); }, }) } @@ -215,14 +215,14 @@ impl Trait { match &self.kind { TraitKind::Native { name, .. } | TraitKind::Internal { name } - | TraitKind::Interface { name } => expected_name == name, - TraitKind::Pred {} => false, + | TraitKind::Interface { name } => name == expected_name, + TraitKind::Predicate => false, } } - fn name(def: Record) -> Result { - let r#trait = def.string_value("trait")?; - let namespace = def.string_value("cppNamespace")?; + fn name(definition: Record) -> Result { + let r#trait = definition.string_value("trait")?; + let namespace = definition.string_value("cppNamespace")?; Ok(if namespace.is_empty() { r#trait From c18b6b1e4075b135ba3b687c8b6efc0540036fec Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Wed, 6 Dec 2023 18:27:52 +0800 Subject: [PATCH 016/108] Refactor macro (#379) --- macro/src/dialect.rs | 12 +- macro/src/dialect/error.rs | 26 +-- macro/src/dialect/error/ods.rs | 27 +++ macro/src/dialect/operation.rs | 230 ++++++++++--------- macro/src/dialect/operation/accessors.rs | 26 +-- macro/src/dialect/operation/builder.rs | 143 ++++++------ macro/src/dialect/operation/field_kind.rs | 3 +- macro/src/dialect/operation/variadic_kind.rs | 2 +- 8 files changed, 248 insertions(+), 221 deletions(-) create mode 100644 macro/src/dialect/error/ods.rs diff --git a/macro/src/dialect.rs b/macro/src/dialect.rs index 9a5563e470..eeffddf76e 100644 --- a/macro/src/dialect.rs +++ b/macro/src/dialect.rs @@ -6,6 +6,7 @@ mod utility; use self::{ error::Error, + operation::generate_operation, utility::{sanitize_documentation, sanitize_snake_case_name}, }; pub use input::DialectInput; @@ -64,9 +65,14 @@ fn generate_dialect_module( .all_derived_definitions("Op") .map(Operation::new) .collect::, _>>()? - .into_iter() - .filter(|operation| operation.dialect_name() == dialect_name) - .map(|operation| operation.to_tokens()) + .iter() + .map(|operation| { + Ok::<_, Error>(if operation.dialect_name()? == dialect_name { + Some(generate_operation(operation)?) + } else { + None + }) + }) .collect::, _>>()?; let doc = format!( diff --git a/macro/src/dialect/error.rs b/macro/src/dialect/error.rs index 4c4a13b367..8eaec98373 100644 --- a/macro/src/dialect/error.rs +++ b/macro/src/dialect/error.rs @@ -1,3 +1,6 @@ +mod ods; + +pub use self::ods::OdsError; use std::{ error, fmt::{self, Display, Formatter}, @@ -78,26 +81,3 @@ impl From for Error { Self::Utf8(error) } } - -#[derive(Debug)] -pub enum OdsError { - ExpectedSuperClass(&'static str), - InvalidTrait, - UnexpectedSuperClass(&'static str), -} - -impl Display for OdsError { - fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { - match self { - Self::ExpectedSuperClass(class) => { - write!(formatter, "record should be a sub-class of {class}",) - } - Self::InvalidTrait => write!(formatter, "record is not a supported trait"), - Self::UnexpectedSuperClass(class) => { - write!(formatter, "record should not be a sub-class of {class}",) - } - } - } -} - -impl error::Error for OdsError {} diff --git a/macro/src/dialect/error/ods.rs b/macro/src/dialect/error/ods.rs new file mode 100644 index 0000000000..2f0b5798af --- /dev/null +++ b/macro/src/dialect/error/ods.rs @@ -0,0 +1,27 @@ +use std::{ + error::Error, + fmt::{self, Display, Formatter}, +}; + +#[derive(Debug)] +pub enum OdsError { + ExpectedSuperClass(&'static str), + InvalidTrait, + UnexpectedSuperClass(&'static str), +} + +impl Display for OdsError { + fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { + match self { + Self::ExpectedSuperClass(class) => { + write!(formatter, "record should be a sub-class of {class}",) + } + Self::InvalidTrait => write!(formatter, "record is not a supported trait"), + Self::UnexpectedSuperClass(class) => { + write!(formatter, "record should not be a sub-class of {class}",) + } + } + } +} + +impl Error for OdsError {} diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index fdee4641ad..b7fce567a4 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -7,8 +7,12 @@ mod sequence_info; mod variadic_kind; use self::{ - builder::OperationBuilder, element_kind::ElementKind, field_kind::FieldKind, - operation_field::OperationField, sequence_info::SequenceInfo, variadic_kind::VariadicKind, + builder::{generate_operation_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::{ @@ -19,15 +23,70 @@ use proc_macro2::TokenStream; use quote::{format_ident, quote}; use tblgen::{error::WithLocation, record::Record}; -#[derive(Clone, Debug)] +pub fn generate_operation(operation: &Operation) -> Result { + let summary = operation.summary()?; + let description = operation.description()?; + let class_name = format_ident!("{}", operation.class_name()?); + let name = &operation.full_name()?; + let accessors = operation + .fields() + .map(|field| field.accessors()) + .collect::, _>>()?; + + let builder = OperationBuilder::new(operation)?; + let builder_tokens = generate_operation_builder(&builder)?; + let builder_fn = builder.create_op_builder_fn()?; + let default_constructor = builder.create_default_constructor()?; + + Ok(quote! { + #[doc = #summary] + #[doc = "\n\n"] + #[doc = #description] + pub struct #class_name<'c> { + operation: ::melior::ir::operation::Operation<'c>, + } + + impl<'c> #class_name<'c> { + pub fn name() -> &'static str { + #name + } + + pub fn operation(&self) -> &::melior::ir::operation::Operation<'c> { + &self.operation + } + + #builder_fn + + #(#accessors)* + } + + #builder_tokens + + #default_constructor + + impl<'c> TryFrom<::melior::ir::operation::Operation<'c>> for #class_name<'c> { + type Error = ::melior::Error; + + fn try_from( + operation: ::melior::ir::operation::Operation<'c>, + ) -> Result { + // TODO Check an operation name. + Ok(Self { operation }) + } + } + + impl<'c> From<#class_name<'c>> for ::melior::ir::operation::Operation<'c> { + fn from(operation: #class_name<'c>) -> ::melior::ir::operation::Operation<'c> { + operation.operation + } + } + }) +} + +#[derive(Debug)] pub struct Operation<'a> { - dialect_name: &'a str, - short_name: &'a str, - full_name: String, - class_name: &'a str, - summary: String, + definition: Record<'a>, can_infer_type: bool, - description: String, regions: Vec>, successors: Vec>, results: Vec>, @@ -38,7 +97,6 @@ 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)); @@ -50,30 +108,7 @@ impl<'a> Operation<'a> { 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, @@ -89,26 +124,65 @@ impl<'a> Operation<'a> { && unfixed_result_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, + definition, + }) + } + + fn dialect(&self) -> Result { + Ok(self.definition.def_value("opDialect")?) + } + + pub fn dialect_name(&self) -> Result<&str, Error> { + Ok(self.dialect()?.name()?) + } + + pub fn class_name(&self) -> Result<&str, Error> { + let name = self.definition.name()?; + + Ok(if name.starts_with('_') { + name + } else if let Some(name) = name.split('_').nth(1) { + // Trim dialect prefix from name. + name + } else { + name + }) + } + + pub fn short_name(&self) -> Result<&str, Error> { + Ok(self.definition.str_value("opName")?) + } + + pub fn full_name(&self) -> Result { + let dialect_name = self.dialect()?.string_value("name")?; + let short_name = self.short_name()?; + + Ok(if dialect_name.is_empty() { + short_name.into() + } else { + format!("{dialect_name}.{short_name}") }) } - pub fn dialect_name(&self) -> &str { - self.dialect_name + pub fn summary(&self) -> Result { + let short_name = self.short_name()?; + let class_name = self.class_name()?; + let summary = self.definition.str_value("summary")?; + + Ok([ + format!("[`{short_name}`]({class_name}) operation."), + if summary.is_empty() { + Default::default() + } else { + summary[0..1].to_uppercase() + &summary[1..] + "." + }, + ] + .join(" ")) + } + + pub fn description(&self) -> Result { + sanitize_documentation(self.definition.str_value("description")?) } pub fn fields(&self) -> impl Iterator> + Clone { @@ -334,62 +408,4 @@ impl<'a> Operation<'a> { }) .collect() } - - pub fn to_tokens(&self) -> Result { - let class_name = format_ident!("{}", &self.class_name); - let name = &self.full_name; - let accessors = self - .fields() - .map(|field| field.accessors()) - .collect::, _>>()?; - let builder = OperationBuilder::new(self)?; - let builder_tokens = builder.to_tokens()?; - let builder_fn = builder.create_op_builder_fn(); - let default_constructor = builder.create_default_constructor()?; - let summary = &self.summary; - let description = &self.description; - - Ok(quote! { - #[doc = #summary] - #[doc = "\n\n"] - #[doc = #description] - pub struct #class_name<'c> { - operation: ::melior::ir::operation::Operation<'c>, - } - - impl<'c> #class_name<'c> { - pub fn name() -> &'static str { - #name - } - - pub fn operation(&self) -> &::melior::ir::operation::Operation<'c> { - &self.operation - } - - #builder_fn - - #(#accessors)* - } - - #builder_tokens - - #default_constructor - - impl<'c> TryFrom<::melior::ir::operation::Operation<'c>> for #class_name<'c> { - type Error = ::melior::Error; - - fn try_from( - operation: ::melior::ir::operation::Operation<'c>, - ) -> Result { - Ok(Self { operation }) - } - } - - impl<'c> From<#class_name<'c>> for ::melior::ir::operation::Operation<'c> { - fn from(operation: #class_name<'c>) -> ::melior::ir::operation::Operation<'c> { - operation.operation - } - } - }) - } } diff --git a/macro/src/dialect/operation/accessors.rs b/macro/src/dialect/operation/accessors.rs index e2f1cd0f62..b48a3d34e5 100644 --- a/macro/src/dialect/operation/accessors.rs +++ b/macro/src/dialect/operation/accessors.rs @@ -153,31 +153,24 @@ impl<'a> OperationField<'a> { Some(if constraint.is_unit()? { quote! { self.operation.attribute(#name).is_some() } } else { - quote! { - self.operation - .attribute(#name)? - .try_into() - .map_err(::melior::Error::from) - } + // TODO Handle returning `melior::Attribute`. + quote! { Ok(self.operation.attribute(#name)?.try_into()?) } }) } }) } fn remover_impl(&self) -> Result, Error> { - Ok(match &self.kind { - FieldKind::Attribute { constraint } => { + Ok(if let FieldKind::Attribute { constraint } = &self.kind { + if constraint.is_unit()? || constraint.is_optional()? { let name = &self.name; - if constraint.is_unit()? || constraint.is_optional()? { - Some(quote! { - self.operation.remove_attribute(#name) - }) - } else { - None - } + Some(quote! { self.operation.remove_attribute(#name) }) + } else { + None } - _ => None, + } else { + None }) } @@ -233,6 +226,7 @@ impl<'a> OperationField<'a> { let return_type = &self.kind.return_type()?; self.getter_impl()?.map(|body| { quote! { + #[allow(clippy::needless_question_mark)] pub fn #ident(&self, context: &'c ::melior::Context) -> #return_type { #body } diff --git a/macro/src/dialect/operation/builder.rs b/macro/src/dialect/operation/builder.rs index 5f5989ccfb..7c068f3539 100644 --- a/macro/src/dialect/operation/builder.rs +++ b/macro/src/dialect/operation/builder.rs @@ -9,6 +9,55 @@ use super::{ use proc_macro2::{Ident, TokenStream}; use quote::{format_ident, quote}; +pub fn generate_operation_builder(builder: &OperationBuilder) -> Result { + let field_names = builder + .type_state + .field_names() + .map(sanitize_snake_case_name) + .collect::, _>>()?; + + let phantom_fields = builder + .type_state + .parameters() + .zip(&field_names) + .map(|(r#type, name)| { + quote! { + #name: ::std::marker::PhantomData<#r#type> + } + }); + + let phantom_arguments = field_names + .iter() + .map(|name| quote! { #name: ::std::marker::PhantomData }) + .collect::>(); + + let builder_fns = builder + .create_builder_fns(&field_names, phantom_arguments.as_slice()) + .collect::, _>>()?; + + let new = builder.create_new_fn(phantom_arguments.as_slice())?; + let build = builder.create_build_fn()?; + + let builder_identifier = builder.builder_identifier()?; + let doc = format!("Builder for {}", builder.operation.summary()?); + let iter_arguments = builder.type_state.parameters(); + + Ok(quote! { + #[doc = #doc] + pub struct #builder_identifier<'c, #(#iter_arguments),*> { + builder: ::melior::ir::operation::OperationBuilder<'c>, + context: &'c ::melior::Context, + #(#phantom_fields),* + } + + #new + + #(#builder_fns)* + + #build + }) +} + pub struct OperationBuilder<'o> { operation: &'o Operation<'o>, type_state: TypeStateList, @@ -27,9 +76,9 @@ impl<'o> OperationBuilder<'o> { field_names: &'a [Ident], phantoms: &'a [TokenStream], ) -> impl Iterator> + 'a { - let builder_ident = self.builder_identifier(); - self.operation.fields().map(move |field| { + // TODO Initialize a builder identifier out of this closure. + let builder_ident = self.builder_identifier()?; let name = sanitize_snake_case_name(field.name)?; let parameter_type = field.kind.parameter_type()?; let argument = quote! { #name: #parameter_type }; @@ -74,6 +123,7 @@ impl<'o> OperationBuilder<'o> { Ok(if field.kind.is_optional()? { let parameters = self.type_state.parameters().collect::>(); + quote! { impl<'c, #(#parameters),*> #builder_ident<'c, #(#parameters),*> { pub fn #name(mut self, #argument) -> #builder_ident<'c, #(#parameters),*> { @@ -88,6 +138,7 @@ impl<'o> OperationBuilder<'o> { let parameters = self.type_state.parameters_without(field.name); let arguments_set = self.type_state.arguments_set(field.name, true); let arguments_unset = self.type_state.arguments_set(field.name, false); + quote! { impl<'c, #(#parameters),*> #builder_ident<'c, #(#arguments_unset),*> { pub fn #name(mut self, #argument) -> #builder_ident<'c, #(#arguments_set),*> { @@ -105,80 +156,31 @@ impl<'o> OperationBuilder<'o> { }) } - pub fn to_tokens(&self) -> Result { - let field_names = self - .type_state - .field_names() - .map(sanitize_snake_case_name) - .collect::, _>>()?; - - let phantom_fields = - self.type_state - .parameters() - .zip(&field_names) - .map(|(r#type, name)| { - quote! { - #name: ::std::marker::PhantomData<#r#type> - } - }); - - let phantom_arguments = field_names - .iter() - .map(|name| quote! { #name: ::std::marker::PhantomData }) - .collect::>(); - - let builder_fns = self - .create_builder_fns(&field_names, phantom_arguments.as_slice()) - .collect::, _>>()?; - - let new = self.create_new_fn(phantom_arguments.as_slice()); - let build = self.create_build_fn(); - - let builder_ident = self.builder_identifier(); - let doc = format!("Builder for {}", self.operation.summary); - let iter_arguments = self.type_state.parameters(); - - Ok(quote! { - #[doc = #doc] - pub struct #builder_ident <'c, #(#iter_arguments),* > { - builder: ::melior::ir::operation::OperationBuilder<'c>, - context: &'c ::melior::Context, - #(#phantom_fields),* - } - - #new - - #(#builder_fns)* - - #build - }) - } - - fn create_build_fn(&self) -> TokenStream { - let builder_ident = self.builder_identifier(); + fn create_build_fn(&self) -> Result { + let builder_ident = self.builder_identifier()?; let arguments = self.type_state.arguments_all_set(true); - let class_name = format_ident!("{}", &self.operation.class_name); + let class_name = format_ident!("{}", &self.operation.class_name()?); let error = format!("should be a valid {class_name}"); let maybe_infer = self .operation .can_infer_type .then_some(quote! { .enable_result_type_inference() }); - quote! { + Ok(quote! { impl<'c> #builder_ident<'c, #(#arguments),*> { pub fn build(self) -> #class_name<'c> { self.builder #maybe_infer.build().expect("valid operation").try_into().expect(#error) } } - } + }) } - fn create_new_fn(&self, phantoms: &[TokenStream]) -> TokenStream { - let builder_ident = self.builder_identifier(); - let name = &self.operation.full_name; + fn create_new_fn(&self, phantoms: &[TokenStream]) -> Result { + let builder_ident = self.builder_identifier()?; + let name = &self.operation.full_name()?; let arguments = self.type_state.arguments_all_set(false); - quote! { + Ok(quote! { impl<'c> #builder_ident<'c, #(#arguments),*> { pub fn new(context: &'c ::melior::Context, location: ::melior::ir::Location<'c>) -> Self { Self { @@ -188,25 +190,26 @@ impl<'o> OperationBuilder<'o> { } } } - } + }) } - pub fn create_op_builder_fn(&self) -> TokenStream { - let builder_ident = self.builder_identifier(); + pub fn create_op_builder_fn(&self) -> Result { + let builder_ident = self.builder_identifier()?; let arguments = self.type_state.arguments_all_set(false); - quote! { + + Ok(quote! { pub fn builder( context: &'c ::melior::Context, location: ::melior::ir::Location<'c> ) -> #builder_ident<'c, #(#arguments),*> { #builder_ident::new(context, location) } - } + }) } pub fn create_default_constructor(&self) -> Result { - let class_name = format_ident!("{}", &self.operation.class_name); - let name = sanitize_snake_case_name(self.operation.short_name)?; + let class_name = format_ident!("{}", &self.operation.class_name()?); + let name = sanitize_snake_case_name(self.operation.short_name()?)?; let arguments = Self::required_fields(self.operation) .map(|field| { let field = field?; @@ -225,7 +228,7 @@ impl<'o> OperationBuilder<'o> { }) .collect::, Error>>()?; - let doc = format!("Creates a new {}", self.operation.summary); + let doc = format!("Creates a new {}", self.operation.summary()?); Ok(quote! { #[allow(clippy::too_many_arguments)] @@ -257,7 +260,7 @@ impl<'o> OperationBuilder<'o> { )) } - fn builder_identifier(&self) -> Ident { - format_ident!("{}Builder", self.operation.class_name) + fn builder_identifier(&self) -> Result { + Ok(format_ident!("{}Builder", self.operation.class_name()?)) } } diff --git a/macro/src/dialect/operation/field_kind.rs b/macro/src/dialect/operation/field_kind.rs index 8412d9d0fb..2b4c67dc6c 100644 --- a/macro/src/dialect/operation/field_kind.rs +++ b/macro/src/dialect/operation/field_kind.rs @@ -126,9 +126,10 @@ impl<'a> FieldKind<'a> { parse_quote!(::melior::ir::operation::OperationResult<'c, '_>) } }; + if !constraint.is_variadic() { Self::create_result_type(base_type) - } else if let VariadicKind::AttributeSized = variadic_kind { + } else if variadic_kind == &VariadicKind::AttributeSized { Self::create_result_type(Self::create_iterator_type(base_type)) } else { Self::create_iterator_type(base_type) diff --git a/macro/src/dialect/operation/variadic_kind.rs b/macro/src/dialect/operation/variadic_kind.rs index 3866c98e2d..eeeb5a1f35 100644 --- a/macro/src/dialect/operation/variadic_kind.rs +++ b/macro/src/dialect/operation/variadic_kind.rs @@ -1,4 +1,4 @@ -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Eq, PartialEq)] pub enum VariadicKind { Simple { unfixed_seen: bool, From 229b7473e8d3ffb4c4750e22270301468c43b05e Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Thu, 7 Dec 2023 19:10:09 +0800 Subject: [PATCH 017/108] Use GitHub Action for Dependabot (#380) --- .github/mergify.yml | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 .github/mergify.yml diff --git a/.github/mergify.yml b/.github/mergify.yml deleted file mode 100644 index 30630317c4..0000000000 --- a/.github/mergify.yml +++ /dev/null @@ -1,11 +0,0 @@ -pull_request_rules: - - name: dependabot - conditions: - - author=dependabot[bot] - actions: - queue: - name: default - method: squash -queue_rules: - - name: default - conditions: [] From 3daf75745db11aab842f87794184c53823fed41e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 16:12:13 +0000 Subject: [PATCH 018/108] build(deps): Bump once_cell from 1.18.0 to 1.19.0 (#381) Bumps [once_cell](https://github.com/matklad/once_cell) from 1.18.0 to 1.19.0.
Changelog

Sourced from once_cell's changelog.

1.19.0

  • Use portable-atomic instead of atomic-polyfill, #251.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=once_cell&package-manager=cargo&previous-version=1.18.0&new-version=1.19.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- macro/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 960a6e5de7..ddb2defb71 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -666,9 +666,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "onig" diff --git a/macro/Cargo.toml b/macro/Cargo.toml index fe758089ef..34eff8d39a 100644 --- a/macro/Cargo.toml +++ b/macro/Cargo.toml @@ -15,7 +15,7 @@ proc-macro = true [dependencies] comrak = "0.20.0" convert_case = "0.6.0" -once_cell = "1.18.0" +once_cell = "1.19.0" proc-macro2 = "1" quote = "1" regex = "1.10.2" From 6fb16c1e60ef5a8415d55f8a90dbd7a567b6cd7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 17:09:51 +0000 Subject: [PATCH 019/108] build(deps): Bump syn from 2.0.39 to 2.0.40 (#382) Bumps [syn](https://github.com/dtolnay/syn) from 2.0.39 to 2.0.40.
Release notes

Sourced from syn's releases.

2.0.40

Commits
  • cf7f40a Release 2.0.40
  • 1ce8ccf Merge pull request #1538 from dtolnay/testinvisible
  • d06bff8 Add test for parsing Delimiter::None in expressions
  • 9ec66d4 Merge pull request #1545 from dtolnay/groupedlet
  • 384621a Fix None-delimited let expression in stmt position
  • 5325b6d Add test of let expr surrounded in None-delimited group
  • 0ddfc27 Merge pull request #1544 from dtolnay/nonedelimloop
  • 9c99b3f Fix stmt boundary after None-delimited group containing loop
  • 2781584 Add test of None-delimited group containing loop in match arm
  • d332928 Simplify token stream construction in Delimiter::None tests
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=syn&package-manager=cargo&previous-version=2.0.39&new-version=2.0.40)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ddb2defb71..6153c269eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,7 +105,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.39", + "syn 2.0.40", "which", ] @@ -128,7 +128,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.39", + "syn 2.0.40", "which", ] @@ -226,7 +226,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.40", ] [[package]] @@ -619,7 +619,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.39", + "syn 2.0.40", "tblgen", "unindent", ] @@ -760,7 +760,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn 2.0.39", + "syn 2.0.40", ] [[package]] @@ -897,7 +897,7 @@ checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.40", ] [[package]] @@ -963,9 +963,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e" dependencies = [ "proc-macro2", "quote", @@ -1033,7 +1033,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.40", ] [[package]] From 816e3c9cc95a16538bd4b16c85176a0c65867e3f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Dec 2023 17:00:01 +0000 Subject: [PATCH 020/108] build(deps): Bump syn from 2.0.40 to 2.0.41 (#383) Bumps [syn](https://github.com/dtolnay/syn) from 2.0.40 to 2.0.41.
Release notes

Sourced from syn's releases.

2.0.41

  • Support parsing syn::Field in parse_quote! (#1548)
Commits
  • 63b1701 Release 2.0.41
  • 920ab7d Merge pull request #1548 from dtolnay/parsequotefield
  • 5e15924 Test parse_quote implementation for Field
  • c268c67 Support parsing Field in parse_quote
  • 2ab0f6a Merge pull request #1547 from dtolnay/testparsequote
  • 46172a4 Add parse_quote tests
  • 0fcdad0 Support punctuated Pairs iterator in snapshot tests
  • 06161ba Update test suite to nightly-2023-12-12
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=syn&package-manager=cargo&previous-version=2.0.40&new-version=2.0.41)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6153c269eb..7e9f488cbb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,7 +105,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.40", + "syn 2.0.41", "which", ] @@ -128,7 +128,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.40", + "syn 2.0.41", "which", ] @@ -226,7 +226,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.40", + "syn 2.0.41", ] [[package]] @@ -619,7 +619,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.40", + "syn 2.0.41", "tblgen", "unindent", ] @@ -760,7 +760,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn 2.0.40", + "syn 2.0.41", ] [[package]] @@ -897,7 +897,7 @@ checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.40", + "syn 2.0.41", ] [[package]] @@ -963,9 +963,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.40" +version = "2.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e" +checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" dependencies = [ "proc-macro2", "quote", @@ -1033,7 +1033,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.40", + "syn 2.0.41", ] [[package]] From bb4d509937ec6a8e71e08e77d736fe98468ac528 Mon Sep 17 00:00:00 2001 From: MrAzteca Date: Tue, 19 Dec 2023 13:59:48 +0100 Subject: [PATCH 021/108] Add support for `ExecutionEngine::lookup()`. (#384) --- melior/src/execution_engine.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/melior/src/execution_engine.rs b/melior/src/execution_engine.rs index c55777bf15..2a77f29d08 100644 --- a/melior/src/execution_engine.rs +++ b/melior/src/execution_engine.rs @@ -1,7 +1,8 @@ use crate::{ir::Module, logical_result::LogicalResult, string_ref::StringRef, Error}; use mlir_sys::{ mlirExecutionEngineCreate, mlirExecutionEngineDestroy, mlirExecutionEngineDumpToObjectFile, - mlirExecutionEngineInvokePacked, mlirExecutionEngineRegisterSymbol, MlirExecutionEngine, + mlirExecutionEngineInvokePacked, mlirExecutionEngineLookup, mlirExecutionEngineRegisterSymbol, + MlirExecutionEngine, }; /// An execution engine. @@ -34,6 +35,11 @@ impl ExecutionEngine { } } + /// Searches a symbol in a module and returns a pointer to it. + pub fn lookup(&self, name: &str) -> *mut () { + unsafe { mlirExecutionEngineLookup(self.raw, StringRef::new(name).to_raw()) as *mut () } + } + /// Invokes a function in a module. The `arguments` argument includes /// pointers to results of the function as well as arguments. /// From 184b57dede5589bd996b30c46cb481a847a6494a Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 19 Dec 2023 22:00:50 +0900 Subject: [PATCH 022/108] chore: Release --- Cargo.lock | 4 ++-- macro/Cargo.toml | 2 +- melior/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7e9f488cbb..604648c656 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -595,7 +595,7 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "melior" -version = "0.14.0" +version = "0.14.1" dependencies = [ "dashmap", "indoc", @@ -608,7 +608,7 @@ dependencies = [ [[package]] name = "melior-macro" -version = "0.8.0" +version = "0.8.1" dependencies = [ "comrak", "convert_case", diff --git a/macro/Cargo.toml b/macro/Cargo.toml index 34eff8d39a..c59d0194c8 100644 --- a/macro/Cargo.toml +++ b/macro/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "melior-macro" description = "Internal macros for Melior" -version = "0.8.0" +version = "0.8.1" edition = "2021" license = "Apache-2.0" repository = "https://github.com/raviqqe/melior" diff --git a/melior/Cargo.toml b/melior/Cargo.toml index c0df35f672..8ee999a30c 100644 --- a/melior/Cargo.toml +++ b/melior/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "melior" description = "The rustic MLIR bindings in Rust" -version = "0.14.0" +version = "0.14.1" edition = "2021" license = "Apache-2.0" repository = "https://github.com/raviqqe/melior" From f1ca6f0ea0550c5412f15c773ca4758f12c29f72 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Wed, 20 Dec 2023 08:51:44 +0900 Subject: [PATCH 023/108] chore: Release --- Cargo.lock | 4 ++-- macro/Cargo.toml | 2 +- melior/Cargo.toml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 604648c656..8b11a0b7b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -595,7 +595,7 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "melior" -version = "0.14.1" +version = "0.15.0" dependencies = [ "dashmap", "indoc", @@ -608,7 +608,7 @@ dependencies = [ [[package]] name = "melior-macro" -version = "0.8.1" +version = "0.9.0" dependencies = [ "comrak", "convert_case", diff --git a/macro/Cargo.toml b/macro/Cargo.toml index c59d0194c8..3db3ed0891 100644 --- a/macro/Cargo.toml +++ b/macro/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "melior-macro" description = "Internal macros for Melior" -version = "0.8.1" +version = "0.9.0" edition = "2021" license = "Apache-2.0" repository = "https://github.com/raviqqe/melior" diff --git a/melior/Cargo.toml b/melior/Cargo.toml index 8ee999a30c..3f3a5c1c89 100644 --- a/melior/Cargo.toml +++ b/melior/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "melior" description = "The rustic MLIR bindings in Rust" -version = "0.14.1" +version = "0.15.0" edition = "2021" license = "Apache-2.0" repository = "https://github.com/raviqqe/melior" @@ -13,7 +13,7 @@ ods-dialects = [] [dependencies] dashmap = "5.5.3" -melior-macro = { version = "0.8", path = "../macro" } +melior-macro = { version = "0.9", path = "../macro" } mlir-sys = "0.2" once_cell = "1" From f1c896508b66686ffdc308f1ff7d1c7362f543af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Dec 2023 16:29:34 +0000 Subject: [PATCH 024/108] build(deps): Bump syn from 2.0.41 to 2.0.42 (#386) Bumps [syn](https://github.com/dtolnay/syn) from 2.0.41 to 2.0.42.
Release notes

Sourced from syn's releases.

2.0.42

  • Documentation improvements
Commits
  • 6dcf8ab Release 2.0.42
  • 4349d0b Merge pull request #1551 from dtolnay/cursorexample
  • 12ff3d1 Add a real-world example for ParseBuffer::cursor
  • bdd0645 Precondition for cmp_asssuming_same_buffer is to check same_buffer
  • a6ac138 Update test suite to nightly-2023-12-19
  • 66ee902 Ignore blocks_in_conditions clippy lint
  • e11575e Ignore uninhabited_references clippy lint
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=syn&package-manager=cargo&previous-version=2.0.41&new-version=2.0.42)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8b11a0b7b4..c553ff8864 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,7 +105,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.41", + "syn 2.0.42", "which", ] @@ -128,7 +128,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.41", + "syn 2.0.42", "which", ] @@ -226,7 +226,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.42", ] [[package]] @@ -619,7 +619,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.41", + "syn 2.0.42", "tblgen", "unindent", ] @@ -760,7 +760,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn 2.0.41", + "syn 2.0.42", ] [[package]] @@ -897,7 +897,7 @@ checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.42", ] [[package]] @@ -963,9 +963,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.41" +version = "2.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" +checksum = "5b7d0a2c048d661a1a59fcd7355baa232f7ed34e0ee4df2eef3c1c1c0d3852d8" dependencies = [ "proc-macro2", "quote", @@ -1033,7 +1033,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.42", ] [[package]] From 63f61744639a7799d404f3143ce8b7654098607e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Dec 2023 16:52:37 +0000 Subject: [PATCH 025/108] build(deps): Bump proc-macro2 from 1.0.70 to 1.0.71 (#387) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.70 to 1.0.71.
Release notes

Sourced from proc-macro2's releases.

1.0.71

  • Turn on deny(unsafe_op_in_unsafe_fn) lint
Commits
  • 593681b Release 1.0.71
  • 6756d15 Merge pull request #427 from dtolnay/unsafeop
  • e95447c Fill in unsafe blocks inside unsafe functions
  • 54f7f80 Turn on deny(unsafe_op_in_unsafe_fn)
  • 49b26d2 Update ui test suite to nightly-2023-12-15
  • 0b963a2 Unbreak binutils-dev install in GitHub Actions
  • f7576d1 Format with new rustfmt that handles let-else
  • 349dc3f Update afl fuzzer from 0.14 to 0.15
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=proc-macro2&package-manager=cargo&previous-version=1.0.70&new-version=1.0.71)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c553ff8864..3291dc8a68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -765,9 +765,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8" dependencies = [ "unicode-ident", ] From a2919ebe412601112759615e1260d52c19e0f2b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Dec 2023 16:44:33 +0000 Subject: [PATCH 026/108] build(deps): Bump syn from 2.0.42 to 2.0.43 (#388) Bumps [syn](https://github.com/dtolnay/syn) from 2.0.42 to 2.0.43.
Release notes

Sourced from syn's releases.

2.0.43

  • Insert trailing comma if not already present when printing a 1-tuple in pattern position (#1553)
Commits
  • 95ee052 Release 2.0.43
  • 7383e81 Merge pull request #1559 from dtolnay/pattuple
  • 712fde5 Fix ToTokens for PatTuple to insert trailing comma
  • ed9b94e Merge pull request #1558 from dtolnay/tupletests
  • ec8517b Add tuple comma tests
  • 3cf16c7 Merge pull request #1557 from dtolnay/snapshotparsequote
  • 553549f Generalize snapshot parsing to types that do not implement Parse
  • f9ad833 Merge pull request #1556 from dtolnay/punctuatedsnapshot
  • 131b40b Debug impl for punctuated::Pairs superseded by Punctuated
  • 3f12d65 Include punctuation tokens in snapshot tests containing Punctuated
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=syn&package-manager=cargo&previous-version=2.0.42&new-version=2.0.43)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3291dc8a68..d7a4d54526 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,7 +105,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.42", + "syn 2.0.43", "which", ] @@ -128,7 +128,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.42", + "syn 2.0.43", "which", ] @@ -226,7 +226,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.42", + "syn 2.0.43", ] [[package]] @@ -619,7 +619,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.42", + "syn 2.0.43", "tblgen", "unindent", ] @@ -760,7 +760,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn 2.0.42", + "syn 2.0.43", ] [[package]] @@ -897,7 +897,7 @@ checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.42", + "syn 2.0.43", ] [[package]] @@ -963,9 +963,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.42" +version = "2.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b7d0a2c048d661a1a59fcd7355baa232f7ed34e0ee4df2eef3c1c1c0d3852d8" +checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53" dependencies = [ "proc-macro2", "quote", @@ -1033,7 +1033,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.42", + "syn 2.0.43", ] [[package]] From cbc9ef2aeb9ea35edf0997b70ebfe38132a1911a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 16:18:12 +0000 Subject: [PATCH 027/108] build(deps): Bump proc-macro2 from 1.0.71 to 1.0.73 (#390) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.71 to 1.0.73.
Release notes

Sourced from proc-macro2's releases.

1.0.73

  • Documentation improvements

1.0.72

  • Improve build script to be robust to proc_macro::Span unstable API changes
Commits
  • 4dce5d7 Release 1.0.73
  • 708540b Merge pull request #431 from dtolnay/doccfg
  • 014fa82 Restore documented cfg on LineColumn
  • df4fa83 Merge pull request #430 from dtolnay/nightlyci
  • 75897cf Make CI verify that proc_macro_span works in latest nightly
  • 643cb89 Release 1.0.72
  • 3db1977 Merge pull request #429 from dtolnay/probe
  • a961bae Test for the specific proc_macro_span API expected by proc-macro2
  • 784ae2e Merge pull request #428 from dtolnay/cargoenvvar
  • 8ade7da Require cargo promised environment variables to be present
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=proc-macro2&package-manager=cargo&previous-version=1.0.71&new-version=1.0.73)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7a4d54526..bbe7e5e001 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -765,9 +765,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.71" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8" +checksum = "2dd5e8a1f1029c43224ad5898e50140c2aebb1705f19e67c918ebf5b9e797fe1" dependencies = [ "unicode-ident", ] From 559380f0bdb9f8961ff37ee8bbf5a1955b2c91f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 16:22:27 +0000 Subject: [PATCH 028/108] build(deps): Bump syn from 2.0.43 to 2.0.44 (#389) Bumps [syn](https://github.com/dtolnay/syn) from 2.0.43 to 2.0.44.
Release notes

Sourced from syn's releases.

2.0.44

  • Documentation improvements
Commits
  • 58b42f5 Release 2.0.44
  • 4523437 Merge pull request #1569 from dtolnay/cfgvisit
  • 694a1bb Render doc cfg on Visit/VisitMut/Fold trait methods
  • 1728630 Add doc cfg on Error::new_spanned
  • 649e426 Mark exprs which are not parsed in "derive" mode as "full"-only
  • 6c4627f Fill in missing doc cfg on Expr and Pat nodes
  • 1cea0be Merge pull request #1568 from dtolnay/doccfg
  • dc2153d Restore doc cfg on re-exports
  • e2b6ebc Fix typo in ast_enum cfg
  • a193361 Fix unused_macros warning on ast_enum when features are disabled
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=syn&package-manager=cargo&previous-version=2.0.43&new-version=2.0.44)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bbe7e5e001..03a07c80a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,7 +105,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.43", + "syn 2.0.44", "which", ] @@ -128,7 +128,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.43", + "syn 2.0.44", "which", ] @@ -226,7 +226,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.44", ] [[package]] @@ -619,7 +619,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.43", + "syn 2.0.44", "tblgen", "unindent", ] @@ -760,7 +760,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn 2.0.43", + "syn 2.0.44", ] [[package]] @@ -783,9 +783,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "22a37c9326af5ed140c86a46655b5278de879853be5573c01df185b6f49a580a" dependencies = [ "proc-macro2", ] @@ -897,7 +897,7 @@ checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.44", ] [[package]] @@ -963,9 +963,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.43" +version = "2.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53" +checksum = "92d27c2c202598d05175a6dd3af46824b7f747f8d8e9b14c623f19fa5069735d" dependencies = [ "proc-macro2", "quote", @@ -1033,7 +1033,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.44", ] [[package]] From f43818cab9945d2f5c5f2239f26a5ec75b4e0889 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 16:42:36 +0000 Subject: [PATCH 029/108] build(deps): Bump quote from 1.0.34 to 1.0.35 (#393) Bumps [quote](https://github.com/dtolnay/quote) from 1.0.34 to 1.0.35.
Release notes

Sourced from quote's releases.

1.0.35

  • Update proc-macro2 to fix caching issue when using a rustc-wrapper such as sccache
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=quote&package-manager=cargo&previous-version=1.0.34&new-version=1.0.35)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 03a07c80a7..52428876a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -765,9 +765,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.73" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dd5e8a1f1029c43224ad5898e50140c2aebb1705f19e67c918ebf5b9e797fe1" +checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db" dependencies = [ "unicode-ident", ] @@ -783,9 +783,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.34" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a37c9326af5ed140c86a46655b5278de879853be5573c01df185b6f49a580a" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] From 64c2dbb8b7f5098be172339e3e23a280921c4d24 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 16:43:11 +0000 Subject: [PATCH 030/108] build(deps): Bump syn from 2.0.44 to 2.0.46 (#392) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [//]: # (dependabot-start) ⚠️ **Dependabot is rebasing this PR** ⚠️ Rebasing might not happen immediately, so don't worry if this takes some time. Note: if you make any changes to this PR yourself, they will take precedence over the rebase. --- [//]: # (dependabot-end) Bumps [syn](https://github.com/dtolnay/syn) from 2.0.44 to 2.0.46.
Release notes

Sourced from syn's releases.

2.0.46

  • Update proc-macro2 to fix caching issue when using a rustc-wrapper such as sccache

2.0.45

  • Parse unsupported expressions in enum discriminants of DeriveInput as Expr::Verbatim in non-"full" mode, instead of error (#1513)
  • Support parsing PatType with parse_quote! (#1573)
Commits
  • 1650c86 Release 2.0.46
  • 65c7710 Pull in proc-macro2 sccache fix
  • 61dee89 Merge pull request #1574 from dtolnay/precedence
  • 36182d4 Move expression Precedence enum to own module
  • 6bfa278 Release 2.0.45
  • 3ba270b Merge pull request #1573 from dtolnay/pattype
  • 969b207 Impl Parse for PatType
  • a0fcd83 Merge pull request #1572 from dtolnay/discriminant
  • 29a7d7b Add a fallback for parsing DeriveInput discriminants to Verbatim in non-full ...
  • 82f1eb7 Ignore diverging_sub_expression clippy lint
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=syn&package-manager=cargo&previous-version=2.0.44&new-version=2.0.46)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 52428876a4..fd3c633542 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,7 +105,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.44", + "syn 2.0.46", "which", ] @@ -128,7 +128,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.44", + "syn 2.0.46", "which", ] @@ -226,7 +226,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.44", + "syn 2.0.46", ] [[package]] @@ -619,7 +619,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.44", + "syn 2.0.46", "tblgen", "unindent", ] @@ -760,7 +760,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn 2.0.44", + "syn 2.0.46", ] [[package]] @@ -897,7 +897,7 @@ checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.44", + "syn 2.0.46", ] [[package]] @@ -963,9 +963,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.44" +version = "2.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d27c2c202598d05175a6dd3af46824b7f747f8d8e9b14c623f19fa5069735d" +checksum = "89456b690ff72fddcecf231caedbe615c59480c93358a93dfae7fc29e3ebbf0e" dependencies = [ "proc-macro2", "quote", @@ -1033,7 +1033,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.44", + "syn 2.0.46", ] [[package]] From 19f551011bc87ba752dd8c4b9b5257202efce033 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 16:15:04 +0000 Subject: [PATCH 031/108] build(deps): Bump proc-macro2 from 1.0.74 to 1.0.75 (#395) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.74 to 1.0.75.
Release notes

Sourced from proc-macro2's releases.

1.0.75

  • Improve error messages related to proc_macro::LexError (#434)
Commits
  • 2a9b955 Release 1.0.75
  • 6d2899c Merge pull request #434 from dtolnay/mismatch
  • 662426c Fix compiler/fallback mismatch when catching rustc lex error panic
  • 4ae50db Distinguish which direction the mismatch occurs
  • cb94081 Add a way to get mismatch backtrace using cfg
  • 3eb1857 Merge pull request #433 from dtolnay/mismatch
  • 8da8b88 Include line number in compiler/fallback mismatch panic
  • 9c5b613 Mark compiler/fallback mismatch as code coldpath
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=proc-macro2&package-manager=cargo&previous-version=1.0.74&new-version=1.0.75)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fd3c633542..ef4b961c07 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -765,9 +765,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.74" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db" +checksum = "907a61bd0f64c2f29cd1cf1dc34d05176426a3f504a78010f08416ddb7b13708" dependencies = [ "unicode-ident", ] From e5ac9f344af8a79e8810a22372470e960dc415fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 16:15:22 +0000 Subject: [PATCH 032/108] build(deps): Bump syn from 2.0.46 to 2.0.47 (#396) Bumps [syn](https://github.com/dtolnay/syn) from 2.0.46 to 2.0.47.
Release notes

Sourced from syn's releases.

2.0.47

  • Improve error messages related to proc_macro::LexError (#1575)
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=syn&package-manager=cargo&previous-version=2.0.46&new-version=2.0.47)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ef4b961c07..420fea0374 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,7 +105,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.46", + "syn 2.0.47", "which", ] @@ -128,7 +128,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.46", + "syn 2.0.47", "which", ] @@ -226,7 +226,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.47", ] [[package]] @@ -619,7 +619,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.46", + "syn 2.0.47", "tblgen", "unindent", ] @@ -760,7 +760,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn 2.0.46", + "syn 2.0.47", ] [[package]] @@ -897,7 +897,7 @@ checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.47", ] [[package]] @@ -963,9 +963,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.46" +version = "2.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89456b690ff72fddcecf231caedbe615c59480c93358a93dfae7fc29e3ebbf0e" +checksum = "1726efe18f42ae774cc644f330953a5e7b3c3003d3edcecf18850fe9d4dd9afb" dependencies = [ "proc-macro2", "quote", @@ -1033,7 +1033,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.47", ] [[package]] From 8a436360a0baecbd10393863fda2cf7d76e213eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Jan 2024 17:00:25 +0000 Subject: [PATCH 033/108] build(deps): Bump syn from 2.0.47 to 2.0.48 (#397) Bumps [syn](https://github.com/dtolnay/syn) from 2.0.47 to 2.0.48.
Release notes

Sourced from syn's releases.

2.0.48

  • Improve error message on unexpected token after else (#1578)
Commits
  • 5e16fc2 Release 2.0.48
  • dc40084 Merge pull request #1578 from dtolnay/elseblock
  • 82fcefc Fix error message on unexpected token after 'else'
  • e8a5c68 Merge pull request #1576 from dtolnay/exhaustive
  • 97b1df6 Pick up changes to non_exhaustive_omitted_patterns lint
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=syn&package-manager=cargo&previous-version=2.0.47&new-version=2.0.48)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 420fea0374..b2aa8078de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,7 +105,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.47", + "syn 2.0.48", "which", ] @@ -128,7 +128,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.47", + "syn 2.0.48", "which", ] @@ -226,7 +226,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -619,7 +619,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.47", + "syn 2.0.48", "tblgen", "unindent", ] @@ -760,7 +760,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -897,7 +897,7 @@ checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -963,9 +963,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.47" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1726efe18f42ae774cc644f330953a5e7b3c3003d3edcecf18850fe9d4dd9afb" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -1033,7 +1033,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] From da28b68ccbea7453af2a17a33aa7582dea362773 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 16:39:13 +0000 Subject: [PATCH 034/108] build(deps): Bump proc-macro2 from 1.0.75 to 1.0.76 (#398) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.75 to 1.0.76.
Release notes

Sourced from proc-macro2's releases.

1.0.76

  • Work around dead_code warning false positive (#435)
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=proc-macro2&package-manager=cargo&previous-version=1.0.75&new-version=1.0.76)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b2aa8078de..c27f43da24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -765,9 +765,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.75" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907a61bd0f64c2f29cd1cf1dc34d05176426a3f504a78010f08416ddb7b13708" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] From 18a16192d2ffd0a6e43cba4adcda25d4808b51ca Mon Sep 17 00:00:00 2001 From: Edgar Date: Tue, 16 Jan 2024 00:55:37 +0100 Subject: [PATCH 035/108] add call_site location (#399) was missing --- melior/src/ir/location.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/melior/src/ir/location.rs b/melior/src/ir/location.rs index 8834442240..bb5dce678e 100644 --- a/melior/src/ir/location.rs +++ b/melior/src/ir/location.rs @@ -5,8 +5,9 @@ use crate::{ utility::print_callback, }; use mlir_sys::{ - mlirLocationEqual, mlirLocationFileLineColGet, mlirLocationFusedGet, mlirLocationGetContext, - mlirLocationNameGet, mlirLocationPrint, mlirLocationUnknownGet, MlirLocation, + mlirLocationCallSiteGet, mlirLocationEqual, mlirLocationFileLineColGet, mlirLocationFusedGet, + mlirLocationGetContext, mlirLocationNameGet, mlirLocationPrint, mlirLocationUnknownGet, + MlirLocation, }; use std::{ ffi::c_void, @@ -57,6 +58,11 @@ impl<'c> Location<'c> { } } + /// Creates a call site location. + pub fn call_site(callee: Location, caller: Location) -> Self { + unsafe { Self::from_raw(mlirLocationCallSiteGet(callee.to_raw(), caller.to_raw())) } + } + /// Creates an unknown location. pub fn unknown(context: &'c Context) -> Self { unsafe { Self::from_raw(mlirLocationUnknownGet(context.to_raw())) } @@ -138,6 +144,13 @@ mod tests { Location::name(&context, "foo", Location::unknown(&context)); } + #[test] + fn call_site() { + let context = Context::new(); + + Location::call_site(Location::unknown(&context), Location::unknown(&context)); + } + #[test] fn unknown() { Location::unknown(&Context::new()); From 29b95f4ad0bce84806e33c35e7443e62321a83bf Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 16 Jan 2024 08:57:47 +0900 Subject: [PATCH 036/108] chore: Release --- Cargo.lock | 2 +- melior/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c27f43da24..9ec93e839b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -595,7 +595,7 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "melior" -version = "0.15.0" +version = "0.15.1" dependencies = [ "dashmap", "indoc", diff --git a/melior/Cargo.toml b/melior/Cargo.toml index 3f3a5c1c89..29a1c18e29 100644 --- a/melior/Cargo.toml +++ b/melior/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "melior" description = "The rustic MLIR bindings in Rust" -version = "0.15.0" +version = "0.15.1" edition = "2021" license = "Apache-2.0" repository = "https://github.com/raviqqe/melior" From 030074a3103a708f04895ee661d418d11b40eb90 Mon Sep 17 00:00:00 2001 From: Edgar Date: Wed, 17 Jan 2024 13:53:37 +0100 Subject: [PATCH 037/108] memref dimensions should be i64 (#400) If you make a memref type with i64::MAX - 1 you will see the output shows memref<-1xTYPE> also the pointer in mlir-sys is a *i64 By the way, do you know how to make a memref like memref ? --- melior/src/ir/type/mem_ref.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/melior/src/ir/type/mem_ref.rs b/melior/src/ir/type/mem_ref.rs index a206f4527a..ec668abfa5 100644 --- a/melior/src/ir/type/mem_ref.rs +++ b/melior/src/ir/type/mem_ref.rs @@ -18,7 +18,7 @@ impl<'c> MemRefType<'c> { /// Creates a mem-ref type. pub fn new( r#type: Type<'c>, - dimensions: &[u64], + dimensions: &[i64], layout: Option>, memory_space: Option>, ) -> Self { From 1769316dd51940baaded5d715762b7cda90aea71 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Wed, 17 Jan 2024 20:59:08 +0800 Subject: [PATCH 038/108] Test dynamic dimension of `memref` type (#401) --- melior/src/ir/type/mem_ref.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/melior/src/ir/type/mem_ref.rs b/melior/src/ir/type/mem_ref.rs index ec668abfa5..4815be9e5c 100644 --- a/melior/src/ir/type/mem_ref.rs +++ b/melior/src/ir/type/mem_ref.rs @@ -96,6 +96,21 @@ mod tests { ); } + #[test] + fn dynamic_dimension() { + let context = Context::new(); + + assert_eq!( + Type::from(MemRefType::new( + Type::float64(&context), + &[i64::MIN], + None, + None, + )), + Type::parse(&context, "memref").unwrap() + ); + } + #[test] fn layout() { let context = Context::new(); From 3b7f482ba617bbc92e912732e7b7c4a3b8bb55ec Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Wed, 17 Jan 2024 21:03:40 +0800 Subject: [PATCH 039/108] Add release workflow (#402) --- .github/workflows/release.yaml | 23 +++++++++++++++++++++++ .gitignore | 1 + 2 files changed, 24 insertions(+) create mode 100644 .github/workflows/release.yaml diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000000..da81127943 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,23 @@ +name: release +on: + push: + branches: + - main + pull_request: +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} +jobs: + release: + runs-on: ubuntu-latest + environment: ${{ github.ref == 'refs/heads/main' && 'release' || 'test' }} + steps: + - uses: actions/checkout@v4 + - uses: swatinem/rust-cache@v2 + - uses: homebrew/actions/setup-homebrew@master + - run: tools/setup.sh + - run: cargo install cargo-workspaces + - run: cargo workspaces publish -y --from-git + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + if: github.ref == 'refs/heads/main' diff --git a/.gitignore b/.gitignore index eb5a316cbd..6d1bbe1b18 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ +.cargo* target From 453db1cd0c177627abeb73201c3645a429e0a06a Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Wed, 17 Jan 2024 22:25:16 +0800 Subject: [PATCH 040/108] Refactor (#403) --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6d1bbe1b18..eb5a316cbd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ -.cargo* target From 34ac730dc8e58966d49eca27320abee2da1b2658 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Wed, 17 Jan 2024 22:34:57 +0800 Subject: [PATCH 041/108] Bump version (#404) --- Cargo.lock | 2 +- melior/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9ec93e839b..9b4e393ce1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -595,7 +595,7 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "melior" -version = "0.15.1" +version = "0.15.2" dependencies = [ "dashmap", "indoc", diff --git a/melior/Cargo.toml b/melior/Cargo.toml index 29a1c18e29..7e387ee52b 100644 --- a/melior/Cargo.toml +++ b/melior/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "melior" description = "The rustic MLIR bindings in Rust" -version = "0.15.1" +version = "0.15.2" edition = "2021" license = "Apache-2.0" repository = "https://github.com/raviqqe/melior" From 81a03f4087a1d1ce372cb7ff1e2e06ce7d938a05 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 16:18:19 +0000 Subject: [PATCH 042/108] build(deps): Bump regex from 1.10.2 to 1.10.3 (#407) Bumps [regex](https://github.com/rust-lang/regex) from 1.10.2 to 1.10.3.
Changelog

Sourced from regex's changelog.

1.10.3 (2024-01-21)

This is a new patch release that fixes the feature configuration of optional dependencies, and fixes an unsound use of bounds check elision.

Bug fixes:

Commits
  • 0c09903 1.10.3
  • 653bb59 deps: bump regex-automata to 0.4.4
  • e7b5401 regex-automata-0.4.4
  • 1bc667d changelog: 1.10.3
  • fbd2537 safety: guard in Input::new against incorrect AsRef implementations
  • 027eebd cargo: set 'default-features = false' for memchr and aho-corasick
  • dc0a9d2 ci: small clean-ups
  • a3d5975 doc: fix link in Index<&str> impl docs
  • 4f5992f doc: tweak Captures documentation
  • 837fd85 regex-cli-0.2.0
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=regex&package-manager=cargo&previous-version=1.10.2&new-version=1.10.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- macro/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9b4e393ce1..62c0f4cc9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -801,9 +801,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", @@ -813,9 +813,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "3b7fa1134405e2ec9353fd416b17f8dacd46c473d7d3fd1cf202706a14eb792a" dependencies = [ "aho-corasick", "memchr", diff --git a/macro/Cargo.toml b/macro/Cargo.toml index 3db3ed0891..1b3c12dfbe 100644 --- a/macro/Cargo.toml +++ b/macro/Cargo.toml @@ -18,7 +18,7 @@ convert_case = "0.6.0" once_cell = "1.19.0" proc-macro2 = "1" quote = "1" -regex = "1.10.2" +regex = "1.10.3" syn = { version = "2", features = ["full"] } tblgen = { version = "0.3.0", features = ["llvm17-0"], default-features = false } unindent = "0.2.3" From eaab657833f11fe545e738ee1181dce831adc6ca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 16:18:34 +0000 Subject: [PATCH 043/108] build(deps): Bump proc-macro2 from 1.0.76 to 1.0.78 (#408) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.76 to 1.0.78.
Release notes

Sourced from proc-macro2's releases.

1.0.78

1.0.77

  • Add a function to reset thread-local span data (#438, thanks @​buchgr)
Commits
  • d850a1d Release 1.0.78
  • 6cefaec Merge pull request #442 from dtolnay/byterange
  • 1082767 Expose Span::byte_range
  • da1be4d Release 1.0.77
  • 69fee37 Merge pull request #440 from dtolnay/example
  • 66a3ef0 Raise minimum tested compiler to 1.63
  • d2441c3 Add example code for invalidate_current_thread_spans
  • 43011bf Ensure invalidate_current_thread_spans has docs even if proc-macro disabled
  • 7e7bb0f Improve documentation of invalidate_current_thread_spans
  • 64778fc Move invalidate_current_thread_spans to proc_macro2::extra
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=proc-macro2&package-manager=cargo&previous-version=1.0.76&new-version=1.0.78)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 62c0f4cc9a..c6011b58c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -765,9 +765,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] From a50eeac043c0fc1bd5147e2e00bce08b7575d304 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 21:56:02 +0000 Subject: [PATCH 044/108] build(deps): Bump shlex from 1.2.0 to 1.3.0 (#409) Bumps [shlex](https://github.com/comex/rust-shlex) from 1.2.0 to 1.3.0.
Changelog

Sourced from shlex's changelog.

1.3.0

  • Full fix for the high-severity security vulnerability RUSTSEC-2024-0006 a.k.a. GHSA-r7qv-8r2h-pg27:
    • Deprecates quote APIs in favor of try_ equivalents that complain about nul bytes.
    • Also adds a builder API, which allows re-enabling nul bytes without using the deprecated interface, and in the future can allow other things (as discussed in quoting_warning).
    • Adds documentation about various security risks that remain, particularly with interactive shells.
  • Adds explicit MSRV of 1.46.0.

1.2.1

  • Partial fix for the high-severity security vulnerability RUSTSEC-2024-0006 a.k.a. GHSA-r7qv-8r2h-pg27 without bumping MSRV:
    • The bytes { and \xa0 are now escaped by quoting functions.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=shlex&package-manager=cargo&previous-version=1.2.0&new-version=1.3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/raviqqe/melior/network/alerts).
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c6011b58c2..0982e2617b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -919,9 +919,9 @@ checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" [[package]] name = "shlex" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "similar" From 71b086b55250e68a29d79bd14b89dedbec14f864 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jan 2024 16:30:00 +0000 Subject: [PATCH 045/108] build(deps): Bump comrak from 0.20.0 to 0.21.0 (#410) Bumps comrak from 0.20.0 to 0.21.0. [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=comrak&package-manager=cargo&previous-version=0.20.0&new-version=0.21.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- macro/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0982e2617b..b1ea7d267a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -243,9 +243,9 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "comrak" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f18e72341e6cdc7489cffb76f993812a14a906db54dedb020044ccc211dcaae" +checksum = "6751998a48e2327773c95f6f8e03c6e77c0156ce539d74c17d2199ff3d05e197" dependencies = [ "clap", "derive_builder", diff --git a/macro/Cargo.toml b/macro/Cargo.toml index 1b3c12dfbe..73b132b916 100644 --- a/macro/Cargo.toml +++ b/macro/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["mlir", "llvm"] proc-macro = true [dependencies] -comrak = "0.20.0" +comrak = "0.21.0" convert_case = "0.6.0" once_cell = "1.19.0" proc-macro2 = "1" From 7478664ece92f6b0e8028c9308a74e0a234f2ba1 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Wed, 14 Feb 2024 00:22:36 +0900 Subject: [PATCH 046/108] Refactor dialect macros (#411) --- macro/src/dialect/operation.rs | 15 ++-- macro/src/dialect/operation/accessors.rs | 60 +++++++------- macro/src/dialect/operation/builder.rs | 49 ++++++------ macro/src/dialect/operation/field_kind.rs | 33 ++++---- macro/src/dialect/types.rs | 96 ++++++++++++++--------- 5 files changed, 133 insertions(+), 120 deletions(-) diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index b7fce567a4..134b977a00 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -33,7 +33,7 @@ pub fn generate_operation(operation: &Operation) -> Result { .map(|field| field.accessors()) .collect::, _>>()?; - let builder = OperationBuilder::new(operation)?; + let builder = OperationBuilder::new(operation); let builder_tokens = generate_operation_builder(&builder)?; let builder_fn = builder.create_op_builder_fn()?; let default_constructor = builder.create_default_constructor()?; @@ -98,7 +98,7 @@ pub struct Operation<'a> { impl<'a> Operation<'a> { pub fn new(definition: Record<'a>) -> Result { let traits = Self::collect_traits(definition)?; - let has_trait = |name| traits.iter().any(|r#trait| r#trait.has_name(name)); + let has_trait = |name| traits.iter().any(|r#trait| r#trait.name() == Some(name)); let arguments = Self::dag_constraints(definition, "arguments")?; let regions = Self::collect_regions(definition)?; @@ -119,10 +119,11 @@ impl<'a> Operation<'a> { 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")) + (r#trait.name() == Some("::mlir::OpTrait::FirstAttrDerivedResultType") + || r#trait.name() == Some("::mlir::OpTrait::SameOperandsAndResultType")) && unfixed_result_count == 0 - || r#trait.has_name("::mlir::InferTypeOpInterface::Trait") && regions.is_empty() + || r#trait.name() == Some("::mlir::InferTypeOpInterface::Trait") + && regions.is_empty() }), regions, definition, @@ -377,7 +378,7 @@ impl<'a> Operation<'a> { .with_location(*definition) .into()) } else { - OperationField::new_attribute(name, AttributeConstraint::new(*definition)) + OperationField::new_attribute(name, AttributeConstraint::new(*definition)?) } }) .collect() @@ -398,7 +399,7 @@ impl<'a> Operation<'a> { if definition.subclass_of("DerivedAttr") { OperationField::new_attribute( definition.name()?, - AttributeConstraint::new(definition), + AttributeConstraint::new(definition)?, ) } else { Err(OdsError::ExpectedSuperClass("DerivedAttr") diff --git a/macro/src/dialect/operation/accessors.rs b/macro/src/dialect/operation/accessors.rs index b48a3d34e5..ffa0002f3f 100644 --- a/macro/src/dialect/operation/accessors.rs +++ b/macro/src/dialect/operation/accessors.rs @@ -6,8 +6,8 @@ use proc_macro2::TokenStream; use quote::{format_ident, quote}; impl<'a> OperationField<'a> { - fn getter_impl(&self) -> Result, Error> { - Ok(match &self.kind { + fn getter(&self) -> Option { + match &self.kind { FieldKind::Element { kind, constraint, @@ -30,19 +30,19 @@ impl<'a> OperationField<'a> { // Only present if the amount of groups is at least the number of // elements. quote! { - if self.operation.#count() < #len { - Err(::melior::Error::#error_variant(#name)) - } else { - self.operation.#kind_ident(#index) - } + if self.operation.#count() < #len { + Err(::melior::Error::#error_variant(#name)) + } else { + self.operation.#kind_ident(#index) + } } } else if constraint.is_variadic() { // A unfixed group // Length computed by subtracting the amount of other // singular elements from the number of elements. quote! { - let group_length = self.operation.#count() - #len + 1; - self.operation.#plural().skip(#index).take(group_length) + let group_length = self.operation.#count() - #len + 1; + self.operation.#plural().skip(#index).take(group_length) } } else if *unfixed_seen { // Single element after unfixed group @@ -86,8 +86,8 @@ impl<'a> OperationField<'a> { let attribute = ::melior::ir::attribute::DenseI32ArrayAttribute::<'c>::try_from( self.operation - .attribute(#attribute_name)? - )?; + .attribute(#attribute_name)? + )?; let start = (0..#index) .map(|index| attribute.element(index)) .collect::, _>>()? @@ -150,19 +150,19 @@ impl<'a> OperationField<'a> { FieldKind::Attribute { constraint } => { let name = &self.name; - Some(if constraint.is_unit()? { + Some(if constraint.is_unit() { quote! { self.operation.attribute(#name).is_some() } } else { // TODO Handle returning `melior::Attribute`. quote! { Ok(self.operation.attribute(#name)?.try_into()?) } }) } - }) + } } - fn remover_impl(&self) -> Result, Error> { - Ok(if let FieldKind::Attribute { constraint } = &self.kind { - if constraint.is_unit()? || constraint.is_optional()? { + fn remover(&self) -> Option { + if let FieldKind::Attribute { constraint } = &self.kind { + if constraint.is_unit() || constraint.is_optional() { let name = &self.name; Some(quote! { self.operation.remove_attribute(#name) }) @@ -171,49 +171,47 @@ impl<'a> OperationField<'a> { } } else { None - }) + } } - fn setter_impl(&self) -> Result, Error> { + fn setter(&self) -> Option { let FieldKind::Attribute { constraint } = &self.kind else { - return Ok(None); + return None; }; let name = &self.name; - Ok(Some(if constraint.is_unit()? { + Some(if constraint.is_unit() { quote! { if value { - self.operation.set_attribute(#name, Attribute::unit(&self.operation.context())); + self.operation.set_attribute(#name, Attribute::unit(&self.operation.context())); } else { - self.operation.remove_attribute(#name) + self.operation.remove_attribute(#name) } } } else { quote! { self.operation.set_attribute(#name, &value.into()); } - })) + }) } pub fn accessors(&self) -> Result { let setter = { let ident = sanitize_snake_case_name(&format!("set_{}", self.name))?; - if let Some(body) = self.setter_impl()? { - let parameter_type = &self.kind.parameter_type()?; + self.setter().map(|body| { + let parameter_type = &self.kind.parameter_type(); quote! { pub fn #ident(&mut self, context: &'c ::melior::Context, value: #parameter_type) { #body } } - } else { - quote!() - } + }) }; let remover = { let ident = sanitize_snake_case_name(&format!("remove_{}", self.name))?; - self.remover_impl()?.map(|body| { + self.remover().map(|body| { quote! { pub fn #ident(&mut self, context: &'c ::melior::Context) -> Result<(), ::melior::Error> { #body @@ -223,8 +221,8 @@ impl<'a> OperationField<'a> { }; let getter = { let ident = &self.sanitized_name; - let return_type = &self.kind.return_type()?; - self.getter_impl()?.map(|body| { + let return_type = &self.kind.return_type(); + self.getter().map(|body| { quote! { #[allow(clippy::needless_question_mark)] pub fn #ident(&self, context: &'c ::melior::Context) -> #return_type { diff --git a/macro/src/dialect/operation/builder.rs b/macro/src/dialect/operation/builder.rs index 7c068f3539..7ca9742a2c 100644 --- a/macro/src/dialect/operation/builder.rs +++ b/macro/src/dialect/operation/builder.rs @@ -64,11 +64,11 @@ pub struct OperationBuilder<'o> { } impl<'o> OperationBuilder<'o> { - pub fn new(operation: &'o Operation<'o>) -> Result { - Ok(Self { + pub fn new(operation: &'o Operation<'o>) -> Self { + Self { operation, - type_state: Self::create_type_state(operation)?, - }) + type_state: Self::create_type_state(operation), + } } pub fn create_builder_fns<'a>( @@ -80,7 +80,7 @@ impl<'o> OperationBuilder<'o> { // TODO Initialize a builder identifier out of this closure. let builder_ident = self.builder_identifier()?; let name = sanitize_snake_case_name(field.name)?; - let parameter_type = field.kind.parameter_type()?; + let parameter_type = field.kind.parameter_type(); let argument = quote! { #name: #parameter_type }; let add = format_ident!("add_{}s", field.kind.as_str()); @@ -121,7 +121,7 @@ impl<'o> OperationBuilder<'o> { } }; - Ok(if field.kind.is_optional()? { + Ok(if field.kind.is_optional() { let parameters = self.type_state.parameters().collect::>(); quote! { @@ -212,21 +212,20 @@ impl<'o> OperationBuilder<'o> { let name = sanitize_snake_case_name(self.operation.short_name()?)?; let arguments = Self::required_fields(self.operation) .map(|field| { - let field = field?; - let parameter_type = &field.kind.parameter_type()?; + let parameter_type = &field.kind.parameter_type(); let parameter_name = &field.sanitized_name; - Ok(quote! { #parameter_name: #parameter_type }) + quote! { #parameter_name: #parameter_type } }) - .chain([Ok(quote! { location: ::melior::ir::Location<'c> })]) - .collect::, Error>>()?; + .chain([quote! { location: ::melior::ir::Location<'c> }]) + .collect::>(); let builder_calls = Self::required_fields(self.operation) .map(|field| { - let parameter_name = &field?.sanitized_name; + let parameter_name = &field.sanitized_name; - Ok(quote! { .#parameter_name(#parameter_name) }) + quote! { .#parameter_name(#parameter_name) } }) - .collect::, Error>>()?; + .collect::>(); let doc = format!("Creates a new {}", self.operation.summary()?); @@ -241,23 +240,19 @@ impl<'o> OperationBuilder<'o> { fn required_fields<'a, 'b>( operation: &'a Operation<'b>, - ) -> impl Iterator, Error>> { - operation - .fields() - .filter(|field| !field.kind.is_result() || !operation.can_infer_type) - .filter_map(|field| match field.kind.is_optional() { - Ok(optional) => (!optional).then_some(Ok(field)), - Err(error) => Some(Err(error)), - }) + ) -> impl Iterator> { + operation.fields().filter(|field| { + (!field.kind.is_result() || !operation.can_infer_type) && !field.kind.is_optional() + }) } - fn create_type_state(operation: &'o Operation<'o>) -> Result { - Ok(TypeStateList::new( + fn create_type_state(operation: &'o Operation<'o>) -> TypeStateList { + TypeStateList::new( Self::required_fields(operation) .enumerate() - .map(|(index, field)| Ok(TypeStateItem::new(index, field?.name.to_string()))) - .collect::>()?, - )) + .map(|(index, field)| TypeStateItem::new(index, field.name.to_string())) + .collect(), + ) } fn builder_identifier(&self) -> Result { diff --git a/macro/src/dialect/operation/field_kind.rs b/macro/src/dialect/operation/field_kind.rs index 2b4c67dc6c..4e825d67f3 100644 --- a/macro/src/dialect/operation/field_kind.rs +++ b/macro/src/dialect/operation/field_kind.rs @@ -1,7 +1,6 @@ use super::{element_kind::ElementKind, SequenceInfo, VariadicKind}; -use crate::dialect::{ - error::Error, - types::{AttributeConstraint, RegionConstraint, SuccessorConstraint, TypeConstraint}, +use crate::dialect::types::{ + AttributeConstraint, RegionConstraint, SuccessorConstraint, TypeConstraint, }; use syn::{parse_quote, Type}; @@ -36,14 +35,14 @@ impl<'a> FieldKind<'a> { } } - pub fn is_optional(&self) -> Result { - Ok(match self { + pub fn is_optional(&self) -> bool { + match self { Self::Element { constraint, .. } => constraint.is_optional(), Self::Attribute { constraint, .. } => { - constraint.is_optional()? || constraint.has_default_value()? + constraint.is_optional() || constraint.has_default_value() } Self::Successor { .. } | Self::Region { .. } => false, - }) + } } pub fn is_result(&self) -> bool { @@ -56,8 +55,8 @@ impl<'a> FieldKind<'a> { ) } - pub fn parameter_type(&self) -> Result { - Ok(match self { + pub fn parameter_type(&self) -> Type { + match self { Self::Element { kind, constraint, .. } => { @@ -76,10 +75,10 @@ impl<'a> FieldKind<'a> { } } Self::Attribute { constraint } => { - if constraint.is_unit()? { + if constraint.is_unit() { parse_quote!(bool) } else { - let r#type: Type = syn::parse_str(constraint.storage_type()?)?; + let r#type = constraint.storage_type(); parse_quote!(#r#type<'c>) } } @@ -99,7 +98,7 @@ impl<'a> FieldKind<'a> { r#type } } - }) + } } fn create_result_type(r#type: Type) -> Type { @@ -110,8 +109,8 @@ impl<'a> FieldKind<'a> { parse_quote!(impl Iterator) } - pub fn return_type(&self) -> Result { - Ok(match self { + pub fn return_type(&self) -> Type { + match self { Self::Element { kind, constraint, @@ -136,10 +135,10 @@ impl<'a> FieldKind<'a> { } } Self::Attribute { constraint } => { - if constraint.is_unit()? { + if constraint.is_unit() { parse_quote!(bool) } else { - Self::create_result_type(self.parameter_type()?) + Self::create_result_type(self.parameter_type()) } } Self::Successor { constraint, .. } => { @@ -158,6 +157,6 @@ impl<'a> FieldKind<'a> { Self::create_result_type(r#type) } } - }) + } } } diff --git a/macro/src/dialect/types.rs b/macro/src/dialect/types.rs index 0549503a17..b173b0c485 100644 --- a/macro/src/dialect/types.rs +++ b/macro/src/dialect/types.rs @@ -1,6 +1,7 @@ use super::error::{Error, OdsError}; use once_cell::sync::Lazy; use std::collections::HashMap; +use syn::Type; use tblgen::{ error::{TableGenError, WithLocation}, record::Record, @@ -95,6 +96,7 @@ impl<'a> TypeConstraint<'a> { self.0.subclass_of("Variadic") } + // TODO Support variadic-of-variadic. #[allow(unused)] pub fn is_variadic_of_variadic(&self) -> bool { self.0.subclass_of("VariadicOfVariadic") @@ -105,64 +107,82 @@ impl<'a> TypeConstraint<'a> { } } -#[derive(Debug, Clone, Copy)] -pub struct AttributeConstraint<'a>(Record<'a>); +#[derive(Debug, Clone)] +pub struct AttributeConstraint<'a> { + record: Record<'a>, + name: &'a str, + storage_type_str: String, + storage_type: Type, + optional: bool, + default: bool, +} impl<'a> AttributeConstraint<'a> { - pub fn new(record: Record<'a>) -> Self { - Self(record) + pub fn new(record: Record<'a>) -> Result { + let storage_type_str = record.string_value("storageType")?; + + Ok(Self { + name: record.name()?, + storage_type: syn::parse_str( + ATTRIBUTE_TYPES + .get(storage_type_str.trim()) + .copied() + .unwrap_or(melior_attribute!(Attribute)), + )?, + storage_type_str, + optional: record.bit_value("isOptional")?, + default: match record.string_value("defaultValue") { + Ok(value) => !value.is_empty(), + Err(error) => { + // `defaultValue` can be uninitialized. + if !matches!(error.error(), TableGenError::InitConversion { .. }) { + return Err(error.into()); + } + + false + } + }, + record, + }) } #[allow(unused)] pub fn is_derived(&self) -> bool { - self.0.subclass_of("DerivedAttr") + self.record.subclass_of("DerivedAttr") } #[allow(unused)] pub fn is_type(&self) -> bool { - self.0.subclass_of("TypeAttrBase") + self.record.subclass_of("TypeAttrBase") } #[allow(unused)] pub fn is_symbol_ref(&self) -> bool { - self.0.name() == Ok("SymbolRefAttr") - || self.0.name() == Ok("FlatSymbolRefAttr") - || self.0.subclass_of("SymbolRefAttr") - || self.0.subclass_of("FlatSymbolRefAttr") + self.name == "SymbolRefAttr" + || self.name == "FlatSymbolRefAttr" + || self.record.subclass_of("SymbolRefAttr") + || self.record.subclass_of("FlatSymbolRefAttr") } #[allow(unused)] pub fn is_enum(&self) -> bool { - self.0.subclass_of("EnumAttrInfo") + self.record.subclass_of("EnumAttrInfo") } - pub fn is_optional(&self) -> Result { - Ok(self.0.bit_value("isOptional")?) + pub fn is_optional(&self) -> bool { + self.optional } - pub fn storage_type(&self) -> Result<&'static str, Error> { - Ok(ATTRIBUTE_TYPES - .get(self.0.string_value("storageType")?.as_str().trim()) - .copied() - .unwrap_or(melior_attribute!(Attribute))) + pub fn storage_type(&self) -> &Type { + &self.storage_type } - pub fn is_unit(&self) -> Result { - Ok(self.0.string_value("storageType")? == mlir_attribute!(UnitAttr)) + pub fn is_unit(&self) -> bool { + self.storage_type_str == mlir_attribute!(UnitAttr) } - pub fn has_default_value(&self) -> Result { - Ok(match self.0.string_value("defaultValue") { - Ok(value) => !value.is_empty(), - Err(error) => { - // `defaultValue` can be uninitialized. - if !matches!(error.error(), TableGenError::InitConversion { .. }) { - return Err(error.into()); - } - - false - } - }) + pub fn has_default_value(&self) -> bool { + self.default } } @@ -194,11 +214,11 @@ impl Trait { TraitKind::Predicate } else if definition.subclass_of("InterfaceTrait") { TraitKind::Interface { - name: Self::name(definition)?, + name: Self::build_name(definition)?, } } else if definition.subclass_of("NativeTrait") { TraitKind::Native { - name: Self::name(definition)?, + name: Self::build_name(definition)?, structural: definition.subclass_of("StructuralOpTrait"), } } else if definition.subclass_of("GenInternalTrait") { @@ -211,16 +231,16 @@ impl Trait { }) } - pub fn has_name(&self, expected_name: &str) -> bool { + pub fn name(&self) -> Option<&str> { match &self.kind { TraitKind::Native { name, .. } | TraitKind::Internal { name } - | TraitKind::Interface { name } => name == expected_name, - TraitKind::Predicate => false, + | TraitKind::Interface { name } => Some(name), + TraitKind::Predicate => None, } } - fn name(definition: Record) -> Result { + fn build_name(definition: Record) -> Result { let r#trait = definition.string_value("trait")?; let namespace = definition.string_value("cppNamespace")?; From d9e39f87c72c08a02b46bb57524ebdbcfb4eacf2 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Wed, 14 Feb 2024 08:57:43 +0900 Subject: [PATCH 047/108] Refactor accessor generator macros (#412) --- macro/src/dialect/operation.rs | 3 +- macro/src/dialect/operation/accessors.rs | 420 +++++++++++------------ 2 files changed, 211 insertions(+), 212 deletions(-) diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 134b977a00..6b2bf55244 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -7,6 +7,7 @@ mod sequence_info; mod variadic_kind; use self::{ + accessors::generate_accessors, builder::{generate_operation_builder, OperationBuilder}, element_kind::ElementKind, field_kind::FieldKind, @@ -30,7 +31,7 @@ pub fn generate_operation(operation: &Operation) -> Result { let name = &operation.full_name()?; let accessors = operation .fields() - .map(|field| field.accessors()) + .map(generate_accessors) .collect::, _>>()?; let builder = OperationBuilder::new(operation); diff --git a/macro/src/dialect/operation/accessors.rs b/macro/src/dialect/operation/accessors.rs index ffa0002f3f..bcbf9033a4 100644 --- a/macro/src/dialect/operation/accessors.rs +++ b/macro/src/dialect/operation/accessors.rs @@ -5,237 +5,235 @@ use super::{ use proc_macro2::TokenStream; use quote::{format_ident, quote}; -impl<'a> OperationField<'a> { - fn getter(&self) -> Option { - match &self.kind { - FieldKind::Element { - kind, - constraint, - sequence_info: SequenceInfo { index, len }, - variadic_kind, - } => { - let kind_ident = format_ident!("{}", kind.as_str()); - let plural = format_ident!("{}s", kind.as_str()); - let count = format_ident!("{}_count", kind.as_str()); - let error_variant = match kind { - ElementKind::Operand => quote!(OperandNotFound), - ElementKind::Result => quote!(ResultNotFound), - }; - let name = self.name; +pub fn generate_accessors(field: &OperationField) -> Result { + let setter = { + let ident = sanitize_snake_case_name(&format!("set_{}", field.name))?; - Some(match variadic_kind { - VariadicKind::Simple { unfixed_seen } => { - if constraint.is_optional() { - // Optional element, and some singular elements. - // Only present if the amount of groups is at least the number of - // elements. - quote! { - if self.operation.#count() < #len { - Err(::melior::Error::#error_variant(#name)) - } else { - self.operation.#kind_ident(#index) - } - } - } else if constraint.is_variadic() { - // A unfixed group - // Length computed by subtracting the amount of other - // singular elements from the number of elements. - quote! { - let group_length = self.operation.#count() - #len + 1; - self.operation.#plural().skip(#index).take(group_length) - } - } else if *unfixed_seen { - // Single element after unfixed group - // Compute the length of that variable group and take the next element - quote! { - let group_length = self.operation.#count() - #len + 1; - self.operation.#kind_ident(#index + group_length - 1) - } - } else { - // All elements so far are singular - quote! { - self.operation.#kind_ident(#index) - } - } - } - VariadicKind::SameSize { - unfixed_count, - preceding_simple_count, - preceding_variadic_count, - } => { - let compute_start_length = quote! { - let total_var_len = self.operation.#count() - #unfixed_count + 1; - let group_len = total_var_len / #unfixed_count; - let start = #preceding_simple_count + #preceding_variadic_count * group_len; - }; - let get_elements = if constraint.has_unfixed() { - quote! { - self.operation.#plural().skip(start).take(group_len) - } - } else { - quote! { - self.operation.#kind_ident(start) - } - }; - - quote! { #compute_start_length #get_elements } - } - VariadicKind::AttributeSized => { - let attribute_name = format!("{}_segment_sizes", kind.as_str()); - let compute_start_length = quote! { - let attribute = - ::melior::ir::attribute::DenseI32ArrayAttribute::<'c>::try_from( - self.operation - .attribute(#attribute_name)? - )?; - let start = (0..#index) - .map(|index| attribute.element(index)) - .collect::, _>>()? - .into_iter() - .sum::() as usize; - let group_len = attribute.element(#index)? as usize; - }; - let get_elements = if !constraint.has_unfixed() { - quote! { - self.operation.#kind_ident(start) - } - } else if constraint.is_optional() { - quote! { - if group_len == 0 { - Err(::melior::Error::#error_variant(#name)) - } else { - self.operation.#kind_ident(start) - } - } - } else { - quote! { - Ok(self.operation.#plural().skip(start).take(group_len)) - } - }; - - quote! { #compute_start_length #get_elements } - } - }) - } - FieldKind::Successor { - constraint, - sequence_info: SequenceInfo { index, .. }, - } => { - Some(if constraint.is_variadic() { - // Only the last successor can be variadic - quote! { - self.operation.successors().skip(#index) - } - } else { - quote! { - self.operation.successor(#index) - } - }) - } - FieldKind::Region { - constraint, - sequence_info: SequenceInfo { index, .. }, - } => { - Some(if constraint.is_variadic() { - // Only the last region can be variadic - quote! { - self.operation.regions().skip(#index) - } - } else { - quote! { - self.operation.region(#index) - } - }) - } - FieldKind::Attribute { constraint } => { - let name = &self.name; + generate_setter(field).map(|body| { + let parameter_type = &field.kind.parameter_type(); - Some(if constraint.is_unit() { - quote! { self.operation.attribute(#name).is_some() } - } else { - // TODO Handle returning `melior::Attribute`. - quote! { Ok(self.operation.attribute(#name)?.try_into()?) } - }) - } - } - } - - fn remover(&self) -> Option { - if let FieldKind::Attribute { constraint } = &self.kind { - if constraint.is_unit() || constraint.is_optional() { - let name = &self.name; - - Some(quote! { self.operation.remove_attribute(#name) }) - } else { - None - } - } else { - None - } - } - - fn setter(&self) -> Option { - let FieldKind::Attribute { constraint } = &self.kind else { - return None; - }; - let name = &self.name; - - Some(if constraint.is_unit() { quote! { - if value { - self.operation.set_attribute(#name, Attribute::unit(&self.operation.context())); - } else { - self.operation.remove_attribute(#name) + pub fn #ident(&mut self, context: &'c ::melior::Context, value: #parameter_type) { + #body } } - } else { + }) + }; + let remover = { + let ident = sanitize_snake_case_name(&format!("remove_{}", field.name))?; + generate_remover(field).map(|body| { + quote! { + pub fn #ident(&mut self, context: &'c ::melior::Context) -> Result<(), ::melior::Error> { + #body + } + } + }) + }; + let getter = { + let ident = &field.sanitized_name; + let return_type = &field.kind.return_type(); + generate_getter(field).map(|body| { quote! { - self.operation.set_attribute(#name, &value.into()); + #[allow(clippy::needless_question_mark)] + pub fn #ident(&self, context: &'c ::melior::Context) -> #return_type { + #body + } } }) - } + }; - pub fn accessors(&self) -> Result { - let setter = { - let ident = sanitize_snake_case_name(&format!("set_{}", self.name))?; + Ok(quote! { + #getter + #setter + #remover + }) +} - self.setter().map(|body| { - let parameter_type = &self.kind.parameter_type(); +fn generate_getter(field: &OperationField) -> Option { + match &field.kind { + FieldKind::Element { + kind, + constraint, + sequence_info: SequenceInfo { index, len }, + variadic_kind, + } => { + let kind_ident = format_ident!("{}", kind.as_str()); + let plural = format_ident!("{}s", kind.as_str()); + let count = format_ident!("{}_count", kind.as_str()); + let error_variant = match kind { + ElementKind::Operand => quote!(OperandNotFound), + ElementKind::Result => quote!(ResultNotFound), + }; + let name = field.name; - quote! { - pub fn #ident(&mut self, context: &'c ::melior::Context, value: #parameter_type) { - #body + Some(match variadic_kind { + VariadicKind::Simple { unfixed_seen } => { + if constraint.is_optional() { + // Optional element, and some singular elements. + // Only present if the amount of groups is at least the number of + // elements. + quote! { + if self.operation.#count() < #len { + Err(::melior::Error::#error_variant(#name)) + } else { + self.operation.#kind_ident(#index) + } + } + } else if constraint.is_variadic() { + // A unfixed group + // Length computed by subtracting the amount of other + // singular elements from the number of elements. + quote! { + let group_length = self.operation.#count() - #len + 1; + self.operation.#plural().skip(#index).take(group_length) + } + } else if *unfixed_seen { + // Single element after unfixed group + // Compute the length of that variable group and take the next element + quote! { + let group_length = self.operation.#count() - #len + 1; + self.operation.#kind_ident(#index + group_length - 1) + } + } else { + // All elements so far are singular + quote! { + self.operation.#kind_ident(#index) + } } } + VariadicKind::SameSize { + unfixed_count, + preceding_simple_count, + preceding_variadic_count, + } => { + let compute_start_length = quote! { + let total_var_len = self.operation.#count() - #unfixed_count + 1; + let group_len = total_var_len / #unfixed_count; + let start = #preceding_simple_count + #preceding_variadic_count * group_len; + }; + let get_elements = if constraint.has_unfixed() { + quote! { + self.operation.#plural().skip(start).take(group_len) + } + } else { + quote! { + self.operation.#kind_ident(start) + } + }; + + quote! { #compute_start_length #get_elements } + } + VariadicKind::AttributeSized => { + let attribute_name = format!("{}_segment_sizes", kind.as_str()); + let compute_start_length = quote! { + let attribute = + ::melior::ir::attribute::DenseI32ArrayAttribute::<'c>::try_from( + self.operation + .attribute(#attribute_name)? + )?; + let start = (0..#index) + .map(|index| attribute.element(index)) + .collect::, _>>()? + .into_iter() + .sum::() as usize; + let group_len = attribute.element(#index)? as usize; + }; + let get_elements = if !constraint.has_unfixed() { + quote! { + self.operation.#kind_ident(start) + } + } else if constraint.is_optional() { + quote! { + if group_len == 0 { + Err(::melior::Error::#error_variant(#name)) + } else { + self.operation.#kind_ident(start) + } + } + } else { + quote! { + Ok(self.operation.#plural().skip(start).take(group_len)) + } + }; + + quote! { #compute_start_length #get_elements } + } }) - }; - let remover = { - let ident = sanitize_snake_case_name(&format!("remove_{}", self.name))?; - self.remover().map(|body| { + } + FieldKind::Successor { + constraint, + sequence_info: SequenceInfo { index, .. }, + } => { + Some(if constraint.is_variadic() { + // Only the last successor can be variadic quote! { - pub fn #ident(&mut self, context: &'c ::melior::Context) -> Result<(), ::melior::Error> { - #body - } + self.operation.successors().skip(#index) + } + } else { + quote! { + self.operation.successor(#index) } }) - }; - let getter = { - let ident = &self.sanitized_name; - let return_type = &self.kind.return_type(); - self.getter().map(|body| { + } + FieldKind::Region { + constraint, + sequence_info: SequenceInfo { index, .. }, + } => { + Some(if constraint.is_variadic() { + // Only the last region can be variadic quote! { - #[allow(clippy::needless_question_mark)] - pub fn #ident(&self, context: &'c ::melior::Context) -> #return_type { - #body - } + self.operation.regions().skip(#index) + } + } else { + quote! { + self.operation.region(#index) } }) - }; + } + FieldKind::Attribute { constraint } => { + let name = &field.name; - Ok(quote! { - #getter - #setter - #remover - }) + Some(if constraint.is_unit() { + quote! { self.operation.attribute(#name).is_some() } + } else { + // TODO Handle returning `melior::Attribute`. + quote! { Ok(self.operation.attribute(#name)?.try_into()?) } + }) + } } } + +fn generate_remover(field: &OperationField) -> Option { + if let FieldKind::Attribute { constraint } = &field.kind { + if constraint.is_unit() || constraint.is_optional() { + let name = &field.name; + + Some(quote! { self.operation.remove_attribute(#name) }) + } else { + None + } + } else { + None + } +} + +fn generate_setter(field: &OperationField) -> Option { + let FieldKind::Attribute { constraint } = &field.kind else { + return None; + }; + let name = &field.name; + + Some(if constraint.is_unit() { + quote! { + if value { + self.operation.set_attribute(#name, Attribute::unit(&self.operation.context())); + } else { + self.operation.remove_attribute(#name) + } + } + } else { + quote! { + self.operation.set_attribute(#name, &value.into()); + } + }) +} From c1b1ea6bef631b494eb83a460f02279493506753 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Thu, 15 Feb 2024 01:12:36 +0900 Subject: [PATCH 048/108] Rename variables (#414) --- macro/src/dialect/operation.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 6b2bf55244..f07940c900 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -285,12 +285,12 @@ impl<'a> Operation<'a> { } fn collect_results( - def: Record<'a>, + definition: Record<'a>, same_size: bool, attribute_sized: bool, ) -> Result<(Vec, usize), Error> { Self::collect_elements( - &Self::dag_constraints(def, "results")? + &Self::dag_constraints(definition, "results")? .into_iter() .map(|(name, constraint)| (name, TypeConstraint::new(constraint))) .collect::>(), @@ -391,10 +391,10 @@ impl<'a> Operation<'a> { definition .values() .filter_map(|value| { - let Ok(def) = Record::try_from(value) else { + let Ok(definition) = Record::try_from(value) else { return None; }; - def.subclass_of("Attr").then_some(def) + definition.subclass_of("Attr").then_some(definition) }) .map(|definition| { if definition.subclass_of("DerivedAttr") { From eab75f568c3c4a21cbaff50c67a2ba7e8fa09976 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Thu, 15 Feb 2024 20:27:22 +0900 Subject: [PATCH 049/108] Bump version (#415) --- Cargo.lock | 4 ++-- macro/Cargo.toml | 2 +- melior/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b1ea7d267a..ae26964a94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -595,7 +595,7 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "melior" -version = "0.15.2" +version = "0.15.3" dependencies = [ "dashmap", "indoc", @@ -608,7 +608,7 @@ dependencies = [ [[package]] name = "melior-macro" -version = "0.9.0" +version = "0.9.1" dependencies = [ "comrak", "convert_case", diff --git a/macro/Cargo.toml b/macro/Cargo.toml index 73b132b916..d02565363c 100644 --- a/macro/Cargo.toml +++ b/macro/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "melior-macro" description = "Internal macros for Melior" -version = "0.9.0" +version = "0.9.1" edition = "2021" license = "Apache-2.0" repository = "https://github.com/raviqqe/melior" diff --git a/melior/Cargo.toml b/melior/Cargo.toml index 7e387ee52b..10ea4bcf8d 100644 --- a/melior/Cargo.toml +++ b/melior/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "melior" description = "The rustic MLIR bindings in Rust" -version = "0.15.2" +version = "0.15.3" edition = "2021" license = "Apache-2.0" repository = "https://github.com/raviqqe/melior" From 9e18bac80e918c0190d5c6259ada05448c2fb720 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Thu, 15 Feb 2024 20:43:05 +0900 Subject: [PATCH 050/108] Refactor `OperationField` (#413) --- macro/src/dialect.rs | 3 +- macro/src/dialect/generation.rs | 78 +++++++++++ .../dialect/generation/attribute_accessor.rs | 81 +++++++++++ .../field_accessor.rs} | 112 +++------------ .../dialect/generation/operation_builder.rs | 55 ++++++++ macro/src/dialect/operation.rs | 113 ++++----------- macro/src/dialect/operation/attribute.rs | 84 +++++++++++ macro/src/dialect/operation/builder.rs | 132 ++++-------------- macro/src/dialect/operation/field_kind.rs | 67 ++------- .../src/dialect/operation/operation_field.rs | 94 +++++++++++-- macro/src/dialect/utility.rs | 9 ++ 11 files changed, 481 insertions(+), 347 deletions(-) create mode 100644 macro/src/dialect/generation.rs create mode 100644 macro/src/dialect/generation/attribute_accessor.rs rename macro/src/dialect/{operation/accessors.rs => generation/field_accessor.rs} (67%) create mode 100644 macro/src/dialect/generation/operation_builder.rs create mode 100644 macro/src/dialect/operation/attribute.rs diff --git a/macro/src/dialect.rs b/macro/src/dialect.rs index eeffddf76e..87c5caae5a 100644 --- a/macro/src/dialect.rs +++ b/macro/src/dialect.rs @@ -1,4 +1,5 @@ mod error; +mod generation; mod input; mod operation; mod types; @@ -6,7 +7,7 @@ mod utility; use self::{ error::Error, - operation::generate_operation, + generation::generate_operation, utility::{sanitize_documentation, sanitize_snake_case_name}, }; pub use input::DialectInput; diff --git a/macro/src/dialect/generation.rs b/macro/src/dialect/generation.rs new file mode 100644 index 0000000000..ab90bc6ee3 --- /dev/null +++ b/macro/src/dialect/generation.rs @@ -0,0 +1,78 @@ +mod attribute_accessor; +mod field_accessor; +mod operation_builder; + +use self::{ + attribute_accessor::generate_attribute_accessors, field_accessor::generate_accessor, + operation_builder::generate_operation_builder, +}; +use super::operation::{Operation, OperationBuilder}; +use crate::dialect::error::Error; +use proc_macro2::TokenStream; +use quote::{format_ident, quote}; + +pub fn generate_operation(operation: &Operation) -> Result { + let summary = operation.summary()?; + let description = operation.description()?; + let class_name = format_ident!("{}", operation.class_name()?); + let name = &operation.full_name()?; + + let field_accessors = operation + .operation_fields() + .map(generate_accessor) + .collect::, _>>()?; + let attribute_accessors = operation + .attributes() + .map(generate_attribute_accessors) + .collect::, _>>()?; + + let builder = OperationBuilder::new(operation); + let builder_tokens = generate_operation_builder(&builder)?; + let builder_fn = builder.create_op_builder_fn()?; + let default_constructor = builder.create_default_constructor()?; + + Ok(quote! { + #[doc = #summary] + #[doc = "\n\n"] + #[doc = #description] + pub struct #class_name<'c> { + operation: ::melior::ir::operation::Operation<'c>, + } + + impl<'c> #class_name<'c> { + pub fn name() -> &'static str { + #name + } + + pub fn operation(&self) -> &::melior::ir::operation::Operation<'c> { + &self.operation + } + + #builder_fn + + #(#field_accessors)* + #(#attribute_accessors)* + } + + #builder_tokens + + #default_constructor + + impl<'c> TryFrom<::melior::ir::operation::Operation<'c>> for #class_name<'c> { + type Error = ::melior::Error; + + fn try_from( + operation: ::melior::ir::operation::Operation<'c>, + ) -> Result { + // TODO Check an operation name. + Ok(Self { operation }) + } + } + + impl<'c> From<#class_name<'c>> for ::melior::ir::operation::Operation<'c> { + fn from(operation: #class_name<'c>) -> ::melior::ir::operation::Operation<'c> { + operation.operation + } + } + }) +} diff --git a/macro/src/dialect/generation/attribute_accessor.rs b/macro/src/dialect/generation/attribute_accessor.rs new file mode 100644 index 0000000000..5e6ccc5313 --- /dev/null +++ b/macro/src/dialect/generation/attribute_accessor.rs @@ -0,0 +1,81 @@ +use crate::dialect::{ + error::Error, + operation::{Attribute, OperationFieldLike}, + utility::sanitize_snake_case_name, +}; +use proc_macro2::TokenStream; +use quote::quote; + +pub fn generate_attribute_accessors(attribute: &Attribute) -> Result { + let getter = generate_getter(attribute)?; + let setter = generate_setter(attribute)?; + let remover = generate_remover(attribute)?; + + Ok(quote! { + #getter + #setter + #remover + }) +} + +fn generate_getter(attribute: &Attribute) -> Result { + let name = attribute.name(); + + let ident = attribute.sanitized_name(); + let return_type = attribute.return_type(); + let body = if attribute.is_unit() { + quote! { self.operation.attribute(#name).is_some() } + } else { + // TODO Handle returning `melior::Attribute`. + quote! { Ok(self.operation.attribute(#name)?.try_into()?) } + }; + + Ok(quote! { + #[allow(clippy::needless_question_mark)] + pub fn #ident(&self, context: &'c ::melior::Context) -> #return_type { + #body + } + }) +} + +fn generate_setter(attribute: &Attribute) -> Result { + let name = attribute.name(); + + let body = if attribute.is_unit() { + quote! { + if value { + self.operation.set_attribute(#name, Attribute::unit(&self.operation.context())); + } else { + self.operation.remove_attribute(#name) + } + } + } else { + quote! { + self.operation.set_attribute(#name, &value.into()); + } + }; + + let ident = sanitize_snake_case_name(&format!("set_{}", attribute.name()))?; + let r#type = attribute.parameter_type(); + + Ok(quote! { + pub fn #ident(&mut self, context: &'c ::melior::Context, value: #r#type) { + #body + } + }) +} + +fn generate_remover(attribute: &Attribute) -> Result, Error> { + Ok(if attribute.is_unit() || attribute.is_optional() { + let name = attribute.name(); + let ident = sanitize_snake_case_name(&format!("remove_{}", attribute.name()))?; + + Some(quote! { + pub fn #ident(&mut self, context: &'c ::melior::Context) -> Result<(), ::melior::Error> { + self.operation.remove_attribute(#name) + } + }) + } else { + None + }) +} diff --git a/macro/src/dialect/operation/accessors.rs b/macro/src/dialect/generation/field_accessor.rs similarity index 67% rename from macro/src/dialect/operation/accessors.rs rename to macro/src/dialect/generation/field_accessor.rs index bcbf9033a4..9e1a4e4df5 100644 --- a/macro/src/dialect/operation/accessors.rs +++ b/macro/src/dialect/generation/field_accessor.rs @@ -1,55 +1,24 @@ -use super::{ - super::{error::Error, utility::sanitize_snake_case_name}, - ElementKind, FieldKind, OperationField, SequenceInfo, VariadicKind, +use crate::dialect::{ + error::Error, + operation::{ElementKind, FieldKind, OperationField, SequenceInfo, VariadicKind}, }; use proc_macro2::TokenStream; use quote::{format_ident, quote}; -pub fn generate_accessors(field: &OperationField) -> Result { - let setter = { - let ident = sanitize_snake_case_name(&format!("set_{}", field.name))?; - - generate_setter(field).map(|body| { - let parameter_type = &field.kind.parameter_type(); - - quote! { - pub fn #ident(&mut self, context: &'c ::melior::Context, value: #parameter_type) { - #body - } - } - }) - }; - let remover = { - let ident = sanitize_snake_case_name(&format!("remove_{}", field.name))?; - generate_remover(field).map(|body| { - quote! { - pub fn #ident(&mut self, context: &'c ::melior::Context) -> Result<(), ::melior::Error> { - #body - } - } - }) - }; - let getter = { - let ident = &field.sanitized_name; - let return_type = &field.kind.return_type(); - generate_getter(field).map(|body| { - quote! { - #[allow(clippy::needless_question_mark)] - pub fn #ident(&self, context: &'c ::melior::Context) -> #return_type { - #body - } - } - }) - }; +pub fn generate_accessor(field: &OperationField) -> Result { + let ident = &field.sanitized_name; + let return_type = &field.kind.return_type(); + let body = generate_getter(field); Ok(quote! { - #getter - #setter - #remover + #[allow(clippy::needless_question_mark)] + pub fn #ident(&self, context: &'c ::melior::Context) -> #return_type { + #body + } }) } -fn generate_getter(field: &OperationField) -> Option { +fn generate_getter(field: &OperationField) -> TokenStream { match &field.kind { FieldKind::Element { kind, @@ -66,7 +35,7 @@ fn generate_getter(field: &OperationField) -> Option { }; let name = field.name; - Some(match variadic_kind { + match variadic_kind { VariadicKind::Simple { unfixed_seen } => { if constraint.is_optional() { // Optional element, and some singular elements. @@ -158,13 +127,13 @@ fn generate_getter(field: &OperationField) -> Option { quote! { #compute_start_length #get_elements } } - }) + } } FieldKind::Successor { constraint, sequence_info: SequenceInfo { index, .. }, } => { - Some(if constraint.is_variadic() { + if constraint.is_variadic() { // Only the last successor can be variadic quote! { self.operation.successors().skip(#index) @@ -173,13 +142,13 @@ fn generate_getter(field: &OperationField) -> Option { quote! { self.operation.successor(#index) } - }) + } } FieldKind::Region { constraint, sequence_info: SequenceInfo { index, .. }, } => { - Some(if constraint.is_variadic() { + if constraint.is_variadic() { // Only the last region can be variadic quote! { self.operation.regions().skip(#index) @@ -188,52 +157,7 @@ fn generate_getter(field: &OperationField) -> Option { quote! { self.operation.region(#index) } - }) - } - FieldKind::Attribute { constraint } => { - let name = &field.name; - - Some(if constraint.is_unit() { - quote! { self.operation.attribute(#name).is_some() } - } else { - // TODO Handle returning `melior::Attribute`. - quote! { Ok(self.operation.attribute(#name)?.try_into()?) } - }) - } - } -} - -fn generate_remover(field: &OperationField) -> Option { - if let FieldKind::Attribute { constraint } = &field.kind { - if constraint.is_unit() || constraint.is_optional() { - let name = &field.name; - - Some(quote! { self.operation.remove_attribute(#name) }) - } else { - None - } - } else { - None - } -} - -fn generate_setter(field: &OperationField) -> Option { - let FieldKind::Attribute { constraint } = &field.kind else { - return None; - }; - let name = &field.name; - - Some(if constraint.is_unit() { - quote! { - if value { - self.operation.set_attribute(#name, Attribute::unit(&self.operation.context())); - } else { - self.operation.remove_attribute(#name) } } - } else { - quote! { - self.operation.set_attribute(#name, &value.into()); - } - }) + } } diff --git a/macro/src/dialect/generation/operation_builder.rs b/macro/src/dialect/generation/operation_builder.rs new file mode 100644 index 0000000000..4256d47c23 --- /dev/null +++ b/macro/src/dialect/generation/operation_builder.rs @@ -0,0 +1,55 @@ +use crate::dialect::{ + error::Error, operation::OperationBuilder, utility::sanitize_snake_case_name, +}; +use proc_macro2::TokenStream; +use quote::quote; + +pub fn generate_operation_builder(builder: &OperationBuilder) -> Result { + let field_names = builder + .type_state() + .field_names() + .map(sanitize_snake_case_name) + .collect::, _>>()?; + + let phantom_fields = + builder + .type_state() + .parameters() + .zip(&field_names) + .map(|(r#type, name)| { + quote! { + #name: ::std::marker::PhantomData<#r#type> + } + }); + + let phantom_arguments = field_names + .iter() + .map(|name| quote! { #name: ::std::marker::PhantomData }) + .collect::>(); + + let builder_fns = builder + .create_builder_fns(&field_names, phantom_arguments.as_slice()) + .collect::, _>>()?; + + let new = builder.create_new_fn(phantom_arguments.as_slice())?; + let build = builder.create_build_fn()?; + + let builder_identifier = builder.builder_identifier()?; + let doc = format!("Builder for {}", builder.operation().summary()?); + let iter_arguments = builder.type_state().parameters(); + + Ok(quote! { + #[doc = #doc] + pub struct #builder_identifier<'c, #(#iter_arguments),*> { + builder: ::melior::ir::operation::OperationBuilder<'c>, + context: &'c ::melior::Context, + #(#phantom_fields),* + } + + #new + + #(#builder_fns)* + + #build + }) +} diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index f07940c900..049b35a956 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -1,4 +1,4 @@ -mod accessors; +mod attribute; mod builder; mod element_kind; mod field_kind; @@ -6,13 +6,9 @@ mod operation_field; mod sequence_info; mod variadic_kind; -use self::{ - accessors::generate_accessors, - builder::{generate_operation_builder, OperationBuilder}, - element_kind::ElementKind, - field_kind::FieldKind, - operation_field::OperationField, - sequence_info::SequenceInfo, +pub use self::{ + attribute::Attribute, builder::OperationBuilder, element_kind::ElementKind, + field_kind::FieldKind, operation_field::OperationField, sequence_info::SequenceInfo, variadic_kind::VariadicKind, }; use super::utility::sanitize_documentation; @@ -20,70 +16,9 @@ use crate::dialect::{ error::{Error, OdsError}, types::{AttributeConstraint, RegionConstraint, SuccessorConstraint, Trait, TypeConstraint}, }; -use proc_macro2::TokenStream; -use quote::{format_ident, quote}; +pub use operation_field::OperationFieldLike; use tblgen::{error::WithLocation, record::Record}; -pub fn generate_operation(operation: &Operation) -> Result { - let summary = operation.summary()?; - let description = operation.description()?; - let class_name = format_ident!("{}", operation.class_name()?); - let name = &operation.full_name()?; - let accessors = operation - .fields() - .map(generate_accessors) - .collect::, _>>()?; - - let builder = OperationBuilder::new(operation); - let builder_tokens = generate_operation_builder(&builder)?; - let builder_fn = builder.create_op_builder_fn()?; - let default_constructor = builder.create_default_constructor()?; - - Ok(quote! { - #[doc = #summary] - #[doc = "\n\n"] - #[doc = #description] - pub struct #class_name<'c> { - operation: ::melior::ir::operation::Operation<'c>, - } - - impl<'c> #class_name<'c> { - pub fn name() -> &'static str { - #name - } - - pub fn operation(&self) -> &::melior::ir::operation::Operation<'c> { - &self.operation - } - - #builder_fn - - #(#accessors)* - } - - #builder_tokens - - #default_constructor - - impl<'c> TryFrom<::melior::ir::operation::Operation<'c>> for #class_name<'c> { - type Error = ::melior::Error; - - fn try_from( - operation: ::melior::ir::operation::Operation<'c>, - ) -> Result { - // TODO Check an operation name. - Ok(Self { operation }) - } - } - - impl<'c> From<#class_name<'c>> for ::melior::ir::operation::Operation<'c> { - fn from(operation: #class_name<'c>) -> ::melior::ir::operation::Operation<'c> { - operation.operation - } - } - }) -} - #[derive(Debug)] pub struct Operation<'a> { definition: Record<'a>, @@ -92,8 +27,8 @@ pub struct Operation<'a> { successors: Vec>, results: Vec>, operands: Vec>, - attributes: Vec>, - derived_attributes: Vec>, + attributes: Vec>, + derived_attributes: Vec>, } impl<'a> Operation<'a> { @@ -187,14 +122,29 @@ impl<'a> Operation<'a> { sanitize_documentation(self.definition.str_value("description")?) } - pub fn fields(&self) -> impl Iterator> + Clone { + pub fn fields(&self) -> impl Iterator + Clone { self.results .iter() .chain(&self.operands) .chain(&self.regions) .chain(&self.successors) - .chain(&self.attributes) - .chain(&self.derived_attributes) + .map(|field| -> &dyn OperationFieldLike { field }) + .chain( + self.attributes() + .map(|field| -> &dyn OperationFieldLike { field }), + ) + } + + pub fn operation_fields(&self) -> impl Iterator> + Clone { + self.results + .iter() + .chain(&self.operands) + .chain(&self.regions) + .chain(&self.successors) + } + + pub fn attributes(&self) -> impl Iterator> + Clone { + self.attributes.iter().chain(&self.derived_attributes) } fn collect_successors(definition: Record<'a>) -> Result, Error> { @@ -369,7 +319,7 @@ impl<'a> Operation<'a> { fn collect_attributes( arguments: &[(&'a str, Record<'a>)], - ) -> Result>, Error> { + ) -> Result>, Error> { arguments .iter() .filter(|(_, definition)| definition.subclass_of("Attr")) @@ -379,15 +329,13 @@ impl<'a> Operation<'a> { .with_location(*definition) .into()) } else { - OperationField::new_attribute(name, AttributeConstraint::new(*definition)?) + Attribute::new(name, AttributeConstraint::new(*definition)?) } }) .collect() } - fn collect_derived_attributes( - definition: Record<'a>, - ) -> Result>, Error> { + fn collect_derived_attributes(definition: Record<'a>) -> Result>, Error> { definition .values() .filter_map(|value| { @@ -398,10 +346,7 @@ impl<'a> Operation<'a> { }) .map(|definition| { if definition.subclass_of("DerivedAttr") { - OperationField::new_attribute( - definition.name()?, - AttributeConstraint::new(definition)?, - ) + Attribute::new(definition.name()?, AttributeConstraint::new(definition)?) } else { Err(OdsError::ExpectedSuperClass("DerivedAttr") .with_location(definition) diff --git a/macro/src/dialect/operation/attribute.rs b/macro/src/dialect/operation/attribute.rs new file mode 100644 index 0000000000..508949e73b --- /dev/null +++ b/macro/src/dialect/operation/attribute.rs @@ -0,0 +1,84 @@ +use crate::dialect::{ + error::Error, + operation::operation_field::OperationFieldLike, + types::AttributeConstraint, + utility::{generate_result_type, sanitize_snake_case_name}, +}; +use proc_macro2::{Ident, TokenStream}; +use quote::quote; +use syn::{parse_quote, Type}; + +#[derive(Debug)] +pub struct Attribute<'a> { + name: &'a str, + sanitized_name: Ident, + constraint: AttributeConstraint<'a>, +} + +impl<'a> Attribute<'a> { + pub fn new(name: &'a str, constraint: AttributeConstraint<'a>) -> Result { + Ok(Self { + name, + sanitized_name: sanitize_snake_case_name(name)?, + constraint, + }) + } + + pub fn is_optional(&self) -> bool { + self.constraint.is_optional() + } + + pub fn is_unit(&self) -> bool { + self.constraint.is_unit() + } +} + +impl OperationFieldLike for Attribute<'_> { + fn name(&self) -> &str { + self.name + } + + fn plural_identifier(&self) -> &str { + "attributes" + } + + fn sanitized_name(&self) -> &Ident { + &self.sanitized_name + } + + fn parameter_type(&self) -> Type { + if self.constraint.is_unit() { + parse_quote!(bool) + } else { + let r#type = self.constraint.storage_type(); + parse_quote!(#r#type<'c>) + } + } + + fn return_type(&self) -> Type { + if self.constraint.is_unit() { + parse_quote!(bool) + } else { + generate_result_type(self.parameter_type()) + } + } + + fn is_optional(&self) -> bool { + self.is_optional() || self.constraint.has_default_value() + } + + fn is_result(&self) -> bool { + false + } + + fn add_arguments(&self, name: &Ident) -> TokenStream { + let name_string = &self.name; + + quote! { + &[( + ::melior::ir::Identifier::new(self.context, #name_string), + #name.into(), + )] + } + } +} diff --git a/macro/src/dialect/operation/builder.rs b/macro/src/dialect/operation/builder.rs index 7ca9742a2c..194e80761d 100644 --- a/macro/src/dialect/operation/builder.rs +++ b/macro/src/dialect/operation/builder.rs @@ -4,60 +4,12 @@ mod type_state_list; use self::{type_state_item::TypeStateItem, type_state_list::TypeStateList}; use super::{ super::{error::Error, utility::sanitize_snake_case_name}, - FieldKind, Operation, OperationField, + operation_field::OperationFieldLike, + Operation, }; use proc_macro2::{Ident, TokenStream}; use quote::{format_ident, quote}; -pub fn generate_operation_builder(builder: &OperationBuilder) -> Result { - let field_names = builder - .type_state - .field_names() - .map(sanitize_snake_case_name) - .collect::, _>>()?; - - let phantom_fields = builder - .type_state - .parameters() - .zip(&field_names) - .map(|(r#type, name)| { - quote! { - #name: ::std::marker::PhantomData<#r#type> - } - }); - - let phantom_arguments = field_names - .iter() - .map(|name| quote! { #name: ::std::marker::PhantomData }) - .collect::>(); - - let builder_fns = builder - .create_builder_fns(&field_names, phantom_arguments.as_slice()) - .collect::, _>>()?; - - let new = builder.create_new_fn(phantom_arguments.as_slice())?; - let build = builder.create_build_fn()?; - - let builder_identifier = builder.builder_identifier()?; - let doc = format!("Builder for {}", builder.operation.summary()?); - let iter_arguments = builder.type_state.parameters(); - - Ok(quote! { - #[doc = #doc] - pub struct #builder_identifier<'c, #(#iter_arguments),*> { - builder: ::melior::ir::operation::OperationBuilder<'c>, - context: &'c ::melior::Context, - #(#phantom_fields),* - } - - #new - - #(#builder_fns)* - - #build - }) -} - pub struct OperationBuilder<'o> { operation: &'o Operation<'o>, type_state: TypeStateList, @@ -71,6 +23,14 @@ impl<'o> OperationBuilder<'o> { } } + pub fn operation(&self) -> &Operation { + self.operation + } + + pub fn type_state(&self) -> &TypeStateList { + &self.type_state + } + pub fn create_builder_fns<'a>( &'a self, field_names: &'a [Ident], @@ -79,49 +39,17 @@ impl<'o> OperationBuilder<'o> { self.operation.fields().map(move |field| { // TODO Initialize a builder identifier out of this closure. let builder_ident = self.builder_identifier()?; - let name = sanitize_snake_case_name(field.name)?; - let parameter_type = field.kind.parameter_type(); + let name = sanitize_snake_case_name(field.name())?; + let parameter_type = field.parameter_type(); let argument = quote! { #name: #parameter_type }; - let add = format_ident!("add_{}s", field.kind.as_str()); + let add = format_ident!("add_{}", field.plural_identifier()); // Argument types can be singular and variadic, but add functions in melior // are always variadic, so we need to create a slice or vec for singular // arguments - let add_arguments = match &field.kind { - FieldKind::Element { constraint, .. } => { - if constraint.has_unfixed() && !constraint.is_optional() { - quote! { #name } - } else { - quote! { &[#name] } - } - } - FieldKind::Attribute { .. } => { - let name_string = &field.name; - - quote! { - &[( - ::melior::ir::Identifier::new(self.context, #name_string), - #name.into(), - )] - } - } - FieldKind::Successor { constraint, .. } => { - if constraint.is_variadic() { - quote! { #name } - } else { - quote! { &[#name] } - } - } - FieldKind::Region { constraint, .. } => { - if constraint.is_variadic() { - quote! { #name } - } else { - quote! { vec![#name] } - } - } - }; + let add_arguments = field.add_arguments(&name); - Ok(if field.kind.is_optional() { + Ok(if field.is_optional() { let parameters = self.type_state.parameters().collect::>(); quote! { @@ -132,12 +60,12 @@ impl<'o> OperationBuilder<'o> { } } } - } else if field.kind.is_result() && self.operation.can_infer_type { + } else if field.is_result() && self.operation.can_infer_type { quote!() } else { - let parameters = self.type_state.parameters_without(field.name); - let arguments_set = self.type_state.arguments_set(field.name, true); - let arguments_unset = self.type_state.arguments_set(field.name, false); + let parameters = self.type_state.parameters_without(field.name()); + let arguments_set = self.type_state.arguments_set(field.name(), true); + let arguments_unset = self.type_state.arguments_set(field.name(), false); quote! { impl<'c, #(#parameters),*> #builder_ident<'c, #(#arguments_unset),*> { @@ -156,7 +84,7 @@ impl<'o> OperationBuilder<'o> { }) } - fn create_build_fn(&self) -> Result { + pub fn create_build_fn(&self) -> Result { let builder_ident = self.builder_identifier()?; let arguments = self.type_state.arguments_all_set(true); let class_name = format_ident!("{}", &self.operation.class_name()?); @@ -175,7 +103,7 @@ impl<'o> OperationBuilder<'o> { }) } - fn create_new_fn(&self, phantoms: &[TokenStream]) -> Result { + pub fn create_new_fn(&self, phantoms: &[TokenStream]) -> Result { let builder_ident = self.builder_identifier()?; let name = &self.operation.full_name()?; let arguments = self.type_state.arguments_all_set(false); @@ -212,8 +140,8 @@ impl<'o> OperationBuilder<'o> { let name = sanitize_snake_case_name(self.operation.short_name()?)?; let arguments = Self::required_fields(self.operation) .map(|field| { - let parameter_type = &field.kind.parameter_type(); - let parameter_name = &field.sanitized_name; + let parameter_type = &field.parameter_type(); + let parameter_name = &field.sanitized_name(); quote! { #parameter_name: #parameter_type } }) @@ -221,7 +149,7 @@ impl<'o> OperationBuilder<'o> { .collect::>(); let builder_calls = Self::required_fields(self.operation) .map(|field| { - let parameter_name = &field.sanitized_name; + let parameter_name = &field.sanitized_name(); quote! { .#parameter_name(#parameter_name) } }) @@ -238,11 +166,11 @@ impl<'o> OperationBuilder<'o> { }) } - fn required_fields<'a, 'b>( - operation: &'a Operation<'b>, - ) -> impl Iterator> { + fn required_fields<'a>( + operation: &'a Operation, + ) -> impl Iterator { operation.fields().filter(|field| { - (!field.kind.is_result() || !operation.can_infer_type) && !field.kind.is_optional() + (!field.is_result() || !operation.can_infer_type) && !field.is_optional() }) } @@ -250,12 +178,12 @@ impl<'o> OperationBuilder<'o> { TypeStateList::new( Self::required_fields(operation) .enumerate() - .map(|(index, field)| TypeStateItem::new(index, field.name.to_string())) + .map(|(index, field)| TypeStateItem::new(index, field.name().to_string())) .collect(), ) } - fn builder_identifier(&self) -> Result { + pub fn builder_identifier(&self) -> Result { Ok(format_ident!("{}Builder", self.operation.class_name()?)) } } diff --git a/macro/src/dialect/operation/field_kind.rs b/macro/src/dialect/operation/field_kind.rs index 4e825d67f3..9611b2ce56 100644 --- a/macro/src/dialect/operation/field_kind.rs +++ b/macro/src/dialect/operation/field_kind.rs @@ -1,6 +1,7 @@ use super::{element_kind::ElementKind, SequenceInfo, VariadicKind}; -use crate::dialect::types::{ - AttributeConstraint, RegionConstraint, SuccessorConstraint, TypeConstraint, +use crate::dialect::{ + types::{RegionConstraint, SuccessorConstraint, TypeConstraint}, + utility::{generate_iterator_type, generate_result_type}, }; use syn::{parse_quote, Type}; @@ -12,9 +13,6 @@ pub enum FieldKind<'a> { sequence_info: SequenceInfo, variadic_kind: VariadicKind, }, - Attribute { - constraint: AttributeConstraint<'a>, - }, Successor { constraint: SuccessorConstraint<'a>, sequence_info: SequenceInfo, @@ -26,35 +24,13 @@ pub enum FieldKind<'a> { } 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) -> bool { 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) -> Type { match self { Self::Element { @@ -74,14 +50,6 @@ impl<'a> FieldKind<'a> { base_type } } - Self::Attribute { constraint } => { - if constraint.is_unit() { - parse_quote!(bool) - } else { - let r#type = 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() { @@ -101,14 +69,6 @@ impl<'a> FieldKind<'a> { } } - 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) -> Type { match self { Self::Element { @@ -127,34 +87,27 @@ impl<'a> FieldKind<'a> { }; if !constraint.is_variadic() { - Self::create_result_type(base_type) + generate_result_type(base_type) } else if variadic_kind == &VariadicKind::AttributeSized { - 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) + generate_result_type(generate_iterator_type(base_type)) } else { - Self::create_result_type(self.parameter_type()) + generate_iterator_type(base_type) } } Self::Successor { constraint, .. } => { let r#type: Type = parse_quote!(::melior::ir::BlockRef<'c, '_>); if constraint.is_variadic() { - Self::create_iterator_type(r#type) + generate_iterator_type(r#type) } else { - Self::create_result_type(r#type) + generate_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) + generate_iterator_type(r#type) } else { - Self::create_result_type(r#type) + generate_result_type(r#type) } } } diff --git a/macro/src/dialect/operation/operation_field.rs b/macro/src/dialect/operation/operation_field.rs index 1977823b79..96ed6402f9 100644 --- a/macro/src/dialect/operation/operation_field.rs +++ b/macro/src/dialect/operation/operation_field.rs @@ -1,34 +1,110 @@ use super::{element_kind::ElementKind, field_kind::FieldKind, SequenceInfo, VariadicKind}; use crate::dialect::{ error::Error, - types::{AttributeConstraint, RegionConstraint, SuccessorConstraint, TypeConstraint}, + types::{RegionConstraint, SuccessorConstraint, TypeConstraint}, utility::sanitize_snake_case_name, }; -use proc_macro2::Ident; +use proc_macro2::{Ident, TokenStream}; +use quote::quote; +use syn::Type; + +// TODO Rename this `OperationField`. +pub trait OperationFieldLike { + fn name(&self) -> &str; + fn plural_identifier(&self) -> &str; + fn sanitized_name(&self) -> &Ident; + fn parameter_type(&self) -> Type; + fn return_type(&self) -> Type; + fn is_optional(&self) -> bool; + // TODO Remove this. + fn is_result(&self) -> bool; + fn add_arguments(&self, name: &Ident) -> TokenStream; +} #[derive(Debug, Clone)] pub struct OperationField<'a> { pub(crate) name: &'a str, + pub(crate) plural_identifier: String, pub(crate) sanitized_name: Ident, pub(crate) kind: FieldKind<'a>, } +impl OperationFieldLike for OperationField<'_> { + fn name(&self) -> &str { + self.name + } + + fn plural_identifier(&self) -> &str { + &self.plural_identifier + } + + fn sanitized_name(&self) -> &Ident { + &self.sanitized_name + } + + fn parameter_type(&self) -> Type { + self.kind.parameter_type() + } + + fn return_type(&self) -> Type { + self.kind.return_type() + } + + fn is_optional(&self) -> bool { + self.kind.is_optional() + } + + fn is_result(&self) -> bool { + matches!( + self.kind, + FieldKind::Element { + kind: ElementKind::Result, + .. + } + ) + } + + fn add_arguments(&self, name: &Ident) -> TokenStream { + match &self.kind { + FieldKind::Element { constraint, .. } => { + if constraint.has_unfixed() && !constraint.is_optional() { + quote! { #name } + } else { + quote! { &[#name] } + } + } + FieldKind::Successor { constraint, .. } => { + if constraint.is_variadic() { + quote! { #name } + } else { + quote! { &[#name] } + } + } + FieldKind::Region { constraint, .. } => { + if constraint.is_variadic() { + quote! { #name } + } else { + quote! { vec![#name] } + } + } + } + } +} + impl<'a> OperationField<'a> { fn new(name: &'a str, kind: FieldKind<'a>) -> Result { Ok(Self { name, + plural_identifier: match kind { + FieldKind::Element { kind, .. } => format!("{}s", kind.as_str()), + FieldKind::Successor { .. } => "successors".into(), + FieldKind::Region { .. } => "regions".into(), + }, 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>, diff --git a/macro/src/dialect/utility.rs b/macro/src/dialect/utility.rs index a13cf22235..29790c0745 100644 --- a/macro/src/dialect/utility.rs +++ b/macro/src/dialect/utility.rs @@ -3,9 +3,18 @@ use comrak::{arena_tree::NodeEdge, format_commonmark, nodes::NodeValue, parse_do use convert_case::{Case, Casing}; use proc_macro2::Ident; use quote::format_ident; +use syn::{parse_quote, Type}; const RESERVED_NAMES: &[&str] = &["name", "operation", "builder"]; +pub fn generate_result_type(r#type: Type) -> Type { + parse_quote!(Result<#r#type, ::melior::Error>) +} + +pub fn generate_iterator_type(r#type: Type) -> Type { + parse_quote!(impl Iterator) +} + pub fn sanitize_snake_case_name(name: &str) -> Result { sanitize_name(&name.to_case(Case::Snake)) } From 8596a8e72c54b90083d6cbed2da437e37560bb99 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Thu, 15 Feb 2024 21:13:23 +0900 Subject: [PATCH 051/108] Test dialect build (#416) --- .github/workflows/test.yaml | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index dfbb902c45..4637491134 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -9,8 +9,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: Swatinem/rust-cache@v2 - - uses: Homebrew/actions/setup-homebrew@master + - uses: swatinem/rust-cache@v2 + - uses: homebrew/actions/setup-homebrew@master - run: tools/setup.sh - run: cargo build --all-features test: @@ -23,15 +23,30 @@ jobs: runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - - uses: Swatinem/rust-cache@v2 - - uses: Homebrew/actions/setup-homebrew@master + - uses: swatinem/rust-cache@v2 + - uses: homebrew/actions/setup-homebrew@master - run: tools/setup.sh - run: cargo test --all-features bench: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: Swatinem/rust-cache@v2 - - uses: Homebrew/actions/setup-homebrew@master + - uses: swatinem/rust-cache@v2 + - uses: homebrew/actions/setup-homebrew@master - run: tools/setup.sh - run: cargo bench + dialect_build: + # TODO Remove this job when refactoring of dialect macros is done. + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: swatinem/rust-cache@v2 + - uses: homebrew/actions/setup-homebrew@master + - run: tools/setup.sh + - run: cargo install cargo-expand + - run: cd melior && cargo expand --features ods-dialects > ~/current.rs + - uses: actions/checkout@v4 + with: + ref: main + - run: cd melior && cargo expand --features ods-dialects > ~/main.rs + - run: diff ~/main.rs ~/current.rs From 026e2be39962aeb32124d2334c5319af05311c88 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Thu, 15 Feb 2024 22:08:30 +0900 Subject: [PATCH 052/108] Refactor dialect macro (#417) --- macro/src/dialect/generation.rs | 2 +- .../dialect/generation/operation_builder.rs | 2 +- macro/src/dialect/operation/builder.rs | 25 ++++++++++--------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/macro/src/dialect/generation.rs b/macro/src/dialect/generation.rs index ab90bc6ee3..c44035048e 100644 --- a/macro/src/dialect/generation.rs +++ b/macro/src/dialect/generation.rs @@ -26,7 +26,7 @@ pub fn generate_operation(operation: &Operation) -> Result { .map(generate_attribute_accessors) .collect::, _>>()?; - let builder = OperationBuilder::new(operation); + let builder = OperationBuilder::new(operation)?; let builder_tokens = generate_operation_builder(&builder)?; let builder_fn = builder.create_op_builder_fn()?; let default_constructor = builder.create_default_constructor()?; diff --git a/macro/src/dialect/generation/operation_builder.rs b/macro/src/dialect/generation/operation_builder.rs index 4256d47c23..9fdf73083a 100644 --- a/macro/src/dialect/generation/operation_builder.rs +++ b/macro/src/dialect/generation/operation_builder.rs @@ -34,7 +34,7 @@ pub fn generate_operation_builder(builder: &OperationBuilder) -> Result { operation: &'o Operation<'o>, + identifier: Ident, type_state: TypeStateList, } impl<'o> OperationBuilder<'o> { - pub fn new(operation: &'o Operation<'o>) -> Self { - Self { + pub fn new(operation: &'o Operation<'o>) -> Result { + Ok(Self { operation, + identifier: format_ident!("{}Builder", operation.class_name()?), type_state: Self::create_type_state(operation), - } + }) } pub fn operation(&self) -> &Operation { self.operation } + pub fn identifier(&self) -> &Ident { + &self.identifier + } + pub fn type_state(&self) -> &TypeStateList { &self.type_state } @@ -37,8 +43,7 @@ impl<'o> OperationBuilder<'o> { phantoms: &'a [TokenStream], ) -> impl Iterator> + 'a { self.operation.fields().map(move |field| { - // TODO Initialize a builder identifier out of this closure. - let builder_ident = self.builder_identifier()?; + let builder_ident = self.identifier(); let name = sanitize_snake_case_name(field.name())?; let parameter_type = field.parameter_type(); let argument = quote! { #name: #parameter_type }; @@ -85,7 +90,7 @@ impl<'o> OperationBuilder<'o> { } pub fn create_build_fn(&self) -> Result { - let builder_ident = self.builder_identifier()?; + let builder_ident = self.identifier(); let arguments = self.type_state.arguments_all_set(true); let class_name = format_ident!("{}", &self.operation.class_name()?); let error = format!("should be a valid {class_name}"); @@ -104,7 +109,7 @@ impl<'o> OperationBuilder<'o> { } pub fn create_new_fn(&self, phantoms: &[TokenStream]) -> Result { - let builder_ident = self.builder_identifier()?; + let builder_ident = self.identifier(); let name = &self.operation.full_name()?; let arguments = self.type_state.arguments_all_set(false); @@ -122,7 +127,7 @@ impl<'o> OperationBuilder<'o> { } pub fn create_op_builder_fn(&self) -> Result { - let builder_ident = self.builder_identifier()?; + let builder_ident = self.identifier(); let arguments = self.type_state.arguments_all_set(false); Ok(quote! { @@ -182,8 +187,4 @@ impl<'o> OperationBuilder<'o> { .collect(), ) } - - pub fn builder_identifier(&self) -> Result { - Ok(format_ident!("{}Builder", self.operation.class_name()?)) - } } From 1cf365b1a2c30bb324d5212e5337e84569efe527 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Thu, 15 Feb 2024 23:11:15 +0900 Subject: [PATCH 053/108] Remove attribute constraint (#418) --- macro/src/dialect.rs | 1 + macro/src/dialect/operation.rs | 12 +- macro/src/dialect/operation/attribute.rs | 96 +++++++++-- macro/src/dialect/trait.rs | 61 +++++++ macro/src/dialect/types.rs | 201 +---------------------- 5 files changed, 155 insertions(+), 216 deletions(-) create mode 100644 macro/src/dialect/trait.rs diff --git a/macro/src/dialect.rs b/macro/src/dialect.rs index 87c5caae5a..05b097b734 100644 --- a/macro/src/dialect.rs +++ b/macro/src/dialect.rs @@ -2,6 +2,7 @@ mod error; mod generation; mod input; mod operation; +mod r#trait; mod types; mod utility; diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 049b35a956..6b6a60b080 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -14,7 +14,8 @@ pub use self::{ use super::utility::sanitize_documentation; use crate::dialect::{ error::{Error, OdsError}, - types::{AttributeConstraint, RegionConstraint, SuccessorConstraint, Trait, TypeConstraint}, + r#trait::Trait, + types::{RegionConstraint, SuccessorConstraint, TypeConstraint}, }; pub use operation_field::OperationFieldLike; use tblgen::{error::WithLocation, record::Record}; @@ -195,9 +196,8 @@ impl<'a> Operation<'a> { while let Some(trait_list) = trait_lists.pop() { for value in trait_list.iter() { - let definition: Record = value - .try_into() - .map_err(|error: tblgen::Error| error.set_location(definition))?; + let definition = + Record::try_from(value).map_err(|error| error.set_location(definition))?; if definition.subclass_of("TraitList") { trait_lists.push(definition.list_value("traits")?); @@ -329,7 +329,7 @@ impl<'a> Operation<'a> { .with_location(*definition) .into()) } else { - Attribute::new(name, AttributeConstraint::new(*definition)?) + Attribute::new(name, *definition) } }) .collect() @@ -346,7 +346,7 @@ impl<'a> Operation<'a> { }) .map(|definition| { if definition.subclass_of("DerivedAttr") { - Attribute::new(definition.name()?, AttributeConstraint::new(definition)?) + Attribute::new(definition.name()?, definition) } else { Err(OdsError::ExpectedSuperClass("DerivedAttr") .with_location(definition) diff --git a/macro/src/dialect/operation/attribute.rs b/macro/src/dialect/operation/attribute.rs index 508949e73b..de91775ecc 100644 --- a/macro/src/dialect/operation/attribute.rs +++ b/macro/src/dialect/operation/attribute.rs @@ -1,35 +1,111 @@ use crate::dialect::{ error::Error, operation::operation_field::OperationFieldLike, - types::AttributeConstraint, utility::{generate_result_type, sanitize_snake_case_name}, }; +use once_cell::sync::Lazy; use proc_macro2::{Ident, TokenStream}; use quote::quote; +use std::collections::HashMap; use syn::{parse_quote, Type}; +use tblgen::{error::TableGenError, Record}; + +macro_rules! prefixed_string { + ($prefix:literal, $name:ident) => { + concat!($prefix, stringify!($name)) + }; +} + +macro_rules! mlir_attribute { + ($name:ident) => { + prefixed_string!("::mlir::", $name) + }; +} + +macro_rules! melior_attribute { + ($name:ident) => { + prefixed_string!("::melior::ir::attribute::", $name) + }; +} + +static ATTRIBUTE_TYPES: Lazy> = Lazy::new(|| { + let mut map = HashMap::new(); + + macro_rules! initialize_attributes { + ($($mlir:ident => $melior:ident),* $(,)*) => { + $( + map.insert( + mlir_attribute!($mlir), + melior_attribute!($melior), + ); + )* + }; + } + + initialize_attributes!( + ArrayAttr => ArrayAttribute, + Attribute => Attribute, + DenseElementsAttr => DenseElementsAttribute, + DenseI32ArrayAttr => DenseI32ArrayAttribute, + FlatSymbolRefAttr => FlatSymbolRefAttribute, + FloatAttr => FloatAttribute, + IntegerAttr => IntegerAttribute, + StringAttr => StringAttribute, + TypeAttr => TypeAttribute, + ); + + map +}); #[derive(Debug)] pub struct Attribute<'a> { name: &'a str, sanitized_name: Ident, - constraint: AttributeConstraint<'a>, + storage_type_string: String, + storage_type: Type, + optional: bool, + default: bool, } impl<'a> Attribute<'a> { - pub fn new(name: &'a str, constraint: AttributeConstraint<'a>) -> Result { + pub fn new(name: &'a str, record: Record<'a>) -> Result { + let storage_type_string = record.string_value("storageType")?; + Ok(Self { name, sanitized_name: sanitize_snake_case_name(name)?, - constraint, + storage_type: syn::parse_str( + ATTRIBUTE_TYPES + .get(storage_type_string.trim()) + .copied() + .unwrap_or(melior_attribute!(Attribute)), + )?, + storage_type_string, + optional: record.bit_value("isOptional")?, + default: match record.string_value("defaultValue") { + Ok(value) => !value.is_empty(), + Err(error) => { + // `defaultValue` can be uninitialized. + if !matches!(error.error(), TableGenError::InitConversion { .. }) { + return Err(error.into()); + } + + false + } + }, }) } pub fn is_optional(&self) -> bool { - self.constraint.is_optional() + self.optional } pub fn is_unit(&self) -> bool { - self.constraint.is_unit() + self.storage_type_string == mlir_attribute!(UnitAttr) + } + + pub fn has_default_value(&self) -> bool { + self.default } } @@ -47,16 +123,16 @@ impl OperationFieldLike for Attribute<'_> { } fn parameter_type(&self) -> Type { - if self.constraint.is_unit() { + if self.is_unit() { parse_quote!(bool) } else { - let r#type = self.constraint.storage_type(); + let r#type = &self.storage_type; parse_quote!(#r#type<'c>) } } fn return_type(&self) -> Type { - if self.constraint.is_unit() { + if self.is_unit() { parse_quote!(bool) } else { generate_result_type(self.parameter_type()) @@ -64,7 +140,7 @@ impl OperationFieldLike for Attribute<'_> { } fn is_optional(&self) -> bool { - self.is_optional() || self.constraint.has_default_value() + self.is_optional() || self.has_default_value() } fn is_result(&self) -> bool { diff --git a/macro/src/dialect/trait.rs b/macro/src/dialect/trait.rs new file mode 100644 index 0000000000..00aa6dad4f --- /dev/null +++ b/macro/src/dialect/trait.rs @@ -0,0 +1,61 @@ +use super::error::{Error, OdsError}; +use tblgen::{error::WithLocation, record::Record}; + +#[derive(Debug, Clone)] +pub enum Trait { + Interface { + name: String, + }, + Internal { + name: String, + }, + Native { + name: String, + #[allow(unused)] + structural: bool, + }, + Predicate, +} + +impl Trait { + pub fn new(definition: Record) -> Result { + Ok(if definition.subclass_of("PredTrait") { + Self::Predicate + } else if definition.subclass_of("InterfaceTrait") { + Self::Interface { + name: Self::build_name(definition)?, + } + } else if definition.subclass_of("NativeTrait") { + Self::Native { + name: Self::build_name(definition)?, + structural: definition.subclass_of("StructuralOpTrait"), + } + } else if definition.subclass_of("GenInternalTrait") { + Self::Internal { + name: definition.string_value("trait")?, + } + } else { + return Err(OdsError::InvalidTrait.with_location(definition).into()); + }) + } + + pub fn name(&self) -> Option<&str> { + match self { + Self::Native { name, .. } | Self::Internal { name } | Self::Interface { name } => { + Some(name) + } + Self::Predicate => None, + } + } + + fn build_name(definition: Record) -> Result { + let r#trait = definition.string_value("trait")?; + let namespace = definition.string_value("cppNamespace")?; + + Ok(if namespace.is_empty() { + r#trait + } else { + format!("{namespace}::{trait}") + }) + } +} diff --git a/macro/src/dialect/types.rs b/macro/src/dialect/types.rs index b173b0c485..61a61d0e69 100644 --- a/macro/src/dialect/types.rs +++ b/macro/src/dialect/types.rs @@ -1,58 +1,4 @@ -use super::error::{Error, OdsError}; -use once_cell::sync::Lazy; -use std::collections::HashMap; -use syn::Type; -use tblgen::{ - error::{TableGenError, WithLocation}, - record::Record, -}; - -macro_rules! prefixed_string { - ($prefix:literal, $name:ident) => { - concat!($prefix, stringify!($name)) - }; -} - -macro_rules! mlir_attribute { - ($name:ident) => { - prefixed_string!("::mlir::", $name) - }; -} - -macro_rules! melior_attribute { - ($name:ident) => { - prefixed_string!("::melior::ir::attribute::", $name) - }; -} - -static ATTRIBUTE_TYPES: Lazy> = Lazy::new(|| { - let mut map = HashMap::new(); - - macro_rules! initialize_attributes { - ($($mlir:ident => $melior:ident),* $(,)*) => { - $( - map.insert( - mlir_attribute!($mlir), - melior_attribute!($melior), - ); - )* - }; - } - - initialize_attributes!( - ArrayAttr => ArrayAttribute, - Attribute => Attribute, - DenseElementsAttr => DenseElementsAttribute, - DenseI32ArrayAttr => DenseI32ArrayAttribute, - FlatSymbolRefAttr => FlatSymbolRefAttribute, - FloatAttr => FloatAttribute, - IntegerAttr => IntegerAttribute, - StringAttr => StringAttribute, - TypeAttr => TypeAttribute, - ); - - map -}); +use tblgen::record::Record; #[derive(Debug, Clone, Copy)] pub struct RegionConstraint<'a>(Record<'a>); @@ -106,148 +52,3 @@ impl<'a> TypeConstraint<'a> { self.is_variadic() || self.is_optional() } } - -#[derive(Debug, Clone)] -pub struct AttributeConstraint<'a> { - record: Record<'a>, - name: &'a str, - storage_type_str: String, - storage_type: Type, - optional: bool, - default: bool, -} - -impl<'a> AttributeConstraint<'a> { - pub fn new(record: Record<'a>) -> Result { - let storage_type_str = record.string_value("storageType")?; - - Ok(Self { - name: record.name()?, - storage_type: syn::parse_str( - ATTRIBUTE_TYPES - .get(storage_type_str.trim()) - .copied() - .unwrap_or(melior_attribute!(Attribute)), - )?, - storage_type_str, - optional: record.bit_value("isOptional")?, - default: match record.string_value("defaultValue") { - Ok(value) => !value.is_empty(), - Err(error) => { - // `defaultValue` can be uninitialized. - if !matches!(error.error(), TableGenError::InitConversion { .. }) { - return Err(error.into()); - } - - false - } - }, - record, - }) - } - - #[allow(unused)] - pub fn is_derived(&self) -> bool { - self.record.subclass_of("DerivedAttr") - } - - #[allow(unused)] - pub fn is_type(&self) -> bool { - self.record.subclass_of("TypeAttrBase") - } - - #[allow(unused)] - pub fn is_symbol_ref(&self) -> bool { - self.name == "SymbolRefAttr" - || self.name == "FlatSymbolRefAttr" - || self.record.subclass_of("SymbolRefAttr") - || self.record.subclass_of("FlatSymbolRefAttr") - } - - #[allow(unused)] - pub fn is_enum(&self) -> bool { - self.record.subclass_of("EnumAttrInfo") - } - - pub fn is_optional(&self) -> bool { - self.optional - } - - pub fn storage_type(&self) -> &Type { - &self.storage_type - } - - pub fn is_unit(&self) -> bool { - self.storage_type_str == mlir_attribute!(UnitAttr) - } - - pub fn has_default_value(&self) -> bool { - self.default - } -} - -#[derive(Debug, Clone)] -enum TraitKind { - Native { - name: String, - #[allow(unused)] - structural: bool, - }, - Predicate, - Internal { - name: String, - }, - Interface { - name: String, - }, -} - -#[derive(Debug, Clone)] -pub struct Trait { - kind: TraitKind, -} - -impl Trait { - pub fn new(definition: Record) -> Result { - Ok(Self { - kind: if definition.subclass_of("PredTrait") { - TraitKind::Predicate - } else if definition.subclass_of("InterfaceTrait") { - TraitKind::Interface { - name: Self::build_name(definition)?, - } - } else if definition.subclass_of("NativeTrait") { - TraitKind::Native { - name: Self::build_name(definition)?, - structural: definition.subclass_of("StructuralOpTrait"), - } - } else if definition.subclass_of("GenInternalTrait") { - TraitKind::Internal { - name: definition.string_value("trait")?, - } - } else { - return Err(OdsError::InvalidTrait.with_location(definition).into()); - }, - }) - } - - pub fn name(&self) -> Option<&str> { - match &self.kind { - TraitKind::Native { name, .. } - | TraitKind::Internal { name } - | TraitKind::Interface { name } => Some(name), - TraitKind::Predicate => None, - } - } - - fn build_name(definition: Record) -> Result { - let r#trait = definition.string_value("trait")?; - let namespace = definition.string_value("cppNamespace")?; - - Ok(if namespace.is_empty() { - r#trait - } else { - format!("{namespace}::{trait}") - }) - } -} From 43140fe97049c43e70178c201b4650fe2881dd9b Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Fri, 16 Feb 2024 00:01:20 +0900 Subject: [PATCH 054/108] Refactor operation generation (#419) --- .../src/dialect/generation/field_accessor.rs | 4 +- macro/src/dialect/operation.rs | 41 ++++++++++--------- .../src/dialect/operation/operation_field.rs | 2 +- macro/src/dialect/types.rs | 2 +- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/macro/src/dialect/generation/field_accessor.rs b/macro/src/dialect/generation/field_accessor.rs index 9e1a4e4df5..46842bba8d 100644 --- a/macro/src/dialect/generation/field_accessor.rs +++ b/macro/src/dialect/generation/field_accessor.rs @@ -80,7 +80,7 @@ fn generate_getter(field: &OperationField) -> TokenStream { let group_len = total_var_len / #unfixed_count; let start = #preceding_simple_count + #preceding_variadic_count * group_len; }; - let get_elements = if constraint.has_unfixed() { + let get_elements = if constraint.is_unfixed() { quote! { self.operation.#plural().skip(start).take(group_len) } @@ -107,7 +107,7 @@ fn generate_getter(field: &OperationField) -> TokenStream { .sum::() as usize; let group_len = attribute.element(#index)? as usize; }; - let get_elements = if !constraint.has_unfixed() { + let get_elements = if !constraint.is_unfixed() { quote! { self.operation.#kind_ident(start) } diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 6b6a60b080..4663b9b9b2 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -18,7 +18,7 @@ use crate::dialect::{ types::{RegionConstraint, SuccessorConstraint, TypeConstraint}, }; pub use operation_field::OperationFieldLike; -use tblgen::{error::WithLocation, record::Record}; +use tblgen::{error::WithLocation, record::Record, TypedInit}; #[derive(Debug)] pub struct Operation<'a> { @@ -215,21 +215,23 @@ impl<'a> Operation<'a> { fn dag_constraints( definition: Record<'a>, - dag_field_name: &str, + name: &str, ) -> Result)>, Error> { definition - .dag_value(dag_field_name)? + .dag_value(name)? .args() .map(|(name, argument)| { - let mut definition: Record = argument - .try_into() - .map_err(|error: tblgen::Error| error.set_location(definition))?; - - if definition.subclass_of("OpVariable") { - definition = definition.def_value("constraint")?; - } + let definition = + Record::try_from(argument).map_err(|error| error.set_location(definition))?; - Ok((name, definition)) + Ok(( + name, + if definition.subclass_of("OpVariable") { + definition.def_value("constraint")? + } else { + definition + }, + )) }) .collect() } @@ -276,7 +278,7 @@ impl<'a> Operation<'a> { ) -> Result<(Vec>, usize), Error> { let unfixed_count = elements .iter() - .filter(|(_, constraint)| constraint.has_unfixed()) + .filter(|(_, constraint)| constraint.is_unfixed()) .count(); let mut variadic_kind = VariadicKind::new(unfixed_count, same_size, attribute_sized); let mut fields = vec![]; @@ -295,7 +297,7 @@ impl<'a> Operation<'a> { match &mut variadic_kind { VariadicKind::Simple { unfixed_seen } => { - if constraint.has_unfixed() { + if constraint.is_unfixed() { *unfixed_seen = true; } } @@ -304,7 +306,7 @@ impl<'a> Operation<'a> { preceding_variadic_count, .. } => { - if constraint.has_unfixed() { + if constraint.is_unfixed() { *preceding_variadic_count += 1; } else { *preceding_simple_count += 1; @@ -338,12 +340,11 @@ impl<'a> Operation<'a> { fn collect_derived_attributes(definition: Record<'a>) -> Result>, Error> { definition .values() - .filter_map(|value| { - let Ok(definition) = Record::try_from(value) else { - return None; - }; - definition.subclass_of("Attr").then_some(definition) - }) + .filter(|value| matches!(value.init, TypedInit::Def(_))) + .map(Record::try_from) + .collect::, _>>()? + .into_iter() + .filter(|definition| definition.subclass_of("Attr")) .map(|definition| { if definition.subclass_of("DerivedAttr") { Attribute::new(definition.name()?, definition) diff --git a/macro/src/dialect/operation/operation_field.rs b/macro/src/dialect/operation/operation_field.rs index 96ed6402f9..7324f3dac2 100644 --- a/macro/src/dialect/operation/operation_field.rs +++ b/macro/src/dialect/operation/operation_field.rs @@ -67,7 +67,7 @@ impl OperationFieldLike for OperationField<'_> { fn add_arguments(&self, name: &Ident) -> TokenStream { match &self.kind { FieldKind::Element { constraint, .. } => { - if constraint.has_unfixed() && !constraint.is_optional() { + if constraint.is_unfixed() && !constraint.is_optional() { quote! { #name } } else { quote! { &[#name] } diff --git a/macro/src/dialect/types.rs b/macro/src/dialect/types.rs index 61a61d0e69..9a569aa111 100644 --- a/macro/src/dialect/types.rs +++ b/macro/src/dialect/types.rs @@ -48,7 +48,7 @@ impl<'a> TypeConstraint<'a> { self.0.subclass_of("VariadicOfVariadic") } - pub fn has_unfixed(&self) -> bool { + pub fn is_unfixed(&self) -> bool { self.is_variadic() || self.is_optional() } } From 45965f04b27ceb8b29abb5261d3893526a8fa8a1 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sat, 17 Feb 2024 00:46:57 +0900 Subject: [PATCH 055/108] Refactor operation builders in dialect macros (#420) --- macro/src/dialect.rs | 4 +- macro/src/dialect/generation.rs | 11 +- .../dialect/generation/attribute_accessor.rs | 10 +- .../dialect/generation/operation_builder.rs | 166 ++++++++++++++++-- macro/src/dialect/operation.rs | 9 + macro/src/dialect/operation/attribute.rs | 17 +- macro/src/dialect/operation/builder.rs | 155 +--------------- .../src/dialect/operation/operation_field.rs | 26 +-- macro/src/dialect/utility.rs | 14 +- 9 files changed, 213 insertions(+), 199 deletions(-) diff --git a/macro/src/dialect.rs b/macro/src/dialect.rs index 05b097b734..c283a867f9 100644 --- a/macro/src/dialect.rs +++ b/macro/src/dialect.rs @@ -9,7 +9,7 @@ mod utility; use self::{ error::Error, generation::generate_operation, - utility::{sanitize_documentation, sanitize_snake_case_name}, + utility::{sanitize_documentation, sanitize_snake_case_identifier}, }; pub use input::DialectInput; use operation::Operation; @@ -81,7 +81,7 @@ fn generate_dialect_module( "`{name}` dialect.\n\n{}", sanitize_documentation(dialect.str_value("description").unwrap_or(""),)? ); - let name = sanitize_snake_case_name(name)?; + let name = sanitize_snake_case_identifier(name)?; Ok(quote! { #[doc = #doc] diff --git a/macro/src/dialect/generation.rs b/macro/src/dialect/generation.rs index c44035048e..e0bf846e9b 100644 --- a/macro/src/dialect/generation.rs +++ b/macro/src/dialect/generation.rs @@ -3,8 +3,11 @@ mod field_accessor; mod operation_builder; use self::{ - attribute_accessor::generate_attribute_accessors, field_accessor::generate_accessor, - operation_builder::generate_operation_builder, + attribute_accessor::generate_attribute_accessors, + field_accessor::generate_accessor, + operation_builder::{ + generate_default_constructor, generate_operation_builder, generate_operation_builder_fn, + }, }; use super::operation::{Operation, OperationBuilder}; use crate::dialect::error::Error; @@ -28,8 +31,8 @@ pub fn generate_operation(operation: &Operation) -> Result { let builder = OperationBuilder::new(operation)?; let builder_tokens = generate_operation_builder(&builder)?; - let builder_fn = builder.create_op_builder_fn()?; - let default_constructor = builder.create_default_constructor()?; + let builder_fn = generate_operation_builder_fn(&builder)?; + let default_constructor = generate_default_constructor(&builder)?; Ok(quote! { #[doc = #summary] diff --git a/macro/src/dialect/generation/attribute_accessor.rs b/macro/src/dialect/generation/attribute_accessor.rs index 5e6ccc5313..02ed99f441 100644 --- a/macro/src/dialect/generation/attribute_accessor.rs +++ b/macro/src/dialect/generation/attribute_accessor.rs @@ -1,7 +1,7 @@ use crate::dialect::{ error::Error, operation::{Attribute, OperationFieldLike}, - utility::sanitize_snake_case_name, + utility::sanitize_snake_case_identifier, }; use proc_macro2::TokenStream; use quote::quote; @@ -21,7 +21,7 @@ pub fn generate_attribute_accessors(attribute: &Attribute) -> Result Result { let name = attribute.name(); - let ident = attribute.sanitized_name(); + let identifier = attribute.singular_identifier(); let return_type = attribute.return_type(); let body = if attribute.is_unit() { quote! { self.operation.attribute(#name).is_some() } @@ -32,7 +32,7 @@ fn generate_getter(attribute: &Attribute) -> Result { Ok(quote! { #[allow(clippy::needless_question_mark)] - pub fn #ident(&self, context: &'c ::melior::Context) -> #return_type { + pub fn #identifier(&self, context: &'c ::melior::Context) -> #return_type { #body } }) @@ -55,7 +55,7 @@ fn generate_setter(attribute: &Attribute) -> Result { } }; - let ident = sanitize_snake_case_name(&format!("set_{}", attribute.name()))?; + let ident = sanitize_snake_case_identifier(&format!("set_{}", attribute.name()))?; let r#type = attribute.parameter_type(); Ok(quote! { @@ -68,7 +68,7 @@ fn generate_setter(attribute: &Attribute) -> Result { fn generate_remover(attribute: &Attribute) -> Result, Error> { Ok(if attribute.is_unit() || attribute.is_optional() { let name = attribute.name(); - let ident = sanitize_snake_case_name(&format!("remove_{}", attribute.name()))?; + let ident = sanitize_snake_case_identifier(&format!("remove_{}", attribute.name()))?; Some(quote! { pub fn #ident(&mut self, context: &'c ::melior::Context) -> Result<(), ::melior::Error> { diff --git a/macro/src/dialect/generation/operation_builder.rs b/macro/src/dialect/generation/operation_builder.rs index 9fdf73083a..299af0464f 100644 --- a/macro/src/dialect/generation/operation_builder.rs +++ b/macro/src/dialect/generation/operation_builder.rs @@ -1,14 +1,15 @@ use crate::dialect::{ - error::Error, operation::OperationBuilder, utility::sanitize_snake_case_name, + error::Error, operation::OperationBuilder, utility::sanitize_snake_case_identifier, }; use proc_macro2::TokenStream; -use quote::quote; +use quote::{format_ident, quote}; +use syn::Ident; pub fn generate_operation_builder(builder: &OperationBuilder) -> Result { let field_names = builder .type_state() .field_names() - .map(sanitize_snake_case_name) + .map(sanitize_snake_case_identifier) .collect::, _>>()?; let phantom_fields = @@ -27,29 +28,168 @@ pub fn generate_operation_builder(builder: &OperationBuilder) -> Result>(); - let builder_fns = builder - .create_builder_fns(&field_names, phantom_arguments.as_slice()) - .collect::, _>>()?; + let builder_fns = generate_builder_fns(builder, &field_names, phantom_arguments.as_slice())?; - let new = builder.create_new_fn(phantom_arguments.as_slice())?; - let build = builder.create_build_fn()?; + let new_fn = generate_new_fn(builder, phantom_arguments.as_slice())?; + let build_fn = generate_build_fn(builder)?; let builder_identifier = builder.identifier(); - let doc = format!("Builder for {}", builder.operation().summary()?); - let iter_arguments = builder.type_state().parameters(); + let doc = format!("A builder for {}", builder.operation().summary()?); + let type_arguments = builder.type_state().parameters(); Ok(quote! { #[doc = #doc] - pub struct #builder_identifier<'c, #(#iter_arguments),*> { + pub struct #builder_identifier<'c, #(#type_arguments),*> { builder: ::melior::ir::operation::OperationBuilder<'c>, context: &'c ::melior::Context, #(#phantom_fields),* } - #new + #new_fn #(#builder_fns)* - #build + #build_fn + }) +} + +fn generate_builder_fns( + builder: &OperationBuilder, + field_names: &[Ident], + phantoms: &[TokenStream], +) -> Result, Error> { + builder.operation().fields().map(move |field| { + let builder_identifier = builder.identifier(); + let identifier = sanitize_snake_case_identifier(field.name())?; + let parameter_type = field.parameter_type(); + let argument = quote! { #identifier: #parameter_type }; + let add = format_ident!("add_{}", field.plural_kind_identifier()); + + // Argument types can be singular and variadic. But `add` functions in Melior + // are always variadic, so we need to create a slice or `Vec` for singular + // arguments. + let add_arguments = field.add_arguments(&identifier); + + Ok(if field.is_optional() { + let parameters = builder.type_state().parameters().collect::>(); + + quote! { + impl<'c, #(#parameters),*> #builder_identifier<'c, #(#parameters),*> { + pub fn #identifier(mut self, #argument) -> #builder_identifier<'c, #(#parameters),*> { + self.builder = self.builder.#add(#add_arguments); + self + } + } + } + } else if field.is_result() && builder.operation().can_infer_type() { + quote!() + } else { + let parameters = builder.type_state().parameters_without(field.name()); + let arguments_set = builder.type_state().arguments_set(field.name(), true); + let arguments_unset = builder.type_state().arguments_set(field.name(), false); + + quote! { + impl<'c, #(#parameters),*> #builder_identifier<'c, #(#arguments_unset),*> { + pub fn #identifier(mut self, #argument) -> #builder_identifier<'c, #(#arguments_set),*> { + self.builder = self.builder.#add(#add_arguments); + let Self { context, mut builder, #(#field_names),* } = self; + #builder_identifier { + context, + builder, + #(#phantoms),* + } + } + } + } + }) + }).collect() +} + +fn generate_build_fn(builder: &OperationBuilder) -> Result { + let builder_ident = builder.identifier(); + let arguments = builder.type_state().arguments_all_set(true); + let class_name = format_ident!("{}", &builder.operation().class_name()?); + let error = format!("should be a valid {class_name}"); + let maybe_infer = builder + .operation() + .can_infer_type() + .then_some(quote! { .enable_result_type_inference() }); + + Ok(quote! { + impl<'c> #builder_ident<'c, #(#arguments),*> { + pub fn build(self) -> #class_name<'c> { + self.builder #maybe_infer.build().expect("valid operation").try_into().expect(#error) + } + } + }) +} + +fn generate_new_fn( + builder: &OperationBuilder, + phantoms: &[TokenStream], +) -> Result { + let builder_ident = builder.identifier(); + let name = &builder.operation().full_name()?; + let arguments = builder.type_state().arguments_all_set(false); + + Ok(quote! { + impl<'c> #builder_ident<'c, #(#arguments),*> { + pub fn new(context: &'c ::melior::Context, location: ::melior::ir::Location<'c>) -> Self { + Self { + context, + builder: ::melior::ir::operation::OperationBuilder::new( #name, location), + #(#phantoms),* + } + } + } + }) +} + +pub fn generate_operation_builder_fn(builder: &OperationBuilder) -> Result { + let builder_ident = builder.identifier(); + let arguments = builder.type_state().arguments_all_set(false); + + Ok(quote! { + pub fn builder( + context: &'c ::melior::Context, + location: ::melior::ir::Location<'c> + ) -> #builder_ident<'c, #(#arguments),*> { + #builder_ident::new(context, location) + } + }) +} + +pub fn generate_default_constructor(builder: &OperationBuilder) -> Result { + let class_name = format_ident!("{}", &builder.operation().class_name()?); + let name = sanitize_snake_case_identifier(builder.operation().short_name()?)?; + let arguments = builder + .operation() + .required_fields() + .map(|field| { + let parameter_type = &field.parameter_type(); + let parameter_name = &field.singular_identifier(); + + quote! { #parameter_name: #parameter_type } + }) + .chain([quote! { location: ::melior::ir::Location<'c> }]) + .collect::>(); + let builder_calls = builder + .operation() + .required_fields() + .map(|field| { + let parameter_name = &field.singular_identifier(); + + quote! { .#parameter_name(#parameter_name) } + }) + .collect::>(); + + let doc = format!("Creates a new {}", builder.operation().summary()?); + + Ok(quote! { + #[allow(clippy::too_many_arguments)] + #[doc = #doc] + pub fn #name<'c>(context: &'c ::melior::Context, #(#arguments),*) -> #class_name<'c> { + #class_name::builder(context, location)#(#builder_calls)*.build() + } }) } diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 4663b9b9b2..63383c5203 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -67,6 +67,10 @@ impl<'a> Operation<'a> { }) } + pub fn can_infer_type(&self) -> bool { + self.can_infer_type + } + fn dialect(&self) -> Result { Ok(self.definition.def_value("opDialect")?) } @@ -148,6 +152,11 @@ impl<'a> Operation<'a> { self.attributes.iter().chain(&self.derived_attributes) } + pub fn required_fields(&self) -> impl Iterator { + self.fields() + .filter(|field| (!field.is_result() || !self.can_infer_type) && !field.is_optional()) + } + fn collect_successors(definition: Record<'a>) -> Result, Error> { let successors_dag = definition.dag_value("successors")?; let len = successors_dag.num_args(); diff --git a/macro/src/dialect/operation/attribute.rs b/macro/src/dialect/operation/attribute.rs index de91775ecc..8d520ce074 100644 --- a/macro/src/dialect/operation/attribute.rs +++ b/macro/src/dialect/operation/attribute.rs @@ -1,12 +1,13 @@ use crate::dialect::{ error::Error, operation::operation_field::OperationFieldLike, - utility::{generate_result_type, sanitize_snake_case_name}, + utility::{generate_result_type, sanitize_snake_case_identifier}, }; use once_cell::sync::Lazy; -use proc_macro2::{Ident, TokenStream}; +use proc_macro2::{Span, TokenStream}; use quote::quote; use std::collections::HashMap; +use syn::Ident; use syn::{parse_quote, Type}; use tblgen::{error::TableGenError, Record}; @@ -60,7 +61,7 @@ static ATTRIBUTE_TYPES: Lazy> = Lazy::new(|| #[derive(Debug)] pub struct Attribute<'a> { name: &'a str, - sanitized_name: Ident, + singular_identifier: Ident, storage_type_string: String, storage_type: Type, optional: bool, @@ -73,7 +74,7 @@ impl<'a> Attribute<'a> { Ok(Self { name, - sanitized_name: sanitize_snake_case_name(name)?, + singular_identifier: sanitize_snake_case_identifier(name)?, storage_type: syn::parse_str( ATTRIBUTE_TYPES .get(storage_type_string.trim()) @@ -114,12 +115,12 @@ impl OperationFieldLike for Attribute<'_> { self.name } - fn plural_identifier(&self) -> &str { - "attributes" + fn singular_identifier(&self) -> &Ident { + &self.singular_identifier } - fn sanitized_name(&self) -> &Ident { - &self.sanitized_name + fn plural_kind_identifier(&self) -> Ident { + Ident::new("attributes", Span::call_site()) } fn parameter_type(&self) -> Type { diff --git a/macro/src/dialect/operation/builder.rs b/macro/src/dialect/operation/builder.rs index 5c0078fd65..22e7784aa1 100644 --- a/macro/src/dialect/operation/builder.rs +++ b/macro/src/dialect/operation/builder.rs @@ -2,13 +2,9 @@ mod type_state_item; mod type_state_list; use self::{type_state_item::TypeStateItem, type_state_list::TypeStateList}; -use super::{ - super::{error::Error, utility::sanitize_snake_case_name}, - operation_field::OperationFieldLike, - Operation, -}; -use proc_macro2::{Ident, TokenStream}; -use quote::{format_ident, quote}; +use super::{super::error::Error, Operation}; +use quote::format_ident; +use syn::Ident; pub struct OperationBuilder<'o> { operation: &'o Operation<'o>, @@ -37,151 +33,10 @@ impl<'o> OperationBuilder<'o> { &self.type_state } - pub fn create_builder_fns<'a>( - &'a self, - field_names: &'a [Ident], - phantoms: &'a [TokenStream], - ) -> impl Iterator> + 'a { - self.operation.fields().map(move |field| { - let builder_ident = self.identifier(); - let name = sanitize_snake_case_name(field.name())?; - let parameter_type = field.parameter_type(); - let argument = quote! { #name: #parameter_type }; - let add = format_ident!("add_{}", field.plural_identifier()); - - // Argument types can be singular and variadic, but add functions in melior - // are always variadic, so we need to create a slice or vec for singular - // arguments - let add_arguments = field.add_arguments(&name); - - Ok(if field.is_optional() { - let parameters = self.type_state.parameters().collect::>(); - - quote! { - impl<'c, #(#parameters),*> #builder_ident<'c, #(#parameters),*> { - pub fn #name(mut self, #argument) -> #builder_ident<'c, #(#parameters),*> { - self.builder = self.builder.#add(#add_arguments); - self - } - } - } - } else if field.is_result() && self.operation.can_infer_type { - quote!() - } else { - let parameters = self.type_state.parameters_without(field.name()); - let arguments_set = self.type_state.arguments_set(field.name(), true); - let arguments_unset = self.type_state.arguments_set(field.name(), false); - - quote! { - impl<'c, #(#parameters),*> #builder_ident<'c, #(#arguments_unset),*> { - pub fn #name(mut self, #argument) -> #builder_ident<'c, #(#arguments_set),*> { - self.builder = self.builder.#add(#add_arguments); - let Self { context, mut builder, #(#field_names),* } = self; - #builder_ident { - context, - builder, - #(#phantoms),* - } - } - } - } - }) - }) - } - - pub fn create_build_fn(&self) -> Result { - let builder_ident = self.identifier(); - let arguments = self.type_state.arguments_all_set(true); - let class_name = format_ident!("{}", &self.operation.class_name()?); - let error = format!("should be a valid {class_name}"); - let maybe_infer = self - .operation - .can_infer_type - .then_some(quote! { .enable_result_type_inference() }); - - Ok(quote! { - impl<'c> #builder_ident<'c, #(#arguments),*> { - pub fn build(self) -> #class_name<'c> { - self.builder #maybe_infer.build().expect("valid operation").try_into().expect(#error) - } - } - }) - } - - pub fn create_new_fn(&self, phantoms: &[TokenStream]) -> Result { - let builder_ident = self.identifier(); - let name = &self.operation.full_name()?; - let arguments = self.type_state.arguments_all_set(false); - - Ok(quote! { - impl<'c> #builder_ident<'c, #(#arguments),*> { - pub fn new(context: &'c ::melior::Context, location: ::melior::ir::Location<'c>) -> Self { - Self { - context, - builder: ::melior::ir::operation::OperationBuilder::new( #name, location), - #(#phantoms),* - } - } - } - }) - } - - pub fn create_op_builder_fn(&self) -> Result { - let builder_ident = self.identifier(); - let arguments = self.type_state.arguments_all_set(false); - - Ok(quote! { - pub fn builder( - context: &'c ::melior::Context, - location: ::melior::ir::Location<'c> - ) -> #builder_ident<'c, #(#arguments),*> { - #builder_ident::new(context, location) - } - }) - } - - pub fn create_default_constructor(&self) -> Result { - let class_name = format_ident!("{}", &self.operation.class_name()?); - let name = sanitize_snake_case_name(self.operation.short_name()?)?; - let arguments = Self::required_fields(self.operation) - .map(|field| { - let parameter_type = &field.parameter_type(); - let parameter_name = &field.sanitized_name(); - - quote! { #parameter_name: #parameter_type } - }) - .chain([quote! { location: ::melior::ir::Location<'c> }]) - .collect::>(); - let builder_calls = Self::required_fields(self.operation) - .map(|field| { - let parameter_name = &field.sanitized_name(); - - quote! { .#parameter_name(#parameter_name) } - }) - .collect::>(); - - let doc = format!("Creates a new {}", self.operation.summary()?); - - Ok(quote! { - #[allow(clippy::too_many_arguments)] - #[doc = #doc] - pub fn #name<'c>(context: &'c ::melior::Context, #(#arguments),*) -> #class_name<'c> { - #class_name::builder(context, location)#(#builder_calls)*.build() - } - }) - } - - fn required_fields<'a>( - operation: &'a Operation, - ) -> impl Iterator { - operation.fields().filter(|field| { - (!field.is_result() || !operation.can_infer_type) && !field.is_optional() - }) - } - fn create_type_state(operation: &'o Operation<'o>) -> TypeStateList { TypeStateList::new( - Self::required_fields(operation) + operation + .required_fields() .enumerate() .map(|(index, field)| TypeStateItem::new(index, field.name().to_string())) .collect(), diff --git a/macro/src/dialect/operation/operation_field.rs b/macro/src/dialect/operation/operation_field.rs index 7324f3dac2..7dd8d845b5 100644 --- a/macro/src/dialect/operation/operation_field.rs +++ b/macro/src/dialect/operation/operation_field.rs @@ -2,17 +2,17 @@ use super::{element_kind::ElementKind, field_kind::FieldKind, SequenceInfo, Vari use crate::dialect::{ error::Error, types::{RegionConstraint, SuccessorConstraint, TypeConstraint}, - utility::sanitize_snake_case_name, + utility::sanitize_snake_case_identifier, }; use proc_macro2::{Ident, TokenStream}; -use quote::quote; +use quote::{format_ident, quote}; use syn::Type; // TODO Rename this `OperationField`. pub trait OperationFieldLike { fn name(&self) -> &str; - fn plural_identifier(&self) -> &str; - fn sanitized_name(&self) -> &Ident; + fn singular_identifier(&self) -> &Ident; + fn plural_kind_identifier(&self) -> Ident; fn parameter_type(&self) -> Type; fn return_type(&self) -> Type; fn is_optional(&self) -> bool; @@ -24,7 +24,7 @@ pub trait OperationFieldLike { #[derive(Debug, Clone)] pub struct OperationField<'a> { pub(crate) name: &'a str, - pub(crate) plural_identifier: String, + pub(crate) plural_identifier: Ident, pub(crate) sanitized_name: Ident, pub(crate) kind: FieldKind<'a>, } @@ -34,12 +34,12 @@ impl OperationFieldLike for OperationField<'_> { self.name } - fn plural_identifier(&self) -> &str { - &self.plural_identifier + fn singular_identifier(&self) -> &Ident { + &self.sanitized_name } - fn sanitized_name(&self) -> &Ident { - &self.sanitized_name + fn plural_kind_identifier(&self) -> Ident { + self.plural_identifier.clone() } fn parameter_type(&self) -> Type { @@ -96,11 +96,11 @@ impl<'a> OperationField<'a> { Ok(Self { name, plural_identifier: match kind { - FieldKind::Element { kind, .. } => format!("{}s", kind.as_str()), - FieldKind::Successor { .. } => "successors".into(), - FieldKind::Region { .. } => "regions".into(), + FieldKind::Element { kind, .. } => format_ident!("{}s", kind.as_str()), + FieldKind::Successor { .. } => format_ident!("successors"), + FieldKind::Region { .. } => format_ident!("regions"), }, - sanitized_name: sanitize_snake_case_name(name)?, + sanitized_name: sanitize_snake_case_identifier(name)?, kind, }) } diff --git a/macro/src/dialect/utility.rs b/macro/src/dialect/utility.rs index 29790c0745..90b45fa558 100644 --- a/macro/src/dialect/utility.rs +++ b/macro/src/dialect/utility.rs @@ -15,7 +15,7 @@ pub fn generate_iterator_type(r#type: Type) -> Type { parse_quote!(impl Iterator) } -pub fn sanitize_snake_case_name(name: &str) -> Result { +pub fn sanitize_snake_case_identifier(name: &str) -> Result { sanitize_name(&name.to_case(Case::Snake)) } @@ -72,20 +72,26 @@ mod tests { #[test] fn sanitize_name_with_dot() { - assert_eq!(sanitize_snake_case_name("foo.bar").unwrap(), "foo_bar"); + assert_eq!( + sanitize_snake_case_identifier("foo.bar").unwrap(), + "foo_bar" + ); } #[test] fn sanitize_name_with_dot_and_underscore() { assert_eq!( - sanitize_snake_case_name("foo.bar_baz").unwrap(), + sanitize_snake_case_identifier("foo.bar_baz").unwrap(), "foo_bar_baz" ); } #[test] fn sanitize_reserved_name() { - assert_eq!(sanitize_snake_case_name("builder").unwrap(), "_builder"); + assert_eq!( + sanitize_snake_case_identifier("builder").unwrap(), + "_builder" + ); } #[test] From affed40f32a03f589507b70a234d865da773da0e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Feb 2024 16:13:29 +0000 Subject: [PATCH 056/108] build(deps): Bump syn from 2.0.48 to 2.0.49 (#423) Bumps [syn](https://github.com/dtolnay/syn) from 2.0.48 to 2.0.49.
Release notes

Sourced from syn's releases.

2.0.49

  • Improve error location when parsing from an empty string literal using LitStr::parse (#1590)
Commits
  • e64c063 Release 2.0.49
  • 981359c Merge pull request #1590 from dtolnay/streof
  • 51298d4 Improve error location at eof in LitStr::parse
  • 270c633 Update test suite to nightly-2024-02-13
  • dc9cf16 Remove FilterAttrs trait when unused
  • 7dcfac7 Ignore dead_code warning in test
  • 9831844 Update signature of Emitter::emit_diagnostic in nightly-2024-02-07
  • 9e8033f Update test suite to nightly-2024-02-07
  • cb3348c Update test suite to nightly-2024-01-23
  • 15b9dbc Update test suite to nightly-2024-01-19
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=syn&package-manager=cargo&previous-version=2.0.48&new-version=2.0.49)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ae26964a94..bac1297ebf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,7 +105,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.48", + "syn 2.0.49", "which", ] @@ -128,7 +128,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.48", + "syn 2.0.49", "which", ] @@ -226,7 +226,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.49", ] [[package]] @@ -619,7 +619,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.48", + "syn 2.0.49", "tblgen", "unindent", ] @@ -760,7 +760,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn 2.0.48", + "syn 2.0.49", ] [[package]] @@ -897,7 +897,7 @@ checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.49", ] [[package]] @@ -963,9 +963,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "915aea9e586f80826ee59f8453c1101f9d1c4b3964cd2460185ee8e299ada496" dependencies = [ "proc-macro2", "quote", @@ -1033,7 +1033,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.49", ] [[package]] From aa8b9f7c9d6c53085e681f4113f753a9e06579cc Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sat, 17 Feb 2024 02:14:50 +0900 Subject: [PATCH 057/108] Refactor operation regions (#422) --- macro/src/dialect/generation.rs | 10 ++- .../src/dialect/generation/field_accessor.rs | 15 ---- .../dialect/generation/operation_builder.rs | 4 +- .../src/dialect/generation/region_accessor.rs | 27 +++++++ macro/src/dialect/operation.rs | 45 ++++++----- macro/src/dialect/operation/attribute.rs | 3 +- macro/src/dialect/operation/builder.rs | 10 +-- macro/src/dialect/operation/field_kind.rs | 24 +----- .../src/dialect/operation/operation_field.rs | 24 +----- macro/src/dialect/operation/region.rs | 80 +++++++++++++++++++ tools/setup.sh | 4 - 11 files changed, 150 insertions(+), 96 deletions(-) create mode 100644 macro/src/dialect/generation/region_accessor.rs create mode 100644 macro/src/dialect/operation/region.rs diff --git a/macro/src/dialect/generation.rs b/macro/src/dialect/generation.rs index e0bf846e9b..9da2aafe2c 100644 --- a/macro/src/dialect/generation.rs +++ b/macro/src/dialect/generation.rs @@ -1,6 +1,7 @@ mod attribute_accessor; mod field_accessor; mod operation_builder; +mod region_accessor; use self::{ attribute_accessor::generate_attribute_accessors, @@ -8,6 +9,7 @@ use self::{ operation_builder::{ generate_default_constructor, generate_operation_builder, generate_operation_builder_fn, }, + region_accessor::generate_region_accessor, }; use super::operation::{Operation, OperationBuilder}; use crate::dialect::error::Error; @@ -21,9 +23,14 @@ pub fn generate_operation(operation: &Operation) -> Result { let name = &operation.full_name()?; let field_accessors = operation - .operation_fields() + .general_fields() .map(generate_accessor) .collect::, _>>()?; + let region_accessors = operation + .regions() + .enumerate() + .map(|(index, region)| generate_region_accessor(index, region)) + .collect::, _>>()?; let attribute_accessors = operation .attributes() .map(generate_attribute_accessors) @@ -54,6 +61,7 @@ pub fn generate_operation(operation: &Operation) -> Result { #builder_fn #(#field_accessors)* + #(#region_accessors)* #(#attribute_accessors)* } diff --git a/macro/src/dialect/generation/field_accessor.rs b/macro/src/dialect/generation/field_accessor.rs index 46842bba8d..0b6f7f9f94 100644 --- a/macro/src/dialect/generation/field_accessor.rs +++ b/macro/src/dialect/generation/field_accessor.rs @@ -144,20 +144,5 @@ fn generate_getter(field: &OperationField) -> TokenStream { } } } - FieldKind::Region { - constraint, - sequence_info: SequenceInfo { index, .. }, - } => { - if constraint.is_variadic() { - // Only the last region can be variadic - quote! { - self.operation.regions().skip(#index) - } - } else { - quote! { - self.operation.region(#index) - } - } - } } } diff --git a/macro/src/dialect/generation/operation_builder.rs b/macro/src/dialect/generation/operation_builder.rs index 299af0464f..617d542b67 100644 --- a/macro/src/dialect/generation/operation_builder.rs +++ b/macro/src/dialect/generation/operation_builder.rs @@ -28,7 +28,7 @@ pub fn generate_operation_builder(builder: &OperationBuilder) -> Result>(); - let builder_fns = generate_builder_fns(builder, &field_names, phantom_arguments.as_slice())?; + let builder_fns = generate_field_fns(builder, &field_names, phantom_arguments.as_slice())?; let new_fn = generate_new_fn(builder, phantom_arguments.as_slice())?; let build_fn = generate_build_fn(builder)?; @@ -53,7 +53,7 @@ pub fn generate_operation_builder(builder: &OperationBuilder) -> Result Result { + let identifier = ®ion.singular_identifier(); + let return_type = ®ion.return_type(); + let body = if region.is_variadic() { + // Only the last region can be variadic. + quote! { + self.operation.regions().skip(#index) + } + } else { + quote! { + self.operation.region(#index) + } + }; + + Ok(quote! { + pub fn #identifier(&self, context: &'c ::melior::Context) -> #return_type { + #body + } + }) +} diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 63383c5203..0ef490e527 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -3,13 +3,14 @@ mod builder; mod element_kind; mod field_kind; mod operation_field; +mod region; mod sequence_info; mod variadic_kind; pub use self::{ attribute::Attribute, builder::OperationBuilder, element_kind::ElementKind, - field_kind::FieldKind, operation_field::OperationField, sequence_info::SequenceInfo, - variadic_kind::VariadicKind, + field_kind::FieldKind, operation_field::OperationField, region::Region, + sequence_info::SequenceInfo, variadic_kind::VariadicKind, }; use super::utility::sanitize_documentation; use crate::dialect::{ @@ -24,7 +25,7 @@ use tblgen::{error::WithLocation, record::Record, TypedInit}; pub struct Operation<'a> { definition: Record<'a>, can_infer_type: bool, - regions: Vec>, + regions: Vec>, successors: Vec>, results: Vec>, operands: Vec>, @@ -127,27 +128,31 @@ impl<'a> Operation<'a> { sanitize_documentation(self.definition.str_value("description")?) } - pub fn fields(&self) -> impl Iterator + Clone { + pub fn fields(&self) -> impl Iterator { + fn convert(field: &impl OperationFieldLike) -> &dyn OperationFieldLike { + field + } + self.results .iter() .chain(&self.operands) - .chain(&self.regions) - .chain(&self.successors) - .map(|field| -> &dyn OperationFieldLike { field }) - .chain( - self.attributes() - .map(|field| -> &dyn OperationFieldLike { field }), - ) + .map(convert) + .chain(self.regions.iter().map(convert)) + .chain(self.successors.iter().map(convert)) + .chain(self.attributes().map(convert)) } - pub fn operation_fields(&self) -> impl Iterator> + Clone { + pub fn general_fields(&self) -> impl Iterator> + Clone { self.results .iter() .chain(&self.operands) - .chain(&self.regions) .chain(&self.successors) } + pub fn regions(&self) -> impl Iterator> + Clone { + self.regions.iter() + } + pub fn attributes(&self) -> impl Iterator> + Clone { self.attributes.iter().chain(&self.derived_attributes) } @@ -178,22 +183,18 @@ impl<'a> Operation<'a> { .collect() } - fn collect_regions(definition: Record<'a>) -> Result, Error> { - let regions_dag = definition.dag_value("regions")?; - let len = regions_dag.num_args(); - - regions_dag + fn collect_regions(definition: Record<'a>) -> Result, Error> { + definition + .dag_value("regions")? .args() - .enumerate() - .map(|(index, (name, value))| { - OperationField::new_region( + .map(|(name, value)| { + Region::new( name, RegionConstraint::new( value .try_into() .map_err(|error: tblgen::Error| error.set_location(definition))?, ), - SequenceInfo { index, len }, ) }) .collect() diff --git a/macro/src/dialect/operation/attribute.rs b/macro/src/dialect/operation/attribute.rs index 8d520ce074..f50dd13ef2 100644 --- a/macro/src/dialect/operation/attribute.rs +++ b/macro/src/dialect/operation/attribute.rs @@ -7,8 +7,7 @@ use once_cell::sync::Lazy; use proc_macro2::{Span, TokenStream}; use quote::quote; use std::collections::HashMap; -use syn::Ident; -use syn::{parse_quote, Type}; +use syn::{parse_quote, Ident, Type}; use tblgen::{error::TableGenError, Record}; macro_rules! prefixed_string { diff --git a/macro/src/dialect/operation/builder.rs b/macro/src/dialect/operation/builder.rs index 22e7784aa1..5049fb8c7f 100644 --- a/macro/src/dialect/operation/builder.rs +++ b/macro/src/dialect/operation/builder.rs @@ -6,14 +6,14 @@ use super::{super::error::Error, Operation}; use quote::format_ident; use syn::Ident; -pub struct OperationBuilder<'o> { - operation: &'o Operation<'o>, +pub struct OperationBuilder<'a> { + operation: &'a Operation<'a>, identifier: Ident, type_state: TypeStateList, } -impl<'o> OperationBuilder<'o> { - pub fn new(operation: &'o Operation<'o>) -> Result { +impl<'a> OperationBuilder<'a> { + pub fn new(operation: &'a Operation<'a>) -> Result { Ok(Self { operation, identifier: format_ident!("{}Builder", operation.class_name()?), @@ -33,7 +33,7 @@ impl<'o> OperationBuilder<'o> { &self.type_state } - fn create_type_state(operation: &'o Operation<'o>) -> TypeStateList { + fn create_type_state(operation: &Operation) -> TypeStateList { TypeStateList::new( operation .required_fields() diff --git a/macro/src/dialect/operation/field_kind.rs b/macro/src/dialect/operation/field_kind.rs index 9611b2ce56..0a95a8e0be 100644 --- a/macro/src/dialect/operation/field_kind.rs +++ b/macro/src/dialect/operation/field_kind.rs @@ -1,6 +1,6 @@ use super::{element_kind::ElementKind, SequenceInfo, VariadicKind}; use crate::dialect::{ - types::{RegionConstraint, SuccessorConstraint, TypeConstraint}, + types::{SuccessorConstraint, TypeConstraint}, utility::{generate_iterator_type, generate_result_type}, }; use syn::{parse_quote, Type}; @@ -17,17 +17,13 @@ pub enum FieldKind<'a> { constraint: SuccessorConstraint<'a>, sequence_info: SequenceInfo, }, - Region { - constraint: RegionConstraint<'a>, - sequence_info: SequenceInfo, - }, } impl<'a> FieldKind<'a> { pub fn is_optional(&self) -> bool { match self { Self::Element { constraint, .. } => constraint.is_optional(), - Self::Successor { .. } | Self::Region { .. } => false, + Self::Successor { .. } => false, } } @@ -58,14 +54,6 @@ impl<'a> FieldKind<'a> { 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 - } - } } } @@ -102,14 +90,6 @@ impl<'a> FieldKind<'a> { generate_result_type(r#type) } } - Self::Region { constraint, .. } => { - let r#type: Type = parse_quote!(::melior::ir::RegionRef<'c, '_>); - if constraint.is_variadic() { - generate_iterator_type(r#type) - } else { - generate_result_type(r#type) - } - } } } } diff --git a/macro/src/dialect/operation/operation_field.rs b/macro/src/dialect/operation/operation_field.rs index 7dd8d845b5..e4736711f1 100644 --- a/macro/src/dialect/operation/operation_field.rs +++ b/macro/src/dialect/operation/operation_field.rs @@ -1,7 +1,7 @@ use super::{element_kind::ElementKind, field_kind::FieldKind, SequenceInfo, VariadicKind}; use crate::dialect::{ error::Error, - types::{RegionConstraint, SuccessorConstraint, TypeConstraint}, + types::{SuccessorConstraint, TypeConstraint}, utility::sanitize_snake_case_identifier, }; use proc_macro2::{Ident, TokenStream}; @@ -80,13 +80,6 @@ impl OperationFieldLike for OperationField<'_> { quote! { &[#name] } } } - FieldKind::Region { constraint, .. } => { - if constraint.is_variadic() { - quote! { #name } - } else { - quote! { vec![#name] } - } - } } } } @@ -98,27 +91,12 @@ impl<'a> OperationField<'a> { plural_identifier: match kind { FieldKind::Element { kind, .. } => format_ident!("{}s", kind.as_str()), FieldKind::Successor { .. } => format_ident!("successors"), - FieldKind::Region { .. } => format_ident!("regions"), }, sanitized_name: sanitize_snake_case_identifier(name)?, kind, }) } - 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>, diff --git a/macro/src/dialect/operation/region.rs b/macro/src/dialect/operation/region.rs new file mode 100644 index 0000000000..5ece300ac2 --- /dev/null +++ b/macro/src/dialect/operation/region.rs @@ -0,0 +1,80 @@ +use super::OperationFieldLike; +use crate::dialect::{ + error::Error, + types::RegionConstraint, + utility::{generate_iterator_type, generate_result_type, sanitize_snake_case_identifier}, +}; +use proc_macro2::{Span, TokenStream}; +use quote::quote; +use syn::{parse_quote, Ident, Type}; + +#[derive(Debug)] +pub struct Region<'a> { + name: &'a str, + singular_identifier: Ident, + constraint: RegionConstraint<'a>, +} + +impl<'a> Region<'a> { + pub fn new(name: &'a str, constraint: RegionConstraint<'a>) -> Result { + Ok(Self { + name, + singular_identifier: sanitize_snake_case_identifier(name)?, + constraint, + }) + } + + pub fn is_variadic(&self) -> bool { + self.constraint.is_variadic() + } +} + +impl OperationFieldLike for Region<'_> { + fn name(&self) -> &str { + self.name + } + + fn singular_identifier(&self) -> &Ident { + &self.singular_identifier + } + + fn plural_kind_identifier(&self) -> Ident { + Ident::new("regions", Span::call_site()) + } + + fn parameter_type(&self) -> Type { + let r#type: Type = parse_quote!(::melior::ir::Region<'c>); + + if self.is_variadic() { + parse_quote!(Vec<#r#type>) + } else { + r#type + } + } + + fn return_type(&self) -> Type { + let r#type: Type = parse_quote!(::melior::ir::RegionRef<'c, '_>); + + if self.is_variadic() { + generate_iterator_type(r#type) + } else { + generate_result_type(r#type) + } + } + + fn is_optional(&self) -> bool { + false + } + + fn is_result(&self) -> bool { + false + } + + fn add_arguments(&self, name: &Ident) -> TokenStream { + if self.is_variadic() { + quote! { #name } + } else { + quote! { vec![#name] } + } + } +} diff --git a/tools/setup.sh b/tools/setup.sh index 11aff0049f..107a5a5175 100755 --- a/tools/setup.sh +++ b/tools/setup.sh @@ -4,10 +4,6 @@ set -e llvm_version=17 -if [ -n "$CI" ]; then - brew install --overwrite python@3.11 -fi - brew install llvm@$llvm_version echo PATH=$(brew --prefix)/opt/llvm@$llvm_version/bin:$PATH >>$GITHUB_ENV From 4bf4cc1384727b417ec25f50b1391de1bfc80c69 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sat, 17 Feb 2024 15:40:30 +0900 Subject: [PATCH 058/108] Refactor operation successor macros (#425) --- macro/src/dialect/generation.rs | 12 ++- .../src/dialect/generation/field_accessor.rs | 15 ---- .../dialect/generation/operation_builder.rs | 20 ++--- .../src/dialect/generation/region_accessor.rs | 11 +-- .../dialect/generation/successor_accessor.rs | 25 ++++++ macro/src/dialect/operation.rs | 36 ++++----- macro/src/dialect/operation/field_kind.rs | 23 +----- .../src/dialect/operation/operation_field.rs | 27 +------ macro/src/dialect/operation/successor.rs | 80 +++++++++++++++++++ 9 files changed, 148 insertions(+), 101 deletions(-) create mode 100644 macro/src/dialect/generation/successor_accessor.rs create mode 100644 macro/src/dialect/operation/successor.rs diff --git a/macro/src/dialect/generation.rs b/macro/src/dialect/generation.rs index 9da2aafe2c..81c22ee9a9 100644 --- a/macro/src/dialect/generation.rs +++ b/macro/src/dialect/generation.rs @@ -2,6 +2,7 @@ mod attribute_accessor; mod field_accessor; mod operation_builder; mod region_accessor; +mod successor_accessor; use self::{ attribute_accessor::generate_attribute_accessors, @@ -10,6 +11,7 @@ use self::{ generate_default_constructor, generate_operation_builder, generate_operation_builder_fn, }, region_accessor::generate_region_accessor, + successor_accessor::generate_successor_accessor, }; use super::operation::{Operation, OperationBuilder}; use crate::dialect::error::Error; @@ -26,11 +28,16 @@ pub fn generate_operation(operation: &Operation) -> Result { .general_fields() .map(generate_accessor) .collect::, _>>()?; + let successor_accessors = operation + .successors() + .enumerate() + .map(|(index, region)| generate_successor_accessor(index, region)) + .collect::>(); let region_accessors = operation .regions() .enumerate() .map(|(index, region)| generate_region_accessor(index, region)) - .collect::, _>>()?; + .collect::>(); let attribute_accessors = operation .attributes() .map(generate_attribute_accessors) @@ -38,7 +45,7 @@ pub fn generate_operation(operation: &Operation) -> Result { let builder = OperationBuilder::new(operation)?; let builder_tokens = generate_operation_builder(&builder)?; - let builder_fn = generate_operation_builder_fn(&builder)?; + let builder_fn = generate_operation_builder_fn(&builder); let default_constructor = generate_default_constructor(&builder)?; Ok(quote! { @@ -61,6 +68,7 @@ pub fn generate_operation(operation: &Operation) -> Result { #builder_fn #(#field_accessors)* + #(#successor_accessors)* #(#region_accessors)* #(#attribute_accessors)* } diff --git a/macro/src/dialect/generation/field_accessor.rs b/macro/src/dialect/generation/field_accessor.rs index 0b6f7f9f94..26b972d5c2 100644 --- a/macro/src/dialect/generation/field_accessor.rs +++ b/macro/src/dialect/generation/field_accessor.rs @@ -129,20 +129,5 @@ fn generate_getter(field: &OperationField) -> TokenStream { } } } - FieldKind::Successor { - constraint, - sequence_info: SequenceInfo { index, .. }, - } => { - if constraint.is_variadic() { - // Only the last successor can be variadic - quote! { - self.operation.successors().skip(#index) - } - } else { - quote! { - self.operation.successor(#index) - } - } - } } } diff --git a/macro/src/dialect/generation/operation_builder.rs b/macro/src/dialect/generation/operation_builder.rs index 617d542b67..37eca0aa87 100644 --- a/macro/src/dialect/generation/operation_builder.rs +++ b/macro/src/dialect/generation/operation_builder.rs @@ -28,7 +28,7 @@ pub fn generate_operation_builder(builder: &OperationBuilder) -> Result>(); - let builder_fns = generate_field_fns(builder, &field_names, phantom_arguments.as_slice())?; + let builder_fns = generate_field_fns(builder, &field_names, phantom_arguments.as_slice()); let new_fn = generate_new_fn(builder, phantom_arguments.as_slice())?; let build_fn = generate_build_fn(builder)?; @@ -57,10 +57,10 @@ fn generate_field_fns( builder: &OperationBuilder, field_names: &[Ident], phantoms: &[TokenStream], -) -> Result, Error> { +) -> Vec { builder.operation().fields().map(move |field| { let builder_identifier = builder.identifier(); - let identifier = sanitize_snake_case_identifier(field.name())?; + let identifier = field.singular_identifier(); let parameter_type = field.parameter_type(); let argument = quote! { #identifier: #parameter_type }; let add = format_ident!("add_{}", field.plural_kind_identifier()); @@ -68,9 +68,9 @@ fn generate_field_fns( // Argument types can be singular and variadic. But `add` functions in Melior // are always variadic, so we need to create a slice or `Vec` for singular // arguments. - let add_arguments = field.add_arguments(&identifier); + let add_arguments = field.add_arguments(identifier); - Ok(if field.is_optional() { + if field.is_optional() { let parameters = builder.type_state().parameters().collect::>(); quote! { @@ -101,7 +101,7 @@ fn generate_field_fns( } } } - }) + } }).collect() } @@ -145,18 +145,18 @@ fn generate_new_fn( }) } -pub fn generate_operation_builder_fn(builder: &OperationBuilder) -> Result { +pub fn generate_operation_builder_fn(builder: &OperationBuilder) -> TokenStream { let builder_ident = builder.identifier(); let arguments = builder.type_state().arguments_all_set(false); - Ok(quote! { + quote! { pub fn builder( context: &'c ::melior::Context, location: ::melior::ir::Location<'c> - ) -> #builder_ident<'c, #(#arguments),*> { + ) -> #builder_ident<'c, #(#arguments),*> { #builder_ident::new(context, location) } - }) + } } pub fn generate_default_constructor(builder: &OperationBuilder) -> Result { diff --git a/macro/src/dialect/generation/region_accessor.rs b/macro/src/dialect/generation/region_accessor.rs index fcc5cb5f44..35b418ae69 100644 --- a/macro/src/dialect/generation/region_accessor.rs +++ b/macro/src/dialect/generation/region_accessor.rs @@ -1,11 +1,8 @@ -use crate::dialect::{ - error::Error, - operation::{OperationFieldLike, Region}, -}; +use crate::dialect::operation::{OperationFieldLike, Region}; use proc_macro2::TokenStream; use quote::quote; -pub fn generate_region_accessor(index: usize, region: &Region) -> Result { +pub fn generate_region_accessor(index: usize, region: &Region) -> TokenStream { let identifier = ®ion.singular_identifier(); let return_type = ®ion.return_type(); let body = if region.is_variadic() { @@ -19,9 +16,9 @@ pub fn generate_region_accessor(index: usize, region: &Region) -> Result #return_type { #body } - }) + } } diff --git a/macro/src/dialect/generation/successor_accessor.rs b/macro/src/dialect/generation/successor_accessor.rs new file mode 100644 index 0000000000..e48ca393a2 --- /dev/null +++ b/macro/src/dialect/generation/successor_accessor.rs @@ -0,0 +1,25 @@ +use crate::dialect::operation::{OperationFieldLike, Successor}; +use proc_macro2::TokenStream; +use quote::quote; + +pub fn generate_successor_accessor(index: usize, successor: &Successor) -> TokenStream { + let identifier = successor.singular_identifier(); + let return_type = successor.return_type(); + let body = if successor.is_variadic() { + // Only the last successor can be variadic. + quote! { + self.operation.successors().skip(#index) + } + } else { + quote! { + self.operation.successor(#index) + } + }; + + quote! { + #[allow(clippy::needless_question_mark)] + pub fn #identifier(&self, context: &'c ::melior::Context) -> #return_type { + #body + } + } +} diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 0ef490e527..6fbcfe2c90 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -5,12 +5,13 @@ mod field_kind; mod operation_field; mod region; mod sequence_info; +mod successor; mod variadic_kind; pub use self::{ attribute::Attribute, builder::OperationBuilder, element_kind::ElementKind, field_kind::FieldKind, operation_field::OperationField, region::Region, - sequence_info::SequenceInfo, variadic_kind::VariadicKind, + sequence_info::SequenceInfo, successor::Successor, variadic_kind::VariadicKind, }; use super::utility::sanitize_documentation; use crate::dialect::{ @@ -26,7 +27,7 @@ pub struct Operation<'a> { definition: Record<'a>, can_infer_type: bool, regions: Vec>, - successors: Vec>, + successors: Vec>, results: Vec>, operands: Vec>, attributes: Vec>, @@ -143,17 +144,18 @@ impl<'a> Operation<'a> { } pub fn general_fields(&self) -> impl Iterator> + Clone { - self.results - .iter() - .chain(&self.operands) - .chain(&self.successors) + self.results.iter().chain(&self.operands) } - pub fn regions(&self) -> impl Iterator> + Clone { + pub fn successors(&self) -> impl Iterator> { + self.successors.iter() + } + + pub fn regions(&self) -> impl Iterator> { self.regions.iter() } - pub fn attributes(&self) -> impl Iterator> + Clone { + pub fn attributes(&self) -> impl Iterator> { self.attributes.iter().chain(&self.derived_attributes) } @@ -162,22 +164,16 @@ impl<'a> Operation<'a> { .filter(|field| (!field.is_result() || !self.can_infer_type) && !field.is_optional()) } - fn collect_successors(definition: Record<'a>) -> Result, Error> { - let successors_dag = definition.dag_value("successors")?; - let len = successors_dag.num_args(); - - successors_dag + fn collect_successors(definition: Record<'a>) -> Result, Error> { + definition + .dag_value("successors")? .args() - .enumerate() - .map(|(index, (name, value))| { - OperationField::new_successor( + .map(|(name, value)| { + Successor::new( name, SuccessorConstraint::new( - value - .try_into() - .map_err(|error: tblgen::Error| error.set_location(definition))?, + Record::try_from(value).map_err(|error| error.set_location(definition))?, ), - SequenceInfo { index, len }, ) }) .collect() diff --git a/macro/src/dialect/operation/field_kind.rs b/macro/src/dialect/operation/field_kind.rs index 0a95a8e0be..af4908063d 100644 --- a/macro/src/dialect/operation/field_kind.rs +++ b/macro/src/dialect/operation/field_kind.rs @@ -1,6 +1,6 @@ use super::{element_kind::ElementKind, SequenceInfo, VariadicKind}; use crate::dialect::{ - types::{SuccessorConstraint, TypeConstraint}, + types::TypeConstraint, utility::{generate_iterator_type, generate_result_type}, }; use syn::{parse_quote, Type}; @@ -13,17 +13,12 @@ pub enum FieldKind<'a> { sequence_info: SequenceInfo, variadic_kind: VariadicKind, }, - Successor { - constraint: SuccessorConstraint<'a>, - sequence_info: SequenceInfo, - }, } impl<'a> FieldKind<'a> { pub fn is_optional(&self) -> bool { match self { Self::Element { constraint, .. } => constraint.is_optional(), - Self::Successor { .. } => false, } } @@ -46,14 +41,6 @@ impl<'a> FieldKind<'a> { base_type } } - Self::Successor { constraint, .. } => { - let r#type: Type = parse_quote!(&::melior::ir::Block<'c>); - if constraint.is_variadic() { - parse_quote!(&[#r#type]) - } else { - r#type - } - } } } @@ -82,14 +69,6 @@ impl<'a> FieldKind<'a> { generate_iterator_type(base_type) } } - Self::Successor { constraint, .. } => { - let r#type: Type = parse_quote!(::melior::ir::BlockRef<'c, '_>); - if constraint.is_variadic() { - generate_iterator_type(r#type) - } else { - generate_result_type(r#type) - } - } } } } diff --git a/macro/src/dialect/operation/operation_field.rs b/macro/src/dialect/operation/operation_field.rs index e4736711f1..913dde3ea0 100644 --- a/macro/src/dialect/operation/operation_field.rs +++ b/macro/src/dialect/operation/operation_field.rs @@ -1,8 +1,6 @@ use super::{element_kind::ElementKind, field_kind::FieldKind, SequenceInfo, VariadicKind}; use crate::dialect::{ - error::Error, - types::{SuccessorConstraint, TypeConstraint}, - utility::sanitize_snake_case_identifier, + error::Error, types::TypeConstraint, utility::sanitize_snake_case_identifier, }; use proc_macro2::{Ident, TokenStream}; use quote::{format_ident, quote}; @@ -10,6 +8,7 @@ use syn::Type; // TODO Rename this `OperationField`. pub trait OperationFieldLike { + // TODO Remove this. fn name(&self) -> &str; fn singular_identifier(&self) -> &Ident; fn plural_kind_identifier(&self) -> Ident; @@ -73,13 +72,6 @@ impl OperationFieldLike for OperationField<'_> { quote! { &[#name] } } } - FieldKind::Successor { constraint, .. } => { - if constraint.is_variadic() { - quote! { #name } - } else { - quote! { &[#name] } - } - } } } } @@ -90,27 +82,12 @@ impl<'a> OperationField<'a> { name, plural_identifier: match kind { FieldKind::Element { kind, .. } => format_ident!("{}s", kind.as_str()), - FieldKind::Successor { .. } => format_ident!("successors"), }, sanitized_name: sanitize_snake_case_identifier(name)?, kind, }) } - 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>, diff --git a/macro/src/dialect/operation/successor.rs b/macro/src/dialect/operation/successor.rs new file mode 100644 index 0000000000..0d8f9721a8 --- /dev/null +++ b/macro/src/dialect/operation/successor.rs @@ -0,0 +1,80 @@ +use super::OperationFieldLike; +use crate::dialect::{ + error::Error, + types::SuccessorConstraint, + utility::{generate_iterator_type, generate_result_type, sanitize_snake_case_identifier}, +}; +use proc_macro2::{Span, TokenStream}; +use quote::quote; +use syn::{parse_quote, Ident, Type}; + +#[derive(Debug)] +pub struct Successor<'a> { + name: &'a str, + singular_identifier: Ident, + constraint: SuccessorConstraint<'a>, +} + +impl<'a> Successor<'a> { + pub fn new(name: &'a str, constraint: SuccessorConstraint<'a>) -> Result { + Ok(Self { + name, + singular_identifier: sanitize_snake_case_identifier(name)?, + constraint, + }) + } + + pub fn is_variadic(&self) -> bool { + self.constraint.is_variadic() + } +} + +impl OperationFieldLike for Successor<'_> { + fn name(&self) -> &str { + self.name + } + + fn singular_identifier(&self) -> &Ident { + &self.singular_identifier + } + + fn plural_kind_identifier(&self) -> Ident { + Ident::new("successors", Span::call_site()) + } + + fn parameter_type(&self) -> Type { + let r#type: Type = parse_quote!(&::melior::ir::Block<'c>); + + if self.is_variadic() { + parse_quote!(&[#r#type]) + } else { + r#type + } + } + + fn return_type(&self) -> Type { + let r#type: Type = parse_quote!(::melior::ir::BlockRef<'c, '_>); + + if self.is_variadic() { + generate_iterator_type(r#type) + } else { + generate_result_type(r#type) + } + } + + fn is_optional(&self) -> bool { + false + } + + fn is_result(&self) -> bool { + false + } + + fn add_arguments(&self, name: &Ident) -> TokenStream { + if self.is_variadic() { + quote! { #name } + } else { + quote! { &[#name] } + } + } +} From 98e0a9bb91ab3a76f3216b1fd45e39daa714b620 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sat, 17 Feb 2024 18:57:09 +0900 Subject: [PATCH 059/108] Refactor operation result macros (#426) --- macro/src/dialect/generation.rs | 22 ++- .../dialect/generation/element_accessor.rs | 113 +++++++++++++++ .../src/dialect/generation/field_accessor.rs | 133 ------------------ .../dialect/generation/operand_accessor.rs | 28 ++++ .../src/dialect/generation/result_accessor.rs | 31 ++++ macro/src/dialect/operation.rs | 47 ++++--- macro/src/dialect/operation/element_kind.rs | 14 -- macro/src/dialect/operation/field_kind.rs | 39 ++--- .../dialect/operation/operation_element.rs | 10 ++ .../src/dialect/operation/operation_field.rs | 70 +++++---- .../src/dialect/operation/operation_result.rs | 96 +++++++++++++ 11 files changed, 369 insertions(+), 234 deletions(-) create mode 100644 macro/src/dialect/generation/element_accessor.rs delete mode 100644 macro/src/dialect/generation/field_accessor.rs create mode 100644 macro/src/dialect/generation/operand_accessor.rs create mode 100644 macro/src/dialect/generation/result_accessor.rs delete mode 100644 macro/src/dialect/operation/element_kind.rs create mode 100644 macro/src/dialect/operation/operation_element.rs create mode 100644 macro/src/dialect/operation/operation_result.rs diff --git a/macro/src/dialect/generation.rs b/macro/src/dialect/generation.rs index 81c22ee9a9..4da87f5223 100644 --- a/macro/src/dialect/generation.rs +++ b/macro/src/dialect/generation.rs @@ -1,16 +1,19 @@ mod attribute_accessor; -mod field_accessor; +mod element_accessor; +mod operand_accessor; mod operation_builder; mod region_accessor; +mod result_accessor; mod successor_accessor; use self::{ attribute_accessor::generate_attribute_accessors, - field_accessor::generate_accessor, + operand_accessor::generate_operand_accessor, operation_builder::{ generate_default_constructor, generate_operation_builder, generate_operation_builder_fn, }, region_accessor::generate_region_accessor, + result_accessor::generate_result_accessor, successor_accessor::generate_successor_accessor, }; use super::operation::{Operation, OperationBuilder}; @@ -24,9 +27,15 @@ pub fn generate_operation(operation: &Operation) -> Result { let class_name = format_ident!("{}", operation.class_name()?); let name = &operation.full_name()?; - let field_accessors = operation - .general_fields() - .map(generate_accessor) + let result_accessors = operation + .results() + .enumerate() + .map(|(index, result)| generate_result_accessor(result, index, operation.result_len())) + .collect::, _>>()?; + let operand_accessors = operation + .operands() + .enumerate() + .map(|(index, operand)| generate_operand_accessor(operand, index, operation.operand_len())) .collect::, _>>()?; let successor_accessors = operation .successors() @@ -67,7 +76,8 @@ pub fn generate_operation(operation: &Operation) -> Result { #builder_fn - #(#field_accessors)* + #(#result_accessors)* + #(#operand_accessors)* #(#successor_accessors)* #(#region_accessors)* #(#attribute_accessors)* diff --git a/macro/src/dialect/generation/element_accessor.rs b/macro/src/dialect/generation/element_accessor.rs new file mode 100644 index 0000000000..05be6f2622 --- /dev/null +++ b/macro/src/dialect/generation/element_accessor.rs @@ -0,0 +1,113 @@ +use crate::dialect::operation::{OperationElement, OperationFieldLike, VariadicKind}; +use proc_macro2::{Span, TokenStream}; +use quote::quote; +use syn::Ident; + +pub fn generate_element_getter( + field: &(impl OperationFieldLike + OperationElement), + singular_kind: &str, + plural_kind: &str, + error_variant: &Ident, + index: usize, + length: usize, +) -> TokenStream { + let kind_singular_identifier = Ident::new(singular_kind, Span::call_site()); + let kind_plural_identifier = Ident::new(plural_kind, Span::call_site()); + let count = Ident::new(&format!("{singular_kind}_count"), Span::call_site()); + let name = field.name(); + + match field.variadic_kind() { + VariadicKind::Simple { unfixed_seen } => { + if field.is_optional() { + // Optional element, and some singular elements. + // Only present if the amount of groups is at least the number of + // elements. + quote! { + if self.operation.#count() < #length { + Err(::melior::Error::#error_variant(#name)) + } else { + self.operation.#kind_singular_identifier(#index) + } + } + } else if field.is_variadic() { + // A unfixed group + // Length computed by subtracting the amount of other + // singular elements from the number of elements. + quote! { + let group_length = self.operation.#count() - #length + 1; + self.operation.#kind_plural_identifier().skip(#index).take(group_length) + } + } else if *unfixed_seen { + // Single element after unfixed group + // Compute the length of that variable group and take the next element + quote! { + let group_length = self.operation.#count() - #length + 1; + self.operation.#kind_singular_identifier(#index + group_length - 1) + } + } else { + // All elements so far are singular + quote! { + self.operation.#kind_singular_identifier(#index) + } + } + } + VariadicKind::SameSize { + unfixed_count, + preceding_simple_count, + preceding_variadic_count, + } => { + let compute_start_length = quote! { + let total_var_len = self.operation.#count() - #unfixed_count + 1; + let group_len = total_var_len / #unfixed_count; + let start = #preceding_simple_count + #preceding_variadic_count * group_len; + }; + let get_elements = if field.is_unfixed() { + quote! { + self.operation.#kind_plural_identifier().skip(start).take(group_len) + } + } else { + quote! { + self.operation.#kind_singular_identifier(start) + } + }; + + quote! { #compute_start_length #get_elements } + } + VariadicKind::AttributeSized => { + let segment_size_attribute = format!("{singular_kind}_segment_sizes"); + let get_elements = if !field.is_unfixed() { + quote! { + self.operation.#kind_singular_identifier(start) + } + } else if field.is_optional() { + quote! { + if group_len == 0 { + Err(::melior::Error::#error_variant(#name)) + } else { + self.operation.#kind_singular_identifier(start) + } + } + } else { + quote! { + Ok(self.operation.#kind_plural_identifier().skip(start).take(group_len)) + } + }; + + quote! { + let attribute = + ::melior::ir::attribute::DenseI32ArrayAttribute::<'c>::try_from( + self.operation + .attribute(#segment_size_attribute)? + )?; + let start = (0..#index) + .map(|index| attribute.element(index)) + .collect::, _>>()? + .into_iter() + .sum::() as usize; + let group_len = attribute.element(#index)? as usize; + + #get_elements + } + } + } +} diff --git a/macro/src/dialect/generation/field_accessor.rs b/macro/src/dialect/generation/field_accessor.rs deleted file mode 100644 index 26b972d5c2..0000000000 --- a/macro/src/dialect/generation/field_accessor.rs +++ /dev/null @@ -1,133 +0,0 @@ -use crate::dialect::{ - error::Error, - operation::{ElementKind, FieldKind, OperationField, SequenceInfo, VariadicKind}, -}; -use proc_macro2::TokenStream; -use quote::{format_ident, quote}; - -pub fn generate_accessor(field: &OperationField) -> Result { - let ident = &field.sanitized_name; - let return_type = &field.kind.return_type(); - let body = generate_getter(field); - - Ok(quote! { - #[allow(clippy::needless_question_mark)] - pub fn #ident(&self, context: &'c ::melior::Context) -> #return_type { - #body - } - }) -} - -fn generate_getter(field: &OperationField) -> TokenStream { - match &field.kind { - FieldKind::Element { - kind, - constraint, - sequence_info: SequenceInfo { index, len }, - variadic_kind, - } => { - let kind_ident = format_ident!("{}", kind.as_str()); - let plural = format_ident!("{}s", kind.as_str()); - let count = format_ident!("{}_count", kind.as_str()); - let error_variant = match kind { - ElementKind::Operand => quote!(OperandNotFound), - ElementKind::Result => quote!(ResultNotFound), - }; - let name = field.name; - - match variadic_kind { - VariadicKind::Simple { unfixed_seen } => { - if constraint.is_optional() { - // Optional element, and some singular elements. - // Only present if the amount of groups is at least the number of - // elements. - quote! { - if self.operation.#count() < #len { - Err(::melior::Error::#error_variant(#name)) - } else { - self.operation.#kind_ident(#index) - } - } - } else if constraint.is_variadic() { - // A unfixed group - // Length computed by subtracting the amount of other - // singular elements from the number of elements. - quote! { - let group_length = self.operation.#count() - #len + 1; - self.operation.#plural().skip(#index).take(group_length) - } - } else if *unfixed_seen { - // Single element after unfixed group - // Compute the length of that variable group and take the next element - quote! { - let group_length = self.operation.#count() - #len + 1; - self.operation.#kind_ident(#index + group_length - 1) - } - } else { - // All elements so far are singular - quote! { - self.operation.#kind_ident(#index) - } - } - } - VariadicKind::SameSize { - unfixed_count, - preceding_simple_count, - preceding_variadic_count, - } => { - let compute_start_length = quote! { - let total_var_len = self.operation.#count() - #unfixed_count + 1; - let group_len = total_var_len / #unfixed_count; - let start = #preceding_simple_count + #preceding_variadic_count * group_len; - }; - let get_elements = if constraint.is_unfixed() { - quote! { - self.operation.#plural().skip(start).take(group_len) - } - } else { - quote! { - self.operation.#kind_ident(start) - } - }; - - quote! { #compute_start_length #get_elements } - } - VariadicKind::AttributeSized => { - let attribute_name = format!("{}_segment_sizes", kind.as_str()); - let compute_start_length = quote! { - let attribute = - ::melior::ir::attribute::DenseI32ArrayAttribute::<'c>::try_from( - self.operation - .attribute(#attribute_name)? - )?; - let start = (0..#index) - .map(|index| attribute.element(index)) - .collect::, _>>()? - .into_iter() - .sum::() as usize; - let group_len = attribute.element(#index)? as usize; - }; - let get_elements = if !constraint.is_unfixed() { - quote! { - self.operation.#kind_ident(start) - } - } else if constraint.is_optional() { - quote! { - if group_len == 0 { - Err(::melior::Error::#error_variant(#name)) - } else { - self.operation.#kind_ident(start) - } - } - } else { - quote! { - Ok(self.operation.#plural().skip(start).take(group_len)) - } - }; - - quote! { #compute_start_length #get_elements } - } - } - } - } -} diff --git a/macro/src/dialect/generation/operand_accessor.rs b/macro/src/dialect/generation/operand_accessor.rs new file mode 100644 index 0000000000..768bac3eb7 --- /dev/null +++ b/macro/src/dialect/generation/operand_accessor.rs @@ -0,0 +1,28 @@ +use super::element_accessor::generate_element_getter; +use crate::dialect::{error::Error, operation::OperationField}; +use proc_macro2::{Ident, Span, TokenStream}; +use quote::quote; + +pub fn generate_operand_accessor( + field: &OperationField, + index: usize, + length: usize, +) -> Result { + let ident = &field.sanitized_name; + let return_type = &field.kind.return_type(); + let body = generate_element_getter( + field, + "operand", + "operands", + &Ident::new("OperandNotFound", Span::call_site()), + index, + length, + ); + + Ok(quote! { + #[allow(clippy::needless_question_mark)] + pub fn #ident(&self, context: &'c ::melior::Context) -> #return_type { + #body + } + }) +} diff --git a/macro/src/dialect/generation/result_accessor.rs b/macro/src/dialect/generation/result_accessor.rs new file mode 100644 index 0000000000..30fb760839 --- /dev/null +++ b/macro/src/dialect/generation/result_accessor.rs @@ -0,0 +1,31 @@ +use super::element_accessor::generate_element_getter; +use crate::dialect::{ + error::Error, + operation::{OperationFieldLike, OperationResult}, +}; +use proc_macro2::{Ident, Span, TokenStream}; +use quote::quote; + +pub fn generate_result_accessor( + result: &OperationResult, + index: usize, + length: usize, +) -> Result { + let identifier = result.singular_identifier(); + let return_type = result.return_type(); + let body = generate_element_getter( + result, + "result", + "results", + &Ident::new("ResultNotFound", Span::call_site()), + index, + length, + ); + + Ok(quote! { + #[allow(clippy::needless_question_mark)] + pub fn #identifier(&self, context: &'c ::melior::Context) -> #return_type { + #body + } + }) +} diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 6fbcfe2c90..f5357d3a3d 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -1,16 +1,17 @@ mod attribute; mod builder; -mod element_kind; mod field_kind; +mod operation_element; mod operation_field; +mod operation_result; mod region; mod sequence_info; mod successor; mod variadic_kind; pub use self::{ - attribute::Attribute, builder::OperationBuilder, element_kind::ElementKind, - field_kind::FieldKind, operation_field::OperationField, region::Region, + attribute::Attribute, builder::OperationBuilder, operation_element::OperationElement, + operation_field::OperationField, operation_result::OperationResult, region::Region, sequence_info::SequenceInfo, successor::Successor, variadic_kind::VariadicKind, }; use super::utility::sanitize_documentation; @@ -28,7 +29,7 @@ pub struct Operation<'a> { can_infer_type: bool, regions: Vec>, successors: Vec>, - results: Vec>, + results: Vec>, operands: Vec>, attributes: Vec>, derived_attributes: Vec>, @@ -133,18 +134,29 @@ impl<'a> Operation<'a> { fn convert(field: &impl OperationFieldLike) -> &dyn OperationFieldLike { field } - self.results .iter() - .chain(&self.operands) .map(convert) + .chain(self.operands.iter().map(convert)) .chain(self.regions.iter().map(convert)) .chain(self.successors.iter().map(convert)) .chain(self.attributes().map(convert)) } - pub fn general_fields(&self) -> impl Iterator> + Clone { - self.results.iter().chain(&self.operands) + pub fn operands(&self) -> impl Iterator> + Clone { + self.operands.iter() + } + + pub fn operand_len(&self) -> usize { + self.operands.len() + } + + pub fn results(&self) -> impl Iterator> + Clone { + self.results.iter() + } + + pub fn result_len(&self) -> usize { + self.results.len() } pub fn successors(&self) -> impl Iterator> { @@ -246,13 +258,15 @@ impl<'a> Operation<'a> { definition: Record<'a>, same_size: bool, attribute_sized: bool, - ) -> Result<(Vec, usize), Error> { + ) -> Result<(Vec, usize), Error> { Self::collect_elements( &Self::dag_constraints(definition, "results")? .into_iter() .map(|(name, constraint)| (name, TypeConstraint::new(constraint))) .collect::>(), - ElementKind::Result, + |name, constraint, _sequence_info, variadic_kind| { + OperationResult::new(name, constraint, variadic_kind) + }, same_size, attribute_sized, ) @@ -269,19 +283,21 @@ impl<'a> Operation<'a> { .filter(|(_, definition)| definition.subclass_of("TypeConstraint")) .map(|(name, definition)| (*name, TypeConstraint::new(*definition))) .collect::>(), - ElementKind::Operand, + |name, constraint, sequence_info, variadic_kind| { + OperationField::new(name, constraint, sequence_info, variadic_kind) + }, same_size, attribute_sized, )? .0) } - fn collect_elements( + fn collect_elements( elements: &[(&'a str, TypeConstraint<'a>)], - element_kind: ElementKind, + create: impl Fn(&'a str, TypeConstraint<'a>, SequenceInfo, VariadicKind) -> Result, same_size: bool, attribute_sized: bool, - ) -> Result<(Vec>, usize), Error> { + ) -> Result<(Vec, usize), Error> { let unfixed_count = elements .iter() .filter(|(_, constraint)| constraint.is_unfixed()) @@ -290,10 +306,9 @@ impl<'a> Operation<'a> { let mut fields = vec![]; for (index, (name, constraint)) in elements.iter().enumerate() { - fields.push(OperationField::new_element( + fields.push(create( name, *constraint, - element_kind, SequenceInfo { index, len: elements.len(), diff --git a/macro/src/dialect/operation/element_kind.rs b/macro/src/dialect/operation/element_kind.rs deleted file mode 100644 index 6f1de942ef..0000000000 --- a/macro/src/dialect/operation/element_kind.rs +++ /dev/null @@ -1,14 +0,0 @@ -#[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 index af4908063d..0eee9f3ab9 100644 --- a/macro/src/dialect/operation/field_kind.rs +++ b/macro/src/dialect/operation/field_kind.rs @@ -1,14 +1,13 @@ -use super::{element_kind::ElementKind, SequenceInfo, VariadicKind}; +use super::{SequenceInfo, VariadicKind}; use crate::dialect::{ types::TypeConstraint, utility::{generate_iterator_type, generate_result_type}, }; use syn::{parse_quote, Type}; -#[derive(Debug, Clone)] +#[derive(Debug)] pub enum FieldKind<'a> { Element { - kind: ElementKind, constraint: TypeConstraint<'a>, sequence_info: SequenceInfo, variadic_kind: VariadicKind, @@ -24,21 +23,13 @@ impl<'a> FieldKind<'a> { pub fn parameter_type(&self) -> Type { 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>) - } - }; + Self::Element { constraint, .. } => { + let r#type: Type = parse_quote!(::melior::ir::Value<'c, '_>); + if constraint.is_variadic() { - parse_quote! { &[#base_type] } + parse_quote! { &[#r#type] } } else { - base_type + r#type } } } @@ -47,26 +38,18 @@ impl<'a> FieldKind<'a> { pub fn return_type(&self) -> Type { 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, '_>) - } - }; + let r#type: Type = parse_quote!(::melior::ir::Value<'c, '_>); if !constraint.is_variadic() { - generate_result_type(base_type) + generate_result_type(r#type) } else if variadic_kind == &VariadicKind::AttributeSized { - generate_result_type(generate_iterator_type(base_type)) + generate_result_type(generate_iterator_type(r#type)) } else { - generate_iterator_type(base_type) + generate_iterator_type(r#type) } } } diff --git a/macro/src/dialect/operation/operation_element.rs b/macro/src/dialect/operation/operation_element.rs new file mode 100644 index 0000000000..9769e4080b --- /dev/null +++ b/macro/src/dialect/operation/operation_element.rs @@ -0,0 +1,10 @@ +use super::{OperationFieldLike, VariadicKind}; + +pub trait OperationElement: OperationFieldLike { + fn is_variadic(&self) -> bool; + fn variadic_kind(&self) -> &VariadicKind; + + fn is_unfixed(&self) -> bool { + self.is_variadic() || self.is_optional() + } +} diff --git a/macro/src/dialect/operation/operation_field.rs b/macro/src/dialect/operation/operation_field.rs index 913dde3ea0..0790764e6f 100644 --- a/macro/src/dialect/operation/operation_field.rs +++ b/macro/src/dialect/operation/operation_field.rs @@ -1,4 +1,4 @@ -use super::{element_kind::ElementKind, field_kind::FieldKind, SequenceInfo, VariadicKind}; +use super::{field_kind::FieldKind, OperationElement, SequenceInfo, VariadicKind}; use crate::dialect::{ error::Error, types::TypeConstraint, utility::sanitize_snake_case_identifier, }; @@ -8,7 +8,6 @@ use syn::Type; // TODO Rename this `OperationField`. pub trait OperationFieldLike { - // TODO Remove this. fn name(&self) -> &str; fn singular_identifier(&self) -> &Ident; fn plural_kind_identifier(&self) -> Ident; @@ -20,7 +19,7 @@ pub trait OperationFieldLike { fn add_arguments(&self, name: &Ident) -> TokenStream; } -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct OperationField<'a> { pub(crate) name: &'a str, pub(crate) plural_identifier: Ident, @@ -28,6 +27,26 @@ pub struct OperationField<'a> { pub(crate) kind: FieldKind<'a>, } +impl<'a> OperationField<'a> { + pub fn new( + name: &'a str, + constraint: TypeConstraint<'a>, + sequence_info: SequenceInfo, + variadic_kind: VariadicKind, + ) -> Result { + Ok(Self { + name, + plural_identifier: format_ident!("operands"), + sanitized_name: sanitize_snake_case_identifier(name)?, + kind: FieldKind::Element { + constraint, + sequence_info, + variadic_kind, + }, + }) + } +} + impl OperationFieldLike for OperationField<'_> { fn name(&self) -> &str { self.name @@ -54,19 +73,13 @@ impl OperationFieldLike for OperationField<'_> { } fn is_result(&self) -> bool { - matches!( - self.kind, - FieldKind::Element { - kind: ElementKind::Result, - .. - } - ) + false } fn add_arguments(&self, name: &Ident) -> TokenStream { match &self.kind { FieldKind::Element { constraint, .. } => { - if constraint.is_unfixed() && !constraint.is_optional() { + if constraint.is_variadic() { quote! { #name } } else { quote! { &[#name] } @@ -76,33 +89,16 @@ impl OperationFieldLike for OperationField<'_> { } } -impl<'a> OperationField<'a> { - fn new(name: &'a str, kind: FieldKind<'a>) -> Result { - Ok(Self { - name, - plural_identifier: match kind { - FieldKind::Element { kind, .. } => format_ident!("{}s", kind.as_str()), - }, - sanitized_name: sanitize_snake_case_identifier(name)?, - kind, - }) +impl OperationElement for OperationField<'_> { + fn is_variadic(&self) -> bool { + match &self.kind { + FieldKind::Element { constraint, .. } => constraint.is_variadic(), + } } - 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, - }, - ) + fn variadic_kind(&self) -> &VariadicKind { + match &self.kind { + FieldKind::Element { variadic_kind, .. } => variadic_kind, + } } } diff --git a/macro/src/dialect/operation/operation_result.rs b/macro/src/dialect/operation/operation_result.rs new file mode 100644 index 0000000000..f91ef9adbb --- /dev/null +++ b/macro/src/dialect/operation/operation_result.rs @@ -0,0 +1,96 @@ +use super::{OperationElement, OperationFieldLike, VariadicKind}; +use crate::dialect::{ + error::Error, + types::TypeConstraint, + utility::{generate_iterator_type, generate_result_type, sanitize_snake_case_identifier}, +}; +use proc_macro2::{Span, TokenStream}; +use quote::quote; +use syn::{parse_quote, Ident, Type}; + +#[derive(Debug)] +pub struct OperationResult<'a> { + name: &'a str, + singular_identifier: Ident, + constraint: TypeConstraint<'a>, + variadic_kind: VariadicKind, +} + +impl<'a> OperationResult<'a> { + pub fn new( + name: &'a str, + constraint: TypeConstraint<'a>, + variadic_kind: VariadicKind, + ) -> Result { + Ok(Self { + name, + singular_identifier: sanitize_snake_case_identifier(name)?, + constraint, + variadic_kind, + }) + } +} + +impl OperationFieldLike for OperationResult<'_> { + fn name(&self) -> &str { + self.name + } + + fn singular_identifier(&self) -> &Ident { + &self.singular_identifier + } + + fn plural_kind_identifier(&self) -> Ident { + Ident::new("results", Span::call_site()) + } + + // TODO Share this logic with `Operand`. + fn parameter_type(&self) -> Type { + let r#type: Type = parse_quote!(::melior::ir::Type<'c>); + + if self.constraint.is_variadic() { + parse_quote! { &[#r#type] } + } else { + r#type + } + } + + // TODO Share this logic with `Operand`. + fn return_type(&self) -> Type { + let r#type: Type = parse_quote!(::melior::ir::operation::OperationResult<'c, '_>); + + if !self.constraint.is_variadic() { + generate_result_type(r#type) + } else if self.variadic_kind == VariadicKind::AttributeSized { + generate_result_type(generate_iterator_type(r#type)) + } else { + generate_iterator_type(r#type) + } + } + + fn is_optional(&self) -> bool { + self.constraint.is_optional() + } + + fn is_result(&self) -> bool { + true + } + + fn add_arguments(&self, name: &Ident) -> TokenStream { + if self.constraint.is_unfixed() && !self.constraint.is_optional() { + quote! { #name } + } else { + quote! { &[#name] } + } + } +} + +impl OperationElement for OperationResult<'_> { + fn is_variadic(&self) -> bool { + self.constraint.is_variadic() + } + + fn variadic_kind(&self) -> &VariadicKind { + &self.variadic_kind + } +} From a2eab4ebc7778a01a97bd863880d87bace39fc18 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sat, 17 Feb 2024 19:26:07 +0900 Subject: [PATCH 060/108] Refactor operand macros (#427) - **Rename** - **Fix** --- .../dialect/generation/attribute_accessor.rs | 2 +- .../dialect/generation/element_accessor.rs | 4 +- .../dialect/generation/operand_accessor.rs | 11 ++- .../src/dialect/generation/region_accessor.rs | 2 +- .../src/dialect/generation/result_accessor.rs | 2 +- .../dialect/generation/successor_accessor.rs | 2 +- macro/src/dialect/operation.rs | 48 ++++------ macro/src/dialect/operation/attribute.rs | 4 +- macro/src/dialect/operation/field_kind.rs | 57 ----------- macro/src/dialect/operation/operand.rs | 94 ++++++++++++++++++ .../dialect/operation/operation_element.rs | 4 +- .../src/dialect/operation/operation_field.rs | 95 +------------------ macro/src/dialect/operation/region.rs | 4 +- .../{operation_result.rs => result.rs} | 4 +- macro/src/dialect/operation/sequence_info.rs | 5 - macro/src/dialect/operation/successor.rs | 4 +- 16 files changed, 138 insertions(+), 204 deletions(-) delete mode 100644 macro/src/dialect/operation/field_kind.rs create mode 100644 macro/src/dialect/operation/operand.rs rename macro/src/dialect/operation/{operation_result.rs => result.rs} (95%) delete mode 100644 macro/src/dialect/operation/sequence_info.rs diff --git a/macro/src/dialect/generation/attribute_accessor.rs b/macro/src/dialect/generation/attribute_accessor.rs index 02ed99f441..f95586d32a 100644 --- a/macro/src/dialect/generation/attribute_accessor.rs +++ b/macro/src/dialect/generation/attribute_accessor.rs @@ -1,6 +1,6 @@ use crate::dialect::{ error::Error, - operation::{Attribute, OperationFieldLike}, + operation::{Attribute, OperationField}, utility::sanitize_snake_case_identifier, }; use proc_macro2::TokenStream; diff --git a/macro/src/dialect/generation/element_accessor.rs b/macro/src/dialect/generation/element_accessor.rs index 05be6f2622..4cb87da9d4 100644 --- a/macro/src/dialect/generation/element_accessor.rs +++ b/macro/src/dialect/generation/element_accessor.rs @@ -1,10 +1,10 @@ -use crate::dialect::operation::{OperationElement, OperationFieldLike, VariadicKind}; +use crate::dialect::operation::{OperationElement, OperationField, VariadicKind}; use proc_macro2::{Span, TokenStream}; use quote::quote; use syn::Ident; pub fn generate_element_getter( - field: &(impl OperationFieldLike + OperationElement), + field: &(impl OperationField + OperationElement), singular_kind: &str, plural_kind: &str, error_variant: &Ident, diff --git a/macro/src/dialect/generation/operand_accessor.rs b/macro/src/dialect/generation/operand_accessor.rs index 768bac3eb7..2af0a69ea2 100644 --- a/macro/src/dialect/generation/operand_accessor.rs +++ b/macro/src/dialect/generation/operand_accessor.rs @@ -1,15 +1,18 @@ use super::element_accessor::generate_element_getter; -use crate::dialect::{error::Error, operation::OperationField}; +use crate::dialect::{ + error::Error, + operation::{Operand, OperationField}, +}; use proc_macro2::{Ident, Span, TokenStream}; use quote::quote; pub fn generate_operand_accessor( - field: &OperationField, + field: &Operand, index: usize, length: usize, ) -> Result { - let ident = &field.sanitized_name; - let return_type = &field.kind.return_type(); + let ident = field.singular_identifier(); + let return_type = field.return_type(); let body = generate_element_getter( field, "operand", diff --git a/macro/src/dialect/generation/region_accessor.rs b/macro/src/dialect/generation/region_accessor.rs index 35b418ae69..1ab8772fbb 100644 --- a/macro/src/dialect/generation/region_accessor.rs +++ b/macro/src/dialect/generation/region_accessor.rs @@ -1,4 +1,4 @@ -use crate::dialect::operation::{OperationFieldLike, Region}; +use crate::dialect::operation::{OperationField, Region}; use proc_macro2::TokenStream; use quote::quote; diff --git a/macro/src/dialect/generation/result_accessor.rs b/macro/src/dialect/generation/result_accessor.rs index 30fb760839..914b2b9f9c 100644 --- a/macro/src/dialect/generation/result_accessor.rs +++ b/macro/src/dialect/generation/result_accessor.rs @@ -1,7 +1,7 @@ use super::element_accessor::generate_element_getter; use crate::dialect::{ error::Error, - operation::{OperationFieldLike, OperationResult}, + operation::{OperationField, OperationResult}, }; use proc_macro2::{Ident, Span, TokenStream}; use quote::quote; diff --git a/macro/src/dialect/generation/successor_accessor.rs b/macro/src/dialect/generation/successor_accessor.rs index e48ca393a2..c42693e2c3 100644 --- a/macro/src/dialect/generation/successor_accessor.rs +++ b/macro/src/dialect/generation/successor_accessor.rs @@ -1,4 +1,4 @@ -use crate::dialect::operation::{OperationFieldLike, Successor}; +use crate::dialect::operation::{OperationField, Successor}; use proc_macro2::TokenStream; use quote::quote; diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index f5357d3a3d..191ac65613 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -1,18 +1,17 @@ mod attribute; mod builder; -mod field_kind; +mod operand; mod operation_element; mod operation_field; -mod operation_result; mod region; -mod sequence_info; +mod result; mod successor; mod variadic_kind; pub use self::{ - attribute::Attribute, builder::OperationBuilder, operation_element::OperationElement, - operation_field::OperationField, operation_result::OperationResult, region::Region, - sequence_info::SequenceInfo, successor::Successor, variadic_kind::VariadicKind, + attribute::Attribute, builder::OperationBuilder, operand::Operand, + operation_element::OperationElement, region::Region, result::OperationResult, + successor::Successor, variadic_kind::VariadicKind, }; use super::utility::sanitize_documentation; use crate::dialect::{ @@ -20,7 +19,7 @@ use crate::dialect::{ r#trait::Trait, types::{RegionConstraint, SuccessorConstraint, TypeConstraint}, }; -pub use operation_field::OperationFieldLike; +pub use operation_field::OperationField; use tblgen::{error::WithLocation, record::Record, TypedInit}; #[derive(Debug)] @@ -30,7 +29,7 @@ pub struct Operation<'a> { regions: Vec>, successors: Vec>, results: Vec>, - operands: Vec>, + operands: Vec>, attributes: Vec>, derived_attributes: Vec>, } @@ -130,10 +129,11 @@ impl<'a> Operation<'a> { sanitize_documentation(self.definition.str_value("description")?) } - pub fn fields(&self) -> impl Iterator { - fn convert(field: &impl OperationFieldLike) -> &dyn OperationFieldLike { + pub fn fields(&self) -> impl Iterator { + fn convert(field: &impl OperationField) -> &dyn OperationField { field } + self.results .iter() .map(convert) @@ -143,7 +143,7 @@ impl<'a> Operation<'a> { .chain(self.attributes().map(convert)) } - pub fn operands(&self) -> impl Iterator> + Clone { + pub fn operands(&self) -> impl Iterator> + Clone { self.operands.iter() } @@ -171,7 +171,7 @@ impl<'a> Operation<'a> { self.attributes.iter().chain(&self.derived_attributes) } - pub fn required_fields(&self) -> impl Iterator { + pub fn required_fields(&self) -> impl Iterator { self.fields() .filter(|field| (!field.is_result() || !self.can_infer_type) && !field.is_optional()) } @@ -264,9 +264,7 @@ impl<'a> Operation<'a> { .into_iter() .map(|(name, constraint)| (name, TypeConstraint::new(constraint))) .collect::>(), - |name, constraint, _sequence_info, variadic_kind| { - OperationResult::new(name, constraint, variadic_kind) - }, + OperationResult::new, same_size, attribute_sized, ) @@ -276,16 +274,14 @@ impl<'a> Operation<'a> { arguments: &[(&'a str, Record<'a>)], same_size: bool, attribute_sized: bool, - ) -> Result>, Error> { + ) -> Result>, Error> { Ok(Self::collect_elements( &arguments .iter() .filter(|(_, definition)| definition.subclass_of("TypeConstraint")) .map(|(name, definition)| (*name, TypeConstraint::new(*definition))) .collect::>(), - |name, constraint, sequence_info, variadic_kind| { - OperationField::new(name, constraint, sequence_info, variadic_kind) - }, + Operand::new, same_size, attribute_sized, )? @@ -294,7 +290,7 @@ impl<'a> Operation<'a> { fn collect_elements( elements: &[(&'a str, TypeConstraint<'a>)], - create: impl Fn(&'a str, TypeConstraint<'a>, SequenceInfo, VariadicKind) -> Result, + create: impl Fn(&'a str, TypeConstraint<'a>, VariadicKind) -> Result, same_size: bool, attribute_sized: bool, ) -> Result<(Vec, usize), Error> { @@ -305,16 +301,8 @@ impl<'a> Operation<'a> { let mut variadic_kind = VariadicKind::new(unfixed_count, same_size, attribute_sized); let mut fields = vec![]; - for (index, (name, constraint)) in elements.iter().enumerate() { - fields.push(create( - name, - *constraint, - SequenceInfo { - index, - len: elements.len(), - }, - variadic_kind.clone(), - )?); + for (name, constraint) in elements { + fields.push(create(name, *constraint, variadic_kind.clone())?); match &mut variadic_kind { VariadicKind::Simple { unfixed_seen } => { diff --git a/macro/src/dialect/operation/attribute.rs b/macro/src/dialect/operation/attribute.rs index f50dd13ef2..341cfddbb4 100644 --- a/macro/src/dialect/operation/attribute.rs +++ b/macro/src/dialect/operation/attribute.rs @@ -1,6 +1,6 @@ use crate::dialect::{ error::Error, - operation::operation_field::OperationFieldLike, + operation::operation_field::OperationField, utility::{generate_result_type, sanitize_snake_case_identifier}, }; use once_cell::sync::Lazy; @@ -109,7 +109,7 @@ impl<'a> Attribute<'a> { } } -impl OperationFieldLike for Attribute<'_> { +impl OperationField for Attribute<'_> { fn name(&self) -> &str { self.name } diff --git a/macro/src/dialect/operation/field_kind.rs b/macro/src/dialect/operation/field_kind.rs deleted file mode 100644 index 0eee9f3ab9..0000000000 --- a/macro/src/dialect/operation/field_kind.rs +++ /dev/null @@ -1,57 +0,0 @@ -use super::{SequenceInfo, VariadicKind}; -use crate::dialect::{ - types::TypeConstraint, - utility::{generate_iterator_type, generate_result_type}, -}; -use syn::{parse_quote, Type}; - -#[derive(Debug)] -pub enum FieldKind<'a> { - Element { - constraint: TypeConstraint<'a>, - sequence_info: SequenceInfo, - variadic_kind: VariadicKind, - }, -} - -impl<'a> FieldKind<'a> { - pub fn is_optional(&self) -> bool { - match self { - Self::Element { constraint, .. } => constraint.is_optional(), - } - } - - pub fn parameter_type(&self) -> Type { - match self { - Self::Element { constraint, .. } => { - let r#type: Type = parse_quote!(::melior::ir::Value<'c, '_>); - - if constraint.is_variadic() { - parse_quote! { &[#r#type] } - } else { - r#type - } - } - } - } - - pub fn return_type(&self) -> Type { - match self { - Self::Element { - constraint, - variadic_kind, - .. - } => { - let r#type: Type = parse_quote!(::melior::ir::Value<'c, '_>); - - if !constraint.is_variadic() { - generate_result_type(r#type) - } else if variadic_kind == &VariadicKind::AttributeSized { - generate_result_type(generate_iterator_type(r#type)) - } else { - generate_iterator_type(r#type) - } - } - } - } -} diff --git a/macro/src/dialect/operation/operand.rs b/macro/src/dialect/operation/operand.rs new file mode 100644 index 0000000000..9d57e5e6c0 --- /dev/null +++ b/macro/src/dialect/operation/operand.rs @@ -0,0 +1,94 @@ +use super::{OperationElement, OperationField, VariadicKind}; +use crate::dialect::{ + error::Error, + types::TypeConstraint, + utility::{generate_iterator_type, generate_result_type, sanitize_snake_case_identifier}, +}; +use proc_macro2::{Ident, TokenStream}; +use quote::{format_ident, quote}; +use syn::{parse_quote, Type}; + +#[derive(Debug)] +pub struct Operand<'a> { + name: &'a str, + singular_identifier: Ident, + constraint: TypeConstraint<'a>, + variadic_kind: VariadicKind, +} + +impl<'a> Operand<'a> { + pub fn new( + name: &'a str, + constraint: TypeConstraint<'a>, + variadic_kind: VariadicKind, + ) -> Result { + Ok(Self { + name, + singular_identifier: sanitize_snake_case_identifier(name)?, + constraint, + variadic_kind, + }) + } +} + +impl OperationField for Operand<'_> { + fn name(&self) -> &str { + self.name + } + + fn singular_identifier(&self) -> &Ident { + &self.singular_identifier + } + + fn plural_kind_identifier(&self) -> Ident { + format_ident!("operands") + } + + fn parameter_type(&self) -> Type { + let r#type: Type = parse_quote!(::melior::ir::Value<'c, '_>); + + if self.constraint.is_variadic() { + parse_quote! { &[#r#type] } + } else { + r#type + } + } + + fn return_type(&self) -> Type { + let r#type: Type = parse_quote!(::melior::ir::Value<'c, '_>); + + if !self.constraint.is_variadic() { + generate_result_type(r#type) + } else if self.variadic_kind == VariadicKind::AttributeSized { + generate_result_type(generate_iterator_type(r#type)) + } else { + generate_iterator_type(r#type) + } + } + + fn is_optional(&self) -> bool { + self.constraint.is_optional() + } + + fn is_result(&self) -> bool { + false + } + + fn add_arguments(&self, name: &Ident) -> TokenStream { + if self.constraint.is_variadic() { + quote! { #name } + } else { + quote! { &[#name] } + } + } +} + +impl OperationElement for Operand<'_> { + fn is_variadic(&self) -> bool { + self.constraint.is_variadic() + } + + fn variadic_kind(&self) -> &VariadicKind { + &self.variadic_kind + } +} diff --git a/macro/src/dialect/operation/operation_element.rs b/macro/src/dialect/operation/operation_element.rs index 9769e4080b..4d64945122 100644 --- a/macro/src/dialect/operation/operation_element.rs +++ b/macro/src/dialect/operation/operation_element.rs @@ -1,6 +1,6 @@ -use super::{OperationFieldLike, VariadicKind}; +use super::{OperationField, VariadicKind}; -pub trait OperationElement: OperationFieldLike { +pub trait OperationElement: OperationField { fn is_variadic(&self) -> bool; fn variadic_kind(&self) -> &VariadicKind; diff --git a/macro/src/dialect/operation/operation_field.rs b/macro/src/dialect/operation/operation_field.rs index 0790764e6f..298fd7ed50 100644 --- a/macro/src/dialect/operation/operation_field.rs +++ b/macro/src/dialect/operation/operation_field.rs @@ -1,104 +1,15 @@ -use super::{field_kind::FieldKind, OperationElement, SequenceInfo, VariadicKind}; -use crate::dialect::{ - error::Error, types::TypeConstraint, utility::sanitize_snake_case_identifier, -}; use proc_macro2::{Ident, TokenStream}; -use quote::{format_ident, quote}; use syn::Type; -// TODO Rename this `OperationField`. -pub trait OperationFieldLike { +pub trait OperationField { fn name(&self) -> &str; fn singular_identifier(&self) -> &Ident; fn plural_kind_identifier(&self) -> Ident; fn parameter_type(&self) -> Type; fn return_type(&self) -> Type; fn is_optional(&self) -> bool; - // TODO Remove this. - fn is_result(&self) -> bool; fn add_arguments(&self, name: &Ident) -> TokenStream; -} - -#[derive(Debug)] -pub struct OperationField<'a> { - pub(crate) name: &'a str, - pub(crate) plural_identifier: Ident, - pub(crate) sanitized_name: Ident, - pub(crate) kind: FieldKind<'a>, -} - -impl<'a> OperationField<'a> { - pub fn new( - name: &'a str, - constraint: TypeConstraint<'a>, - sequence_info: SequenceInfo, - variadic_kind: VariadicKind, - ) -> Result { - Ok(Self { - name, - plural_identifier: format_ident!("operands"), - sanitized_name: sanitize_snake_case_identifier(name)?, - kind: FieldKind::Element { - constraint, - sequence_info, - variadic_kind, - }, - }) - } -} - -impl OperationFieldLike for OperationField<'_> { - fn name(&self) -> &str { - self.name - } - - fn singular_identifier(&self) -> &Ident { - &self.sanitized_name - } - - fn plural_kind_identifier(&self) -> Ident { - self.plural_identifier.clone() - } - fn parameter_type(&self) -> Type { - self.kind.parameter_type() - } - - fn return_type(&self) -> Type { - self.kind.return_type() - } - - fn is_optional(&self) -> bool { - self.kind.is_optional() - } - - fn is_result(&self) -> bool { - false - } - - fn add_arguments(&self, name: &Ident) -> TokenStream { - match &self.kind { - FieldKind::Element { constraint, .. } => { - if constraint.is_variadic() { - quote! { #name } - } else { - quote! { &[#name] } - } - } - } - } -} - -impl OperationElement for OperationField<'_> { - fn is_variadic(&self) -> bool { - match &self.kind { - FieldKind::Element { constraint, .. } => constraint.is_variadic(), - } - } - - fn variadic_kind(&self) -> &VariadicKind { - match &self.kind { - FieldKind::Element { variadic_kind, .. } => variadic_kind, - } - } + // TODO Remove this. + fn is_result(&self) -> bool; } diff --git a/macro/src/dialect/operation/region.rs b/macro/src/dialect/operation/region.rs index 5ece300ac2..085699e355 100644 --- a/macro/src/dialect/operation/region.rs +++ b/macro/src/dialect/operation/region.rs @@ -1,4 +1,4 @@ -use super::OperationFieldLike; +use super::OperationField; use crate::dialect::{ error::Error, types::RegionConstraint, @@ -29,7 +29,7 @@ impl<'a> Region<'a> { } } -impl OperationFieldLike for Region<'_> { +impl OperationField for Region<'_> { fn name(&self) -> &str { self.name } diff --git a/macro/src/dialect/operation/operation_result.rs b/macro/src/dialect/operation/result.rs similarity index 95% rename from macro/src/dialect/operation/operation_result.rs rename to macro/src/dialect/operation/result.rs index f91ef9adbb..e91ca60cdf 100644 --- a/macro/src/dialect/operation/operation_result.rs +++ b/macro/src/dialect/operation/result.rs @@ -1,4 +1,4 @@ -use super::{OperationElement, OperationFieldLike, VariadicKind}; +use super::{OperationElement, OperationField, VariadicKind}; use crate::dialect::{ error::Error, types::TypeConstraint, @@ -31,7 +31,7 @@ impl<'a> OperationResult<'a> { } } -impl OperationFieldLike for OperationResult<'_> { +impl OperationField for OperationResult<'_> { fn name(&self) -> &str { self.name } diff --git a/macro/src/dialect/operation/sequence_info.rs b/macro/src/dialect/operation/sequence_info.rs deleted file mode 100644 index 1dd7f85553..0000000000 --- a/macro/src/dialect/operation/sequence_info.rs +++ /dev/null @@ -1,5 +0,0 @@ -#[derive(Debug, Clone)] -pub struct SequenceInfo { - pub index: usize, - pub len: usize, -} diff --git a/macro/src/dialect/operation/successor.rs b/macro/src/dialect/operation/successor.rs index 0d8f9721a8..7c88403edb 100644 --- a/macro/src/dialect/operation/successor.rs +++ b/macro/src/dialect/operation/successor.rs @@ -1,4 +1,4 @@ -use super::OperationFieldLike; +use super::OperationField; use crate::dialect::{ error::Error, types::SuccessorConstraint, @@ -29,7 +29,7 @@ impl<'a> Successor<'a> { } } -impl OperationFieldLike for Successor<'_> { +impl OperationField for Successor<'_> { fn name(&self) -> &str { self.name } From 9c733bf3ca6b8249e16906019611de4a0e9b090a Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sat, 17 Feb 2024 19:35:18 +0900 Subject: [PATCH 061/108] Refactor successor and region macros (#428) - **Fix** - **Fix** --- macro/src/dialect/operation.rs | 16 +++++++-------- macro/src/dialect/operation/region.rs | 9 ++++---- macro/src/dialect/operation/successor.rs | 9 ++++---- macro/src/dialect/types.rs | 26 ------------------------ 4 files changed, 15 insertions(+), 45 deletions(-) diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 191ac65613..a52bcee9c9 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -17,7 +17,7 @@ use super::utility::sanitize_documentation; use crate::dialect::{ error::{Error, OdsError}, r#trait::Trait, - types::{RegionConstraint, SuccessorConstraint, TypeConstraint}, + types::TypeConstraint, }; pub use operation_field::OperationField; use tblgen::{error::WithLocation, record::Record, TypedInit}; @@ -183,9 +183,9 @@ impl<'a> Operation<'a> { .map(|(name, value)| { Successor::new( name, - SuccessorConstraint::new( - Record::try_from(value).map_err(|error| error.set_location(definition))?, - ), + Record::try_from(value) + .map_err(|error| error.set_location(definition))? + .subclass_of("VariadicSuccessor"), ) }) .collect() @@ -198,11 +198,9 @@ impl<'a> Operation<'a> { .map(|(name, value)| { Region::new( name, - RegionConstraint::new( - value - .try_into() - .map_err(|error: tblgen::Error| error.set_location(definition))?, - ), + Record::try_from(value) + .map_err(|error| error.set_location(definition))? + .subclass_of("VariadicRegion"), ) }) .collect() diff --git a/macro/src/dialect/operation/region.rs b/macro/src/dialect/operation/region.rs index 085699e355..b209e4b561 100644 --- a/macro/src/dialect/operation/region.rs +++ b/macro/src/dialect/operation/region.rs @@ -1,7 +1,6 @@ use super::OperationField; use crate::dialect::{ error::Error, - types::RegionConstraint, utility::{generate_iterator_type, generate_result_type, sanitize_snake_case_identifier}, }; use proc_macro2::{Span, TokenStream}; @@ -12,20 +11,20 @@ use syn::{parse_quote, Ident, Type}; pub struct Region<'a> { name: &'a str, singular_identifier: Ident, - constraint: RegionConstraint<'a>, + variadic: bool, } impl<'a> Region<'a> { - pub fn new(name: &'a str, constraint: RegionConstraint<'a>) -> Result { + pub fn new(name: &'a str, variadic: bool) -> Result { Ok(Self { name, singular_identifier: sanitize_snake_case_identifier(name)?, - constraint, + variadic, }) } pub fn is_variadic(&self) -> bool { - self.constraint.is_variadic() + self.variadic } } diff --git a/macro/src/dialect/operation/successor.rs b/macro/src/dialect/operation/successor.rs index 7c88403edb..1d5b56b1dc 100644 --- a/macro/src/dialect/operation/successor.rs +++ b/macro/src/dialect/operation/successor.rs @@ -1,7 +1,6 @@ use super::OperationField; use crate::dialect::{ error::Error, - types::SuccessorConstraint, utility::{generate_iterator_type, generate_result_type, sanitize_snake_case_identifier}, }; use proc_macro2::{Span, TokenStream}; @@ -12,20 +11,20 @@ use syn::{parse_quote, Ident, Type}; pub struct Successor<'a> { name: &'a str, singular_identifier: Ident, - constraint: SuccessorConstraint<'a>, + variadic: bool, } impl<'a> Successor<'a> { - pub fn new(name: &'a str, constraint: SuccessorConstraint<'a>) -> Result { + pub fn new(name: &'a str, variadic: bool) -> Result { Ok(Self { name, singular_identifier: sanitize_snake_case_identifier(name)?, - constraint, + variadic, }) } pub fn is_variadic(&self) -> bool { - self.constraint.is_variadic() + self.variadic } } diff --git a/macro/src/dialect/types.rs b/macro/src/dialect/types.rs index 9a569aa111..395bbffeb7 100644 --- a/macro/src/dialect/types.rs +++ b/macro/src/dialect/types.rs @@ -1,31 +1,5 @@ use tblgen::record::Record; -#[derive(Debug, Clone, Copy)] -pub struct RegionConstraint<'a>(Record<'a>); - -impl<'a> RegionConstraint<'a> { - pub fn new(record: Record<'a>) -> Self { - Self(record) - } - - pub fn is_variadic(&self) -> bool { - self.0.subclass_of("VariadicRegion") - } -} - -#[derive(Debug, Clone, Copy)] -pub struct SuccessorConstraint<'a>(Record<'a>); - -impl<'a> SuccessorConstraint<'a> { - pub fn new(record: Record<'a>) -> Self { - Self(record) - } - - pub fn is_variadic(&self) -> bool { - self.0.subclass_of("VariadicSuccessor") - } -} - #[derive(Debug, Clone, Copy)] pub struct TypeConstraint<'a>(Record<'a>); From 13a4fd846b809df374d31274766d1378aff2c4eb Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sat, 17 Feb 2024 19:54:08 +0900 Subject: [PATCH 062/108] Refactor type macro (#429) --- macro/src/dialect.rs | 2 +- macro/src/dialect/operation.rs | 20 +++++++------- macro/src/dialect/operation/operand.rs | 18 ++++++------- macro/src/dialect/operation/result.rs | 18 ++++++------- macro/src/dialect/type.rs | 36 ++++++++++++++++++++++++++ macro/src/dialect/types.rs | 28 -------------------- 6 files changed, 65 insertions(+), 57 deletions(-) create mode 100644 macro/src/dialect/type.rs delete mode 100644 macro/src/dialect/types.rs diff --git a/macro/src/dialect.rs b/macro/src/dialect.rs index c283a867f9..abf140ef31 100644 --- a/macro/src/dialect.rs +++ b/macro/src/dialect.rs @@ -3,7 +3,7 @@ mod generation; mod input; mod operation; mod r#trait; -mod types; +mod r#type; mod utility; use self::{ diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index a52bcee9c9..9f6c48dfeb 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -17,7 +17,7 @@ use super::utility::sanitize_documentation; use crate::dialect::{ error::{Error, OdsError}, r#trait::Trait, - types::TypeConstraint, + r#type::Type, }; pub use operation_field::OperationField; use tblgen::{error::WithLocation, record::Record, TypedInit}; @@ -260,7 +260,7 @@ impl<'a> Operation<'a> { Self::collect_elements( &Self::dag_constraints(definition, "results")? .into_iter() - .map(|(name, constraint)| (name, TypeConstraint::new(constraint))) + .map(|(name, constraint)| (name, Type::new(constraint))) .collect::>(), OperationResult::new, same_size, @@ -277,7 +277,7 @@ impl<'a> Operation<'a> { &arguments .iter() .filter(|(_, definition)| definition.subclass_of("TypeConstraint")) - .map(|(name, definition)| (*name, TypeConstraint::new(*definition))) + .map(|(name, definition)| (*name, Type::new(*definition))) .collect::>(), Operand::new, same_size, @@ -287,24 +287,24 @@ impl<'a> Operation<'a> { } fn collect_elements( - elements: &[(&'a str, TypeConstraint<'a>)], - create: impl Fn(&'a str, TypeConstraint<'a>, VariadicKind) -> Result, + elements: &[(&'a str, Type)], + create: impl Fn(&'a str, Type, VariadicKind) -> Result, same_size: bool, attribute_sized: bool, ) -> Result<(Vec, usize), Error> { let unfixed_count = elements .iter() - .filter(|(_, constraint)| constraint.is_unfixed()) + .filter(|(_, r#type)| r#type.is_unfixed()) .count(); let mut variadic_kind = VariadicKind::new(unfixed_count, same_size, attribute_sized); let mut fields = vec![]; - for (name, constraint) in elements { - fields.push(create(name, *constraint, variadic_kind.clone())?); + for (name, r#type) in elements { + fields.push(create(name, *r#type, variadic_kind.clone())?); match &mut variadic_kind { VariadicKind::Simple { unfixed_seen } => { - if constraint.is_unfixed() { + if r#type.is_unfixed() { *unfixed_seen = true; } } @@ -313,7 +313,7 @@ impl<'a> Operation<'a> { preceding_variadic_count, .. } => { - if constraint.is_unfixed() { + if r#type.is_unfixed() { *preceding_variadic_count += 1; } else { *preceding_simple_count += 1; diff --git a/macro/src/dialect/operation/operand.rs b/macro/src/dialect/operation/operand.rs index 9d57e5e6c0..bec72a377f 100644 --- a/macro/src/dialect/operation/operand.rs +++ b/macro/src/dialect/operation/operand.rs @@ -1,7 +1,7 @@ use super::{OperationElement, OperationField, VariadicKind}; use crate::dialect::{ error::Error, - types::TypeConstraint, + r#type::Type as ElementType, utility::{generate_iterator_type, generate_result_type, sanitize_snake_case_identifier}, }; use proc_macro2::{Ident, TokenStream}; @@ -12,20 +12,20 @@ use syn::{parse_quote, Type}; pub struct Operand<'a> { name: &'a str, singular_identifier: Ident, - constraint: TypeConstraint<'a>, + r#type: ElementType, variadic_kind: VariadicKind, } impl<'a> Operand<'a> { pub fn new( name: &'a str, - constraint: TypeConstraint<'a>, + r#type: ElementType, variadic_kind: VariadicKind, ) -> Result { Ok(Self { name, singular_identifier: sanitize_snake_case_identifier(name)?, - constraint, + r#type, variadic_kind, }) } @@ -47,7 +47,7 @@ impl OperationField for Operand<'_> { fn parameter_type(&self) -> Type { let r#type: Type = parse_quote!(::melior::ir::Value<'c, '_>); - if self.constraint.is_variadic() { + if self.r#type.is_variadic() { parse_quote! { &[#r#type] } } else { r#type @@ -57,7 +57,7 @@ impl OperationField for Operand<'_> { fn return_type(&self) -> Type { let r#type: Type = parse_quote!(::melior::ir::Value<'c, '_>); - if !self.constraint.is_variadic() { + if !self.r#type.is_variadic() { generate_result_type(r#type) } else if self.variadic_kind == VariadicKind::AttributeSized { generate_result_type(generate_iterator_type(r#type)) @@ -67,7 +67,7 @@ impl OperationField for Operand<'_> { } fn is_optional(&self) -> bool { - self.constraint.is_optional() + self.r#type.is_optional() } fn is_result(&self) -> bool { @@ -75,7 +75,7 @@ impl OperationField for Operand<'_> { } fn add_arguments(&self, name: &Ident) -> TokenStream { - if self.constraint.is_variadic() { + if self.r#type.is_variadic() { quote! { #name } } else { quote! { &[#name] } @@ -85,7 +85,7 @@ impl OperationField for Operand<'_> { impl OperationElement for Operand<'_> { fn is_variadic(&self) -> bool { - self.constraint.is_variadic() + self.r#type.is_variadic() } fn variadic_kind(&self) -> &VariadicKind { diff --git a/macro/src/dialect/operation/result.rs b/macro/src/dialect/operation/result.rs index e91ca60cdf..a8629ee8b1 100644 --- a/macro/src/dialect/operation/result.rs +++ b/macro/src/dialect/operation/result.rs @@ -1,7 +1,7 @@ use super::{OperationElement, OperationField, VariadicKind}; use crate::dialect::{ error::Error, - types::TypeConstraint, + r#type::Type as ElementType, utility::{generate_iterator_type, generate_result_type, sanitize_snake_case_identifier}, }; use proc_macro2::{Span, TokenStream}; @@ -12,20 +12,20 @@ use syn::{parse_quote, Ident, Type}; pub struct OperationResult<'a> { name: &'a str, singular_identifier: Ident, - constraint: TypeConstraint<'a>, + r#type: ElementType, variadic_kind: VariadicKind, } impl<'a> OperationResult<'a> { pub fn new( name: &'a str, - constraint: TypeConstraint<'a>, + r#type: ElementType, variadic_kind: VariadicKind, ) -> Result { Ok(Self { name, singular_identifier: sanitize_snake_case_identifier(name)?, - constraint, + r#type, variadic_kind, }) } @@ -48,7 +48,7 @@ impl OperationField for OperationResult<'_> { fn parameter_type(&self) -> Type { let r#type: Type = parse_quote!(::melior::ir::Type<'c>); - if self.constraint.is_variadic() { + if self.r#type.is_variadic() { parse_quote! { &[#r#type] } } else { r#type @@ -59,7 +59,7 @@ impl OperationField for OperationResult<'_> { fn return_type(&self) -> Type { let r#type: Type = parse_quote!(::melior::ir::operation::OperationResult<'c, '_>); - if !self.constraint.is_variadic() { + if !self.r#type.is_variadic() { generate_result_type(r#type) } else if self.variadic_kind == VariadicKind::AttributeSized { generate_result_type(generate_iterator_type(r#type)) @@ -69,7 +69,7 @@ impl OperationField for OperationResult<'_> { } fn is_optional(&self) -> bool { - self.constraint.is_optional() + self.r#type.is_optional() } fn is_result(&self) -> bool { @@ -77,7 +77,7 @@ impl OperationField for OperationResult<'_> { } fn add_arguments(&self, name: &Ident) -> TokenStream { - if self.constraint.is_unfixed() && !self.constraint.is_optional() { + if self.r#type.is_unfixed() && !self.r#type.is_optional() { quote! { #name } } else { quote! { &[#name] } @@ -87,7 +87,7 @@ impl OperationField for OperationResult<'_> { impl OperationElement for OperationResult<'_> { fn is_variadic(&self) -> bool { - self.constraint.is_variadic() + self.r#type.is_variadic() } fn variadic_kind(&self) -> &VariadicKind { diff --git a/macro/src/dialect/type.rs b/macro/src/dialect/type.rs new file mode 100644 index 0000000000..1d7b8e936c --- /dev/null +++ b/macro/src/dialect/type.rs @@ -0,0 +1,36 @@ +use tblgen::record::Record; + +#[derive(Debug, Clone, Copy)] +pub struct Type { + optional: bool, + variadic: bool, + variadic_of_variadic: bool, +} + +impl Type { + pub fn new(record: Record) -> Self { + Self { + optional: record.subclass_of("Optional"), + variadic: record.subclass_of("Variadic"), + variadic_of_variadic: record.subclass_of("VariadicOfVariadic"), + } + } + + pub fn is_optional(&self) -> bool { + self.optional + } + + pub fn is_variadic(&self) -> bool { + self.variadic + } + + // TODO Support variadic-of-variadic. + #[allow(unused)] + pub fn is_variadic_of_variadic(&self) -> bool { + self.variadic_of_variadic + } + + pub fn is_unfixed(&self) -> bool { + self.is_variadic() || self.is_optional() + } +} diff --git a/macro/src/dialect/types.rs b/macro/src/dialect/types.rs deleted file mode 100644 index 395bbffeb7..0000000000 --- a/macro/src/dialect/types.rs +++ /dev/null @@ -1,28 +0,0 @@ -use tblgen::record::Record; - -#[derive(Debug, Clone, Copy)] -pub struct TypeConstraint<'a>(Record<'a>); - -impl<'a> TypeConstraint<'a> { - pub fn new(record: Record<'a>) -> Self { - Self(record) - } - - pub fn is_optional(&self) -> bool { - self.0.subclass_of("Optional") - } - - pub fn is_variadic(&self) -> bool { - self.0.subclass_of("Variadic") - } - - // TODO Support variadic-of-variadic. - #[allow(unused)] - pub fn is_variadic_of_variadic(&self) -> bool { - self.0.subclass_of("VariadicOfVariadic") - } - - pub fn is_unfixed(&self) -> bool { - self.is_variadic() || self.is_optional() - } -} From 19bfecebd9c5c05b2181e78db0187f06afd507d8 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sat, 17 Feb 2024 22:02:36 +0900 Subject: [PATCH 063/108] Fix accessor order (#430) --- macro/src/dialect/generation.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/macro/src/dialect/generation.rs b/macro/src/dialect/generation.rs index 4da87f5223..2968dfcf63 100644 --- a/macro/src/dialect/generation.rs +++ b/macro/src/dialect/generation.rs @@ -37,16 +37,16 @@ pub fn generate_operation(operation: &Operation) -> Result { .enumerate() .map(|(index, operand)| generate_operand_accessor(operand, index, operation.operand_len())) .collect::, _>>()?; - let successor_accessors = operation - .successors() - .enumerate() - .map(|(index, region)| generate_successor_accessor(index, region)) - .collect::>(); let region_accessors = operation .regions() .enumerate() .map(|(index, region)| generate_region_accessor(index, region)) .collect::>(); + let successor_accessors = operation + .successors() + .enumerate() + .map(|(index, region)| generate_successor_accessor(index, region)) + .collect::>(); let attribute_accessors = operation .attributes() .map(generate_attribute_accessors) @@ -78,8 +78,8 @@ pub fn generate_operation(operation: &Operation) -> Result { #(#result_accessors)* #(#operand_accessors)* - #(#successor_accessors)* #(#region_accessors)* + #(#successor_accessors)* #(#attribute_accessors)* } From 79aa9a25237eb6978a77927b4516b30ee9f8e955 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sat, 17 Feb 2024 22:08:07 +0900 Subject: [PATCH 064/108] Bump version (#431) --- Cargo.lock | 4 ++-- macro/Cargo.toml | 2 +- melior/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bac1297ebf..dba89c6d9b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -595,7 +595,7 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "melior" -version = "0.15.3" +version = "0.15.4" dependencies = [ "dashmap", "indoc", @@ -608,7 +608,7 @@ dependencies = [ [[package]] name = "melior-macro" -version = "0.9.1" +version = "0.9.2" dependencies = [ "comrak", "convert_case", diff --git a/macro/Cargo.toml b/macro/Cargo.toml index d02565363c..27b3f805c3 100644 --- a/macro/Cargo.toml +++ b/macro/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "melior-macro" description = "Internal macros for Melior" -version = "0.9.1" +version = "0.9.2" edition = "2021" license = "Apache-2.0" repository = "https://github.com/raviqqe/melior" diff --git a/melior/Cargo.toml b/melior/Cargo.toml index 10ea4bcf8d..5ed6998311 100644 --- a/melior/Cargo.toml +++ b/melior/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "melior" description = "The rustic MLIR bindings in Rust" -version = "0.15.3" +version = "0.15.4" edition = "2021" license = "Apache-2.0" repository = "https://github.com/raviqqe/melior" From 06843c2270a594c3da945090ae810edef99bc13a Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sat, 17 Feb 2024 22:33:50 +0900 Subject: [PATCH 065/108] Remove `context` arguments (#432) --- .../dialect/generation/attribute_accessor.rs | 2 +- .../dialect/generation/element_accessor.rs | 13 +++---- .../dialect/generation/operand_accessor.rs | 3 +- .../src/dialect/generation/region_accessor.rs | 2 +- .../src/dialect/generation/result_accessor.rs | 3 +- .../dialect/generation/successor_accessor.rs | 3 +- macro/tests/operand.rs | 20 +++++------ macro/tests/region.rs | 36 +++++++++---------- rust-toolchain.toml | 3 ++ 9 files changed, 43 insertions(+), 42 deletions(-) create mode 100644 rust-toolchain.toml diff --git a/macro/src/dialect/generation/attribute_accessor.rs b/macro/src/dialect/generation/attribute_accessor.rs index f95586d32a..67a2e5112a 100644 --- a/macro/src/dialect/generation/attribute_accessor.rs +++ b/macro/src/dialect/generation/attribute_accessor.rs @@ -32,7 +32,7 @@ fn generate_getter(attribute: &Attribute) -> Result { Ok(quote! { #[allow(clippy::needless_question_mark)] - pub fn #identifier(&self, context: &'c ::melior::Context) -> #return_type { + pub fn #identifier(&self) -> #return_type { #body } }) diff --git a/macro/src/dialect/generation/element_accessor.rs b/macro/src/dialect/generation/element_accessor.rs index 4cb87da9d4..62fa3aa8e6 100644 --- a/macro/src/dialect/generation/element_accessor.rs +++ b/macro/src/dialect/generation/element_accessor.rs @@ -56,11 +56,6 @@ pub fn generate_element_getter( preceding_simple_count, preceding_variadic_count, } => { - let compute_start_length = quote! { - let total_var_len = self.operation.#count() - #unfixed_count + 1; - let group_len = total_var_len / #unfixed_count; - let start = #preceding_simple_count + #preceding_variadic_count * group_len; - }; let get_elements = if field.is_unfixed() { quote! { self.operation.#kind_plural_identifier().skip(start).take(group_len) @@ -71,7 +66,13 @@ pub fn generate_element_getter( } }; - quote! { #compute_start_length #get_elements } + quote! { + let total_var_len = self.operation.#count() - #unfixed_count + 1; + let group_len = total_var_len / #unfixed_count; + let start = #preceding_simple_count + #preceding_variadic_count * group_len; + + #get_elements + } } VariadicKind::AttributeSized => { let segment_size_attribute = format!("{singular_kind}_segment_sizes"); diff --git a/macro/src/dialect/generation/operand_accessor.rs b/macro/src/dialect/generation/operand_accessor.rs index 2af0a69ea2..44d906ad6b 100644 --- a/macro/src/dialect/generation/operand_accessor.rs +++ b/macro/src/dialect/generation/operand_accessor.rs @@ -23,8 +23,7 @@ pub fn generate_operand_accessor( ); Ok(quote! { - #[allow(clippy::needless_question_mark)] - pub fn #ident(&self, context: &'c ::melior::Context) -> #return_type { + pub fn #ident(&self) -> #return_type { #body } }) diff --git a/macro/src/dialect/generation/region_accessor.rs b/macro/src/dialect/generation/region_accessor.rs index 1ab8772fbb..7852f9669b 100644 --- a/macro/src/dialect/generation/region_accessor.rs +++ b/macro/src/dialect/generation/region_accessor.rs @@ -17,7 +17,7 @@ pub fn generate_region_accessor(index: usize, region: &Region) -> TokenStream { }; quote! { - pub fn #identifier(&self, context: &'c ::melior::Context) -> #return_type { + pub fn #identifier(&self) -> #return_type { #body } } diff --git a/macro/src/dialect/generation/result_accessor.rs b/macro/src/dialect/generation/result_accessor.rs index 914b2b9f9c..d6b284b829 100644 --- a/macro/src/dialect/generation/result_accessor.rs +++ b/macro/src/dialect/generation/result_accessor.rs @@ -23,8 +23,7 @@ pub fn generate_result_accessor( ); Ok(quote! { - #[allow(clippy::needless_question_mark)] - pub fn #identifier(&self, context: &'c ::melior::Context) -> #return_type { + pub fn #identifier(&self) -> #return_type { #body } }) diff --git a/macro/src/dialect/generation/successor_accessor.rs b/macro/src/dialect/generation/successor_accessor.rs index c42693e2c3..1c4b1174a7 100644 --- a/macro/src/dialect/generation/successor_accessor.rs +++ b/macro/src/dialect/generation/successor_accessor.rs @@ -17,8 +17,7 @@ pub fn generate_successor_accessor(index: usize, successor: &Successor) -> Token }; quote! { - #[allow(clippy::needless_question_mark)] - pub fn #identifier(&self, context: &'c ::melior::Context) -> #return_type { + pub fn #identifier(&self) -> #return_type { #body } } diff --git a/macro/tests/operand.rs b/macro/tests/operand.rs index 2843cc442b..310ba15d8e 100644 --- a/macro/tests/operand.rs +++ b/macro/tests/operand.rs @@ -17,7 +17,7 @@ fn simple() { let r#type = Type::parse(&context, "i32").unwrap(); let block = Block::new(&[(r#type, location), (r#type, location)]); - let op = operand_test::simple( + let operation = operand_test::simple( &context, r#type, block.argument(0).unwrap().into(), @@ -25,9 +25,9 @@ fn simple() { location, ); - assert_eq!(op.lhs(&context).unwrap(), block.argument(0).unwrap().into()); - assert_eq!(op.rhs(&context).unwrap(), block.argument(1).unwrap().into()); - assert_eq!(op.operation().operand_count(), 2); + assert_eq!(operation.lhs().unwrap(), block.argument(0).unwrap().into()); + assert_eq!(operation.rhs().unwrap(), block.argument(1).unwrap().into()); + assert_eq!(operation.operation().operand_count(), 2); } #[test] @@ -39,7 +39,7 @@ fn variadic_after_single() { let r#type = Type::parse(&context, "i32").unwrap(); let block = Block::new(&[(r#type, location), (r#type, location), (r#type, location)]); - let op = operand_test::variadic( + let operation = operand_test::variadic( &context, r#type, block.argument(0).unwrap().into(), @@ -51,17 +51,17 @@ fn variadic_after_single() { ); assert_eq!( - op.first(&context).unwrap(), + operation.first().unwrap(), block.argument(0).unwrap().into() ); assert_eq!( - op.others(&context).next(), + operation.others().next(), Some(block.argument(2).unwrap().into()) ); assert_eq!( - op.others(&context).nth(1), + operation.others().nth(1), Some(block.argument(1).unwrap().into()) ); - assert_eq!(op.operation().operand_count(), 3); - assert_eq!(op.others(&context).count(), 2); + assert_eq!(operation.operation().operand_count(), 3); + assert_eq!(operation.others().count(), 2); } diff --git a/macro/tests/region.rs b/macro/tests/region.rs index 5a5fffcce2..16d89529cc 100644 --- a/macro/tests/region.rs +++ b/macro/tests/region.rs @@ -15,14 +15,11 @@ fn single() { let location = Location::unknown(&context); - let op = { - let block = Block::new(&[]); - let r1 = Region::new(); - r1.append_block(block); - region_test::single(&context, r1, location) - }; + let region = Region::new(); + region.append_block(Block::new(&[])); + let operation = region_test::single(&context, region, location); - assert!(op.default_region(&context).unwrap().first_block().is_some()); + assert!(operation.default_region().unwrap().first_block().is_some()); } #[test] @@ -32,11 +29,11 @@ fn variadic_after_single() { let location = Location::unknown(&context); - let op = { + let operation = { let block = Block::new(&[]); - let (r1, r2, r3) = (Region::new(), Region::new(), Region::new()); - r2.append_block(block); - region_test::variadic(&context, r1, vec![r2, r3], location) + let regions = (Region::new(), Region::new(), Region::new()); + regions.1.append_block(block); + region_test::variadic(&context, regions.0, vec![regions.1, regions.2], location) }; let op2 = { @@ -49,18 +46,21 @@ fn variadic_after_single() { .build() }; - assert_eq!(op.operation().to_string(), op2.operation().to_string()); + assert_eq!( + operation.operation().to_string(), + op2.operation().to_string() + ); - assert!(op.default_region(&context).unwrap().first_block().is_none()); - assert_eq!(op.other_regions(&context).count(), 2); - assert!(op - .other_regions(&context) + assert!(operation.default_region().unwrap().first_block().is_none()); + assert_eq!(operation.other_regions().count(), 2); + assert!(operation + .other_regions() .next() .unwrap() .first_block() .is_some()); - assert!(op - .other_regions(&context) + assert!(operation + .other_regions() .nth(1) .unwrap() .first_block() diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000000..4ada0663a0 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "stable" +components = ["clippy", "rustfmt", "rust-analyzer", "rust-src"] From e6da40056be72f587c714c188f74806788879a10 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sat, 17 Feb 2024 22:44:52 +0900 Subject: [PATCH 066/108] Refactor attribute accessor macros (#433) - **Refactor attribute accessor error handling** --- macro/src/dialect/generation.rs | 2 +- .../dialect/generation/attribute_accessor.rs | 44 +++++++++---------- macro/src/dialect/operation/attribute.rs | 12 +++++ 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/macro/src/dialect/generation.rs b/macro/src/dialect/generation.rs index 2968dfcf63..f3c9428cfd 100644 --- a/macro/src/dialect/generation.rs +++ b/macro/src/dialect/generation.rs @@ -50,7 +50,7 @@ pub fn generate_operation(operation: &Operation) -> Result { let attribute_accessors = operation .attributes() .map(generate_attribute_accessors) - .collect::, _>>()?; + .collect::>(); let builder = OperationBuilder::new(operation)?; let builder_tokens = generate_operation_builder(&builder)?; diff --git a/macro/src/dialect/generation/attribute_accessor.rs b/macro/src/dialect/generation/attribute_accessor.rs index 67a2e5112a..32a229ca58 100644 --- a/macro/src/dialect/generation/attribute_accessor.rs +++ b/macro/src/dialect/generation/attribute_accessor.rs @@ -1,24 +1,20 @@ -use crate::dialect::{ - error::Error, - operation::{Attribute, OperationField}, - utility::sanitize_snake_case_identifier, -}; +use crate::dialect::operation::{Attribute, OperationField}; use proc_macro2::TokenStream; use quote::quote; -pub fn generate_attribute_accessors(attribute: &Attribute) -> Result { - let getter = generate_getter(attribute)?; - let setter = generate_setter(attribute)?; - let remover = generate_remover(attribute)?; +pub fn generate_attribute_accessors(attribute: &Attribute) -> TokenStream { + let getter = generate_getter(attribute); + let setter = generate_setter(attribute); + let remover = generate_remover(attribute); - Ok(quote! { + quote! { #getter #setter #remover - }) + } } -fn generate_getter(attribute: &Attribute) -> Result { +fn generate_getter(attribute: &Attribute) -> TokenStream { let name = attribute.name(); let identifier = attribute.singular_identifier(); @@ -30,15 +26,15 @@ fn generate_getter(attribute: &Attribute) -> Result { quote! { Ok(self.operation.attribute(#name)?.try_into()?) } }; - Ok(quote! { + quote! { #[allow(clippy::needless_question_mark)] pub fn #identifier(&self) -> #return_type { #body } - }) + } } -fn generate_setter(attribute: &Attribute) -> Result { +fn generate_setter(attribute: &Attribute) -> TokenStream { let name = attribute.name(); let body = if attribute.is_unit() { @@ -55,27 +51,27 @@ fn generate_setter(attribute: &Attribute) -> Result { } }; - let ident = sanitize_snake_case_identifier(&format!("set_{}", attribute.name()))?; + let identifier = attribute.set_identifier(); let r#type = attribute.parameter_type(); - Ok(quote! { - pub fn #ident(&mut self, context: &'c ::melior::Context, value: #r#type) { + quote! { + pub fn #identifier(&mut self, context: &'c ::melior::Context, value: #r#type) { #body } - }) + } } -fn generate_remover(attribute: &Attribute) -> Result, Error> { - Ok(if attribute.is_unit() || attribute.is_optional() { +fn generate_remover(attribute: &Attribute) -> Option { + if attribute.is_unit() || attribute.is_optional() { let name = attribute.name(); - let ident = sanitize_snake_case_identifier(&format!("remove_{}", attribute.name()))?; + let identifier = attribute.remove_identifier(); Some(quote! { - pub fn #ident(&mut self, context: &'c ::melior::Context) -> Result<(), ::melior::Error> { + pub fn #identifier(&mut self, context: &'c ::melior::Context) -> Result<(), ::melior::Error> { self.operation.remove_attribute(#name) } }) } else { None - }) + } } diff --git a/macro/src/dialect/operation/attribute.rs b/macro/src/dialect/operation/attribute.rs index 341cfddbb4..c4cc29dba9 100644 --- a/macro/src/dialect/operation/attribute.rs +++ b/macro/src/dialect/operation/attribute.rs @@ -62,6 +62,8 @@ pub struct Attribute<'a> { name: &'a str, singular_identifier: Ident, storage_type_string: String, + set_identifier: Ident, + remove_identifier: Ident, storage_type: Type, optional: bool, default: bool, @@ -74,6 +76,8 @@ impl<'a> Attribute<'a> { Ok(Self { name, singular_identifier: sanitize_snake_case_identifier(name)?, + set_identifier: sanitize_snake_case_identifier(&format!("set_{name}"))?, + remove_identifier: sanitize_snake_case_identifier(&format!("remove_{name}"))?, storage_type: syn::parse_str( ATTRIBUTE_TYPES .get(storage_type_string.trim()) @@ -96,6 +100,14 @@ impl<'a> Attribute<'a> { }) } + pub fn set_identifier(&self) -> &Ident { + &self.set_identifier + } + + pub fn remove_identifier(&self) -> &Ident { + &self.remove_identifier + } + pub fn is_optional(&self) -> bool { self.optional } From e2d56443b8abb40aef57a96b937677bba076edeb Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sat, 17 Feb 2024 22:51:15 +0900 Subject: [PATCH 067/108] Remove more `context` arguments (#434) - **Remove more `context` arguments** --- macro/src/dialect/generation/attribute_accessor.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/macro/src/dialect/generation/attribute_accessor.rs b/macro/src/dialect/generation/attribute_accessor.rs index 32a229ca58..f6c4a7151b 100644 --- a/macro/src/dialect/generation/attribute_accessor.rs +++ b/macro/src/dialect/generation/attribute_accessor.rs @@ -55,7 +55,7 @@ fn generate_setter(attribute: &Attribute) -> TokenStream { let r#type = attribute.parameter_type(); quote! { - pub fn #identifier(&mut self, context: &'c ::melior::Context, value: #r#type) { + pub fn #identifier(&mut self, value: #r#type) { #body } } @@ -67,7 +67,7 @@ fn generate_remover(attribute: &Attribute) -> Option { let identifier = attribute.remove_identifier(); Some(quote! { - pub fn #identifier(&mut self, context: &'c ::melior::Context) -> Result<(), ::melior::Error> { + pub fn #identifier(&mut self) -> Result<(), ::melior::Error> { self.operation.remove_attribute(#name) } }) From b8b284b72aa6d7955b227ab06dce5ac6712c65eb Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sat, 17 Feb 2024 23:14:03 +0900 Subject: [PATCH 068/108] Fix method names (#435) --- macro/src/dialect/generation.rs | 4 +++- .../dialect/generation/operation_builder.rs | 4 +++- macro/tests/operand.rs | 4 ++-- macro/tests/region.rs | 20 +++++++++++-------- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/macro/src/dialect/generation.rs b/macro/src/dialect/generation.rs index f3c9428cfd..541fb4fa3b 100644 --- a/macro/src/dialect/generation.rs +++ b/macro/src/dialect/generation.rs @@ -66,11 +66,13 @@ pub fn generate_operation(operation: &Operation) -> Result { } impl<'c> #class_name<'c> { + /// Returns a name. pub fn name() -> &'static str { #name } - pub fn operation(&self) -> &::melior::ir::operation::Operation<'c> { + /// Returns a generic operation. + pub fn as_operation(&self) -> &::melior::ir::operation::Operation<'c> { &self.operation } diff --git a/macro/src/dialect/generation/operation_builder.rs b/macro/src/dialect/generation/operation_builder.rs index 37eca0aa87..bb9df3d4af 100644 --- a/macro/src/dialect/generation/operation_builder.rs +++ b/macro/src/dialect/generation/operation_builder.rs @@ -53,6 +53,7 @@ pub fn generate_operation_builder(builder: &OperationBuilder) -> Result TokenStream let arguments = builder.type_state().arguments_all_set(false); quote! { + /// Creates a builder. pub fn builder( context: &'c ::melior::Context, location: ::melior::ir::Location<'c> - ) -> #builder_ident<'c, #(#arguments),*> { + ) -> #builder_ident<'c, #(#arguments),*> { #builder_ident::new(context, location) } } diff --git a/macro/tests/operand.rs b/macro/tests/operand.rs index 310ba15d8e..52c1c15280 100644 --- a/macro/tests/operand.rs +++ b/macro/tests/operand.rs @@ -27,7 +27,7 @@ fn simple() { assert_eq!(operation.lhs().unwrap(), block.argument(0).unwrap().into()); assert_eq!(operation.rhs().unwrap(), block.argument(1).unwrap().into()); - assert_eq!(operation.operation().operand_count(), 2); + assert_eq!(operation.as_operation().operand_count(), 2); } #[test] @@ -62,6 +62,6 @@ fn variadic_after_single() { operation.others().nth(1), Some(block.argument(1).unwrap().into()) ); - assert_eq!(operation.operation().operand_count(), 3); + assert_eq!(operation.as_operation().operand_count(), 3); assert_eq!(operation.others().count(), 2); } diff --git a/macro/tests/region.rs b/macro/tests/region.rs index 16d89529cc..c91981c871 100644 --- a/macro/tests/region.rs +++ b/macro/tests/region.rs @@ -29,14 +29,14 @@ fn variadic_after_single() { let location = Location::unknown(&context); - let operation = { + let one_operation = { let block = Block::new(&[]); let regions = (Region::new(), Region::new(), Region::new()); regions.1.append_block(block); region_test::variadic(&context, regions.0, vec![regions.1, regions.2], location) }; - let op2 = { + let other_operation = { let block = Block::new(&[]); let (r1, r2, r3) = (Region::new(), Region::new(), Region::new()); r2.append_block(block); @@ -47,19 +47,23 @@ fn variadic_after_single() { }; assert_eq!( - operation.operation().to_string(), - op2.operation().to_string() + one_operation.as_operation().to_string(), + other_operation.as_operation().to_string() ); - assert!(operation.default_region().unwrap().first_block().is_none()); - assert_eq!(operation.other_regions().count(), 2); - assert!(operation + assert!(one_operation + .default_region() + .unwrap() + .first_block() + .is_none()); + assert_eq!(one_operation.other_regions().count(), 2); + assert!(one_operation .other_regions() .next() .unwrap() .first_block() .is_some()); - assert!(operation + assert!(one_operation .other_regions() .nth(1) .unwrap() From adec6aed54f6bcb2247918d47f305c326233103a Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sat, 17 Feb 2024 23:29:38 +0900 Subject: [PATCH 069/108] Remove some todos (#437) - **Remove done todo** --- melior/src/dialect.rs | 20 ++++++++++++++++---- melior/src/string_ref.rs | 4 ---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/melior/src/dialect.rs b/melior/src/dialect.rs index a7cafbd2d3..098106b186 100644 --- a/melior/src/dialect.rs +++ b/melior/src/dialect.rs @@ -16,7 +16,7 @@ use crate::{ string_ref::StringRef, }; use mlir_sys::{mlirDialectEqual, mlirDialectGetContext, mlirDialectGetNamespace, MlirDialect}; -use std::marker::PhantomData; +use std::{marker::PhantomData, str::Utf8Error}; #[cfg(feature = "ods-dialects")] pub mod ods; @@ -35,9 +35,8 @@ impl<'c> Dialect<'c> { } /// Gets a namespace. - // TODO Return &str. - pub fn namespace(&self) -> StringRef { - unsafe { StringRef::from_raw(mlirDialectGetNamespace(self.raw)) } + pub fn namespace(&self) -> Result<&str, Utf8Error> { + unsafe { StringRef::from_raw(mlirDialectGetNamespace(self.raw)) }.as_str() } /// Creates a dialect from a raw object. @@ -65,6 +64,19 @@ impl<'c> Eq for Dialect<'c> {} mod tests { use super::*; + #[test] + fn namespace() { + let context = Context::new(); + + assert_eq!( + DialectHandle::llvm() + .load_dialect(&context) + .namespace() + .unwrap(), + "llvm" + ); + } + #[test] fn equal() { let context = Context::new(); diff --git a/melior/src/string_ref.rs b/melior/src/string_ref.rs index 159ca3db7f..dfc2783338 100644 --- a/melior/src/string_ref.rs +++ b/melior/src/string_ref.rs @@ -7,10 +7,6 @@ use std::{ }; /// A string reference. -// https://mlir.llvm.org/docs/CAPI/#stringref -// -// TODO The documentation says string refs do not have to be null-terminated. -// But it looks like some functions do not handle strings not null-terminated? #[derive(Clone, Copy, Debug)] pub struct StringRef<'a> { raw: MlirStringRef, From 07a3b7d16738a408d8343c386db85c8b37a081a1 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sat, 17 Feb 2024 23:51:21 +0900 Subject: [PATCH 070/108] Remove "new" in documentation (#438) - **Remove new** --- macro/src/dialect/generation/operation_builder.rs | 2 +- melior/src/pass/external.rs | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/macro/src/dialect/generation/operation_builder.rs b/macro/src/dialect/generation/operation_builder.rs index bb9df3d4af..52eae9c6a6 100644 --- a/macro/src/dialect/generation/operation_builder.rs +++ b/macro/src/dialect/generation/operation_builder.rs @@ -185,7 +185,7 @@ pub fn generate_default_constructor(builder: &OperationBuilder) -> Result>(); - let doc = format!("Creates a new {}", builder.operation().summary()?); + let doc = format!("Creates a {}", builder.operation().summary()?); Ok(quote! { #[allow(clippy::too_many_arguments)] diff --git a/melior/src/pass/external.rs b/melior/src/pass/external.rs index ee4f0daa75..75fcff454a 100644 --- a/melior/src/pass/external.rs +++ b/melior/src/pass/external.rs @@ -56,24 +56,25 @@ unsafe extern "C" fn callback_destruct<'a, T: RunExternalPass<'a>>(pass: *mut T) } unsafe extern "C" fn callback_initialize<'a, T: RunExternalPass<'a>>( - ctx: MlirContext, + context: MlirContext, pass: *mut T, ) -> MlirLogicalResult { pass.as_mut() .expect("pass should be valid when called") - .initialize(ContextRef::from_raw(ctx)); + .initialize(ContextRef::from_raw(context)); + MlirLogicalResult { value: 1 } } unsafe extern "C" fn callback_run<'a, T: RunExternalPass<'a>>( - op: MlirOperation, + operation: MlirOperation, mlir_pass: MlirExternalPass, pass: *mut T, ) { pass.as_mut() .expect("pass should be valid when called") .run( - OperationRef::from_raw(op), + OperationRef::from_raw(operation), ExternalPass::from_raw(mlir_pass), ) } From 16bb4ec504215a3030e9c02e653fdcc3a9d0205d Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 18 Feb 2024 01:00:01 +0900 Subject: [PATCH 071/108] Refactor builder logic (#442) - **Refactor builder logic** --- .../dialect/generation/operation_builder.rs | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/macro/src/dialect/generation/operation_builder.rs b/macro/src/dialect/generation/operation_builder.rs index 52eae9c6a6..2106879bcd 100644 --- a/macro/src/dialect/generation/operation_builder.rs +++ b/macro/src/dialect/generation/operation_builder.rs @@ -3,7 +3,6 @@ use crate::dialect::{ }; use proc_macro2::TokenStream; use quote::{format_ident, quote}; -use syn::Ident; pub fn generate_operation_builder(builder: &OperationBuilder) -> Result { let field_names = builder @@ -25,12 +24,12 @@ pub fn generate_operation_builder(builder: &OperationBuilder) -> Result>(); - let builder_fns = generate_field_fns(builder, &field_names, phantom_arguments.as_slice()); + let field_fns = generate_field_fns(builder, &phantom_arguments); - let new_fn = generate_new_fn(builder, phantom_arguments.as_slice())?; + let new_fn = generate_new_fn(builder, &phantom_arguments)?; let build_fn = generate_build_fn(builder)?; let builder_identifier = builder.identifier(); @@ -47,18 +46,14 @@ pub fn generate_operation_builder(builder: &OperationBuilder) -> Result Vec { +fn generate_field_fns(builder: &OperationBuilder, phantoms: &[TokenStream]) -> Vec { builder.operation().fields().map(move |field| { let builder_identifier = builder.identifier(); let identifier = field.singular_identifier(); @@ -91,12 +86,10 @@ fn generate_field_fns( quote! { impl<'c, #(#parameters),*> #builder_identifier<'c, #(#arguments_unset),*> { - pub fn #identifier(mut self, #argument) -> #builder_identifier<'c, #(#arguments_set),*> { - self.builder = self.builder.#add(#add_arguments); - let Self { context, mut builder, #(#field_names),* } = self; + pub fn #identifier(self, #argument) -> #builder_identifier<'c, #(#arguments_set),*> { #builder_identifier { - context, - builder, + context: self.context, + builder: self.builder.#add(#add_arguments), #(#phantoms),* } } From b538d3efb1e28a14975504cd1a4f62dff9f7bad0 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 18 Feb 2024 01:43:55 +0900 Subject: [PATCH 072/108] Tuple type state (#443) --- .../dialect/generation/operation_builder.rs | 45 +++++-------------- .../operation/builder/type_state_list.rs | 4 -- 2 files changed, 10 insertions(+), 39 deletions(-) diff --git a/macro/src/dialect/generation/operation_builder.rs b/macro/src/dialect/generation/operation_builder.rs index 2106879bcd..09e6320df2 100644 --- a/macro/src/dialect/generation/operation_builder.rs +++ b/macro/src/dialect/generation/operation_builder.rs @@ -5,43 +5,21 @@ use proc_macro2::TokenStream; use quote::{format_ident, quote}; pub fn generate_operation_builder(builder: &OperationBuilder) -> Result { - let field_names = builder - .type_state() - .field_names() - .map(sanitize_snake_case_identifier) - .collect::, _>>()?; - - let phantom_fields = - builder - .type_state() - .parameters() - .zip(&field_names) - .map(|(r#type, name)| { - quote! { - #name: ::std::marker::PhantomData<#r#type> - } - }); - - let phantom_arguments = field_names - .iter() - .map(|name| quote! { #name: Default::default() }) - .collect::>(); - - let field_fns = generate_field_fns(builder, &phantom_arguments); - - let new_fn = generate_new_fn(builder, &phantom_arguments)?; + let state_types = builder.type_state().parameters(); + let field_fns = generate_field_fns(builder); + let new_fn = generate_new_fn(builder)?; let build_fn = generate_build_fn(builder)?; - let builder_identifier = builder.identifier(); + let identifier = builder.identifier(); let doc = format!("A builder for {}", builder.operation().summary()?); let type_arguments = builder.type_state().parameters(); Ok(quote! { #[doc = #doc] - pub struct #builder_identifier<'c, #(#type_arguments),*> { + pub struct #identifier<'c, #(#type_arguments),*> { builder: ::melior::ir::operation::OperationBuilder<'c>, context: &'c ::melior::Context, - #(#phantom_fields),* + _state: ::std::marker::PhantomData<(#(#state_types),*)>, } #new_fn @@ -53,7 +31,7 @@ pub fn generate_operation_builder(builder: &OperationBuilder) -> Result Vec { +fn generate_field_fns(builder: &OperationBuilder) -> Vec { builder.operation().fields().map(move |field| { let builder_identifier = builder.identifier(); let identifier = field.singular_identifier(); @@ -90,7 +68,7 @@ fn generate_field_fns(builder: &OperationBuilder, phantoms: &[TokenStream]) -> V #builder_identifier { context: self.context, builder: self.builder.#add(#add_arguments), - #(#phantoms),* + _state: Default::default(), } } } @@ -118,10 +96,7 @@ fn generate_build_fn(builder: &OperationBuilder) -> Result { }) } -fn generate_new_fn( - builder: &OperationBuilder, - phantoms: &[TokenStream], -) -> Result { +fn generate_new_fn(builder: &OperationBuilder) -> Result { let builder_ident = builder.identifier(); let name = &builder.operation().full_name()?; let arguments = builder.type_state().arguments_all_set(false); @@ -132,7 +107,7 @@ fn generate_new_fn( Self { context, builder: ::melior::ir::operation::OperationBuilder::new( #name, location), - #(#phantoms),* + _state: Default::default(), } } } diff --git a/macro/src/dialect/operation/builder/type_state_list.rs b/macro/src/dialect/operation/builder/type_state_list.rs index 9fd358337c..fa4b7dc1c7 100644 --- a/macro/src/dialect/operation/builder/type_state_list.rs +++ b/macro/src/dialect/operation/builder/type_state_list.rs @@ -19,10 +19,6 @@ impl TypeStateList { } } - pub fn field_names(&self) -> impl Iterator { - self.items.iter().map(|item| item.field_name()) - } - pub fn parameters(&self) -> impl Iterator { self.items.iter().map(|item| item.generic_param()) } From ec313edf2b240389587e69afd60d53621e4222c3 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 18 Feb 2024 02:03:41 +0900 Subject: [PATCH 073/108] Refactor accessors (#444) - **Fix** --- macro/src/dialect/generation.rs | 8 +++--- .../dialect/generation/element_accessor.rs | 11 +++++++- .../dialect/generation/operand_accessor.rs | 26 ++++--------------- .../src/dialect/generation/region_accessor.rs | 2 +- .../src/dialect/generation/result_accessor.rs | 20 +++----------- .../dialect/generation/successor_accessor.rs | 2 +- 6 files changed, 25 insertions(+), 44 deletions(-) diff --git a/macro/src/dialect/generation.rs b/macro/src/dialect/generation.rs index 541fb4fa3b..8d98376a88 100644 --- a/macro/src/dialect/generation.rs +++ b/macro/src/dialect/generation.rs @@ -31,21 +31,21 @@ pub fn generate_operation(operation: &Operation) -> Result { .results() .enumerate() .map(|(index, result)| generate_result_accessor(result, index, operation.result_len())) - .collect::, _>>()?; + .collect::>(); let operand_accessors = operation .operands() .enumerate() .map(|(index, operand)| generate_operand_accessor(operand, index, operation.operand_len())) - .collect::, _>>()?; + .collect::>(); let region_accessors = operation .regions() .enumerate() - .map(|(index, region)| generate_region_accessor(index, region)) + .map(|(index, region)| generate_region_accessor(region, index)) .collect::>(); let successor_accessors = operation .successors() .enumerate() - .map(|(index, region)| generate_successor_accessor(index, region)) + .map(|(index, region)| generate_successor_accessor(region, index)) .collect::>(); let attribute_accessors = operation .attributes() diff --git a/macro/src/dialect/generation/element_accessor.rs b/macro/src/dialect/generation/element_accessor.rs index 62fa3aa8e6..a51fbf5cf5 100644 --- a/macro/src/dialect/generation/element_accessor.rs +++ b/macro/src/dialect/generation/element_accessor.rs @@ -16,7 +16,7 @@ pub fn generate_element_getter( let count = Ident::new(&format!("{singular_kind}_count"), Span::call_site()); let name = field.name(); - match field.variadic_kind() { + let body = match field.variadic_kind() { VariadicKind::Simple { unfixed_seen } => { if field.is_optional() { // Optional element, and some singular elements. @@ -110,5 +110,14 @@ pub fn generate_element_getter( #get_elements } } + }; + + let identifier = field.singular_identifier(); + let return_type = field.return_type(); + + quote! { + pub fn #identifier(&self) -> #return_type { + #body + } } } diff --git a/macro/src/dialect/generation/operand_accessor.rs b/macro/src/dialect/generation/operand_accessor.rs index 44d906ad6b..5cb22f5aac 100644 --- a/macro/src/dialect/generation/operand_accessor.rs +++ b/macro/src/dialect/generation/operand_accessor.rs @@ -1,30 +1,14 @@ use super::element_accessor::generate_element_getter; -use crate::dialect::{ - error::Error, - operation::{Operand, OperationField}, -}; +use crate::dialect::operation::Operand; use proc_macro2::{Ident, Span, TokenStream}; -use quote::quote; -pub fn generate_operand_accessor( - field: &Operand, - index: usize, - length: usize, -) -> Result { - let ident = field.singular_identifier(); - let return_type = field.return_type(); - let body = generate_element_getter( - field, +pub fn generate_operand_accessor(operand: &Operand, index: usize, length: usize) -> TokenStream { + generate_element_getter( + operand, "operand", "operands", &Ident::new("OperandNotFound", Span::call_site()), index, length, - ); - - Ok(quote! { - pub fn #ident(&self) -> #return_type { - #body - } - }) + ) } diff --git a/macro/src/dialect/generation/region_accessor.rs b/macro/src/dialect/generation/region_accessor.rs index 7852f9669b..b259ab9d10 100644 --- a/macro/src/dialect/generation/region_accessor.rs +++ b/macro/src/dialect/generation/region_accessor.rs @@ -2,7 +2,7 @@ use crate::dialect::operation::{OperationField, Region}; use proc_macro2::TokenStream; use quote::quote; -pub fn generate_region_accessor(index: usize, region: &Region) -> TokenStream { +pub fn generate_region_accessor(region: &Region, index: usize) -> TokenStream { let identifier = ®ion.singular_identifier(); let return_type = ®ion.return_type(); let body = if region.is_variadic() { diff --git a/macro/src/dialect/generation/result_accessor.rs b/macro/src/dialect/generation/result_accessor.rs index d6b284b829..a18beec720 100644 --- a/macro/src/dialect/generation/result_accessor.rs +++ b/macro/src/dialect/generation/result_accessor.rs @@ -1,30 +1,18 @@ use super::element_accessor::generate_element_getter; -use crate::dialect::{ - error::Error, - operation::{OperationField, OperationResult}, -}; +use crate::dialect::operation::OperationResult; use proc_macro2::{Ident, Span, TokenStream}; -use quote::quote; pub fn generate_result_accessor( result: &OperationResult, index: usize, length: usize, -) -> Result { - let identifier = result.singular_identifier(); - let return_type = result.return_type(); - let body = generate_element_getter( +) -> TokenStream { + generate_element_getter( result, "result", "results", &Ident::new("ResultNotFound", Span::call_site()), index, length, - ); - - Ok(quote! { - pub fn #identifier(&self) -> #return_type { - #body - } - }) + ) } diff --git a/macro/src/dialect/generation/successor_accessor.rs b/macro/src/dialect/generation/successor_accessor.rs index 1c4b1174a7..45a20bae98 100644 --- a/macro/src/dialect/generation/successor_accessor.rs +++ b/macro/src/dialect/generation/successor_accessor.rs @@ -2,7 +2,7 @@ use crate::dialect::operation::{OperationField, Successor}; use proc_macro2::TokenStream; use quote::quote; -pub fn generate_successor_accessor(index: usize, successor: &Successor) -> TokenStream { +pub fn generate_successor_accessor(successor: &Successor, index: usize) -> TokenStream { let identifier = successor.singular_identifier(); let return_type = successor.return_type(); let body = if successor.is_variadic() { From ef730089849929e06347f79f560491bed30e7d75 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 18 Feb 2024 02:54:37 +0900 Subject: [PATCH 074/108] Fix operation name (#436) --- macro/src/dialect/generation.rs | 18 ++++---- .../dialect/generation/operation_builder.rs | 22 +++++----- macro/src/dialect/operation.rs | 44 +++++++++++-------- macro/src/dialect/operation/builder.rs | 10 ++--- macro/tests/region.rs | 2 +- melior/src/dialect/ods.rs | 2 +- 6 files changed, 52 insertions(+), 46 deletions(-) diff --git a/macro/src/dialect/generation.rs b/macro/src/dialect/generation.rs index 8d98376a88..9737b14b35 100644 --- a/macro/src/dialect/generation.rs +++ b/macro/src/dialect/generation.rs @@ -24,8 +24,8 @@ use quote::{format_ident, quote}; pub fn generate_operation(operation: &Operation) -> Result { let summary = operation.summary()?; let description = operation.description()?; - let class_name = format_ident!("{}", operation.class_name()?); - let name = &operation.full_name()?; + let identifier = format_ident!("{}", operation.name()); + let operation_name = operation.full_operation_name()?; let result_accessors = operation .results() @@ -52,7 +52,7 @@ pub fn generate_operation(operation: &Operation) -> Result { .map(generate_attribute_accessors) .collect::>(); - let builder = OperationBuilder::new(operation)?; + let builder = OperationBuilder::new(operation); let builder_tokens = generate_operation_builder(&builder)?; let builder_fn = generate_operation_builder_fn(&builder); let default_constructor = generate_default_constructor(&builder)?; @@ -61,14 +61,14 @@ pub fn generate_operation(operation: &Operation) -> Result { #[doc = #summary] #[doc = "\n\n"] #[doc = #description] - pub struct #class_name<'c> { + pub struct #identifier<'c> { operation: ::melior::ir::operation::Operation<'c>, } - impl<'c> #class_name<'c> { + impl<'c> #identifier<'c> { /// Returns a name. pub fn name() -> &'static str { - #name + #operation_name } /// Returns a generic operation. @@ -89,7 +89,7 @@ pub fn generate_operation(operation: &Operation) -> Result { #default_constructor - impl<'c> TryFrom<::melior::ir::operation::Operation<'c>> for #class_name<'c> { + impl<'c> TryFrom<::melior::ir::operation::Operation<'c>> for #identifier<'c> { type Error = ::melior::Error; fn try_from( @@ -100,8 +100,8 @@ pub fn generate_operation(operation: &Operation) -> Result { } } - impl<'c> From<#class_name<'c>> for ::melior::ir::operation::Operation<'c> { - fn from(operation: #class_name<'c>) -> ::melior::ir::operation::Operation<'c> { + impl<'c> From<#identifier<'c>> for ::melior::ir::operation::Operation<'c> { + fn from(operation: #identifier<'c>) -> Self { operation.operation } } diff --git a/macro/src/dialect/generation/operation_builder.rs b/macro/src/dialect/generation/operation_builder.rs index 09e6320df2..618b9898ea 100644 --- a/macro/src/dialect/generation/operation_builder.rs +++ b/macro/src/dialect/generation/operation_builder.rs @@ -78,18 +78,18 @@ fn generate_field_fns(builder: &OperationBuilder) -> Vec { } fn generate_build_fn(builder: &OperationBuilder) -> Result { - let builder_ident = builder.identifier(); + let builder_identifier = builder.identifier(); let arguments = builder.type_state().arguments_all_set(true); - let class_name = format_ident!("{}", &builder.operation().class_name()?); - let error = format!("should be a valid {class_name}"); + let operation_identifier = format_ident!("{}", &builder.operation().name()); + let error = format!("should be a valid {operation_identifier}"); let maybe_infer = builder .operation() .can_infer_type() .then_some(quote! { .enable_result_type_inference() }); Ok(quote! { - impl<'c> #builder_ident<'c, #(#arguments),*> { - pub fn build(self) -> #class_name<'c> { + impl<'c> #builder_identifier<'c, #(#arguments),*> { + pub fn build(self) -> #operation_identifier<'c> { self.builder #maybe_infer.build().expect("valid operation").try_into().expect(#error) } } @@ -98,7 +98,7 @@ fn generate_build_fn(builder: &OperationBuilder) -> Result { fn generate_new_fn(builder: &OperationBuilder) -> Result { let builder_ident = builder.identifier(); - let name = &builder.operation().full_name()?; + let name = &builder.operation().full_operation_name()?; let arguments = builder.type_state().arguments_all_set(false); Ok(quote! { @@ -106,7 +106,7 @@ fn generate_new_fn(builder: &OperationBuilder) -> Result { pub fn new(context: &'c ::melior::Context, location: ::melior::ir::Location<'c>) -> Self { Self { context, - builder: ::melior::ir::operation::OperationBuilder::new( #name, location), + builder: ::melior::ir::operation::OperationBuilder::new(#name, location), _state: Default::default(), } } @@ -130,8 +130,8 @@ pub fn generate_operation_builder_fn(builder: &OperationBuilder) -> TokenStream } pub fn generate_default_constructor(builder: &OperationBuilder) -> Result { - let class_name = format_ident!("{}", &builder.operation().class_name()?); - let name = sanitize_snake_case_identifier(builder.operation().short_name()?)?; + let identifier = format_ident!("{}", &builder.operation().name()); + let name = sanitize_snake_case_identifier(builder.operation().operation_name()?)?; let arguments = builder .operation() .required_fields() @@ -158,8 +158,8 @@ pub fn generate_default_constructor(builder: &OperationBuilder) -> Result(context: &'c ::melior::Context, #(#arguments),*) -> #class_name<'c> { - #class_name::builder(context, location)#(#builder_calls)*.build() + pub fn #name<'c>(context: &'c ::melior::Context, #(#arguments),*) -> #identifier<'c> { + #identifier::builder(context, location)#(#builder_calls)*.build() } }) } diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 9f6c48dfeb..36944b687e 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -25,6 +25,7 @@ use tblgen::{error::WithLocation, record::Record, TypedInit}; #[derive(Debug)] pub struct Operation<'a> { definition: Record<'a>, + name: String, can_infer_type: bool, regions: Vec>, successors: Vec>, @@ -48,6 +49,7 @@ impl<'a> Operation<'a> { )?; Ok(Self { + name: Self::build_name(definition)?, successors: Self::collect_successors(definition)?, operands: Self::collect_operands( &arguments, @@ -69,6 +71,23 @@ impl<'a> Operation<'a> { }) } + fn build_name(definition: Record) -> Result { + let name = definition.name()?; + + Ok(if let Some((_, name)) = name.split_once('_') { + name + } else { + name + } + .trim_end_matches("Op") + .to_owned() + + "Operation") + } + + pub fn name(&self) -> &str { + &self.name + } + pub fn can_infer_type(&self) -> bool { self.can_infer_type } @@ -81,26 +100,13 @@ impl<'a> Operation<'a> { Ok(self.dialect()?.name()?) } - pub fn class_name(&self) -> Result<&str, Error> { - let name = self.definition.name()?; - - Ok(if name.starts_with('_') { - name - } else if let Some(name) = name.split('_').nth(1) { - // Trim dialect prefix from name. - name - } else { - name - }) - } - - pub fn short_name(&self) -> Result<&str, Error> { + pub fn operation_name(&self) -> Result<&str, Error> { Ok(self.definition.str_value("opName")?) } - pub fn full_name(&self) -> Result { + pub fn full_operation_name(&self) -> Result { let dialect_name = self.dialect()?.string_value("name")?; - let short_name = self.short_name()?; + let short_name = self.operation_name()?; Ok(if dialect_name.is_empty() { short_name.into() @@ -110,12 +116,12 @@ impl<'a> Operation<'a> { } pub fn summary(&self) -> Result { - let short_name = self.short_name()?; - let class_name = self.class_name()?; + let short_name = self.operation_name()?; + let name = &self.name; let summary = self.definition.str_value("summary")?; Ok([ - format!("[`{short_name}`]({class_name}) operation."), + format!("[`{short_name}`]({name}) operation."), if summary.is_empty() { Default::default() } else { diff --git a/macro/src/dialect/operation/builder.rs b/macro/src/dialect/operation/builder.rs index 5049fb8c7f..679fce99dd 100644 --- a/macro/src/dialect/operation/builder.rs +++ b/macro/src/dialect/operation/builder.rs @@ -2,7 +2,7 @@ mod type_state_item; mod type_state_list; use self::{type_state_item::TypeStateItem, type_state_list::TypeStateList}; -use super::{super::error::Error, Operation}; +use super::Operation; use quote::format_ident; use syn::Ident; @@ -13,12 +13,12 @@ pub struct OperationBuilder<'a> { } impl<'a> OperationBuilder<'a> { - pub fn new(operation: &'a Operation<'a>) -> Result { - Ok(Self { + pub fn new(operation: &'a Operation<'a>) -> Self { + Self { operation, - identifier: format_ident!("{}Builder", operation.class_name()?), + identifier: format_ident!("{}Builder", operation.name()), type_state: Self::create_type_state(operation), - }) + } } pub fn operation(&self) -> &Operation { diff --git a/macro/tests/region.rs b/macro/tests/region.rs index c91981c871..c6e021fa99 100644 --- a/macro/tests/region.rs +++ b/macro/tests/region.rs @@ -40,7 +40,7 @@ fn variadic_after_single() { let block = Block::new(&[]); let (r1, r2, r3) = (Region::new(), Region::new(), Region::new()); r2.append_block(block); - region_test::VariadicOp::builder(&context, location) + region_test::VariadicOperation::builder(&context, location) .default_region(r1) .other_regions(vec![r2, r3]) .build() diff --git a/melior/src/dialect/ods.rs b/melior/src/dialect/ods.rs index 43322430c0..c028f2869e 100644 --- a/melior/src/dialect/ods.rs +++ b/melior/src/dialect/ods.rs @@ -216,7 +216,7 @@ mod tests { let i64_type = IntegerType::new(&context, 64); block.append_operation( - llvm::AllocaOpBuilder::new(&context, location) + llvm::AllocaOperationBuilder::new(&context, location) .alignment(IntegerAttribute::new(8, i64_type.into())) .elem_type(TypeAttribute::new(i64_type.into())) .array_size(alloca_size) From 1ad5a68fc14b89d0500adbd97327aaaf449f0f56 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 18 Feb 2024 18:56:41 +0900 Subject: [PATCH 075/108] Refactor dialect build job (#446) --- .github/workflows/test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 4637491134..8432ccfed4 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -44,9 +44,9 @@ jobs: - uses: homebrew/actions/setup-homebrew@master - run: tools/setup.sh - run: cargo install cargo-expand - - run: cd melior && cargo expand --features ods-dialects > ~/current.rs + - run: cd melior && cargo expand --all-features dialect::ods > ~/current.rs - uses: actions/checkout@v4 with: ref: main - - run: cd melior && cargo expand --features ods-dialects > ~/main.rs + - run: cd melior && cargo expand --all-features dialect::ods > ~/main.rs - run: diff ~/main.rs ~/current.rs From 30eaeb5c13887e5866479e692ebc92cee627a5ef Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 18 Feb 2024 19:10:50 +0900 Subject: [PATCH 076/108] Update operation documentation (#445) - **Update operation documentation** --- macro/src/dialect/generation.rs | 4 +- .../dialect/generation/element_accessor.rs | 22 ++++----- .../dialect/generation/operation_builder.rs | 19 ++++---- macro/src/dialect/operation.rs | 45 ++++++++++--------- 4 files changed, 49 insertions(+), 41 deletions(-) diff --git a/macro/src/dialect/generation.rs b/macro/src/dialect/generation.rs index 9737b14b35..317552b690 100644 --- a/macro/src/dialect/generation.rs +++ b/macro/src/dialect/generation.rs @@ -22,10 +22,10 @@ use proc_macro2::TokenStream; use quote::{format_ident, quote}; pub fn generate_operation(operation: &Operation) -> Result { - let summary = operation.summary()?; + let summary = operation.summary(); let description = operation.description()?; let identifier = format_ident!("{}", operation.name()); - let operation_name = operation.full_operation_name()?; + let operation_name = operation.full_operation_name(); let result_accessors = operation .results() diff --git a/macro/src/dialect/generation/element_accessor.rs b/macro/src/dialect/generation/element_accessor.rs index a51fbf5cf5..371c888f8b 100644 --- a/macro/src/dialect/generation/element_accessor.rs +++ b/macro/src/dialect/generation/element_accessor.rs @@ -11,8 +11,8 @@ pub fn generate_element_getter( index: usize, length: usize, ) -> TokenStream { - let kind_singular_identifier = Ident::new(singular_kind, Span::call_site()); - let kind_plural_identifier = Ident::new(plural_kind, Span::call_site()); + let singular_kind_identifier = Ident::new(singular_kind, Span::call_site()); + let plural_kind_identifier = Ident::new(plural_kind, Span::call_site()); let count = Ident::new(&format!("{singular_kind}_count"), Span::call_site()); let name = field.name(); @@ -26,7 +26,7 @@ pub fn generate_element_getter( if self.operation.#count() < #length { Err(::melior::Error::#error_variant(#name)) } else { - self.operation.#kind_singular_identifier(#index) + self.operation.#singular_kind_identifier(#index) } } } else if field.is_variadic() { @@ -35,19 +35,19 @@ pub fn generate_element_getter( // singular elements from the number of elements. quote! { let group_length = self.operation.#count() - #length + 1; - self.operation.#kind_plural_identifier().skip(#index).take(group_length) + self.operation.#plural_kind_identifier().skip(#index).take(group_length) } } else if *unfixed_seen { // Single element after unfixed group // Compute the length of that variable group and take the next element quote! { let group_length = self.operation.#count() - #length + 1; - self.operation.#kind_singular_identifier(#index + group_length - 1) + self.operation.#singular_kind_identifier(#index + group_length - 1) } } else { // All elements so far are singular quote! { - self.operation.#kind_singular_identifier(#index) + self.operation.#singular_kind_identifier(#index) } } } @@ -58,11 +58,11 @@ pub fn generate_element_getter( } => { let get_elements = if field.is_unfixed() { quote! { - self.operation.#kind_plural_identifier().skip(start).take(group_len) + self.operation.#plural_kind_identifier().skip(start).take(group_len) } } else { quote! { - self.operation.#kind_singular_identifier(start) + self.operation.#singular_kind_identifier(start) } }; @@ -78,19 +78,19 @@ pub fn generate_element_getter( let segment_size_attribute = format!("{singular_kind}_segment_sizes"); let get_elements = if !field.is_unfixed() { quote! { - self.operation.#kind_singular_identifier(start) + self.operation.#singular_kind_identifier(start) } } else if field.is_optional() { quote! { if group_len == 0 { Err(::melior::Error::#error_variant(#name)) } else { - self.operation.#kind_singular_identifier(start) + self.operation.#singular_kind_identifier(start) } } } else { quote! { - Ok(self.operation.#kind_plural_identifier().skip(start).take(group_len)) + Ok(self.operation.#plural_kind_identifier().skip(start).take(group_len)) } }; diff --git a/macro/src/dialect/generation/operation_builder.rs b/macro/src/dialect/generation/operation_builder.rs index 618b9898ea..a69e0c87c1 100644 --- a/macro/src/dialect/generation/operation_builder.rs +++ b/macro/src/dialect/generation/operation_builder.rs @@ -7,11 +7,14 @@ use quote::{format_ident, quote}; pub fn generate_operation_builder(builder: &OperationBuilder) -> Result { let state_types = builder.type_state().parameters(); let field_fns = generate_field_fns(builder); - let new_fn = generate_new_fn(builder)?; + let new_fn = generate_new_fn(builder); let build_fn = generate_build_fn(builder)?; let identifier = builder.identifier(); - let doc = format!("A builder for {}", builder.operation().summary()?); + let doc = format!( + "A builder for {}.", + builder.operation().documentation_name() + ); let type_arguments = builder.type_state().parameters(); Ok(quote! { @@ -96,12 +99,12 @@ fn generate_build_fn(builder: &OperationBuilder) -> Result { }) } -fn generate_new_fn(builder: &OperationBuilder) -> Result { +fn generate_new_fn(builder: &OperationBuilder) -> TokenStream { let builder_ident = builder.identifier(); - let name = &builder.operation().full_operation_name()?; + let name = &builder.operation().full_operation_name(); let arguments = builder.type_state().arguments_all_set(false); - Ok(quote! { + quote! { impl<'c> #builder_ident<'c, #(#arguments),*> { pub fn new(context: &'c ::melior::Context, location: ::melior::ir::Location<'c>) -> Self { Self { @@ -111,7 +114,7 @@ fn generate_new_fn(builder: &OperationBuilder) -> Result { } } } - }) + } } pub fn generate_operation_builder_fn(builder: &OperationBuilder) -> TokenStream { @@ -131,7 +134,7 @@ pub fn generate_operation_builder_fn(builder: &OperationBuilder) -> TokenStream pub fn generate_default_constructor(builder: &OperationBuilder) -> Result { let identifier = format_ident!("{}", &builder.operation().name()); - let name = sanitize_snake_case_identifier(builder.operation().operation_name()?)?; + let name = sanitize_snake_case_identifier(builder.operation().operation_name())?; let arguments = builder .operation() .required_fields() @@ -153,7 +156,7 @@ pub fn generate_default_constructor(builder: &OperationBuilder) -> Result>(); - let doc = format!("Creates a {}", builder.operation().summary()?); + let doc = format!("Creates {}.", builder.operation().documentation_name()); Ok(quote! { #[allow(clippy::too_many_arguments)] diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 36944b687e..a5df6bb1cf 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -26,6 +26,9 @@ use tblgen::{error::WithLocation, record::Record, TypedInit}; pub struct Operation<'a> { definition: Record<'a>, name: String, + dialect_name: &'a str, + operation_name: &'a str, + summary: String, can_infer_type: bool, regions: Vec>, successors: Vec>, @@ -50,6 +53,9 @@ impl<'a> Operation<'a> { Ok(Self { name: Self::build_name(definition)?, + dialect_name: definition.def_value("opDialect")?.str_value("name")?, + operation_name: definition.str_value("opName")?, + summary: definition.str_value("summary")?.into(), successors: Self::collect_successors(definition)?, operands: Self::collect_operands( &arguments, @@ -100,35 +106,34 @@ impl<'a> Operation<'a> { Ok(self.dialect()?.name()?) } - pub fn operation_name(&self) -> Result<&str, Error> { - Ok(self.definition.str_value("opName")?) + pub fn operation_name(&self) -> &str { + self.operation_name } - pub fn full_operation_name(&self) -> Result { - let dialect_name = self.dialect()?.string_value("name")?; - let short_name = self.operation_name()?; - - Ok(if dialect_name.is_empty() { - short_name.into() + pub fn full_operation_name(&self) -> String { + if self.dialect_name.is_empty() { + self.operation_name.into() } else { - format!("{dialect_name}.{short_name}") - }) + format!("{}.{}", self.dialect_name, self.operation_name) + } } - pub fn summary(&self) -> Result { - let short_name = self.operation_name()?; - let name = &self.name; - let summary = self.definition.str_value("summary")?; + pub fn documentation_name(&self) -> String { + format!("a(n) [`{}`]({}) operation", self.operation_name, &self.name) + } + + pub fn summary(&self) -> String { + let name = self.documentation_name(); - Ok([ - format!("[`{short_name}`]({name}) operation."), - if summary.is_empty() { + format!( + "{}. {}", + name[..1].to_uppercase() + &name[1..], + if self.summary.is_empty() { Default::default() } else { - summary[0..1].to_uppercase() + &summary[1..] + "." + self.summary.to_owned() + "." }, - ] - .join(" ")) + ) } pub fn description(&self) -> Result { From 0c8515fd249aab6ce4a08323cf9d6659b61e4adc Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 18 Feb 2024 19:25:25 +0900 Subject: [PATCH 077/108] Fix capitalization in documentation (#447) --- macro/src/dialect/operation.rs | 11 +++++------ macro/src/dialect/utility.rs | 13 +++++++++++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index a5df6bb1cf..2e089a0b08 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -18,6 +18,7 @@ use crate::dialect::{ error::{Error, OdsError}, r#trait::Trait, r#type::Type, + utility::capitalize_string, }; pub use operation_field::OperationField; use tblgen::{error::WithLocation, record::Record, TypedInit}; @@ -28,7 +29,7 @@ pub struct Operation<'a> { name: String, dialect_name: &'a str, operation_name: &'a str, - summary: String, + summary: &'a str, can_infer_type: bool, regions: Vec>, successors: Vec>, @@ -55,7 +56,7 @@ impl<'a> Operation<'a> { name: Self::build_name(definition)?, dialect_name: definition.def_value("opDialect")?.str_value("name")?, operation_name: definition.str_value("opName")?, - summary: definition.str_value("summary")?.into(), + summary: definition.str_value("summary")?, successors: Self::collect_successors(definition)?, operands: Self::collect_operands( &arguments, @@ -123,15 +124,13 @@ impl<'a> Operation<'a> { } pub fn summary(&self) -> String { - let name = self.documentation_name(); - format!( "{}. {}", - name[..1].to_uppercase() + &name[1..], + capitalize_string(&self.documentation_name()), if self.summary.is_empty() { Default::default() } else { - self.summary.to_owned() + "." + capitalize_string(self.summary) + "." }, ) } diff --git a/macro/src/dialect/utility.rs b/macro/src/dialect/utility.rs index 90b45fa558..de70d79af8 100644 --- a/macro/src/dialect/utility.rs +++ b/macro/src/dialect/utility.rs @@ -65,6 +65,14 @@ pub fn sanitize_documentation(string: &str) -> Result { Ok(String::from_utf8(buffer)?) } +pub fn capitalize_string(string: &str) -> String { + if string.is_empty() { + "".into() + } else { + string[..1].to_uppercase() + &string[1..] + } +} + #[cfg(test)] mod tests { use super::*; @@ -109,4 +117,9 @@ mod tests { "``` text\nfoo\n```\n\n``` text\nbar\n```\n" ); } + + #[test] + fn capitalize() { + assert_eq!(&capitalize_string("foo"), "Foo"); + } } From d94d23c87595cb5e35692d265cee4ae940e2dd3e Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 18 Feb 2024 19:30:57 +0900 Subject: [PATCH 078/108] Refactor variable names (#448) - **Refactor** --- macro/src/dialect/generation/operation_builder.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/macro/src/dialect/generation/operation_builder.rs b/macro/src/dialect/generation/operation_builder.rs index a69e0c87c1..44a627acfd 100644 --- a/macro/src/dialect/generation/operation_builder.rs +++ b/macro/src/dialect/generation/operation_builder.rs @@ -81,7 +81,7 @@ fn generate_field_fns(builder: &OperationBuilder) -> Vec { } fn generate_build_fn(builder: &OperationBuilder) -> Result { - let builder_identifier = builder.identifier(); + let identifier = builder.identifier(); let arguments = builder.type_state().arguments_all_set(true); let operation_identifier = format_ident!("{}", &builder.operation().name()); let error = format!("should be a valid {operation_identifier}"); @@ -91,7 +91,7 @@ fn generate_build_fn(builder: &OperationBuilder) -> Result { .then_some(quote! { .enable_result_type_inference() }); Ok(quote! { - impl<'c> #builder_identifier<'c, #(#arguments),*> { + impl<'c> #identifier<'c, #(#arguments),*> { pub fn build(self) -> #operation_identifier<'c> { self.builder #maybe_infer.build().expect("valid operation").try_into().expect(#error) } @@ -100,12 +100,12 @@ fn generate_build_fn(builder: &OperationBuilder) -> Result { } fn generate_new_fn(builder: &OperationBuilder) -> TokenStream { - let builder_ident = builder.identifier(); + let identifier = builder.identifier(); let name = &builder.operation().full_operation_name(); let arguments = builder.type_state().arguments_all_set(false); quote! { - impl<'c> #builder_ident<'c, #(#arguments),*> { + impl<'c> #identifier<'c, #(#arguments),*> { pub fn new(context: &'c ::melior::Context, location: ::melior::ir::Location<'c>) -> Self { Self { context, From 1bf729f3bc6df63c36cbb4e800de4a0cea893801 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 18 Feb 2024 19:39:31 +0900 Subject: [PATCH 079/108] Refactor operation builder generation (#449) --- .../dialect/generation/operation_builder.rs | 113 +++++++++++------- 1 file changed, 71 insertions(+), 42 deletions(-) diff --git a/macro/src/dialect/generation/operation_builder.rs b/macro/src/dialect/generation/operation_builder.rs index 44a627acfd..8c3d1a689f 100644 --- a/macro/src/dialect/generation/operation_builder.rs +++ b/macro/src/dialect/generation/operation_builder.rs @@ -1,12 +1,38 @@ use crate::dialect::{ - error::Error, operation::OperationBuilder, utility::sanitize_snake_case_identifier, + error::Error, + operation::{OperationBuilder, OperationField}, + utility::sanitize_snake_case_identifier, }; use proc_macro2::TokenStream; use quote::{format_ident, quote}; pub fn generate_operation_builder(builder: &OperationBuilder) -> Result { - let state_types = builder.type_state().parameters(); - let field_fns = generate_field_fns(builder); + let result_fns = builder + .operation() + .results() + .map(|result| generate_field_fn(builder, result)) + .collect::>(); + let operand_fns = builder + .operation() + .operands() + .map(|operand| generate_field_fn(builder, operand)) + .collect::>(); + let region_fns = builder + .operation() + .regions() + .map(|region| generate_field_fn(builder, region)) + .collect::>(); + let successor_fns = builder + .operation() + .successors() + .map(|successor| generate_field_fn(builder, successor)) + .collect::>(); + let attribute_fns = builder + .operation() + .attributes() + .map(|attribute| generate_field_fn(builder, attribute)) + .collect::>(); + let new_fn = generate_new_fn(builder); let build_fn = generate_build_fn(builder)?; @@ -16,6 +42,7 @@ pub fn generate_operation_builder(builder: &OperationBuilder) -> Result Result Vec { - builder.operation().fields().map(move |field| { - let builder_identifier = builder.identifier(); - let identifier = field.singular_identifier(); - let parameter_type = field.parameter_type(); - let argument = quote! { #identifier: #parameter_type }; - let add = format_ident!("add_{}", field.plural_kind_identifier()); - - // Argument types can be singular and variadic. But `add` functions in Melior - // are always variadic, so we need to create a slice or `Vec` for singular - // arguments. - let add_arguments = field.add_arguments(identifier); - - if field.is_optional() { - let parameters = builder.type_state().parameters().collect::>(); - - quote! { - impl<'c, #(#parameters),*> #builder_identifier<'c, #(#parameters),*> { - pub fn #identifier(mut self, #argument) -> #builder_identifier<'c, #(#parameters),*> { - self.builder = self.builder.#add(#add_arguments); - self - } +fn generate_field_fn(builder: &OperationBuilder, field: &impl OperationField) -> TokenStream { + let builder_identifier = builder.identifier(); + let identifier = field.singular_identifier(); + let parameter_type = field.parameter_type(); + let argument = quote! { #identifier: #parameter_type }; + let add = format_ident!("add_{}", field.plural_kind_identifier()); + + // Argument types can be singular and variadic. But `add` functions in Melior + // are always variadic, so we need to create a slice or `Vec` for singular + // arguments. + let add_arguments = field.add_arguments(identifier); + + if field.is_optional() { + let parameters = builder.type_state().parameters().collect::>(); + + quote! { + impl<'c, #(#parameters),*> #builder_identifier<'c, #(#parameters),*> { + pub fn #identifier(mut self, #argument) -> #builder_identifier<'c, #(#parameters),*> { + self.builder = self.builder.#add(#add_arguments); + self } } - } else if field.is_result() && builder.operation().can_infer_type() { - quote!() - } else { - let parameters = builder.type_state().parameters_without(field.name()); - let arguments_set = builder.type_state().arguments_set(field.name(), true); - let arguments_unset = builder.type_state().arguments_set(field.name(), false); - - quote! { - impl<'c, #(#parameters),*> #builder_identifier<'c, #(#arguments_unset),*> { - pub fn #identifier(self, #argument) -> #builder_identifier<'c, #(#arguments_set),*> { - #builder_identifier { - context: self.context, - builder: self.builder.#add(#add_arguments), - _state: Default::default(), - } + } + } else if field.is_result() && builder.operation().can_infer_type() { + quote!() + } else { + let parameters = builder.type_state().parameters_without(field.name()); + let arguments_set = builder.type_state().arguments_set(field.name(), true); + let arguments_unset = builder.type_state().arguments_set(field.name(), false); + + quote! { + impl<'c, #(#parameters),*> #builder_identifier<'c, #(#arguments_unset),*> { + pub fn #identifier(self, #argument) -> #builder_identifier<'c, #(#arguments_set),*> { + #builder_identifier { + context: self.context, + builder: self.builder.#add(#add_arguments), + _state: Default::default(), } } } } - }).collect() + } } fn generate_build_fn(builder: &OperationBuilder) -> Result { From 52ea69f58d26c34c41e29c568fa49b881dcc6879 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 18 Feb 2024 19:51:59 +0900 Subject: [PATCH 080/108] Refactor field builder generation (#450) --- .../dialect/generation/operation_builder.rs | 22 +++++++------ macro/src/dialect/operation.rs | 31 +++++++++---------- macro/src/dialect/operation/attribute.rs | 4 --- macro/src/dialect/operation/operand.rs | 4 --- .../src/dialect/operation/operation_field.rs | 3 -- macro/src/dialect/operation/region.rs | 4 --- macro/src/dialect/operation/result.rs | 4 --- macro/src/dialect/operation/successor.rs | 4 --- 8 files changed, 27 insertions(+), 49 deletions(-) diff --git a/macro/src/dialect/generation/operation_builder.rs b/macro/src/dialect/generation/operation_builder.rs index 8c3d1a689f..a9365962ad 100644 --- a/macro/src/dialect/generation/operation_builder.rs +++ b/macro/src/dialect/generation/operation_builder.rs @@ -7,11 +7,15 @@ use proc_macro2::TokenStream; use quote::{format_ident, quote}; pub fn generate_operation_builder(builder: &OperationBuilder) -> Result { - let result_fns = builder - .operation() - .results() - .map(|result| generate_field_fn(builder, result)) - .collect::>(); + let result_fns = if builder.operation().can_infer_type() { + Default::default() + } else { + builder + .operation() + .results() + .map(|result| generate_field_fn(builder, result)) + .collect::>() + }; let operand_fns = builder .operation() .operands() @@ -70,7 +74,7 @@ fn generate_field_fn(builder: &OperationBuilder, field: &impl OperationField) -> let identifier = field.singular_identifier(); let parameter_type = field.parameter_type(); let argument = quote! { #identifier: #parameter_type }; - let add = format_ident!("add_{}", field.plural_kind_identifier()); + let add_identifier = format_ident!("add_{}", field.plural_kind_identifier()); // Argument types can be singular and variadic. But `add` functions in Melior // are always variadic, so we need to create a slice or `Vec` for singular @@ -83,13 +87,11 @@ fn generate_field_fn(builder: &OperationBuilder, field: &impl OperationField) -> quote! { impl<'c, #(#parameters),*> #builder_identifier<'c, #(#parameters),*> { pub fn #identifier(mut self, #argument) -> #builder_identifier<'c, #(#parameters),*> { - self.builder = self.builder.#add(#add_arguments); + self.builder = self.builder.#add_identifier(#add_arguments); self } } } - } else if field.is_result() && builder.operation().can_infer_type() { - quote!() } else { let parameters = builder.type_state().parameters_without(field.name()); let arguments_set = builder.type_state().arguments_set(field.name(), true); @@ -100,7 +102,7 @@ fn generate_field_fn(builder: &OperationBuilder, field: &impl OperationField) -> pub fn #identifier(self, #argument) -> #builder_identifier<'c, #(#arguments_set),*> { #builder_identifier { context: self.context, - builder: self.builder.#add(#add_arguments), + builder: self.builder.#add_identifier(#add_arguments), _state: Default::default(), } } diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 2e089a0b08..1cd22e954a 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -139,20 +139,6 @@ impl<'a> Operation<'a> { sanitize_documentation(self.definition.str_value("description")?) } - pub fn fields(&self) -> impl Iterator { - fn convert(field: &impl OperationField) -> &dyn OperationField { - field - } - - self.results - .iter() - .map(convert) - .chain(self.operands.iter().map(convert)) - .chain(self.regions.iter().map(convert)) - .chain(self.successors.iter().map(convert)) - .chain(self.attributes().map(convert)) - } - pub fn operands(&self) -> impl Iterator> + Clone { self.operands.iter() } @@ -182,8 +168,21 @@ impl<'a> Operation<'a> { } pub fn required_fields(&self) -> impl Iterator { - self.fields() - .filter(|field| (!field.is_result() || !self.can_infer_type) && !field.is_optional()) + fn convert(field: &impl OperationField) -> &dyn OperationField { + field + } + + (if self.can_infer_type { + Default::default() + } else { + self.results.iter() + }) + .map(convert) + .chain(self.operands.iter().map(convert)) + .chain(self.regions.iter().map(convert)) + .chain(self.successors.iter().map(convert)) + .chain(self.attributes().map(convert)) + .filter(|field| !field.is_optional()) } fn collect_successors(definition: Record<'a>) -> Result, Error> { diff --git a/macro/src/dialect/operation/attribute.rs b/macro/src/dialect/operation/attribute.rs index c4cc29dba9..55f0bbb0c7 100644 --- a/macro/src/dialect/operation/attribute.rs +++ b/macro/src/dialect/operation/attribute.rs @@ -155,10 +155,6 @@ impl OperationField for Attribute<'_> { self.is_optional() || self.has_default_value() } - fn is_result(&self) -> bool { - false - } - fn add_arguments(&self, name: &Ident) -> TokenStream { let name_string = &self.name; diff --git a/macro/src/dialect/operation/operand.rs b/macro/src/dialect/operation/operand.rs index bec72a377f..90086d7a3e 100644 --- a/macro/src/dialect/operation/operand.rs +++ b/macro/src/dialect/operation/operand.rs @@ -70,10 +70,6 @@ impl OperationField for Operand<'_> { self.r#type.is_optional() } - fn is_result(&self) -> bool { - false - } - fn add_arguments(&self, name: &Ident) -> TokenStream { if self.r#type.is_variadic() { quote! { #name } diff --git a/macro/src/dialect/operation/operation_field.rs b/macro/src/dialect/operation/operation_field.rs index 298fd7ed50..04a5f10991 100644 --- a/macro/src/dialect/operation/operation_field.rs +++ b/macro/src/dialect/operation/operation_field.rs @@ -9,7 +9,4 @@ pub trait OperationField { fn return_type(&self) -> Type; fn is_optional(&self) -> bool; fn add_arguments(&self, name: &Ident) -> TokenStream; - - // TODO Remove this. - fn is_result(&self) -> bool; } diff --git a/macro/src/dialect/operation/region.rs b/macro/src/dialect/operation/region.rs index b209e4b561..5a61b771e4 100644 --- a/macro/src/dialect/operation/region.rs +++ b/macro/src/dialect/operation/region.rs @@ -65,10 +65,6 @@ impl OperationField for Region<'_> { false } - fn is_result(&self) -> bool { - false - } - fn add_arguments(&self, name: &Ident) -> TokenStream { if self.is_variadic() { quote! { #name } diff --git a/macro/src/dialect/operation/result.rs b/macro/src/dialect/operation/result.rs index a8629ee8b1..fb3870946e 100644 --- a/macro/src/dialect/operation/result.rs +++ b/macro/src/dialect/operation/result.rs @@ -72,10 +72,6 @@ impl OperationField for OperationResult<'_> { self.r#type.is_optional() } - fn is_result(&self) -> bool { - true - } - fn add_arguments(&self, name: &Ident) -> TokenStream { if self.r#type.is_unfixed() && !self.r#type.is_optional() { quote! { #name } diff --git a/macro/src/dialect/operation/successor.rs b/macro/src/dialect/operation/successor.rs index 1d5b56b1dc..597c3b0838 100644 --- a/macro/src/dialect/operation/successor.rs +++ b/macro/src/dialect/operation/successor.rs @@ -65,10 +65,6 @@ impl OperationField for Successor<'_> { false } - fn is_result(&self) -> bool { - false - } - fn add_arguments(&self, name: &Ident) -> TokenStream { if self.is_variadic() { quote! { #name } From a427010ed1ae4fcdfaae54e9e69c61e814a991c1 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 18 Feb 2024 20:00:22 +0900 Subject: [PATCH 081/108] Refactor (#451) --- .../dialect/operation/builder/type_state_item.rs | 13 ++++++------- .../dialect/operation/builder/type_state_list.rs | 6 +++--- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/macro/src/dialect/operation/builder/type_state_item.rs b/macro/src/dialect/operation/builder/type_state_item.rs index 82798e7607..82c0bc36f7 100644 --- a/macro/src/dialect/operation/builder/type_state_item.rs +++ b/macro/src/dialect/operation/builder/type_state_item.rs @@ -4,16 +4,15 @@ use syn::GenericArgument; #[derive(Debug)] pub struct TypeStateItem { field_name: String, - generic_param: GenericArgument, + generic_parameter: GenericArgument, } impl TypeStateItem { pub fn new(index: usize, field_name: String) -> Self { + let identifier = format_ident!("T{}", index); + Self { - generic_param: { - let ident = format_ident!("T{}", index); - syn::parse2(quote!(#ident)).expect("Ident is a valid GenericArgument") - }, + generic_parameter: syn::parse2(quote!(#identifier)).expect("valid GenericArgument"), field_name, } } @@ -22,7 +21,7 @@ impl TypeStateItem { &self.field_name } - pub fn generic_param(&self) -> &GenericArgument { - &self.generic_param + pub fn generic_parameter(&self) -> &GenericArgument { + &self.generic_parameter } } diff --git a/macro/src/dialect/operation/builder/type_state_list.rs b/macro/src/dialect/operation/builder/type_state_list.rs index fa4b7dc1c7..9d0dc58c17 100644 --- a/macro/src/dialect/operation/builder/type_state_list.rs +++ b/macro/src/dialect/operation/builder/type_state_list.rs @@ -20,7 +20,7 @@ impl TypeStateList { } pub fn parameters(&self) -> impl Iterator { - self.items.iter().map(|item| item.generic_param()) + self.items.iter().map(|item| item.generic_parameter()) } pub fn parameters_without<'a>( @@ -30,7 +30,7 @@ impl TypeStateList { self.items .iter() .filter(move |item| item.field_name() != field_name) - .map(|item| item.generic_param()) + .map(|item| item.generic_parameter()) } pub fn arguments_set<'a>( @@ -42,7 +42,7 @@ impl TypeStateList { if item.field_name() == field_name { self.set_argument(set) } else { - item.generic_param() + item.generic_parameter() } }) } From 8cff0bba1a31672f7377ba448ca2e54255b7e6da Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 18 Feb 2024 20:20:00 +0900 Subject: [PATCH 082/108] Refactor attribute generation (#452) - **Refactor** --- .../dialect/generation/attribute_accessor.rs | 7 +- .../operation/builder/type_state_item.rs | 6 +- .../operation/builder/type_state_list.rs | 7 +- melior/src/integer.rs | 65 ------------------- melior/src/ir/operation.rs | 4 +- 5 files changed, 11 insertions(+), 78 deletions(-) delete mode 100644 melior/src/integer.rs diff --git a/macro/src/dialect/generation/attribute_accessor.rs b/macro/src/dialect/generation/attribute_accessor.rs index f6c4a7151b..1f9c9575a7 100644 --- a/macro/src/dialect/generation/attribute_accessor.rs +++ b/macro/src/dialect/generation/attribute_accessor.rs @@ -22,7 +22,6 @@ fn generate_getter(attribute: &Attribute) -> TokenStream { let body = if attribute.is_unit() { quote! { self.operation.attribute(#name).is_some() } } else { - // TODO Handle returning `melior::Attribute`. quote! { Ok(self.operation.attribute(#name)?.try_into()?) } }; @@ -40,14 +39,14 @@ fn generate_setter(attribute: &Attribute) -> TokenStream { let body = if attribute.is_unit() { quote! { if value { - self.operation.set_attribute(#name, Attribute::unit(&self.operation.context())); + self.operation.set_attribute(#name, Attribute::unit(self.operation.context())); } else { self.operation.remove_attribute(#name) } } } else { quote! { - self.operation.set_attribute(#name, &value.into()); + self.operation.set_attribute(#name, value.into()); } }; @@ -62,7 +61,7 @@ fn generate_setter(attribute: &Attribute) -> TokenStream { } fn generate_remover(attribute: &Attribute) -> Option { - if attribute.is_unit() || attribute.is_optional() { + if attribute.is_optional() { let name = attribute.name(); let identifier = attribute.remove_identifier(); diff --git a/macro/src/dialect/operation/builder/type_state_item.rs b/macro/src/dialect/operation/builder/type_state_item.rs index 82c0bc36f7..d06256888f 100644 --- a/macro/src/dialect/operation/builder/type_state_item.rs +++ b/macro/src/dialect/operation/builder/type_state_item.rs @@ -1,5 +1,5 @@ -use quote::{format_ident, quote}; -use syn::GenericArgument; +use quote::format_ident; +use syn::{parse_quote, GenericArgument}; #[derive(Debug)] pub struct TypeStateItem { @@ -12,7 +12,7 @@ impl TypeStateItem { let identifier = format_ident!("T{}", index); Self { - generic_parameter: syn::parse2(quote!(#identifier)).expect("valid GenericArgument"), + generic_parameter: parse_quote!(#identifier), field_name, } } diff --git a/macro/src/dialect/operation/builder/type_state_list.rs b/macro/src/dialect/operation/builder/type_state_list.rs index 9d0dc58c17..d1808a1d4c 100644 --- a/macro/src/dialect/operation/builder/type_state_list.rs +++ b/macro/src/dialect/operation/builder/type_state_list.rs @@ -1,7 +1,6 @@ use super::type_state_item::TypeStateItem; -use quote::quote; use std::iter::repeat; -use syn::GenericArgument; +use syn::{parse_quote, GenericArgument}; #[derive(Debug)] pub struct TypeStateList { @@ -14,8 +13,8 @@ impl TypeStateList { pub fn new(items: Vec) -> Self { Self { items, - unset: syn::parse2(quote!(::melior::dialect::ods::__private::Unset)).unwrap(), - set: syn::parse2(quote!(::melior::dialect::ods::__private::Set)).unwrap(), + unset: parse_quote!(::melior::dialect::ods::__private::Unset), + set: parse_quote!(::melior::dialect::ods::__private::Set), } } diff --git a/melior/src/integer.rs b/melior/src/integer.rs deleted file mode 100644 index 30a4317570..0000000000 --- a/melior/src/integer.rs +++ /dev/null @@ -1,65 +0,0 @@ -use super::{Attribute, AttributeLike}; -use crate::{ - ir::{Type, TypeLike}, - Context, Error, -}; -use mlir_sys::{mlirIntegerAttrGet, MlirAttribute}; -use std::{ - fmt::{self, Debug, Display, Formatter}, - marker::PhantomData, -}; - -/// An integer attribute. -// Attributes are always values but their internal storage is owned by contexts. -#[derive(Clone, Copy)] -pub struct Integer<'c> { - raw: MlirAttribute, - _context: PhantomData<&'c Context>, -} - -impl<'c> Integer<'c> { - /// Creates an integer. - pub fn new(integer: i64, r#type: Type<'c>) -> Self { - unsafe { Self::from_raw(mlirIntegerAttrGet(r#type.to_raw(), integer)) } - } - - unsafe fn from_raw(raw: MlirAttribute) -> Self { - Self { - raw, - _context: Default::default(), - } - } -} - -impl<'c> AttributeLike<'c> for Integer<'c> { - fn to_raw(&self) -> MlirAttribute { - self.raw - } -} - -impl<'c> TryFrom> for Integer<'c> { - type Error = Error; - - fn try_from(attribute: Attribute<'c>) -> Result { - if attribute.is_integer() { - Ok(unsafe { Self::from_raw(attribute.to_raw()) }) - } else { - Err(Error::AttributeExpected( - "integer", - format!("{}", attribute), - )) - } - } -} - -impl<'c> Display for Integer<'c> { - fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { - Display::fmt(&Attribute::from(*self), formatter) - } -} - -impl<'c> Debug for Integer<'c> { - fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { - Display::fmt(self, formatter) - } -} diff --git a/melior/src/ir/operation.rs b/melior/src/ir/operation.rs index 81bac060cc..f1e8298d42 100644 --- a/melior/src/ir/operation.rs +++ b/melior/src/ir/operation.rs @@ -200,7 +200,7 @@ impl<'c> Operation<'c> { } /// Sets the attribute with the given name to the given attribute. - pub fn set_attribute(&mut self, name: &str, attribute: &Attribute<'c>) { + pub fn set_attribute(&mut self, name: &str, attribute: Attribute<'c>) { unsafe { mlirOperationSetAttributeByName( self.raw, @@ -569,7 +569,7 @@ mod tests { ); assert!(operation.remove_attribute("foo").is_ok()); assert!(operation.remove_attribute("foo").is_err()); - operation.set_attribute("foo", &StringAttribute::new(&context, "foo").into()); + operation.set_attribute("foo", StringAttribute::new(&context, "foo").into()); assert_eq!( operation.attribute("foo").map(|a| a.to_string()), Ok("\"foo\"".into()) From cde38fdda37031e2ea001953fbc20283ad644b62 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 18 Feb 2024 21:03:08 +0900 Subject: [PATCH 083/108] Refactor `add_regions` function (#453) --- macro/src/dialect/operation/region.rs | 11 ++++- melior/src/dialect/func.rs | 2 +- melior/src/dialect/llvm.rs | 2 +- melior/src/dialect/scf.rs | 10 ++-- melior/src/ir/module.rs | 2 +- melior/src/ir/operation.rs | 2 +- melior/src/ir/operation/builder.rs | 69 +++++++++++++++------------ 7 files changed, 57 insertions(+), 41 deletions(-) diff --git a/macro/src/dialect/operation/region.rs b/macro/src/dialect/operation/region.rs index 5a61b771e4..3ccfe82355 100644 --- a/macro/src/dialect/operation/region.rs +++ b/macro/src/dialect/operation/region.rs @@ -38,7 +38,14 @@ impl OperationField for Region<'_> { } fn plural_kind_identifier(&self) -> Ident { - Ident::new("regions", Span::call_site()) + Ident::new( + if self.variadic { + "regions_vec" + } else { + "regions" + }, + Span::call_site(), + ) } fn parameter_type(&self) -> Type { @@ -69,7 +76,7 @@ impl OperationField for Region<'_> { if self.is_variadic() { quote! { #name } } else { - quote! { vec![#name] } + quote! { [#name] } } } } diff --git a/melior/src/dialect/func.rs b/melior/src/dialect/func.rs index aec6a54443..99899aaf49 100644 --- a/melior/src/dialect/func.rs +++ b/melior/src/dialect/func.rs @@ -70,7 +70,7 @@ pub fn func<'c>( (Identifier::new(context, "function_type"), r#type.into()), ]) .add_attributes(attributes) - .add_regions(vec![region]) + .add_regions([region]) .build() .expect("valid operation") } diff --git a/melior/src/dialect/llvm.rs b/melior/src/dialect/llvm.rs index e0654cc7fe..8d8a5158af 100644 --- a/melior/src/dialect/llvm.rs +++ b/melior/src/dialect/llvm.rs @@ -213,7 +213,7 @@ pub fn func<'c>( (Identifier::new(context, "function_type"), r#type.into()), ]) .add_attributes(attributes) - .add_regions(vec![region]) + .add_regions([region]) .build() .expect("valid operation") } diff --git a/melior/src/dialect/scf.rs b/melior/src/dialect/scf.rs index 6e9173c708..e9ba67fd0b 100644 --- a/melior/src/dialect/scf.rs +++ b/melior/src/dialect/scf.rs @@ -29,7 +29,7 @@ pub fn execute_region<'c>( ) -> Operation<'c> { OperationBuilder::new("scf.execute_region", location) .add_results(result_types) - .add_regions(vec![region]) + .add_regions([region]) .build() .expect("valid operation") } @@ -44,7 +44,7 @@ pub fn r#for<'c>( ) -> Operation<'c> { OperationBuilder::new("scf.for", location) .add_operands(&[start, end, step]) - .add_regions(vec![region]) + .add_regions([region]) .build() .expect("valid operation") } @@ -60,7 +60,7 @@ pub fn r#if<'c>( OperationBuilder::new("scf.if", location) .add_operands(&[condition]) .add_results(result_types) - .add_regions(vec![then_region, else_region]) + .add_regions([then_region, else_region]) .build() .expect("valid operation") } @@ -78,7 +78,7 @@ pub fn index_switch<'c>( .add_operands(&[condition]) .add_results(result_types) .add_attributes(&[(Identifier::new(context, "cases"), cases.into())]) - .add_regions(regions) + .add_regions_vec(regions) .build() .expect("valid operation") } @@ -94,7 +94,7 @@ pub fn r#while<'c>( OperationBuilder::new("scf.while", location) .add_operands(initial_values) .add_results(result_types) - .add_regions(vec![before_region, after_region]) + .add_regions([before_region, after_region]) .build() .expect("valid operation") } diff --git a/melior/src/ir/module.rs b/melior/src/ir/module.rs index aaff464400..f655dae79e 100644 --- a/melior/src/ir/module.rs +++ b/melior/src/ir/module.rs @@ -126,7 +126,7 @@ mod tests { let module = Module::from_operation( OperationBuilder::new("builtin.module", Location::unknown(&context)) - .add_regions(vec![region]) + .add_regions([region]) .build() .unwrap(), ) diff --git a/melior/src/ir/operation.rs b/melior/src/ir/operation.rs index f1e8298d42..a84d9db56a 100644 --- a/melior/src/ir/operation.rs +++ b/melior/src/ir/operation.rs @@ -540,7 +540,7 @@ mod tests { context.set_allow_unregistered_dialects(true); let operation = OperationBuilder::new("foo", Location::unknown(&context)) - .add_regions(vec![Region::new()]) + .add_regions([Region::new()]) .build() .unwrap(); diff --git a/melior/src/ir/operation/builder.rs b/melior/src/ir/operation/builder.rs index fcbaaf59a9..fe68add68a 100644 --- a/melior/src/ir/operation/builder.rs +++ b/melior/src/ir/operation/builder.rs @@ -11,7 +11,10 @@ use mlir_sys::{ mlirOperationStateAddSuccessors, mlirOperationStateEnableResultTypeInference, mlirOperationStateGet, MlirOperationState, }; -use std::marker::PhantomData; +use std::{ + marker::PhantomData, + mem::{forget, transmute, ManuallyDrop}, +}; /// An operation builder. pub struct OperationBuilder<'c> { @@ -34,7 +37,7 @@ impl<'c> OperationBuilder<'c> { mlirOperationStateAddResults( &mut self.raw, results.len() as isize, - results as *const _ as *const _, + results.as_ptr() as *const _, ) } @@ -47,7 +50,7 @@ impl<'c> OperationBuilder<'c> { mlirOperationStateAddOperands( &mut self.raw, operands.len() as isize, - operands as *const _ as *const _, + operands.as_ptr() as *const _, ) } @@ -55,12 +58,27 @@ impl<'c> OperationBuilder<'c> { } /// Adds regions. - pub fn add_regions(mut self, regions: Vec>) -> Self { + pub fn add_regions(mut self, regions: [Region<'c>; N]) -> Self { + unsafe { + mlirOperationStateAddOwnedRegions( + &mut self.raw, + regions.len() as isize, + regions.as_ptr() as *const _, + ) + } + + forget(regions); + + self + } + + /// Adds regions in a [`Vec`](std::vec::Vec). + pub fn add_regions_vec(mut self, regions: Vec>) -> Self { unsafe { mlirOperationStateAddOwnedRegions( &mut self.raw, regions.len() as isize, - regions.leak().as_ptr() as *const _ as *const _, + transmute::<_, Vec>>(regions).as_ptr() as *const _, ) } @@ -70,38 +88,29 @@ impl<'c> OperationBuilder<'c> { /// Adds successor blocks. // TODO Fix this to ensure blocks are alive while they are referenced by the // operation. - // TODO Should we accept `BlockRef`? pub fn add_successors(mut self, successors: &[&Block<'c>]) -> Self { - unsafe { - mlirOperationStateAddSuccessors( - &mut self.raw, - successors.len() as isize, - successors - .iter() - .map(|block| block.to_raw()) - .collect::>() - .as_ptr() as *const _, - ) + for block in successors { + unsafe { + mlirOperationStateAddSuccessors(&mut self.raw, 1, &[block.to_raw()] as *const _) + } } self } /// Adds attributes. - // TODO Should we accept `NamedAttribute`? pub fn add_attributes(mut self, attributes: &[(Identifier<'c>, Attribute<'c>)]) -> Self { - unsafe { - mlirOperationStateAddAttributes( - &mut self.raw, - attributes.len() as isize, - attributes - .iter() - .map(|(identifier, attribute)| { - mlirNamedAttributeGet(identifier.to_raw(), attribute.to_raw()) - }) - .collect::>() - .as_ptr() as *const _, - ) + for (identifier, attribute) in attributes { + unsafe { + mlirOperationStateAddAttributes( + &mut self.raw, + 1, + &[mlirNamedAttributeGet( + identifier.to_raw(), + attribute.to_raw(), + )] as *const _, + ) + } } self @@ -172,7 +181,7 @@ mod tests { context.set_allow_unregistered_dialects(true); OperationBuilder::new("foo", Location::unknown(&context)) - .add_regions(vec![Region::new()]) + .add_regions([Region::new()]) .build() .unwrap(); } From 0e42c7fd5522673b1d11ab4929b8318fd853dfc9 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 18 Feb 2024 21:08:51 +0900 Subject: [PATCH 084/108] Refactor (#454) --- 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 1cd22e954a..6908c06804 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -31,10 +31,10 @@ pub struct Operation<'a> { operation_name: &'a str, summary: &'a str, can_infer_type: bool, - regions: Vec>, - successors: Vec>, results: Vec>, operands: Vec>, + regions: Vec>, + successors: Vec>, attributes: Vec>, derived_attributes: Vec>, } @@ -139,14 +139,6 @@ impl<'a> Operation<'a> { sanitize_documentation(self.definition.str_value("description")?) } - pub fn operands(&self) -> impl Iterator> + Clone { - self.operands.iter() - } - - pub fn operand_len(&self) -> usize { - self.operands.len() - } - pub fn results(&self) -> impl Iterator> + Clone { self.results.iter() } @@ -155,14 +147,22 @@ impl<'a> Operation<'a> { self.results.len() } - pub fn successors(&self) -> impl Iterator> { - self.successors.iter() + pub fn operands(&self) -> impl Iterator> + Clone { + self.operands.iter() + } + + pub fn operand_len(&self) -> usize { + self.operands.len() } pub fn regions(&self) -> impl Iterator> { self.regions.iter() } + pub fn successors(&self) -> impl Iterator> { + self.successors.iter() + } + pub fn attributes(&self) -> impl Iterator> { self.attributes.iter().chain(&self.derived_attributes) } From c1e07af1bba5fa435be626a0bae6aef97effe0e5 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 18 Feb 2024 23:11:02 +0900 Subject: [PATCH 085/108] Improve articles (#455) - **Improve documentation** --- macro/src/dialect/operation.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index 6908c06804..ed241b4bcd 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -23,6 +23,9 @@ use crate::dialect::{ pub use operation_field::OperationField; use tblgen::{error::WithLocation, record::Record, TypedInit}; +// spell-checker: disable-next-line +const VOWELS: &str = "aeiou"; + #[derive(Debug)] pub struct Operation<'a> { definition: Record<'a>, @@ -120,7 +123,16 @@ impl<'a> Operation<'a> { } pub fn documentation_name(&self) -> String { - format!("a(n) [`{}`]({}) operation", self.operation_name, &self.name) + format!( + "{} [`{}`]({}) operation", + if VOWELS.contains(&self.operation_name()[..1]) { + "an" + } else { + "a" + }, + self.operation_name, + &self.name + ) } pub fn summary(&self) -> String { From 512acac2f8a4baddf329cf3f06d6be8eb98c8fe0 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 18 Feb 2024 23:52:09 +0900 Subject: [PATCH 086/108] Refactor operation builder macro (#456) --- macro/src/dialect.rs | 11 +--- macro/src/dialect/generation.rs | 15 ++--- .../dialect/generation/operation_builder.rs | 44 ++++++------- macro/src/dialect/operation.rs | 66 ++++++++++--------- 4 files changed, 66 insertions(+), 70 deletions(-) diff --git a/macro/src/dialect.rs b/macro/src/dialect.rs index abf140ef31..c4eae9ce52 100644 --- a/macro/src/dialect.rs +++ b/macro/src/dialect.rs @@ -68,14 +68,9 @@ fn generate_dialect_module( .map(Operation::new) .collect::, _>>()? .iter() - .map(|operation| { - Ok::<_, Error>(if operation.dialect_name()? == dialect_name { - Some(generate_operation(operation)?) - } else { - None - }) - }) - .collect::, _>>()?; + .filter(|operation| operation.dialect_name() == dialect_name) + .map(generate_operation) + .collect::>(); let doc = format!( "`{name}` dialect.\n\n{}", diff --git a/macro/src/dialect/generation.rs b/macro/src/dialect/generation.rs index 317552b690..8b515abe4f 100644 --- a/macro/src/dialect/generation.rs +++ b/macro/src/dialect/generation.rs @@ -17,13 +17,12 @@ use self::{ successor_accessor::generate_successor_accessor, }; use super::operation::{Operation, OperationBuilder}; -use crate::dialect::error::Error; use proc_macro2::TokenStream; use quote::{format_ident, quote}; -pub fn generate_operation(operation: &Operation) -> Result { +pub fn generate_operation(operation: &Operation) -> TokenStream { let summary = operation.summary(); - let description = operation.description()?; + let description = operation.description(); let identifier = format_ident!("{}", operation.name()); let operation_name = operation.full_operation_name(); @@ -53,11 +52,11 @@ pub fn generate_operation(operation: &Operation) -> Result { .collect::>(); let builder = OperationBuilder::new(operation); - let builder_tokens = generate_operation_builder(&builder)?; + let builder_tokens = generate_operation_builder(&builder); let builder_fn = generate_operation_builder_fn(&builder); - let default_constructor = generate_default_constructor(&builder)?; + let default_constructor = generate_default_constructor(&builder); - Ok(quote! { + quote! { #[doc = #summary] #[doc = "\n\n"] #[doc = #description] @@ -94,7 +93,7 @@ pub fn generate_operation(operation: &Operation) -> Result { fn try_from( operation: ::melior::ir::operation::Operation<'c>, - ) -> Result { + ) -> Result { // TODO Check an operation name. Ok(Self { operation }) } @@ -105,5 +104,5 @@ pub fn generate_operation(operation: &Operation) -> Result { operation.operation } } - }) + } } diff --git a/macro/src/dialect/generation/operation_builder.rs b/macro/src/dialect/generation/operation_builder.rs index a9365962ad..9f4a92df31 100644 --- a/macro/src/dialect/generation/operation_builder.rs +++ b/macro/src/dialect/generation/operation_builder.rs @@ -1,12 +1,8 @@ -use crate::dialect::{ - error::Error, - operation::{OperationBuilder, OperationField}, - utility::sanitize_snake_case_identifier, -}; +use crate::dialect::operation::{OperationBuilder, OperationField}; use proc_macro2::TokenStream; use quote::{format_ident, quote}; -pub fn generate_operation_builder(builder: &OperationBuilder) -> Result { +pub fn generate_operation_builder(builder: &OperationBuilder) -> TokenStream { let result_fns = if builder.operation().can_infer_type() { Default::default() } else { @@ -38,7 +34,7 @@ pub fn generate_operation_builder(builder: &OperationBuilder) -> Result>(); let new_fn = generate_new_fn(builder); - let build_fn = generate_build_fn(builder)?; + let build_fn = generate_build_fn(builder); let identifier = builder.identifier(); let doc = format!( @@ -48,7 +44,7 @@ pub fn generate_operation_builder(builder: &OperationBuilder) -> Result { builder: ::melior::ir::operation::OperationBuilder<'c>, @@ -65,7 +61,7 @@ pub fn generate_operation_builder(builder: &OperationBuilder) -> Result } } -fn generate_build_fn(builder: &OperationBuilder) -> Result { +fn generate_build_fn(builder: &OperationBuilder) -> TokenStream { let identifier = builder.identifier(); let arguments = builder.type_state().arguments_all_set(true); let operation_identifier = format_ident!("{}", &builder.operation().name()); @@ -121,13 +117,13 @@ fn generate_build_fn(builder: &OperationBuilder) -> Result { .can_infer_type() .then_some(quote! { .enable_result_type_inference() }); - Ok(quote! { + quote! { impl<'c> #identifier<'c, #(#arguments),*> { pub fn build(self) -> #operation_identifier<'c> { self.builder #maybe_infer.build().expect("valid operation").try_into().expect(#error) } } - }) + } } fn generate_new_fn(builder: &OperationBuilder) -> TokenStream { @@ -163,17 +159,17 @@ pub fn generate_operation_builder_fn(builder: &OperationBuilder) -> TokenStream } } -pub fn generate_default_constructor(builder: &OperationBuilder) -> Result { - let identifier = format_ident!("{}", &builder.operation().name()); - let name = sanitize_snake_case_identifier(builder.operation().operation_name())?; +pub fn generate_default_constructor(builder: &OperationBuilder) -> TokenStream { + let operation_identifier = format_ident!("{}", &builder.operation().name()); + let constructor_identifier = builder.operation().constructor_identifier(); let arguments = builder .operation() .required_fields() .map(|field| { - let parameter_type = &field.parameter_type(); - let parameter_name = &field.singular_identifier(); + let r#type = &field.parameter_type(); + let name = &field.singular_identifier(); - quote! { #parameter_name: #parameter_type } + quote! { #name: #r#type } }) .chain([quote! { location: ::melior::ir::Location<'c> }]) .collect::>(); @@ -181,19 +177,19 @@ pub fn generate_default_constructor(builder: &OperationBuilder) -> Result>(); let doc = format!("Creates {}.", builder.operation().documentation_name()); - Ok(quote! { + quote! { #[allow(clippy::too_many_arguments)] #[doc = #doc] - pub fn #name<'c>(context: &'c ::melior::Context, #(#arguments),*) -> #identifier<'c> { - #identifier::builder(context, location)#(#builder_calls)*.build() + pub fn #constructor_identifier<'c>(context: &'c ::melior::Context, #(#arguments),*) -> #operation_identifier<'c> { + #operation_identifier::builder(context, location)#(#builder_calls)*.build() } - }) + } } diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index ed241b4bcd..cf1b2ac781 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -13,7 +13,7 @@ pub use self::{ operation_element::OperationElement, region::Region, result::OperationResult, successor::Successor, variadic_kind::VariadicKind, }; -use super::utility::sanitize_documentation; +use super::utility::{sanitize_documentation, sanitize_snake_case_identifier}; use crate::dialect::{ error::{Error, OdsError}, r#trait::Trait, @@ -21,6 +21,8 @@ use crate::dialect::{ utility::capitalize_string, }; pub use operation_field::OperationField; +use std::collections::HashSet; +use syn::Ident; use tblgen::{error::WithLocation, record::Record, TypedInit}; // spell-checker: disable-next-line @@ -28,11 +30,13 @@ const VOWELS: &str = "aeiou"; #[derive(Debug)] pub struct Operation<'a> { - definition: Record<'a>, name: String, + short_dialect_name: &'a str, dialect_name: &'a str, operation_name: &'a str, + constructor_identifier: Ident, summary: &'a str, + description: String, can_infer_type: bool, results: Vec>, operands: Vec>, @@ -44,31 +48,29 @@ pub struct Operation<'a> { impl<'a> Operation<'a> { pub fn new(definition: Record<'a>) -> Result { + let operation_name = definition.str_value("opName")?; let traits = Self::collect_traits(definition)?; - let has_trait = |name| traits.iter().any(|r#trait| r#trait.name() == Some(name)); + let trait_names = traits + .iter() + .flat_map(|r#trait| r#trait.name()) + .collect::>(); let arguments = Self::dag_constraints(definition, "arguments")?; let regions = Self::collect_regions(definition)?; let (results, unfixed_result_count) = Self::collect_results( definition, - has_trait("::mlir::OpTrait::SameVariadicResultSize"), - has_trait("::mlir::OpTrait::AttrSizedResultSegments"), + trait_names.contains("::mlir::OpTrait::SameVariadicResultSize"), + trait_names.contains("::mlir::OpTrait::AttrSizedResultSegments"), )?; Ok(Self { name: Self::build_name(definition)?, - dialect_name: definition.def_value("opDialect")?.str_value("name")?, - operation_name: definition.str_value("opName")?, + dialect_name: definition.def_value("opDialect")?.name()?, + short_dialect_name: definition.def_value("opDialect")?.str_value("name")?, + operation_name, + constructor_identifier: sanitize_snake_case_identifier(operation_name)?, summary: definition.str_value("summary")?, - 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)?, + description: sanitize_documentation(definition.str_value("description")?)?, can_infer_type: traits.iter().any(|r#trait| { (r#trait.name() == Some("::mlir::OpTrait::FirstAttrDerivedResultType") || r#trait.name() == Some("::mlir::OpTrait::SameOperandsAndResultType")) @@ -76,8 +78,16 @@ impl<'a> Operation<'a> { || r#trait.name() == Some("::mlir::InferTypeOpInterface::Trait") && regions.is_empty() }), + results, + operands: Self::collect_operands( + &arguments, + trait_names.contains("::mlir::OpTrait::SameVariadicOperandSize"), + trait_names.contains("::mlir::OpTrait::AttrSizedOperandSegments"), + )?, regions, - definition, + successors: Self::collect_successors(definition)?, + attributes: Self::collect_attributes(&arguments)?, + derived_attributes: Self::collect_derived_attributes(definition)?, }) } @@ -102,12 +112,8 @@ impl<'a> Operation<'a> { self.can_infer_type } - fn dialect(&self) -> Result { - Ok(self.definition.def_value("opDialect")?) - } - - pub fn dialect_name(&self) -> Result<&str, Error> { - Ok(self.dialect()?.name()?) + pub fn dialect_name(&self) -> &str { + self.dialect_name } pub fn operation_name(&self) -> &str { @@ -115,11 +121,7 @@ impl<'a> Operation<'a> { } pub fn full_operation_name(&self) -> String { - if self.dialect_name.is_empty() { - self.operation_name.into() - } else { - format!("{}.{}", self.dialect_name, self.operation_name) - } + format!("{}.{}", self.short_dialect_name, self.operation_name) } pub fn documentation_name(&self) -> String { @@ -147,8 +149,12 @@ impl<'a> Operation<'a> { ) } - pub fn description(&self) -> Result { - sanitize_documentation(self.definition.str_value("description")?) + pub fn description(&self) -> &str { + &self.description + } + + pub fn constructor_identifier(&self) -> &Ident { + &self.constructor_identifier } pub fn results(&self) -> impl Iterator> + Clone { From f21d1d0937de40ac16e7b2f5ca9b87cac97dc413 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Mon, 19 Feb 2024 00:02:56 +0900 Subject: [PATCH 087/108] LLVM intrinsic dialect (#457) Close #339. --- melior/src/dialect/ods.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/melior/src/dialect/ods.rs b/melior/src/dialect/ods.rs index c028f2869e..f033e22117 100644 --- a/melior/src/dialect/ods.rs +++ b/melior/src/dialect/ods.rs @@ -50,7 +50,7 @@ melior_macro::dialect! { melior_macro::dialect! { name: "llvm", // spell-checker: disable-next-line - table_gen: r#"include "mlir/Dialect/LLVMIR/LLVMOps.td""# + table_gen: r#"include "mlir/Dialect/LLVMIR/LLVMOps.td" include "mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td""# } melior_macro::dialect! { name: "memref", From 9c438b4ffd952defa79f69a4cc89b6955610b8bd Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Mon, 19 Feb 2024 00:13:57 +0900 Subject: [PATCH 088/108] Update document workflow (#459) - **Update document workflow** --- .github/workflows/document.yaml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/.github/workflows/document.yaml b/.github/workflows/document.yaml index 9ee23d46f9..e4609d6ec4 100644 --- a/.github/workflows/document.yaml +++ b/.github/workflows/document.yaml @@ -4,17 +4,22 @@ on: branches: - main pull_request: +permissions: + contents: read + pages: write + id-token: write jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: Swatinem/rust-cache@v2 - - uses: Homebrew/actions/setup-homebrew@master + - uses: actions/configure-pages@v4 + - uses: swatinem/rust-cache@v2 + - uses: homebrew/actions/setup-homebrew@master - run: tools/setup.sh - run: cargo doc --all-features - - uses: peaceiris/actions-gh-pages@v3 - if: github.ref == 'refs/heads/main' + - uses: actions/upload-pages-artifact@v3 with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: target/doc + path: target/doc + - uses: actions/deploy-pages@v4 + if: github.ref == 'refs/heads/main' From 34abb62b9f819f95d79eb802a43d1a7d47dd7551 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Mon, 19 Feb 2024 20:07:25 +0900 Subject: [PATCH 089/108] Fix `add_*` method calls (#461) - **Fix** - **Fix** - **Fix** - **Fix** - **Fix** - **Fix** --- melior/src/dialect/ods.rs | 48 +++++++++++++++++-- .../melior__dialect__ods__tests__addf.snap | 11 +++++ ...or__dialect__ods__tests__addf_builder.snap | 11 +++++ 3 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 melior/src/dialect/snapshots/melior__dialect__ods__tests__addf.snap create mode 100644 melior/src/dialect/snapshots/melior__dialect__ods__tests__addf_builder.snap diff --git a/melior/src/dialect/ods.rs b/melior/src/dialect/ods.rs index f033e22117..81a5634083 100644 --- a/melior/src/dialect/ods.rs +++ b/melior/src/dialect/ods.rs @@ -180,6 +180,46 @@ mod tests { insta::assert_display_snapshot!(name, module.as_operation()); } + #[test] + fn compile_arith_addf() { + let context = create_test_context(); + let location = Location::unknown(&context); + let r#type = Type::float32(&context); + + test_operation("addf", &context, &[r#type, r#type], |block| { + block.append_operation( + arith::addf( + &context, + block.argument(0).unwrap().into(), + block.argument(1).unwrap().into(), + location, + ) + .into(), + ); + + block.append_operation(func::r#return(&[], location)); + }); + } + + #[test] + fn compile_arith_addf_builder_with_reverse_order() { + let context = create_test_context(); + let location = Location::unknown(&context); + let r#type = Type::float32(&context); + + test_operation("addf_builder", &context, &[r#type, r#type], |block| { + block.append_operation( + arith::AddFOperationBuilder::new(&context, location) + .rhs(block.argument(1).unwrap().into()) + .lhs(block.argument(0).unwrap().into()) + .build() + .into(), + ); + + block.append_operation(func::r#return(&[], location)); + }); + } + #[test] fn compile_llvm_alloca() { let context = create_test_context(); @@ -188,12 +228,11 @@ mod tests { test_operation("alloc", &context, &[integer_type], |block| { let alloca_size = block.argument(0).unwrap().into(); - let i64_type = IntegerType::new(&context, 64); block.append_operation( llvm::alloca( &context, - dialect::llvm::r#type::pointer(i64_type.into(), 0), + dialect::llvm::r#type::pointer(integer_type.into(), 0), alloca_size, location, ) @@ -213,12 +252,11 @@ mod tests { test_operation("alloc_builder", &context, &[integer_type], |block| { let alloca_size = block.argument(0).unwrap().into(); - let i64_type = IntegerType::new(&context, 64); block.append_operation( llvm::AllocaOperationBuilder::new(&context, location) - .alignment(IntegerAttribute::new(8, i64_type.into())) - .elem_type(TypeAttribute::new(i64_type.into())) + .alignment(IntegerAttribute::new(8, integer_type.into())) + .elem_type(TypeAttribute::new(integer_type.into())) .array_size(alloca_size) .res(ptr_type) .build() diff --git a/melior/src/dialect/snapshots/melior__dialect__ods__tests__addf.snap b/melior/src/dialect/snapshots/melior__dialect__ods__tests__addf.snap new file mode 100644 index 0000000000..64a0509709 --- /dev/null +++ b/melior/src/dialect/snapshots/melior__dialect__ods__tests__addf.snap @@ -0,0 +1,11 @@ +--- +source: melior/src/dialect/ods.rs +expression: module.as_operation() +--- +module attributes {llvm.data_layout = ""} { + llvm.func @foo(%arg0: f32, %arg1: f32) { + %0 = llvm.fadd %arg0, %arg1 : f32 + llvm.return + } +} + diff --git a/melior/src/dialect/snapshots/melior__dialect__ods__tests__addf_builder.snap b/melior/src/dialect/snapshots/melior__dialect__ods__tests__addf_builder.snap new file mode 100644 index 0000000000..5346119ef3 --- /dev/null +++ b/melior/src/dialect/snapshots/melior__dialect__ods__tests__addf_builder.snap @@ -0,0 +1,11 @@ +--- +source: melior/src/dialect/ods.rs +expression: module.as_operation() +--- +module attributes {llvm.data_layout = ""} { + llvm.func @foo(%arg0: f32, %arg1: f32) { + %0 = llvm.fadd %arg1, %arg0 : f32 + llvm.return + } +} + From ebbb8bd6f180d49b363af5082cb637244601a351 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Mon, 19 Feb 2024 20:16:04 +0900 Subject: [PATCH 090/108] Refactor type state list (#462) --- .../operation/builder/type_state_list.rs | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/macro/src/dialect/operation/builder/type_state_list.rs b/macro/src/dialect/operation/builder/type_state_list.rs index d1808a1d4c..f6829956b6 100644 --- a/macro/src/dialect/operation/builder/type_state_list.rs +++ b/macro/src/dialect/operation/builder/type_state_list.rs @@ -5,17 +5,11 @@ use syn::{parse_quote, GenericArgument}; #[derive(Debug)] pub struct TypeStateList { items: Vec, - unset: GenericArgument, - set: GenericArgument, } impl TypeStateList { pub fn new(items: Vec) -> Self { - Self { - items, - unset: parse_quote!(::melior::dialect::ods::__private::Unset), - set: parse_quote!(::melior::dialect::ods::__private::Set), - } + Self { items } } pub fn parameters(&self) -> impl Iterator { @@ -36,25 +30,25 @@ impl TypeStateList { &'a self, field_name: &'a str, set: bool, - ) -> impl Iterator { + ) -> impl Iterator + 'a { self.items.iter().map(move |item| { if item.field_name() == field_name { self.set_argument(set) } else { - item.generic_parameter() + item.generic_parameter().clone() } }) } - pub fn arguments_all_set(&self, set: bool) -> impl Iterator { + pub fn arguments_all_set(&self, set: bool) -> impl Iterator { repeat(self.set_argument(set)).take(self.items.len()) } - fn set_argument(&self, set: bool) -> &GenericArgument { + fn set_argument(&self, set: bool) -> GenericArgument { if set { - &self.set + parse_quote!(::melior::dialect::ods::__private::Set) } else { - &self.unset + parse_quote!(::melior::dialect::ods::__private::Unset) } } } From c8e75c5531b108576bdef0cc802e872fad101e12 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Mon, 19 Feb 2024 20:23:30 +0900 Subject: [PATCH 091/108] Copy documentation directory first (#463) --- .github/workflows/document.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/document.yaml b/.github/workflows/document.yaml index e4609d6ec4..82be6f4240 100644 --- a/.github/workflows/document.yaml +++ b/.github/workflows/document.yaml @@ -18,8 +18,9 @@ jobs: - uses: homebrew/actions/setup-homebrew@master - run: tools/setup.sh - run: cargo doc --all-features + - run: cp -LR target/doc /tmp - uses: actions/upload-pages-artifact@v3 with: - path: target/doc + path: /tmp/doc - uses: actions/deploy-pages@v4 if: github.ref == 'refs/heads/main' From 295fac347e737cb798234a71f300a1e3b3f3e227 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Mon, 19 Feb 2024 20:47:07 +0900 Subject: [PATCH 092/108] Fix documentation deployment (#464) - **Revert "Copy documentation directory first (#463)"** - **Fix permissions** --- .github/workflows/document.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/document.yaml b/.github/workflows/document.yaml index 82be6f4240..e7c1b63a06 100644 --- a/.github/workflows/document.yaml +++ b/.github/workflows/document.yaml @@ -18,9 +18,9 @@ jobs: - uses: homebrew/actions/setup-homebrew@master - run: tools/setup.sh - run: cargo doc --all-features - - run: cp -LR target/doc /tmp + - run: rm target/doc/.lock - uses: actions/upload-pages-artifact@v3 with: - path: /tmp/doc + path: target/doc - uses: actions/deploy-pages@v4 if: github.ref == 'refs/heads/main' From ab7104a19edc272152cbb3169937fefc722a3312 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Mon, 19 Feb 2024 23:31:34 +0900 Subject: [PATCH 093/108] `OperationRefMut` (#466) This supersedes #460. --- melior/src/ir/module.rs | 24 ++++++++++-- melior/src/ir/operation.rs | 78 +++++++++++++++++++++++++++++++++++++- 2 files changed, 97 insertions(+), 5 deletions(-) diff --git a/melior/src/ir/module.rs b/melior/src/ir/module.rs index f655dae79e..d02b76a6f1 100644 --- a/melior/src/ir/module.rs +++ b/melior/src/ir/module.rs @@ -1,4 +1,4 @@ -use super::{BlockRef, Location, Operation, OperationRef}; +use super::{operation::OperationRefMut, BlockRef, Location, Operation, OperationRef}; use crate::{ context::{Context, ContextRef}, string_ref::StringRef, @@ -33,10 +33,15 @@ impl<'c> Module<'c> { } /// Converts a module into an operation. - pub fn as_operation(&self) -> OperationRef { + pub fn as_operation(&self) -> OperationRef<'c, '_> { unsafe { OperationRef::from_raw(mlirModuleGetOperation(self.raw)) } } + /// Converts a module into a mutable operation. + pub fn as_operation_mut(&mut self) -> OperationRefMut<'c, '_> { + unsafe { OperationRefMut::from_raw(mlirModuleGetOperation(self.raw)) } + } + /// Gets a context. pub fn context(&self) -> ContextRef<'c> { unsafe { ContextRef::from_raw(mlirModuleGetContext(self.raw)) } @@ -93,7 +98,7 @@ impl<'c> Drop for Module<'c> { mod tests { use super::*; use crate::{ - ir::{operation::OperationBuilder, Block, Region}, + ir::{attribute::StringAttribute, operation::OperationBuilder, Block, Region}, test::create_test_context, }; @@ -147,4 +152,17 @@ mod tests { ) .is_none()); } + + #[test] + fn set_attribute() { + let context = create_test_context(); + + let mut module = Module::new(Location::unknown(&context)); + + module + .as_operation_mut() + .set_attribute("sym_name", StringAttribute::new(&context, "foo").into()); + + assert!(module.as_operation().verify()); + } } diff --git a/melior/src/ir/operation.rs b/melior/src/ir/operation.rs index a84d9db56a..1131821af4 100644 --- a/melior/src/ir/operation.rs +++ b/melior/src/ir/operation.rs @@ -31,7 +31,7 @@ use std::{ ffi::c_void, fmt::{Debug, Display, Formatter}, marker::PhantomData, - ops::Deref, + ops::{Deref, DerefMut}, }; /// An operation. @@ -351,6 +351,7 @@ impl<'c, 'a> OperationRef<'c, 'a> { /// /// The returned reference is safe to use only in the lifetime scope of the /// operation reference. + // TODO Remove this? pub unsafe fn to_ref(&self) -> &'a Operation<'c> { // As we can't deref OperationRef<'a> into `&'a Operation`, we forcibly cast its // lifetime here to extend it from the lifetime of `ObjectRef<'a>` itself into @@ -390,7 +391,7 @@ impl<'c, 'a> OperationRef<'c, 'a> { } impl<'c, 'a> Deref for OperationRef<'c, 'a> { - type Target = Operation<'a>; + type Target = Operation<'c>; fn deref(&self) -> &Self::Target { unsafe { transmute(self) } @@ -417,6 +418,79 @@ impl<'c, 'a> Debug for OperationRef<'c, 'a> { } } +/// A mutable reference to an operation. +#[derive(Clone, Copy)] +pub struct OperationRefMut<'c, 'a> { + raw: MlirOperation, + _reference: PhantomData<&'a Operation<'c>>, +} + +impl<'c, 'a> OperationRefMut<'c, 'a> { + /// Converts an operation reference into a raw object. + pub const fn to_raw(self) -> MlirOperation { + self.raw + } + + /// Creates an operation reference from a raw object. + /// + /// # Safety + /// + /// A raw object must be valid. + pub unsafe fn from_raw(raw: MlirOperation) -> Self { + Self { + raw, + _reference: Default::default(), + } + } + + /// Creates an optional operation reference from a raw object. + /// + /// # Safety + /// + /// A raw object must be valid. + pub unsafe fn from_option_raw(raw: MlirOperation) -> Option { + if raw.ptr.is_null() { + None + } else { + Some(Self::from_raw(raw)) + } + } +} + +impl<'c, 'a> Deref for OperationRefMut<'c, 'a> { + type Target = Operation<'a>; + + fn deref(&self) -> &Self::Target { + unsafe { transmute(self) } + } +} + +impl<'c, 'a> DerefMut for OperationRefMut<'c, 'a> { + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { transmute(self) } + } +} + +impl<'c, 'a> PartialEq for OperationRefMut<'c, 'a> { + fn eq(&self, other: &Self) -> bool { + unsafe { mlirOperationEqual(self.raw, other.raw) } + } +} + +impl<'c, 'a> Eq for OperationRefMut<'c, 'a> {} + +impl<'c, 'a> Display for OperationRefMut<'c, 'a> { + fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { + Display::fmt(self.deref(), formatter) + } +} + +impl<'c, 'a> Debug for OperationRefMut<'c, 'a> { + fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { + Debug::fmt(self.deref(), formatter) + } +} + #[cfg(test)] mod tests { use super::*; From 56b4a923a334bb02e1e8fed4cfc610c243ac730c Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Mon, 19 Feb 2024 23:45:03 +0900 Subject: [PATCH 094/108] Fix linting (#468) --- melior/src/dialect/ods.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/melior/src/dialect/ods.rs b/melior/src/dialect/ods.rs index 81a5634083..d6d2f96f2b 100644 --- a/melior/src/dialect/ods.rs +++ b/melior/src/dialect/ods.rs @@ -232,7 +232,7 @@ mod tests { block.append_operation( llvm::alloca( &context, - dialect::llvm::r#type::pointer(integer_type.into(), 0), + dialect::llvm::r#type::pointer(integer_type, 0), alloca_size, location, ) @@ -255,8 +255,8 @@ mod tests { block.append_operation( llvm::AllocaOperationBuilder::new(&context, location) - .alignment(IntegerAttribute::new(8, integer_type.into())) - .elem_type(TypeAttribute::new(integer_type.into())) + .alignment(IntegerAttribute::new(8, integer_type)) + .elem_type(TypeAttribute::new(integer_type)) .array_size(alloca_size) .res(ptr_type) .build() From ae44f0cca6762669f4bd0310e86828966dc7ec56 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Mon, 19 Feb 2024 23:47:24 +0900 Subject: [PATCH 095/108] Fix `OperationRef` lifetime (#469) --- melior/src/ir/operation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/melior/src/ir/operation.rs b/melior/src/ir/operation.rs index 1131821af4..c5fe4c4ba6 100644 --- a/melior/src/ir/operation.rs +++ b/melior/src/ir/operation.rs @@ -458,7 +458,7 @@ impl<'c, 'a> OperationRefMut<'c, 'a> { } impl<'c, 'a> Deref for OperationRefMut<'c, 'a> { - type Target = Operation<'a>; + type Target = Operation<'c>; fn deref(&self) -> &Self::Target { unsafe { transmute(self) } From bf3c01def19c16db68547d0f1aec8c7050ac042a Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Mon, 19 Feb 2024 23:57:02 +0900 Subject: [PATCH 096/108] Refactor lifetime annotation (#470) --- melior/src/ir/operation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/melior/src/ir/operation.rs b/melior/src/ir/operation.rs index c5fe4c4ba6..0aec6e2ccb 100644 --- a/melior/src/ir/operation.rs +++ b/melior/src/ir/operation.rs @@ -305,7 +305,7 @@ impl<'c> PartialEq for Operation<'c> { impl<'c> Eq for Operation<'c> {} -impl<'a> Display for Operation<'a> { +impl<'c> Display for Operation<'c> { fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { let mut data = (formatter, Ok(())); From 2e2bc959502e6eb853626134db7ae129517931c0 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 20 Feb 2024 08:56:36 +0900 Subject: [PATCH 097/108] Rename gets returns (#471) --- melior/src/context.rs | 6 +-- melior/src/dialect.rs | 4 +- melior/src/dialect/handle.rs | 2 +- melior/src/ir/affine_map.rs | 2 +- melior/src/ir/attribute/array.rs | 4 +- melior/src/ir/attribute/attribute_like.rs | 6 +-- melior/src/ir/attribute/dense_elements.rs | 6 +-- melior/src/ir/attribute/dense_i32_array.rs | 4 +- melior/src/ir/attribute/dense_i64_array.rs | 4 +- melior/src/ir/attribute/type.rs | 2 +- melior/src/ir/block.rs | 14 +++---- melior/src/ir/block/argument.rs | 4 +- melior/src/ir/identifier.rs | 2 +- melior/src/ir/location.rs | 2 +- melior/src/ir/module.rs | 4 +- melior/src/ir/operation.rs | 44 +++++++++++----------- melior/src/ir/operation/result.rs | 4 +- melior/src/ir/region.rs | 2 +- melior/src/ir/type/function.rs | 8 ++-- melior/src/ir/type/integer.rs | 2 +- melior/src/ir/type/mem_ref.rs | 6 +-- melior/src/ir/type/ranked_tensor.rs | 2 +- melior/src/ir/type/shaped_type_like.rs | 6 +-- melior/src/ir/type/tuple.rs | 4 +- melior/src/ir/type/type_like.rs | 4 +- melior/src/ir/value/value_like.rs | 2 +- melior/src/pass/manager.rs | 2 +- melior/src/pass/operation_manager.rs | 2 +- 28 files changed, 77 insertions(+), 77 deletions(-) diff --git a/melior/src/context.rs b/melior/src/context.rs index 7315cd85ce..ffcedbd5b6 100644 --- a/melior/src/context.rs +++ b/melior/src/context.rs @@ -31,17 +31,17 @@ impl Context { } } - /// Gets a number of registered dialects. + /// Returns a number of registered dialects. pub fn registered_dialect_count(&self) -> usize { unsafe { mlirContextGetNumRegisteredDialects(self.raw) as usize } } - /// Gets a number of loaded dialects. + /// Returns a number of loaded dialects. pub fn loaded_dialect_count(&self) -> usize { unsafe { mlirContextGetNumLoadedDialects(self.raw) as usize } } - /// Gets or loads a dialect. + /// Returns or loads a dialect. pub fn get_or_load_dialect(&self, name: &str) -> Dialect { let name = StringRef::new(name); diff --git a/melior/src/dialect.rs b/melior/src/dialect.rs index 098106b186..f0b625b5be 100644 --- a/melior/src/dialect.rs +++ b/melior/src/dialect.rs @@ -29,12 +29,12 @@ pub struct Dialect<'c> { } impl<'c> Dialect<'c> { - /// Gets a context. + /// Returns a context. pub fn context(&self) -> ContextRef<'c> { unsafe { ContextRef::from_raw(mlirDialectGetContext(self.raw)) } } - /// Gets a namespace. + /// Returns a namespace. pub fn namespace(&self) -> Result<&str, Utf8Error> { unsafe { StringRef::from_raw(mlirDialectGetNamespace(self.raw)) }.as_str() } diff --git a/melior/src/dialect/handle.rs b/melior/src/dialect/handle.rs index d8f365c7c3..837c2c3e7a 100644 --- a/melior/src/dialect/handle.rs +++ b/melior/src/dialect/handle.rs @@ -76,7 +76,7 @@ impl DialectHandle { unsafe { Self::from_raw(mlirGetDialectHandle__tensor__()) } } - /// Gets a namespace. + /// Returns a namespace. pub fn namespace(&self) -> StringRef { unsafe { StringRef::from_raw(mlirDialectHandleGetNamespace(self.raw)) } } diff --git a/melior/src/ir/affine_map.rs b/melior/src/ir/affine_map.rs index 94c151e00f..31f354d217 100644 --- a/melior/src/ir/affine_map.rs +++ b/melior/src/ir/affine_map.rs @@ -20,7 +20,7 @@ pub struct AffineMap<'c> { } impl<'c> AffineMap<'c> { - /// Gets a context. + /// Returns a context. pub fn context(&self) -> ContextRef<'c> { unsafe { ContextRef::from_raw(mlirAffineMapGetContext(self.raw)) } } diff --git a/melior/src/ir/attribute/array.rs b/melior/src/ir/attribute/array.rs index bcf04941fd..175f424afc 100644 --- a/melior/src/ir/attribute/array.rs +++ b/melior/src/ir/attribute/array.rs @@ -22,7 +22,7 @@ impl<'c> ArrayAttribute<'c> { } } - /// Gets a length. + /// Returns a length. pub fn len(&self) -> usize { (unsafe { mlirArrayAttrGetNumElements(self.attribute.to_raw()) }) as usize } @@ -32,7 +32,7 @@ impl<'c> ArrayAttribute<'c> { self.len() == 0 } - /// Gets an element. + /// Returns an element. pub fn element(&self, index: usize) -> Result, Error> { if index < self.len() { Ok(unsafe { diff --git a/melior/src/ir/attribute/attribute_like.rs b/melior/src/ir/attribute/attribute_like.rs index e70c5386f0..e363035c15 100644 --- a/melior/src/ir/attribute/attribute_like.rs +++ b/melior/src/ir/attribute/attribute_like.rs @@ -13,17 +13,17 @@ pub trait AttributeLike<'c> { /// Converts a attribute into a raw object. fn to_raw(&self) -> MlirAttribute; - /// Gets a context. + /// Returns a context. fn context(&self) -> ContextRef<'c> { unsafe { ContextRef::from_raw(mlirAttributeGetContext(self.to_raw())) } } - /// Gets a type. + /// Returns a type. fn r#type(&self) -> Type { unsafe { Type::from_raw(mlirAttributeGetType(self.to_raw())) } } - /// Gets a type ID. + /// Returns a type ID. fn type_id(&self) -> TypeId<'c> { unsafe { TypeId::from_raw(mlirAttributeGetTypeID(self.to_raw())) } } diff --git a/melior/src/ir/attribute/dense_elements.rs b/melior/src/ir/attribute/dense_elements.rs index b89816983c..2edcabdd2d 100644 --- a/melior/src/ir/attribute/dense_elements.rs +++ b/melior/src/ir/attribute/dense_elements.rs @@ -30,7 +30,7 @@ impl<'c> DenseElementsAttribute<'c> { } } - /// Gets a length. + /// Returns a length. pub fn len(&self) -> usize { (unsafe { mlirElementsAttrGetNumElements(self.attribute.to_raw()) }) as usize } @@ -40,7 +40,7 @@ impl<'c> DenseElementsAttribute<'c> { self.len() == 0 } - /// Gets an i32 element. + /// Returns an i32 element. // TODO Prevent calling these type specific methods on other types. pub fn i32_element(&self, index: usize) -> Result { if !self.is_dense_int_elements() { @@ -61,7 +61,7 @@ impl<'c> DenseElementsAttribute<'c> { } } - /// Gets an i64 element. + /// Returns an i64 element. pub fn i64_element(&self, index: usize) -> Result { if !self.is_dense_int_elements() { Err(Error::ElementExpected { diff --git a/melior/src/ir/attribute/dense_i32_array.rs b/melior/src/ir/attribute/dense_i32_array.rs index 55df3f59b2..7250bc6c47 100644 --- a/melior/src/ir/attribute/dense_i32_array.rs +++ b/melior/src/ir/attribute/dense_i32_array.rs @@ -22,7 +22,7 @@ impl<'c> DenseI32ArrayAttribute<'c> { } } - /// Gets a length. + /// Returns a length. pub fn len(&self) -> usize { (unsafe { mlirDenseArrayGetNumElements(self.attribute.to_raw()) }) as usize } @@ -32,7 +32,7 @@ impl<'c> DenseI32ArrayAttribute<'c> { self.len() == 0 } - /// Gets an element. + /// Returns an element. pub fn element(&self, index: usize) -> Result { if index < self.len() { Ok(unsafe { mlirDenseI32ArrayGetElement(self.attribute.to_raw(), index as isize) }) diff --git a/melior/src/ir/attribute/dense_i64_array.rs b/melior/src/ir/attribute/dense_i64_array.rs index 46e09b93f3..e6bc727677 100644 --- a/melior/src/ir/attribute/dense_i64_array.rs +++ b/melior/src/ir/attribute/dense_i64_array.rs @@ -22,7 +22,7 @@ impl<'c> DenseI64ArrayAttribute<'c> { } } - /// Gets a length. + /// Returns a length. pub fn len(&self) -> usize { (unsafe { mlirDenseArrayGetNumElements(self.attribute.to_raw()) }) as usize } @@ -32,7 +32,7 @@ impl<'c> DenseI64ArrayAttribute<'c> { self.len() == 0 } - /// Gets an element. + /// Returns an element. pub fn element(&self, index: usize) -> Result { if index < self.len() { Ok(unsafe { mlirDenseI64ArrayGetElement(self.attribute.to_raw(), index as isize) }) diff --git a/melior/src/ir/attribute/type.rs b/melior/src/ir/attribute/type.rs index 9cb43784bc..9e839ffb93 100644 --- a/melior/src/ir/attribute/type.rs +++ b/melior/src/ir/attribute/type.rs @@ -17,7 +17,7 @@ impl<'c> TypeAttribute<'c> { unsafe { Self::from_raw(mlirTypeAttrGet(r#type.to_raw())) } } - /// Gets a type value. + /// Returns a type value. pub fn value(&self) -> Type<'c> { unsafe { Type::from_raw(mlirTypeAttrGetValue(self.to_raw())) } } diff --git a/melior/src/ir/block.rs b/melior/src/ir/block.rs index 474f054278..b6409d581f 100644 --- a/melior/src/ir/block.rs +++ b/melior/src/ir/block.rs @@ -48,7 +48,7 @@ impl<'c> Block<'c> { } } - /// Gets an argument at a position. + /// Returns an argument at a position. pub fn argument(&self, index: usize) -> Result, Error> { unsafe { if index < self.argument_count() { @@ -66,12 +66,12 @@ impl<'c> Block<'c> { } } - /// Gets a number of arguments. + /// Returns a number of arguments. pub fn argument_count(&self) -> usize { unsafe { mlirBlockGetNumArguments(self.raw) as usize } } - /// Gets the first operation. + /// Returns the first operation. pub fn first_operation(&self) -> Option { unsafe { let operation = mlirBlockGetFirstOperation(self.raw); @@ -84,19 +84,19 @@ impl<'c> Block<'c> { } } - /// Gets a terminator operation. + /// Returns a terminator operation. pub fn terminator(&self) -> Option { unsafe { OperationRef::from_option_raw(mlirBlockGetTerminator(self.raw)) } } - /// Gets a parent region. + /// Returns a parent region. // TODO Store lifetime of regions in blocks, or create another type like // `InsertedBlockRef`? pub fn parent_region(&self) -> Option> { unsafe { RegionRef::from_option_raw(mlirBlockGetParentRegion(self.raw)) } } - /// Gets a parent operation. + /// Returns a parent operation. pub fn parent_operation(&self) -> Option { unsafe { OperationRef::from_option_raw(mlirBlockGetParentOperation(self.raw)) } } @@ -187,7 +187,7 @@ impl<'c> Block<'c> { } } - /// Gets a next block in a region. + /// Returns a next block in a region. pub fn next_in_region(&self) -> Option> { unsafe { BlockRef::from_option_raw(mlirBlockGetNextInRegion(self.raw)) } } diff --git a/melior/src/ir/block/argument.rs b/melior/src/ir/block/argument.rs index 8f203db509..261628dc9c 100644 --- a/melior/src/ir/block/argument.rs +++ b/melior/src/ir/block/argument.rs @@ -15,12 +15,12 @@ pub struct BlockArgument<'c, 'a> { } impl<'c, 'a> BlockArgument<'c, 'a> { - /// Gets an argument number. + /// Returns an argument number. pub fn argument_number(&self) -> usize { unsafe { mlirBlockArgumentGetArgNumber(self.value.to_raw()) as usize } } - /// Gets an owner operation. + /// Returns an owner operation. pub fn owner(&self) -> BlockRef<'c, '_> { unsafe { BlockRef::from_raw(mlirBlockArgumentGetOwner(self.value.to_raw())) } } diff --git a/melior/src/ir/identifier.rs b/melior/src/ir/identifier.rs index 215f4a2038..5ee7a14206 100644 --- a/melior/src/ir/identifier.rs +++ b/melior/src/ir/identifier.rs @@ -26,7 +26,7 @@ impl<'c> Identifier<'c> { } } - /// Gets a context. + /// Returns a context. pub fn context(&self) -> ContextRef<'c> { unsafe { ContextRef::from_raw(mlirIdentifierGetContext(self.raw)) } } diff --git a/melior/src/ir/location.rs b/melior/src/ir/location.rs index bb5dce678e..897e5f282d 100644 --- a/melior/src/ir/location.rs +++ b/melior/src/ir/location.rs @@ -68,7 +68,7 @@ impl<'c> Location<'c> { unsafe { Self::from_raw(mlirLocationUnknownGet(context.to_raw())) } } - /// Gets a context. + /// Returns a context. pub fn context(&self) -> ContextRef<'c> { unsafe { ContextRef::from_raw(mlirLocationGetContext(self.raw)) } } diff --git a/melior/src/ir/module.rs b/melior/src/ir/module.rs index d02b76a6f1..5aab48ba9d 100644 --- a/melior/src/ir/module.rs +++ b/melior/src/ir/module.rs @@ -42,12 +42,12 @@ impl<'c> Module<'c> { unsafe { OperationRefMut::from_raw(mlirModuleGetOperation(self.raw)) } } - /// Gets a context. + /// Returns a context. pub fn context(&self) -> ContextRef<'c> { unsafe { ContextRef::from_raw(mlirModuleGetContext(self.raw)) } } - /// Gets a block of a module body. + /// Returns a block of a module body. pub fn body(&self) -> BlockRef<'c, '_> { unsafe { BlockRef::from_raw(mlirModuleGetBody(self.raw)) } } diff --git a/melior/src/ir/operation.rs b/melior/src/ir/operation.rs index 0aec6e2ccb..170b147336 100644 --- a/melior/src/ir/operation.rs +++ b/melior/src/ir/operation.rs @@ -41,29 +41,29 @@ pub struct Operation<'c> { } impl<'c> Operation<'c> { - /// Gets a context. + /// Returns a context. pub fn context(&self) -> ContextRef<'c> { unsafe { ContextRef::from_raw(mlirOperationGetContext(self.raw)) } } - /// Gets a name. + /// Returns a name. pub fn name(&self) -> Identifier<'c> { unsafe { Identifier::from_raw(mlirOperationGetName(self.raw)) } } - /// Gets a block. + /// Returns a block. // TODO Store lifetime of block in operations, or create another type like // `AppendedOperationRef`? pub fn block(&self) -> Option> { unsafe { BlockRef::from_option_raw(mlirOperationGetBlock(self.raw)) } } - /// Gets the number of operands. + /// Returns the number of operands. pub fn operand_count(&self) -> usize { unsafe { mlirOperationGetNumOperands(self.raw) as usize } } - /// Gets the operand at a position. + /// Returns the operand at a position. pub fn operand(&self, index: usize) -> Result, Error> { if index < self.operand_count() { Ok(unsafe { Value::from_raw(mlirOperationGetOperand(self.raw, index as isize)) }) @@ -76,17 +76,17 @@ impl<'c> Operation<'c> { } } - /// Gets all operands. + /// Returns all operands. pub fn operands(&self) -> impl Iterator> { (0..self.operand_count()).map(|index| self.operand(index).expect("valid operand index")) } - /// Gets the number of results. + /// Returns the number of results. pub fn result_count(&self) -> usize { unsafe { mlirOperationGetNumResults(self.raw) as usize } } - /// Gets a result at a position. + /// Returns a result at a position. pub fn result(&self, index: usize) -> Result, Error> { if index < self.result_count() { Ok(unsafe { @@ -101,17 +101,17 @@ impl<'c> Operation<'c> { } } - /// Gets all results. + /// Returns all results. pub fn results(&self) -> impl Iterator> { (0..self.result_count()).map(|index| self.result(index).expect("valid result index")) } - /// Gets the number of regions. + /// Returns the number of regions. pub fn region_count(&self) -> usize { unsafe { mlirOperationGetNumRegions(self.raw) as usize } } - /// Gets a region at a position. + /// Returns a region at a position. pub fn region(&self, index: usize) -> Result, Error> { if index < self.region_count() { Ok(unsafe { RegionRef::from_raw(mlirOperationGetRegion(self.raw, index as isize)) }) @@ -124,17 +124,17 @@ impl<'c> Operation<'c> { } } - /// Gets all regions. + /// Returns all regions. pub fn regions(&self) -> impl Iterator> { (0..self.region_count()).map(|index| self.region(index).expect("valid result index")) } - /// Gets the number of successors. + /// Returns the number of successors. pub fn successor_count(&self) -> usize { unsafe { mlirOperationGetNumSuccessors(self.raw) as usize } } - /// Gets a successor at a position. + /// Returns a successor at a position. pub fn successor(&self, index: usize) -> Result, Error> { if index < self.successor_count() { Ok(unsafe { BlockRef::from_raw(mlirOperationGetSuccessor(self.raw, index as isize)) }) @@ -147,18 +147,18 @@ impl<'c> Operation<'c> { } } - /// Gets all successors. + /// Returns all successors. pub fn successors(&self) -> impl Iterator> { (0..self.successor_count()) .map(|index| self.successor(index).expect("valid successor index")) } - /// Gets the number of attributes. + /// Returns the number of attributes. pub fn attribute_count(&self) -> usize { unsafe { mlirOperationGetNumAttributes(self.raw) as usize } } - /// Gets a attribute at a position. + /// Returns a attribute at a position. pub fn attribute_at(&self, index: usize) -> Result<(Identifier<'c>, Attribute<'c>), Error> { if index < self.attribute_count() { unsafe { @@ -177,13 +177,13 @@ impl<'c> Operation<'c> { } } - /// Gets all attributes. + /// Returns all attributes. pub fn attributes(&self) -> impl Iterator, Attribute<'c>)> + '_ { (0..self.attribute_count()) .map(|index| self.attribute_at(index).expect("valid attribute index")) } - /// Gets a attribute with the given name. + /// Returns a attribute with the given name. pub fn attribute(&self, name: &str) -> Result, Error> { unsafe { Attribute::from_option_raw(mlirOperationGetAttributeByName( @@ -217,7 +217,7 @@ impl<'c> Operation<'c> { .ok_or(Error::AttributeNotFound(name.into())) } - /// Gets the next operation in the same block. + /// Returns the next operation in the same block. pub fn next_in_block(&self) -> Option> { unsafe { OperationRef::from_option_raw(mlirOperationGetNextInBlock(self.raw)) } } @@ -337,12 +337,12 @@ pub struct OperationRef<'c, 'a> { } impl<'c, 'a> OperationRef<'c, 'a> { - /// Gets a result at a position. + /// Returns a result at a position. pub fn result(self, index: usize) -> Result, Error> { unsafe { self.to_ref() }.result(index) } - /// Gets an operation. + /// Returns an operation. /// /// This function is different from `deref` because the correct lifetime is /// kept for the return type. diff --git a/melior/src/ir/operation/result.rs b/melior/src/ir/operation/result.rs index 682f3387eb..914acfdb0a 100644 --- a/melior/src/ir/operation/result.rs +++ b/melior/src/ir/operation/result.rs @@ -12,12 +12,12 @@ pub struct OperationResult<'c, 'a> { } impl<'c, 'a> OperationResult<'c, 'a> { - /// Gets a result number. + /// Returns a result number. pub fn result_number(&self) -> usize { unsafe { mlirOpResultGetResultNumber(self.value.to_raw()) as usize } } - /// Gets an owner operation. + /// Returns an owner operation. pub fn owner(&self) -> OperationRef { unsafe { OperationRef::from_raw(mlirOpResultGetOwner(self.value.to_raw())) } } diff --git a/melior/src/ir/region.rs b/melior/src/ir/region.rs index 95db6432b3..4d5e91cdff 100644 --- a/melior/src/ir/region.rs +++ b/melior/src/ir/region.rs @@ -26,7 +26,7 @@ impl<'c> Region<'c> { } } - /// Gets the first block in a region. + /// Returns the first block in a region. pub fn first_block(&self) -> Option> { unsafe { let block = mlirRegionGetFirstBlock(self.raw); diff --git a/melior/src/ir/type/function.rs b/melior/src/ir/type/function.rs index 1bf3ea7aa1..0e9ecff9d1 100644 --- a/melior/src/ir/type/function.rs +++ b/melior/src/ir/type/function.rs @@ -27,7 +27,7 @@ impl<'c> FunctionType<'c> { } } - /// Gets an input at a position. + /// Returns an input at a position. pub fn input(&self, index: usize) -> Result, Error> { if index < self.input_count() { unsafe { @@ -45,7 +45,7 @@ impl<'c> FunctionType<'c> { } } - /// Gets a result at a position. + /// Returns a result at a position. pub fn result(&self, index: usize) -> Result, Error> { if index < self.result_count() { unsafe { @@ -63,12 +63,12 @@ impl<'c> FunctionType<'c> { } } - /// Gets a number of inputs. + /// Returns a number of inputs. pub fn input_count(&self) -> usize { unsafe { mlirFunctionTypeGetNumInputs(self.r#type.to_raw()) as usize } } - /// Gets a number of results. + /// Returns a number of results. pub fn result_count(&self) -> usize { unsafe { mlirFunctionTypeGetNumResults(self.r#type.to_raw()) as usize } } diff --git a/melior/src/ir/type/integer.rs b/melior/src/ir/type/integer.rs index b4c2a53447..e5448af5ff 100644 --- a/melior/src/ir/type/integer.rs +++ b/melior/src/ir/type/integer.rs @@ -30,7 +30,7 @@ impl<'c> IntegerType<'c> { unsafe { Self::from_raw(mlirIntegerTypeUnsignedGet(context.to_raw(), bits)) } } - /// Gets a bit width. + /// Returns a bit width. pub fn width(&self) -> u32 { unsafe { mlirIntegerTypeGetWidth(self.to_raw()) } } diff --git a/melior/src/ir/type/mem_ref.rs b/melior/src/ir/type/mem_ref.rs index 4815be9e5c..3789ad535f 100644 --- a/melior/src/ir/type/mem_ref.rs +++ b/melior/src/ir/type/mem_ref.rs @@ -53,17 +53,17 @@ impl<'c> MemRefType<'c> { } } - /// Gets a layout. + /// Returns a layout. pub fn layout(&self) -> Attribute<'c> { unsafe { Attribute::from_raw(mlirMemRefTypeGetLayout(self.r#type.to_raw())) } } - /// Gets an affine map. + /// Returns an affine map. pub fn affine_map(&self) -> AffineMap<'c> { unsafe { AffineMap::from_raw(mlirMemRefTypeGetAffineMap(self.r#type.to_raw())) } } - /// Gets a memory space. + /// Returns a memory space. pub fn memory_space(&self) -> Option> { unsafe { Attribute::from_option_raw(mlirMemRefTypeGetMemorySpace(self.r#type.to_raw())) } } diff --git a/melior/src/ir/type/ranked_tensor.rs b/melior/src/ir/type/ranked_tensor.rs index 6b6f21f054..1459a87115 100644 --- a/melior/src/ir/type/ranked_tensor.rs +++ b/melior/src/ir/type/ranked_tensor.rs @@ -45,7 +45,7 @@ impl<'c> RankedTensorType<'c> { } } - /// Gets an encoding. + /// Returns an encoding. pub fn encoding(&self) -> Option> { unsafe { Attribute::from_option_raw(mlirRankedTensorTypeGetEncoding(self.r#type.to_raw())) } } diff --git a/melior/src/ir/type/shaped_type_like.rs b/melior/src/ir/type/shaped_type_like.rs index f2bcd80bbb..a48d483721 100644 --- a/melior/src/ir/type/shaped_type_like.rs +++ b/melior/src/ir/type/shaped_type_like.rs @@ -8,17 +8,17 @@ use mlir_sys::{ /// Trait for shaped types. pub trait ShapedTypeLike<'c>: TypeLike<'c> { - /// Gets a element type. + /// Returns a element type. fn element(&self) -> Type<'c> { unsafe { Type::from_raw(mlirShapedTypeGetElementType(self.to_raw())) } } - /// Gets a rank. + /// Returns a rank. fn rank(&self) -> usize { (unsafe { mlirShapedTypeGetRank(self.to_raw()) }) as usize } - /// Gets a dimension size. + /// Returns a dimension size. fn dim_size(&self, index: usize) -> Result { if index < self.rank() { Ok((unsafe { mlirShapedTypeGetDimSize(self.to_raw(), index as isize) }) as usize) diff --git a/melior/src/ir/type/tuple.rs b/melior/src/ir/type/tuple.rs index 0fb56e3ae1..ece14a6d1d 100644 --- a/melior/src/ir/type/tuple.rs +++ b/melior/src/ir/type/tuple.rs @@ -20,7 +20,7 @@ impl<'c> TupleType<'c> { } } - /// Gets a field at a position. + /// Returns a field at a position. pub fn r#type(&self, index: usize) -> Result { if index < self.type_count() { unsafe { @@ -38,7 +38,7 @@ impl<'c> TupleType<'c> { } } - /// Gets a number of fields. + /// Returns a number of fields. pub fn type_count(&self) -> usize { unsafe { mlirTupleTypeGetNumTypes(self.r#type.to_raw()) as usize } } diff --git a/melior/src/ir/type/type_like.rs b/melior/src/ir/type/type_like.rs index 21a0c9f590..06d65a27b7 100644 --- a/melior/src/ir/type/type_like.rs +++ b/melior/src/ir/type/type_like.rs @@ -7,12 +7,12 @@ pub trait TypeLike<'c> { /// Converts a type into a raw object. fn to_raw(&self) -> MlirType; - /// Gets a context. + /// Returns a context. fn context(&self) -> ContextRef<'c> { unsafe { ContextRef::from_raw(mlirTypeGetContext(self.to_raw())) } } - /// Gets an ID. + /// Returns an ID. fn id(&self) -> TypeId<'c> { unsafe { TypeId::from_raw(mlirTypeGetTypeID(self.to_raw())) } } diff --git a/melior/src/ir/value/value_like.rs b/melior/src/ir/value/value_like.rs index 4ed5652072..71b49d5a0c 100644 --- a/melior/src/ir/value/value_like.rs +++ b/melior/src/ir/value/value_like.rs @@ -8,7 +8,7 @@ pub trait ValueLike<'c> { /// Converts a value into a raw value. fn to_raw(&self) -> MlirValue; - /// Gets a type. + /// Returns a type. fn r#type(&self) -> Type<'c> { unsafe { Type::from_raw(mlirValueGetType(self.to_raw())) } } diff --git a/melior/src/pass/manager.rs b/melior/src/pass/manager.rs index dfae3496e7..23465e6ebf 100644 --- a/melior/src/pass/manager.rs +++ b/melior/src/pass/manager.rs @@ -26,7 +26,7 @@ impl<'c> PassManager<'c> { } } - /// Gets an operation pass manager for nested operations corresponding to a + /// Returns an operation pass manager for nested operations corresponding to a /// given name. pub fn nested_under(&self, name: &str) -> OperationPassManager { let name = StringRef::new(name); diff --git a/melior/src/pass/operation_manager.rs b/melior/src/pass/operation_manager.rs index 41e4051538..df772b12ad 100644 --- a/melior/src/pass/operation_manager.rs +++ b/melior/src/pass/operation_manager.rs @@ -18,7 +18,7 @@ pub struct OperationPassManager<'c, 'a> { } impl<'c, 'a> OperationPassManager<'c, 'a> { - /// Gets an operation pass manager for nested operations corresponding to a + /// Returns an operation pass manager for nested operations corresponding to a /// given name. pub fn nested_under(&self, name: &str) -> Self { let name = StringRef::new(name); From e4ae91f984a621779b7c7d5f6c10fdc006d91be3 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 20 Feb 2024 09:07:45 +0900 Subject: [PATCH 098/108] Fix more lifetimes (#472) - **Rename gets returns** - **Remove todo** --- melior/src/ir/block.rs | 8 ++++---- melior/src/ir/operation.rs | 1 - melior/src/ir/operation/result.rs | 2 +- melior/src/pass/external.rs | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/melior/src/ir/block.rs b/melior/src/ir/block.rs index b6409d581f..eb6724e504 100644 --- a/melior/src/ir/block.rs +++ b/melior/src/ir/block.rs @@ -72,7 +72,7 @@ impl<'c> Block<'c> { } /// Returns the first operation. - pub fn first_operation(&self) -> Option { + pub fn first_operation(&self) -> Option> { unsafe { let operation = mlirBlockGetFirstOperation(self.raw); @@ -85,7 +85,7 @@ impl<'c> Block<'c> { } /// Returns a terminator operation. - pub fn terminator(&self) -> Option { + pub fn terminator(&self) -> Option> { unsafe { OperationRef::from_option_raw(mlirBlockGetTerminator(self.raw)) } } @@ -97,7 +97,7 @@ impl<'c> Block<'c> { } /// Returns a parent operation. - pub fn parent_operation(&self) -> Option { + pub fn parent_operation(&self) -> Option> { unsafe { OperationRef::from_option_raw(mlirBlockGetParentOperation(self.raw)) } } @@ -143,7 +143,7 @@ impl<'c> Block<'c> { /// Inserts an operation after another. pub fn insert_operation_after( &self, - one: OperationRef, + one: OperationRef<'c, '_>, other: Operation<'c>, ) -> OperationRef<'c, '_> { unsafe { diff --git a/melior/src/ir/operation.rs b/melior/src/ir/operation.rs index 170b147336..90c91690bd 100644 --- a/melior/src/ir/operation.rs +++ b/melior/src/ir/operation.rs @@ -351,7 +351,6 @@ impl<'c, 'a> OperationRef<'c, 'a> { /// /// The returned reference is safe to use only in the lifetime scope of the /// operation reference. - // TODO Remove this? pub unsafe fn to_ref(&self) -> &'a Operation<'c> { // As we can't deref OperationRef<'a> into `&'a Operation`, we forcibly cast its // lifetime here to extend it from the lifetime of `ObjectRef<'a>` itself into diff --git a/melior/src/ir/operation/result.rs b/melior/src/ir/operation/result.rs index 914acfdb0a..84869688d3 100644 --- a/melior/src/ir/operation/result.rs +++ b/melior/src/ir/operation/result.rs @@ -18,7 +18,7 @@ impl<'c, 'a> OperationResult<'c, 'a> { } /// Returns an owner operation. - pub fn owner(&self) -> OperationRef { + pub fn owner(&self) -> OperationRef<'c, '_> { unsafe { OperationRef::from_raw(mlirOpResultGetOwner(self.value.to_raw())) } } diff --git a/melior/src/pass/external.rs b/melior/src/pass/external.rs index 75fcff454a..4899617bdf 100644 --- a/melior/src/pass/external.rs +++ b/melior/src/pass/external.rs @@ -315,7 +315,7 @@ mod tests { let pass_manager = PassManager::new(&context); pass_manager.add_pass(create_external( - |operation: OperationRef, pass: ExternalPass<'_>| { + |operation: OperationRef, pass: ExternalPass| { assert!(operation.verify()); assert!( operation From 0d61d34d7e4febc9f5883c526f93872aa0f602ba Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 20 Feb 2024 09:11:44 +0900 Subject: [PATCH 099/108] Bump versions (#473) --- Cargo.lock | 4 ++-- macro/Cargo.toml | 2 +- melior/Cargo.toml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dba89c6d9b..2d7fd8b8b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -595,7 +595,7 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "melior" -version = "0.15.4" +version = "0.16.0" dependencies = [ "dashmap", "indoc", @@ -608,7 +608,7 @@ dependencies = [ [[package]] name = "melior-macro" -version = "0.9.2" +version = "0.10.0" dependencies = [ "comrak", "convert_case", diff --git a/macro/Cargo.toml b/macro/Cargo.toml index 27b3f805c3..2f39802c7c 100644 --- a/macro/Cargo.toml +++ b/macro/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "melior-macro" description = "Internal macros for Melior" -version = "0.9.2" +version = "0.10.0" edition = "2021" license = "Apache-2.0" repository = "https://github.com/raviqqe/melior" diff --git a/melior/Cargo.toml b/melior/Cargo.toml index 5ed6998311..6af2d45ff5 100644 --- a/melior/Cargo.toml +++ b/melior/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "melior" description = "The rustic MLIR bindings in Rust" -version = "0.15.4" +version = "0.16.0" edition = "2021" license = "Apache-2.0" repository = "https://github.com/raviqqe/melior" @@ -13,7 +13,7 @@ ods-dialects = [] [dependencies] dashmap = "5.5.3" -melior-macro = { version = "0.9", path = "../macro" } +melior-macro = { version = "0.10", path = "../macro" } mlir-sys = "0.2" once_cell = "1" From 44a53aa97ea11eca6509d97e78a69a8a6a7c739f Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 20 Feb 2024 09:34:04 +0900 Subject: [PATCH 100/108] Add `remove_in_parent` (#474) --- melior/src/ir/block.rs | 26 +++++++++-------- melior/src/ir/operation.rs | 42 ++++++++++++++++++++++++++-- melior/src/pass/manager.rs | 4 +-- melior/src/pass/operation_manager.rs | 4 +-- 4 files changed, 59 insertions(+), 17 deletions(-) diff --git a/melior/src/ir/block.rs b/melior/src/ir/block.rs index eb6724e504..4163735706 100644 --- a/melior/src/ir/block.rs +++ b/melior/src/ir/block.rs @@ -3,7 +3,9 @@ mod argument; pub use self::argument::BlockArgument; -use super::{Location, Operation, OperationRef, RegionRef, Type, TypeLike, Value}; +use super::{ + operation::OperationRefMut, Location, Operation, OperationRef, RegionRef, Type, TypeLike, Value, +}; use crate::{context::Context, utility::print_callback, Error}; use mlir_sys::{ mlirBlockAddArgument, mlirBlockAppendOwnedOperation, mlirBlockCreate, mlirBlockDestroy, @@ -71,24 +73,26 @@ impl<'c> Block<'c> { unsafe { mlirBlockGetNumArguments(self.raw) as usize } } - /// Returns the first operation. + /// Returns a reference to the first operation. pub fn first_operation(&self) -> Option> { - unsafe { - let operation = mlirBlockGetFirstOperation(self.raw); + unsafe { OperationRef::from_option_raw(mlirBlockGetFirstOperation(self.raw)) } + } - if operation.ptr.is_null() { - None - } else { - Some(OperationRef::from_raw(operation)) - } - } + /// Returns a mutable reference to the first operation. + pub fn first_operation_mut(&mut self) -> Option> { + unsafe { OperationRefMut::from_option_raw(mlirBlockGetFirstOperation(self.raw)) } } - /// Returns a terminator operation. + /// Returns a reference to a terminator operation. pub fn terminator(&self) -> Option> { unsafe { OperationRef::from_option_raw(mlirBlockGetTerminator(self.raw)) } } + /// Returns a mutable reference to a terminator operation. + pub fn terminator_mut(&mut self) -> Option> { + unsafe { OperationRefMut::from_option_raw(mlirBlockGetTerminator(self.raw)) } + } + /// Returns a parent region. // TODO Store lifetime of regions in blocks, or create another type like // `InsertedBlockRef`? diff --git a/melior/src/ir/operation.rs b/melior/src/ir/operation.rs index 90c91690bd..2fa4557457 100644 --- a/melior/src/ir/operation.rs +++ b/melior/src/ir/operation.rs @@ -24,7 +24,7 @@ use mlir_sys::{ mlirOperationGetNumAttributes, mlirOperationGetNumOperands, mlirOperationGetNumRegions, mlirOperationGetNumResults, mlirOperationGetNumSuccessors, mlirOperationGetOperand, mlirOperationGetRegion, mlirOperationGetResult, mlirOperationGetSuccessor, mlirOperationPrint, - mlirOperationPrintWithFlags, mlirOperationRemoveAttributeByName, + mlirOperationPrintWithFlags, mlirOperationRemoveAttributeByName, mlirOperationRemoveFromParent, mlirOperationSetAttributeByName, mlirOperationVerify, MlirOperation, }; use std::{ @@ -217,11 +217,21 @@ impl<'c> Operation<'c> { .ok_or(Error::AttributeNotFound(name.into())) } - /// Returns the next operation in the same block. + /// Returns a reference to the next operation in the same block. pub fn next_in_block(&self) -> Option> { unsafe { OperationRef::from_option_raw(mlirOperationGetNextInBlock(self.raw)) } } + /// Returns a mutable reference to the next operation in the same block. + pub fn next_in_block_mut(&self) -> Option> { + unsafe { OperationRefMut::from_option_raw(mlirOperationGetNextInBlock(self.raw)) } + } + + /// Removes itself from a parent block. + pub fn remove_from_parent(&mut self) { + unsafe { mlirOperationRemoveFromParent(self.raw) } + } + /// Verifies an operation. pub fn verify(&self) -> bool { unsafe { mlirOperationVerify(self.raw) } @@ -716,4 +726,32 @@ mod tests { Ok("\"foo\"() : () -> () [unknown]".into()) ); } + + #[test] + fn remove_from_parent() { + let context = create_test_context(); + context.set_allow_unregistered_dialects(true); + let mut block = Block::new(&[]); + + let first_operation = block.append_operation( + OperationBuilder::new("foo", Location::unknown(&context)) + .add_results(&[Type::index(&context)]) + .build() + .unwrap(), + ); + block.append_operation( + OperationBuilder::new("bar", Location::unknown(&context)) + .add_operands(&[first_operation.result(0).unwrap().into()]) + .build() + .unwrap(), + ); + block + .first_operation_mut() + .unwrap() + .next_in_block_mut() + .unwrap() + .remove_from_parent(); + + assert_eq!(block.first_operation().unwrap().next_in_block(), None); + } } diff --git a/melior/src/pass/manager.rs b/melior/src/pass/manager.rs index 23465e6ebf..c69ca15b25 100644 --- a/melior/src/pass/manager.rs +++ b/melior/src/pass/manager.rs @@ -26,8 +26,8 @@ impl<'c> PassManager<'c> { } } - /// Returns an operation pass manager for nested operations corresponding to a - /// given name. + /// Returns an operation pass manager for nested operations corresponding to + /// a given name. pub fn nested_under(&self, name: &str) -> OperationPassManager { let name = StringRef::new(name); diff --git a/melior/src/pass/operation_manager.rs b/melior/src/pass/operation_manager.rs index df772b12ad..df1086a7e0 100644 --- a/melior/src/pass/operation_manager.rs +++ b/melior/src/pass/operation_manager.rs @@ -18,8 +18,8 @@ pub struct OperationPassManager<'c, 'a> { } impl<'c, 'a> OperationPassManager<'c, 'a> { - /// Returns an operation pass manager for nested operations corresponding to a - /// given name. + /// Returns an operation pass manager for nested operations corresponding to + /// a given name. pub fn nested_under(&self, name: &str) -> Self { let name = StringRef::new(name); From 54ca072987d93a07a125736fb85c725ec79223d2 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 20 Feb 2024 21:10:10 +0900 Subject: [PATCH 101/108] Fix remove test (#475) --- melior/src/ir/operation.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/melior/src/ir/operation.rs b/melior/src/ir/operation.rs index 2fa4557457..34de621bc7 100644 --- a/melior/src/ir/operation.rs +++ b/melior/src/ir/operation.rs @@ -731,27 +731,28 @@ mod tests { fn remove_from_parent() { let context = create_test_context(); context.set_allow_unregistered_dialects(true); + + let location = Location::unknown(&context); let mut block = Block::new(&[]); let first_operation = block.append_operation( - OperationBuilder::new("foo", Location::unknown(&context)) + OperationBuilder::new("foo", location) .add_results(&[Type::index(&context)]) .build() .unwrap(), ); block.append_operation( - OperationBuilder::new("bar", Location::unknown(&context)) + OperationBuilder::new("bar", location) .add_operands(&[first_operation.result(0).unwrap().into()]) .build() .unwrap(), ); - block - .first_operation_mut() - .unwrap() - .next_in_block_mut() - .unwrap() - .remove_from_parent(); + block.first_operation_mut().unwrap().remove_from_parent(); assert_eq!(block.first_operation().unwrap().next_in_block(), None); + assert_eq!( + block.first_operation().unwrap().to_string(), + "\"bar\"(<>) : (index) -> ()" + ); } } From 7be430bfde9d7bac6c3c2889974cbd68d73470a9 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Tue, 20 Feb 2024 21:26:34 +0900 Subject: [PATCH 102/108] Parent operation (#476) --- melior/src/ir/operation.rs | 54 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/melior/src/ir/operation.rs b/melior/src/ir/operation.rs index 34de621bc7..8ad1f9ef81 100644 --- a/melior/src/ir/operation.rs +++ b/melior/src/ir/operation.rs @@ -23,8 +23,9 @@ use mlir_sys::{ mlirOperationGetContext, mlirOperationGetName, mlirOperationGetNextInBlock, mlirOperationGetNumAttributes, mlirOperationGetNumOperands, mlirOperationGetNumRegions, mlirOperationGetNumResults, mlirOperationGetNumSuccessors, mlirOperationGetOperand, - mlirOperationGetRegion, mlirOperationGetResult, mlirOperationGetSuccessor, mlirOperationPrint, - mlirOperationPrintWithFlags, mlirOperationRemoveAttributeByName, mlirOperationRemoveFromParent, + mlirOperationGetParentOperation, mlirOperationGetRegion, mlirOperationGetResult, + mlirOperationGetSuccessor, mlirOperationPrint, mlirOperationPrintWithFlags, + mlirOperationRemoveAttributeByName, mlirOperationRemoveFromParent, mlirOperationSetAttributeByName, mlirOperationVerify, MlirOperation, }; use std::{ @@ -227,6 +228,16 @@ impl<'c> Operation<'c> { unsafe { OperationRefMut::from_option_raw(mlirOperationGetNextInBlock(self.raw)) } } + /// Returns a reference to the next operation in the same block. + pub fn previous_in_block(&self) -> Option> { + unsafe { OperationRef::from_option_raw(mlirOperationGetNextInBlock(self.raw)) } + } + + /// Returns a reference to a parent operation. + pub fn parent_operation(&self) -> Option> { + unsafe { OperationRef::from_option_raw(mlirOperationGetParentOperation(self.raw)) } + } + /// Removes itself from a parent block. pub fn remove_from_parent(&mut self) { unsafe { mlirOperationRemoveFromParent(self.raw) } @@ -755,4 +766,43 @@ mod tests { "\"bar\"(<>) : (index) -> ()" ); } + + #[test] + fn parent_operation() { + let context = create_test_context(); + context.set_allow_unregistered_dialects(true); + + let location = Location::unknown(&context); + let block = Block::new(&[]); + + let operation = block.append_operation( + OperationBuilder::new("foo", location) + .add_results(&[Type::index(&context)]) + .add_regions([{ + let region = Region::new(); + + let block = Block::new(&[]); + block.append_operation(OperationBuilder::new("bar", location).build().unwrap()); + + region.append_block(block); + region + }]) + .build() + .unwrap(), + ); + + assert_eq!(operation.parent_operation(), None); + assert_eq!( + &operation + .region(0) + .unwrap() + .first_block() + .unwrap() + .first_operation() + .unwrap() + .parent_operation() + .unwrap(), + &operation + ); + } } From 6ccd1fb89c2fbca9930b353e65de5c73c8e3a0d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:31:55 +0000 Subject: [PATCH 103/108] build(deps): Bump insta from 1.34.0 to 1.35.1 (#477) Bumps [insta](https://github.com/mitsuhiko/insta) from 1.34.0 to 1.35.1.
Changelog

Sourced from insta's changelog.

1.35.1

  • Fixed a bug with diffs showing bogus newlines.

1.35.0

  • Fixed a crash when a file named .config was in the root.
  • Added new alternative match .. { ... } syntax to redactions for better rustfmt support. (#428)
  • The --package parameter can be supplied multiple times now. (#427)
  • Leading newlines in snapshots are now ignored to resolve issues with inline snapshots that were never able to match. (#444)
  • cargo insta test now accepts the --test parameter multiple times. (#437)
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=insta&package-manager=cargo&previous-version=1.34.0&new-version=1.35.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- melior/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d7fd8b8b2..57652a683e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -511,9 +511,9 @@ checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8" [[package]] name = "insta" -version = "1.34.0" +version = "1.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d64600be34b2fcfc267740a243fa7744441bb4947a619ac4e5bb6507f35fbfc" +checksum = "7c985c1bef99cf13c58fade470483d81a2bfe846ebde60ed28cc2dddec2df9e2" dependencies = [ "console", "lazy_static", diff --git a/melior/Cargo.toml b/melior/Cargo.toml index 6af2d45ff5..b8857c1e3b 100644 --- a/melior/Cargo.toml +++ b/melior/Cargo.toml @@ -19,5 +19,5 @@ once_cell = "1" [dev-dependencies] indoc = "2.0.4" -insta = "1.34.0" +insta = "1.35.1" pretty_assertions = "1.4.0" From ddb2dd9a0ac0094561e4a5e9384613aad296c796 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:32:50 +0000 Subject: [PATCH 104/108] build(deps): Bump syn from 2.0.49 to 2.0.50 (#478) Bumps [syn](https://github.com/dtolnay/syn) from 2.0.49 to 2.0.50.
Release notes

Sourced from syn's releases.

2.0.50

  • Fix unused_imports warnings when compiled by rustc 1.78
Commits
  • 0dae015 Release 2.0.50
  • 2b493c3 Update location of Pat variant aliases
  • 07a435d Fix doc links now that crate::* is no longer imported
  • 713f932 Eliminate glob imports
  • 6eb82a9 Eliminate glob imports from codegen
  • 896a730 Eliminate glob imports from examples
  • 866c80c Update test suite to nightly-2024-02-18
  • d4b499e Update test suite to nightly-2024-02-17
  • 38956e6 Update test suite to nightly-2024-02-16
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=syn&package-manager=cargo&previous-version=2.0.49&new-version=2.0.50)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 57652a683e..815194cccc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,7 +105,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.49", + "syn 2.0.50", "which", ] @@ -128,7 +128,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.49", + "syn 2.0.50", "which", ] @@ -226,7 +226,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.49", + "syn 2.0.50", ] [[package]] @@ -619,7 +619,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.49", + "syn 2.0.50", "tblgen", "unindent", ] @@ -760,7 +760,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn 2.0.49", + "syn 2.0.50", ] [[package]] @@ -897,7 +897,7 @@ checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.49", + "syn 2.0.50", ] [[package]] @@ -963,9 +963,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.49" +version = "2.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915aea9e586f80826ee59f8453c1101f9d1c4b3964cd2460185ee8e299ada496" +checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb" dependencies = [ "proc-macro2", "quote", @@ -1033,7 +1033,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.49", + "syn 2.0.50", ] [[package]] From 0e472c82116ef1be7633ea1e1394232819dd55fa Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sat, 24 Feb 2024 18:55:57 +1100 Subject: [PATCH 105/108] Split type parameters in type states (#465) --- .../dialect/generation/operation_builder.rs | 17 +-- macro/src/dialect/operation.rs | 42 ++++-- macro/src/dialect/operation/attribute.rs | 10 +- macro/src/dialect/operation/builder.rs | 31 ++-- .../dialect/operation/builder/type_state.rs | 137 ++++++++++++++++++ .../operation/builder/type_state_item.rs | 27 ---- .../operation/builder/type_state_list.rs | 54 ------- 7 files changed, 195 insertions(+), 123 deletions(-) create mode 100644 macro/src/dialect/operation/builder/type_state.rs delete mode 100644 macro/src/dialect/operation/builder/type_state_item.rs delete mode 100644 macro/src/dialect/operation/builder/type_state_list.rs diff --git a/macro/src/dialect/generation/operation_builder.rs b/macro/src/dialect/generation/operation_builder.rs index 9f4a92df31..860e4c8da3 100644 --- a/macro/src/dialect/generation/operation_builder.rs +++ b/macro/src/dialect/generation/operation_builder.rs @@ -41,15 +41,14 @@ pub fn generate_operation_builder(builder: &OperationBuilder) -> TokenStream { "A builder for {}.", builder.operation().documentation_name() ); - let type_arguments = builder.type_state().parameters(); - let state_types = builder.type_state().parameters(); + let type_parameters = builder.type_state().parameters().collect::>(); quote! { #[doc = #doc] - pub struct #identifier<'c, #(#type_arguments),*> { + pub struct #identifier<'c, #(#type_parameters),*> { builder: ::melior::ir::operation::OperationBuilder<'c>, context: &'c ::melior::Context, - _state: ::std::marker::PhantomData<(#(#state_types),*)>, + _state: ::std::marker::PhantomData<(#(#type_parameters),*)>, } #new_fn @@ -90,8 +89,8 @@ fn generate_field_fn(builder: &OperationBuilder, field: &impl OperationField) -> } } else { let parameters = builder.type_state().parameters_without(field.name()); - let arguments_set = builder.type_state().arguments_set(field.name(), true); - let arguments_unset = builder.type_state().arguments_set(field.name(), false); + let arguments_set = builder.type_state().arguments_with(field.name(), true); + let arguments_unset = builder.type_state().arguments_with(field.name(), false); quote! { impl<'c, #(#parameters),*> #builder_identifier<'c, #(#arguments_unset),*> { @@ -109,7 +108,7 @@ fn generate_field_fn(builder: &OperationBuilder, field: &impl OperationField) -> fn generate_build_fn(builder: &OperationBuilder) -> TokenStream { let identifier = builder.identifier(); - let arguments = builder.type_state().arguments_all_set(true); + let arguments = builder.type_state().arguments_with_all(true); let operation_identifier = format_ident!("{}", &builder.operation().name()); let error = format!("should be a valid {operation_identifier}"); let maybe_infer = builder @@ -129,7 +128,7 @@ fn generate_build_fn(builder: &OperationBuilder) -> TokenStream { fn generate_new_fn(builder: &OperationBuilder) -> TokenStream { let identifier = builder.identifier(); let name = &builder.operation().full_operation_name(); - let arguments = builder.type_state().arguments_all_set(false); + let arguments = builder.type_state().arguments_with_all(false); quote! { impl<'c> #identifier<'c, #(#arguments),*> { @@ -146,7 +145,7 @@ fn generate_new_fn(builder: &OperationBuilder) -> TokenStream { pub fn generate_operation_builder_fn(builder: &OperationBuilder) -> TokenStream { let builder_ident = builder.identifier(); - let arguments = builder.type_state().arguments_all_set(false); + let arguments = builder.type_state().arguments_with_all(false); quote! { /// Creates a builder. diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index cf1b2ac781..d4ec239438 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -185,22 +185,42 @@ impl<'a> Operation<'a> { self.attributes.iter().chain(&self.derived_attributes) } + pub fn required_results(&self) -> impl Iterator { + if self.can_infer_type { + Default::default() + } else { + self.results.iter() + } + .filter(|field| !field.is_optional()) + } + + pub fn required_operands(&self) -> impl Iterator { + self.operands.iter().filter(|field| !field.is_optional()) + } + + pub fn required_regions(&self) -> impl Iterator { + self.regions.iter().filter(|field| !field.is_optional()) + } + + pub fn required_successors(&self) -> impl Iterator { + self.successors.iter().filter(|field| !field.is_optional()) + } + + pub fn required_attributes(&self) -> impl Iterator { + self.attributes.iter().filter(|field| !field.is_optional()) + } + pub fn required_fields(&self) -> impl Iterator { fn convert(field: &impl OperationField) -> &dyn OperationField { field } - (if self.can_infer_type { - Default::default() - } else { - self.results.iter() - }) - .map(convert) - .chain(self.operands.iter().map(convert)) - .chain(self.regions.iter().map(convert)) - .chain(self.successors.iter().map(convert)) - .chain(self.attributes().map(convert)) - .filter(|field| !field.is_optional()) + self.required_results() + .map(convert) + .chain(self.required_operands().map(convert)) + .chain(self.required_regions().map(convert)) + .chain(self.required_successors().map(convert)) + .chain(self.required_attributes().map(convert)) } fn collect_successors(definition: Record<'a>) -> Result, Error> { diff --git a/macro/src/dialect/operation/attribute.rs b/macro/src/dialect/operation/attribute.rs index 55f0bbb0c7..9da7bcf32d 100644 --- a/macro/src/dialect/operation/attribute.rs +++ b/macro/src/dialect/operation/attribute.rs @@ -108,17 +108,9 @@ impl<'a> Attribute<'a> { &self.remove_identifier } - pub fn is_optional(&self) -> bool { - self.optional - } - pub fn is_unit(&self) -> bool { self.storage_type_string == mlir_attribute!(UnitAttr) } - - pub fn has_default_value(&self) -> bool { - self.default - } } impl OperationField for Attribute<'_> { @@ -152,7 +144,7 @@ impl OperationField for Attribute<'_> { } fn is_optional(&self) -> bool { - self.is_optional() || self.has_default_value() + self.optional || self.default } fn add_arguments(&self, name: &Ident) -> TokenStream { diff --git a/macro/src/dialect/operation/builder.rs b/macro/src/dialect/operation/builder.rs index 679fce99dd..b8638a083f 100644 --- a/macro/src/dialect/operation/builder.rs +++ b/macro/src/dialect/operation/builder.rs @@ -1,15 +1,14 @@ -mod type_state_item; -mod type_state_list; +mod type_state; -use self::{type_state_item::TypeStateItem, type_state_list::TypeStateList}; -use super::Operation; +use self::type_state::TypeState; +use super::{Operation, OperationField}; use quote::format_ident; use syn::Ident; pub struct OperationBuilder<'a> { operation: &'a Operation<'a>, identifier: Ident, - type_state: TypeStateList, + type_state: TypeState, } impl<'a> OperationBuilder<'a> { @@ -29,17 +28,23 @@ impl<'a> OperationBuilder<'a> { &self.identifier } - pub fn type_state(&self) -> &TypeStateList { + pub fn type_state(&self) -> &TypeState { &self.type_state } - fn create_type_state(operation: &Operation) -> TypeStateList { - TypeStateList::new( - operation - .required_fields() - .enumerate() - .map(|(index, field)| TypeStateItem::new(index, field.name().to_string())) - .collect(), + fn create_type_state(operation: &Operation) -> TypeState { + TypeState::new( + Self::build_names(operation.required_results()), + Self::build_names(operation.required_operands()), + Self::build_names(operation.required_regions()), + Self::build_names(operation.required_successors()), + Self::build_names(operation.required_attributes()), ) } + + fn build_names<'b>( + fields: impl Iterator, + ) -> Vec { + fields.map(|field| field.name().into()).collect() + } } diff --git a/macro/src/dialect/operation/builder/type_state.rs b/macro/src/dialect/operation/builder/type_state.rs new file mode 100644 index 0000000000..896a1da793 --- /dev/null +++ b/macro/src/dialect/operation/builder/type_state.rs @@ -0,0 +1,137 @@ +use quote::format_ident; +use std::iter::repeat; +use syn::{parse_quote, GenericArgument}; + +const RESULT_PREFIX: &str = "T"; +const OPERAND_PREFIX: &str = "O"; +const REGION_PREFIX: &str = "R"; +const SUCCESSOR_PREFIX: &str = "S"; +const ATTRIBUTE_PREFIX: &str = "A"; + +#[derive(Debug)] +pub struct TypeState { + results: Vec, + operands: Vec, + regions: Vec, + successors: Vec, + attributes: Vec, +} + +impl TypeState { + pub fn new( + results: Vec, + operands: Vec, + regions: Vec, + successors: Vec, + attributes: Vec, + ) -> Self { + Self { + results, + operands, + regions, + successors, + attributes, + } + } + + fn ordered_fields(&self) -> impl Iterator { + [ + (self.results.as_slice(), RESULT_PREFIX), + (&self.operands, OPERAND_PREFIX), + (&self.regions, REGION_PREFIX), + (&self.successors, SUCCESSOR_PREFIX), + ] + .into_iter() + } + + fn unordered_fields(&self) -> impl Iterator { + [(self.attributes.as_slice(), ATTRIBUTE_PREFIX)].into_iter() + } + + fn all_fields(&self) -> impl Iterator { + self.ordered_fields().chain(self.unordered_fields()) + } + + pub fn parameters(&self) -> impl Iterator + '_ { + self.all_fields() + .flat_map(|(fields, prefix)| Self::build_parameters(fields, prefix)) + } + + pub fn parameters_without<'a>( + &'a self, + field: &'a str, + ) -> impl Iterator + 'a { + self.all_fields() + .flat_map(|(fields, prefix)| Self::build_parameters_without(fields, prefix, field)) + } + + pub fn arguments_with<'a>( + &'a self, + field: &'a str, + set: bool, + ) -> impl Iterator + 'a { + self.all_fields().flat_map(move |(fields, prefix)| { + Self::build_arguments_with(fields, prefix, field, set) + }) + } + + pub fn arguments_with_all(&self, set: bool) -> impl Iterator + '_ { + self.all_fields() + .flat_map(move |(fields, _)| Self::build_arguments_with_all(fields, set)) + } + + fn build_parameters<'a>( + fields: &[String], + prefix: &'a str, + ) -> impl Iterator + 'a { + (0..fields.len()).map(|index| Self::build_generic_argument(prefix, index)) + } + + fn build_parameters_without<'a>( + fields: &'a [String], + prefix: &'a str, + field: &'a str, + ) -> impl Iterator + 'a { + fields + .iter() + .enumerate() + .filter(move |(_, other)| *other != field) + .map(|(index, _)| Self::build_generic_argument(prefix, index)) + } + + fn build_arguments_with<'a>( + fields: &'a [String], + prefix: &'a str, + field: &'a str, + set: bool, + ) -> impl Iterator + 'a { + fields.iter().enumerate().map(move |(index, other)| { + if other == field { + Self::build_argument(set) + } else { + Self::build_generic_argument(prefix, index) + } + }) + } + + fn build_arguments_with_all( + fields: &[String], + set: bool, + ) -> impl Iterator { + repeat(Self::build_argument(set)).take(fields.len()) + } + + fn build_generic_argument(prefix: &str, index: usize) -> GenericArgument { + let identifier = format_ident!("{prefix}{index}"); + + parse_quote!(#identifier) + } + + fn build_argument(set: bool) -> GenericArgument { + if set { + parse_quote!(::melior::dialect::ods::__private::Set) + } else { + parse_quote!(::melior::dialect::ods::__private::Unset) + } + } +} diff --git a/macro/src/dialect/operation/builder/type_state_item.rs b/macro/src/dialect/operation/builder/type_state_item.rs deleted file mode 100644 index d06256888f..0000000000 --- a/macro/src/dialect/operation/builder/type_state_item.rs +++ /dev/null @@ -1,27 +0,0 @@ -use quote::format_ident; -use syn::{parse_quote, GenericArgument}; - -#[derive(Debug)] -pub struct TypeStateItem { - field_name: String, - generic_parameter: GenericArgument, -} - -impl TypeStateItem { - pub fn new(index: usize, field_name: String) -> Self { - let identifier = format_ident!("T{}", index); - - Self { - generic_parameter: parse_quote!(#identifier), - field_name, - } - } - - pub fn field_name(&self) -> &str { - &self.field_name - } - - pub fn generic_parameter(&self) -> &GenericArgument { - &self.generic_parameter - } -} diff --git a/macro/src/dialect/operation/builder/type_state_list.rs b/macro/src/dialect/operation/builder/type_state_list.rs deleted file mode 100644 index f6829956b6..0000000000 --- a/macro/src/dialect/operation/builder/type_state_list.rs +++ /dev/null @@ -1,54 +0,0 @@ -use super::type_state_item::TypeStateItem; -use std::iter::repeat; -use syn::{parse_quote, GenericArgument}; - -#[derive(Debug)] -pub struct TypeStateList { - items: Vec, -} - -impl TypeStateList { - pub fn new(items: Vec) -> Self { - Self { items } - } - - pub fn parameters(&self) -> impl Iterator { - self.items.iter().map(|item| item.generic_parameter()) - } - - pub fn parameters_without<'a>( - &'a self, - field_name: &'a str, - ) -> impl Iterator { - self.items - .iter() - .filter(move |item| item.field_name() != field_name) - .map(|item| item.generic_parameter()) - } - - pub fn arguments_set<'a>( - &'a self, - field_name: &'a str, - set: bool, - ) -> impl Iterator + 'a { - self.items.iter().map(move |item| { - if item.field_name() == field_name { - self.set_argument(set) - } else { - item.generic_parameter().clone() - } - }) - } - - pub fn arguments_all_set(&self, set: bool) -> impl Iterator { - repeat(self.set_argument(set)).take(self.items.len()) - } - - fn set_argument(&self, set: bool) -> GenericArgument { - if set { - parse_quote!(::melior::dialect::ods::__private::Set) - } else { - parse_quote!(::melior::dialect::ods::__private::Unset) - } - } -} From be284daa50622632453571b24ef52a9f2c47c4fe Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sat, 24 Feb 2024 19:07:06 +1100 Subject: [PATCH 106/108] Fix attribute accessor (#479) --- macro/src/dialect/generation.rs | 2 +- macro/src/dialect/operation.rs | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/macro/src/dialect/generation.rs b/macro/src/dialect/generation.rs index 8b515abe4f..dd0b5e5517 100644 --- a/macro/src/dialect/generation.rs +++ b/macro/src/dialect/generation.rs @@ -47,7 +47,7 @@ pub fn generate_operation(operation: &Operation) -> TokenStream { .map(|(index, region)| generate_successor_accessor(region, index)) .collect::>(); let attribute_accessors = operation - .attributes() + .all_attributes() .map(generate_attribute_accessors) .collect::>(); diff --git a/macro/src/dialect/operation.rs b/macro/src/dialect/operation.rs index d4ec239438..cd64e9122e 100644 --- a/macro/src/dialect/operation.rs +++ b/macro/src/dialect/operation.rs @@ -182,7 +182,11 @@ impl<'a> Operation<'a> { } pub fn attributes(&self) -> impl Iterator> { - self.attributes.iter().chain(&self.derived_attributes) + self.attributes.iter() + } + + pub fn all_attributes(&self) -> impl Iterator> { + self.attributes().chain(&self.derived_attributes) } pub fn required_results(&self) -> impl Iterator { From 553490c644580a2d1742c07d20c5a1c664151153 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sat, 24 Feb 2024 19:27:45 +1100 Subject: [PATCH 107/108] Ordered type state arguments (#480) --- .../dialect/operation/builder/type_state.rs | 55 ++++++++++++++++--- melior/src/dialect/ods.rs | 2 +- ...or__dialect__ods__tests__addf_builder.snap | 3 +- 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/macro/src/dialect/operation/builder/type_state.rs b/macro/src/dialect/operation/builder/type_state.rs index 896a1da793..64cac6ce66 100644 --- a/macro/src/dialect/operation/builder/type_state.rs +++ b/macro/src/dialect/operation/builder/type_state.rs @@ -61,8 +61,13 @@ impl TypeState { &'a self, field: &'a str, ) -> impl Iterator + 'a { - self.all_fields() - .flat_map(|(fields, prefix)| Self::build_parameters_without(fields, prefix, field)) + self.ordered_fields() + .flat_map(|(fields, prefix)| { + Self::build_ordered_parameters_without(fields, prefix, field) + }) + .chain(self.unordered_fields().flat_map(|(fields, prefix)| { + Self::build_unordered_parameters_without(fields, prefix, field) + })) } pub fn arguments_with<'a>( @@ -70,9 +75,13 @@ impl TypeState { field: &'a str, set: bool, ) -> impl Iterator + 'a { - self.all_fields().flat_map(move |(fields, prefix)| { - Self::build_arguments_with(fields, prefix, field, set) - }) + self.ordered_fields() + .flat_map(move |(fields, prefix)| { + Self::build_ordered_arguments_with(fields, prefix, field, set) + }) + .chain(self.unordered_fields().flat_map(move |(fields, prefix)| { + Self::build_unordered_arguments_with(fields, prefix, field, set) + })) } pub fn arguments_with_all(&self, set: bool) -> impl Iterator + '_ { @@ -87,7 +96,21 @@ impl TypeState { (0..fields.len()).map(|index| Self::build_generic_argument(prefix, index)) } - fn build_parameters_without<'a>( + fn build_ordered_parameters_without<'a>( + fields: &'a [String], + prefix: &'a str, + field: &'a str, + ) -> impl Iterator + 'a { + Self::build_parameters(fields, prefix).skip( + fields + .iter() + .position(|other| *other == field) + .map(|index| index + 1) + .unwrap_or(0), + ) + } + + fn build_unordered_parameters_without<'a>( fields: &'a [String], prefix: &'a str, field: &'a str, @@ -99,7 +122,25 @@ impl TypeState { .map(|(index, _)| Self::build_generic_argument(prefix, index)) } - fn build_arguments_with<'a>( + fn build_ordered_arguments_with<'a>( + fields: &'a [String], + prefix: &'a str, + field: &'a str, + set: bool, + ) -> Box + 'a> { + let Some(index) = fields.iter().position(|other| *other == field) else { + return Box::new(Self::build_parameters(fields, prefix)); + }; + + Box::new( + repeat(Self::build_argument(true)) + .take(index) + .chain([Self::build_argument(set)]) + .chain(Self::build_parameters(fields, prefix).skip(index + 1)), + ) + } + + fn build_unordered_arguments_with<'a>( fields: &'a [String], prefix: &'a str, field: &'a str, diff --git a/melior/src/dialect/ods.rs b/melior/src/dialect/ods.rs index d6d2f96f2b..cc605b5584 100644 --- a/melior/src/dialect/ods.rs +++ b/melior/src/dialect/ods.rs @@ -210,8 +210,8 @@ mod tests { test_operation("addf_builder", &context, &[r#type, r#type], |block| { block.append_operation( arith::AddFOperationBuilder::new(&context, location) - .rhs(block.argument(1).unwrap().into()) .lhs(block.argument(0).unwrap().into()) + .rhs(block.argument(1).unwrap().into()) .build() .into(), ); diff --git a/melior/src/dialect/snapshots/melior__dialect__ods__tests__addf_builder.snap b/melior/src/dialect/snapshots/melior__dialect__ods__tests__addf_builder.snap index 5346119ef3..274c615c14 100644 --- a/melior/src/dialect/snapshots/melior__dialect__ods__tests__addf_builder.snap +++ b/melior/src/dialect/snapshots/melior__dialect__ods__tests__addf_builder.snap @@ -4,8 +4,7 @@ expression: module.as_operation() --- module attributes {llvm.data_layout = ""} { llvm.func @foo(%arg0: f32, %arg1: f32) { - %0 = llvm.fadd %arg1, %arg0 : f32 + %0 = llvm.fadd %arg0, %arg1 : f32 llvm.return } } - From 9c3823d0e5776ae680f12c231c600c54d0a01be3 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sat, 24 Feb 2024 19:39:48 +1100 Subject: [PATCH 108/108] Bump versions (#481) --- Cargo.lock | 4 ++-- macro/Cargo.toml | 2 +- melior/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 815194cccc..7db5c2eb35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -595,7 +595,7 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "melior" -version = "0.16.0" +version = "0.16.1" dependencies = [ "dashmap", "indoc", @@ -608,7 +608,7 @@ dependencies = [ [[package]] name = "melior-macro" -version = "0.10.0" +version = "0.10.1" dependencies = [ "comrak", "convert_case", diff --git a/macro/Cargo.toml b/macro/Cargo.toml index 2f39802c7c..2fb4384c33 100644 --- a/macro/Cargo.toml +++ b/macro/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "melior-macro" description = "Internal macros for Melior" -version = "0.10.0" +version = "0.10.1" edition = "2021" license = "Apache-2.0" repository = "https://github.com/raviqqe/melior" diff --git a/melior/Cargo.toml b/melior/Cargo.toml index b8857c1e3b..8587bf49b9 100644 --- a/melior/Cargo.toml +++ b/melior/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "melior" description = "The rustic MLIR bindings in Rust" -version = "0.16.0" +version = "0.16.1" edition = "2021" license = "Apache-2.0" repository = "https://github.com/raviqqe/melior"