From 99da49df6f38bd63d9aaa7e8c50a9e75a0df2baa Mon Sep 17 00:00:00 2001 From: "github-merge-queue[bot]" Date: Fri, 7 Jun 2024 19:37:36 +0000 Subject: [PATCH] deploy: 01c487a0b1d29c20aa62cadaf8ed71c2116e8c25 --- cairo_native/libfuncs/felt252/fn.build.html | 2 +- .../felt252/fn.build_binary_operation.html | 2 +- .../libfuncs/felt252/fn.build_const.html | 2 +- .../libfuncs/felt252/fn.build_is_zero.html | 2 +- cairo_native/libfuncs/felt252/index.html | 2 +- cairo_native/utils/index.html | 2 +- help.html | 4 +- settings.html | 4 +- src/cairo_native/libfuncs/felt252.rs.html | 418 ++++++------------ src/cairo_native/utils.rs.html | 246 ----------- 10 files changed, 141 insertions(+), 543 deletions(-) diff --git a/cairo_native/libfuncs/felt252/fn.build.html b/cairo_native/libfuncs/felt252/fn.build.html index d8d142ff4..d25234e11 100644 --- a/cairo_native/libfuncs/felt252/fn.build.html +++ b/cairo_native/libfuncs/felt252/fn.build.html @@ -1,5 +1,5 @@ build in cairo_native::libfuncs::felt252 - Rust -
pub fn build<'ctx, 'this>(
+    
pub fn build<'ctx, 'this>(
     context: &'ctx Context,
     registry: &ProgramRegistry<CoreType, CoreLibfunc>,
     entry: &'this Block<'ctx>,
diff --git a/cairo_native/libfuncs/felt252/fn.build_binary_operation.html b/cairo_native/libfuncs/felt252/fn.build_binary_operation.html
index 83ea0147f..6ad78d178 100644
--- a/cairo_native/libfuncs/felt252/fn.build_binary_operation.html
+++ b/cairo_native/libfuncs/felt252/fn.build_binary_operation.html
@@ -1,5 +1,5 @@
 build_binary_operation in cairo_native::libfuncs::felt252 - Rust
-    
pub fn build_binary_operation<'ctx, 'this>(
+    
pub fn build_binary_operation<'ctx, 'this>(
     context: &'ctx Context,
     registry: &ProgramRegistry<CoreType, CoreLibfunc>,
     entry: &'this Block<'ctx>,
diff --git a/cairo_native/libfuncs/felt252/fn.build_const.html b/cairo_native/libfuncs/felt252/fn.build_const.html
index 512d397e4..35c1d44ff 100644
--- a/cairo_native/libfuncs/felt252/fn.build_const.html
+++ b/cairo_native/libfuncs/felt252/fn.build_const.html
@@ -1,5 +1,5 @@
 build_const in cairo_native::libfuncs::felt252 - Rust
-    
pub fn build_const<'ctx, 'this>(
+    
pub fn build_const<'ctx, 'this>(
     context: &'ctx Context,
     registry: &ProgramRegistry<CoreType, CoreLibfunc>,
     entry: &'this Block<'ctx>,
diff --git a/cairo_native/libfuncs/felt252/fn.build_is_zero.html b/cairo_native/libfuncs/felt252/fn.build_is_zero.html
index 0892f19e1..9e3fd4ede 100644
--- a/cairo_native/libfuncs/felt252/fn.build_is_zero.html
+++ b/cairo_native/libfuncs/felt252/fn.build_is_zero.html
@@ -1,5 +1,5 @@
 build_is_zero in cairo_native::libfuncs::felt252 - Rust
-    
pub fn build_is_zero<'ctx, 'this>(
+    
pub fn build_is_zero<'ctx, 'this>(
     context: &'ctx Context,
     _registry: &ProgramRegistry<CoreType, CoreLibfunc>,
     entry: &'this Block<'ctx>,
diff --git a/cairo_native/libfuncs/felt252/index.html b/cairo_native/libfuncs/felt252/index.html
index 5dc25b467..d5781358d 100644
--- a/cairo_native/libfuncs/felt252/index.html
+++ b/cairo_native/libfuncs/felt252/index.html
@@ -1,2 +1,2 @@
 cairo_native::libfuncs::felt252 - Rust
-    
Expand description

Functions§

  • Select and call the correct libfunc builder function from the selector.
  • Generate MLIR operations for the following libfuncs:
  • Generate MLIR operations for the felt252_const libfunc.
  • Generate MLIR operations for the felt252_is_zero libfunc.
\ No newline at end of file +
Expand description

Functions§

  • Select and call the correct libfunc builder function from the selector.
  • Generate MLIR operations for the following libfuncs:
  • Generate MLIR operations for the felt252_const libfunc.
  • Generate MLIR operations for the felt252_is_zero libfunc.
\ No newline at end of file diff --git a/cairo_native/utils/index.html b/cairo_native/utils/index.html index 16b9bcc1b..314ba564c 100644 --- a/cairo_native/utils/index.html +++ b/cairo_native/utils/index.html @@ -1,2 +1,2 @@ cairo_native::utils - Rust -

Module cairo_native::utils

source ·
Expand description

§Various utilities

Structs§

Constants§

Traits§

Functions§

\ No newline at end of file +

Module cairo_native::utils

source ·
Expand description

§Various utilities

Structs§

Constants§

Traits§

Functions§

\ No newline at end of file diff --git a/help.html b/help.html index a47b990ff..6be553292 100644 --- a/help.html +++ b/help.html @@ -1,2 +1,2 @@ -Help -

Rustdoc help

Back
\ No newline at end of file +Help +

Rustdoc help

Back
\ No newline at end of file diff --git a/settings.html b/settings.html index 1f893e136..ed1c128fe 100644 --- a/settings.html +++ b/settings.html @@ -1,2 +1,2 @@ -Settings -

Rustdoc settings

Back
\ No newline at end of file +Settings +

Rustdoc settings

Back
\ No newline at end of file diff --git a/src/cairo_native/libfuncs/felt252.rs.html b/src/cairo_native/libfuncs/felt252.rs.html index fd0024a02..c21eef173 100644 --- a/src/cairo_native/libfuncs/felt252.rs.html +++ b/src/cairo_native/libfuncs/felt252.rs.html @@ -700,91 +700,14 @@

Files

698 699 700 -701 -702 -703 -704 -705 -706 -707 -708 -709 -710 -711 -712 -713 -714 -715 -716 -717 -718 -719 -720 -721 -722 -723 -724 -725 -726 -727 -728 -729 -730 -731 -732 -733 -734 -735 -736 -737 -738 -739 -740 -741 -742 -743 -744 -745 -746 -747 -748 -749 -750 -751 -752 -753 -754 -755 -756 -757 -758 -759 -760 -761 -762 -763 -764 -765 -766 -767 -768 -769 -770 -771 -772 -773 -774 -775 -776 -777 -778
//! # `Felt`-related libfuncs
 
 use super::LibfuncHelper;
 use crate::{
+    block_ext::BlockExt,
     error::{Error, Result},
     metadata::{prime_modulo::PrimeModuloMeta, MetadataStorage},
-    utils::{mlir_asm, ProgramRegistryExt},
+    utils::ProgramRegistryExt,
 };
 use cairo_lang_sierra::{
     extensions::{
@@ -803,10 +726,7 @@ 

Files

arith::{self, CmpiPredicate}, cf, }, - ir::{ - attribute::IntegerAttribute, r#type::IntegerType, Attribute, Block, Location, Value, - ValueLike, - }, + ir::{r#type::IntegerType, Block, Location, Value, ValueLike}, Context, }; use num_bigint::{Sign, ToBigInt}; @@ -849,7 +769,6 @@

Files

metadata: &mut MetadataStorage, info: &Felt252BinaryOperationConcrete, ) -> Result<()> { - let bool_ty = IntegerType::new(context, 1).into(); let felt252_ty = registry.build_type( context, helper, @@ -860,39 +779,10 @@

Files

let i256 = IntegerType::new(context, 256).into(); let i512 = IntegerType::new(context, 512).into(); - let attr_prime_i256 = Attribute::parse( - context, - &format!( - "{} : {i256}", - metadata - .get::<PrimeModuloMeta<Felt>>() - .ok_or(Error::MissingMetadata)? - .prime() - ), - ) - .ok_or(Error::ParseAttributeError)?; - let attr_prime_i512 = Attribute::parse( - context, - &format!( - "{} : {i512}", - metadata - .get::<PrimeModuloMeta<Felt>>() - .ok_or(Error::MissingMetadata)? - .prime() - ), - ) - .ok_or(Error::ParseAttributeError)?; - - let attr_cmp_uge = IntegerAttribute::new( - IntegerType::new(context, 64).into(), - CmpiPredicate::Uge as i64, - ) - .into(); - let attr_cmp_ult = IntegerAttribute::new( - IntegerType::new(context, 64).into(), - CmpiPredicate::Ult as i64, - ) - .into(); + let prime = metadata + .get::<PrimeModuloMeta<Felt>>() + .ok_or(Error::MissingMetadata)? + .prime(); let (op, lhs, rhs) = match info { Felt252BinaryOperationConcrete::WithVar(operation) => ( @@ -914,13 +804,8 @@

Files

_ => operation.c.to_biguint().expect("sign already checked"), }; - let attr_c = Attribute::parse(context, &format!("{value} : {felt252_ty}")) - .ok_or(Error::MissingMetadata)?; - // TODO: Ensure that the constant is on the correct side of the operation. - mlir_asm! { context, entry, location => - ; rhs = "arith.constant"() { "value" = attr_c } : () -> felt252_ty - } + let rhs = entry.const_int_from_type(context, location, value, felt252_ty)?; (operation.operator, entry.argument(0)?.into(), rhs) } @@ -928,53 +813,74 @@

Files

let result = match op { Felt252BinaryOperator::Add => { - mlir_asm! { context, entry, location => - ; lhs = "arith.extui"(lhs) : (felt252_ty) -> i256 - ; rhs = "arith.extui"(rhs) : (felt252_ty) -> i256 - ; result = "arith.addi"(lhs, rhs) : (i256, i256) -> i256 - - ; prime = "arith.constant"() { "value" = attr_prime_i256 } : () -> i256 - ; result_mod = "arith.subi"(result, prime) : (i256, i256) -> i256 - ; is_out_of_range = "arith.cmpi"(result, prime) { "predicate" = attr_cmp_uge } : (i256, i256) -> bool_ty + let lhs = entry.append_op_result(arith::extui(lhs, i256, location))?; + let rhs = entry.append_op_result(arith::extui(rhs, i256, location))?; + let result = entry.append_op_result(arith::addi(lhs, rhs, location))?; - ; result = "arith.select"(is_out_of_range, result_mod, result) : (bool_ty, i256, i256) -> i256 - ; result = "arith.trunci"(result) : (i256) -> felt252_ty - }; + let prime = entry.const_int_from_type(context, location, prime.clone(), i256)?; + let result_mod = entry.append_op_result(arith::subi(result, prime, location))?; + let is_out_of_range = entry.append_op_result(arith::cmpi( + context, + CmpiPredicate::Uge, + result, + prime, + location, + ))?; - result - } + let result = entry.append_op_result(arith::select( + is_out_of_range, + result_mod, + result, + location, + ))?; + entry.append_op_result(arith::trunci(result, felt252_ty, location))? + } Felt252BinaryOperator::Sub => { - mlir_asm! { context, entry, location => - ; lhs = "arith.extui"(lhs) : (felt252_ty) -> i256 - ; rhs = "arith.extui"(rhs) : (felt252_ty) -> i256 - ; result = "arith.subi"(lhs, rhs) : (i256, i256) -> i256 - - ; prime = "arith.constant"() { "value" = attr_prime_i256 } : () -> i256 - ; result_mod = "arith.addi"(result, prime) : (i256, i256) -> i256 - ; is_out_of_range = "arith.cmpi"(lhs, rhs) { "predicate" = attr_cmp_ult } : (i256, i256) -> bool_ty + let lhs = entry.append_op_result(arith::extui(lhs, i256, location))?; + let rhs = entry.append_op_result(arith::extui(rhs, i256, location))?; + let result = entry.append_op_result(arith::subi(lhs, rhs, location))?; - ; result = "arith.select"(is_out_of_range, result_mod, result) : (bool_ty, i256, i256) -> i256 - ; result = "arith.trunci"(result) : (i256) -> felt252_ty - } + let prime = entry.const_int_from_type(context, location, prime.clone(), i256)?; + let result_mod = entry.append_op_result(arith::addi(result, prime, location))?; + let is_out_of_range = entry.append_op_result(arith::cmpi( + context, + CmpiPredicate::Ult, + lhs, + rhs, + location, + ))?; - result - } + let result = entry.append_op_result(arith::select( + is_out_of_range, + result_mod, + result, + location, + ))?; + entry.append_op_result(arith::trunci(result, felt252_ty, location))? + } Felt252BinaryOperator::Mul => { - mlir_asm! { context, entry, location => - ; lhs = "arith.extui"(lhs) : (felt252_ty) -> i512 - ; rhs = "arith.extui"(rhs) : (felt252_ty) -> i512 - ; result = "arith.muli"(lhs, rhs) : (i512, i512) -> i512 - - ; prime = "arith.constant"() { "value" = attr_prime_i512 } : () -> i512 - ; result_mod = "arith.remui"(result, prime) : (i512, i512) -> i512 - ; is_out_of_range = "arith.cmpi"(result, prime) { "predicate" = attr_cmp_uge } : (i512, i512) -> bool_ty + let lhs = entry.append_op_result(arith::extui(lhs, i512, location))?; + let rhs = entry.append_op_result(arith::extui(rhs, i512, location))?; + let result = entry.append_op_result(arith::muli(lhs, rhs, location))?; - ; result = "arith.select"(is_out_of_range, result_mod, result) : (bool_ty, i512, i512) -> i512 - ; result = "arith.trunci"(result) : (i512) -> felt252_ty - } + let prime = entry.const_int_from_type(context, location, prime.clone(), i512)?; + let result_mod = entry.append_op_result(arith::remui(result, prime, location))?; + let is_out_of_range = entry.append_op_result(arith::cmpi( + context, + CmpiPredicate::Uge, + result, + prime, + location, + ))?; - result - } + let result = entry.append_op_result(arith::select( + is_out_of_range, + result_mod, + result, + location, + ))?; + entry.append_op_result(arith::trunci(result, felt252_ty, location))? + } Felt252BinaryOperator::Div => { // The extended euclidean algorithm calculates the greatest common divisor of two integers, // as well as the bezout coefficients x and y such that for inputs a and b, ax+by=gcd(a,b) @@ -997,28 +903,12 @@

Files

// Egcd works by calculating a series of remainders, each the remainder of dividing the previous two // For the initial setup, r0 = PRIME, r1 = a // This order is chosen because if we reverse them, then the first iteration will just swap them - let prev_remainder = start_block - .append_operation(arith::constant(context, attr_prime_i512, location)) - .result(0)? - .into(); + let prev_remainder = + start_block.const_int_from_type(context, location, prime.clone(), i512)?; let remainder = start_block.argument(0)?.into(); // Similarly we'll calculate another series which starts 0,1,... and from which we will retrieve the modular inverse of a - let prev_inverse = start_block - .append_operation(arith::constant( - context, - IntegerAttribute::new(i512, 0).into(), - location, - )) - .result(0)? - .into(); - let inverse = start_block - .append_operation(arith::constant( - context, - IntegerAttribute::new(i512, 1).into(), - location, - )) - .result(0)? - .into(); + let prev_inverse = start_block.const_int_from_type(context, location, 0, i512)?; + let inverse = start_block.const_int_from_type(context, location, 1, i512)?; start_block.append_operation(cf::br( loop_block, &[prev_remainder, remainder, prev_inverse, inverse], @@ -1033,47 +923,30 @@

Files

let inverse = loop_block.argument(3)?.into(); // First calculate q = rem_(i-1)/rem_i, rounded down - let quotient = loop_block - .append_operation(arith::divui(prev_remainder, remainder, location)) - .result(0)? - .into(); + let quotient = + loop_block.append_op_result(arith::divui(prev_remainder, remainder, location))?; // Then r_(i+1) = r_(i-1) - q * r_i, and inv_(i+1) = inv_(i-1) - q * inv_i - let rem_times_quo = loop_block - .append_operation(arith::muli(remainder, quotient, location)) - .result(0)? - .into(); - let inv_times_quo = loop_block - .append_operation(arith::muli(inverse, quotient, location)) - .result(0)? - .into(); - let next_remainder = loop_block - .append_operation(arith::subi(prev_remainder, rem_times_quo, location)) - .result(0)? - .into(); - let next_inverse = loop_block - .append_operation(arith::subi(prev_inverse, inv_times_quo, location)) - .result(0)? - .into(); + let rem_times_quo = + loop_block.append_op_result(arith::muli(remainder, quotient, location))?; + let inv_times_quo = + loop_block.append_op_result(arith::muli(inverse, quotient, location))?; + let next_remainder = loop_block.append_op_result(arith::subi( + prev_remainder, + rem_times_quo, + location, + ))?; + let next_inverse = + loop_block.append_op_result(arith::subi(prev_inverse, inv_times_quo, location))?; // If r_(i+1) is 0, then inv_i is the inverse - let zero = loop_block - .append_operation(arith::constant( - context, - IntegerAttribute::new(i512, 0).into(), - location, - )) - .result(0)? - .into(); - let next_remainder_eq_zero = loop_block - .append_operation(arith::cmpi( - context, - CmpiPredicate::Eq, - next_remainder, - zero, - location, - )) - .result(0)? - .into(); + let zero = loop_block.const_int_from_type(context, location, 0, i512)?; + let next_remainder_eq_zero = loop_block.append_op_result(arith::cmpi( + context, + CmpiPredicate::Eq, + next_remainder, + zero, + location, + ))?; loop_block.append_operation(cf::cond_br( context, next_remainder_eq_zero, @@ -1087,14 +960,7 @@

Files

// egcd sometimes returns a negative number for the inverse, // in such cases we must simply wrap it around back into [0, PRIME) // this suffices because |inv_i| <= divfloor(PRIME,2) - let zero = negative_check_block - .append_operation(arith::constant( - context, - IntegerAttribute::new(i512, 0).into(), - location, - )) - .result(0)? - .into(); + let zero = negative_check_block.const_int_from_type(context, location, 0, i512)?; let is_negative = negative_check_block .append_operation(arith::cmpi( @@ -1107,23 +973,16 @@

Files

.result(0)? .into(); // if the inverse is < 0, add PRIME - let prime = negative_check_block - .append_operation(arith::constant(context, attr_prime_i512, location)) - .result(0)? - .into(); - let wrapped_inverse = negative_check_block - .append_operation(arith::addi(inverse, prime, location)) - .result(0)? - .into(); - let inverse = negative_check_block - .append_operation(arith::select( - is_negative, - wrapped_inverse, - inverse, - location, - )) - .result(0)? - .into(); + let prime = + negative_check_block.const_int_from_type(context, location, prime.clone(), i512)?; + let wrapped_inverse = + negative_check_block.append_op_result(arith::addi(inverse, prime, location))?; + let inverse = negative_check_block.append_op_result(arith::select( + is_negative, + wrapped_inverse, + inverse, + location, + ))?; negative_check_block.append_operation(cf::br( inverse_result_block, &[inverse], @@ -1132,31 +991,35 @@

Files

// Div Logic Start // Fetch operands - let lhs = entry - .append_operation(arith::extui(lhs, i512, location)) - .result(0)? - .into(); - let rhs = entry - .append_operation(arith::extui(rhs, i512, location)) - .result(0)? - .into(); + let lhs = entry.append_op_result(arith::extui(lhs, i512, location))?; + let rhs = entry.append_op_result(arith::extui(rhs, i512, location))?; // Calculate inverse of rhs, callling the inverse implementation's starting block entry.append_operation(cf::br(start_block, &[rhs], location)); // Fetch the inverse result from the result block let inverse = inverse_result_block.argument(0)?.into(); // Peform lhs * (1/ rhs) - let result = inverse_result_block - .append_operation(arith::muli(lhs, inverse, location)) - .result(0)? - .into(); + let result = + inverse_result_block.append_op_result(arith::muli(lhs, inverse, location))?; // Apply modulo and convert result to felt252 - mlir_asm! { context, inverse_result_block, location => - ; result_mod = "arith.remui"(result, prime) : (i512, i512) -> i512 - ; is_out_of_range = "arith.cmpi"(result, prime) { "predicate" = attr_cmp_uge } : (i512, i512) -> bool_ty + let result_mod = + inverse_result_block.append_op_result(arith::remui(result, prime, location))?; + let is_out_of_range = inverse_result_block.append_op_result(arith::cmpi( + context, + CmpiPredicate::Uge, + result, + prime, + location, + ))?; + + let result = inverse_result_block.append_op_result(arith::select( + is_out_of_range, + result_mod, + result, + location, + ))?; + let result = inverse_result_block + .append_op_result(arith::trunci(result, felt252_ty, location))?; - ; result = "arith.select"(is_out_of_range, result_mod, result) : (bool_ty, i512, i512) -> i512 - ; result = "arith.trunci"(result) : (i512) -> felt252_ty - } inverse_result_block.append_operation(helper.br(0, &[result], location)); return Ok(()); } @@ -1198,14 +1061,8 @@

Files

&info.branch_signatures()[0].vars[0].ty, )?; - let attr_c = Attribute::parse(context, &format!("{value} : {felt252_ty}")) - .ok_or(Error::ParseAttributeError)?; - - mlir_asm! { context, entry, location => - ; k0 = "arith.constant"() { "value" = attr_c } : () -> felt252_ty - } - - entry.append_operation(helper.br(0, &[k0], location)); + let value = entry.const_int_from_type(context, location, value, felt252_ty)?; + entry.append_operation(helper.br(0, &[value], location)); Ok(()) } @@ -1221,24 +1078,11 @@

Files

) -> Result<()> { let arg0: Value = entry.argument(0)?.into(); - let op = entry.append_operation(arith::constant( - context, - IntegerAttribute::new(arg0.r#type(), 0).into(), - location, - )); - let const_0 = op.result(0)?.into(); - - let op = entry.append_operation(arith::cmpi( - context, - CmpiPredicate::Eq, - arg0, - const_0, - location, - )); - let condition = op.result(0)?.into(); + let k0 = entry.const_int_from_type(context, location, 0, arg0.r#type())?; + let condition = + entry.append_op_result(arith::cmpi(context, CmpiPredicate::Eq, arg0, k0, location))?; entry.append_operation(helper.cond_br(context, condition, [0, 1], [&[], &[arg0]], location)); - Ok(()) } diff --git a/src/cairo_native/utils.rs.html b/src/cairo_native/utils.rs.html index 8c3d3cbe3..08838d784 100644 --- a/src/cairo_native/utils.rs.html +++ b/src/cairo_native/utils.rs.html @@ -1323,129 +1323,6 @@

Files

1321 1322 1323 -1324 -1325 -1326 -1327 -1328 -1329 -1330 -1331 -1332 -1333 -1334 -1335 -1336 -1337 -1338 -1339 -1340 -1341 -1342 -1343 -1344 -1345 -1346 -1347 -1348 -1349 -1350 -1351 -1352 -1353 -1354 -1355 -1356 -1357 -1358 -1359 -1360 -1361 -1362 -1363 -1364 -1365 -1366 -1367 -1368 -1369 -1370 -1371 -1372 -1373 -1374 -1375 -1376 -1377 -1378 -1379 -1380 -1381 -1382 -1383 -1384 -1385 -1386 -1387 -1388 -1389 -1390 -1391 -1392 -1393 -1394 -1395 -1396 -1397 -1398 -1399 -1400 -1401 -1402 -1403 -1404 -1405 -1406 -1407 -1408 -1409 -1410 -1411 -1412 -1413 -1414 -1415 -1416 -1417 -1418 -1419 -1420 -1421 -1422 -1423 -1424 -1425 -1426 -1427 -1428 -1429 -1430 -1431 -1432 -1433 -1434 -1435 -1436 -1437 -1438 -1439 -1440 -1441 -1442 -1443 -1444 -1445 -1446
//! # Various utilities
 
 use crate::{
@@ -1968,129 +1845,6 @@ 

Files

} } -/// The `mlir_asm!` macro is a shortcut to manually building operations. -/// -/// It works by forwarding the custom DSL code to their respective functions within melior's -/// `OperationBuilder`. -/// -/// The DSL's syntax is similar to that of MLIR, but has some differences, or rather restrictions, -/// due to the way declarative macros work: -/// - All macro invocations need the MLIR context, the target block and the operations' locations. -/// - The operations are defined using a syntax similar to that of MLIR's generic operations, with -/// some differences. The results are Rust variables (MLIR values) and the inputs (operands, -/// attributes...) are all Rust expressions that evaluate to their respective type. -/// -/// Check out the [felt252 libfunc implementations](crate::libfuncs::felt252) for an example on their usage. -macro_rules! mlir_asm { - ( - $context:expr, $block:expr, $location:expr => - $( ; $( $( $ret:ident ),+ = )? $op:literal - ( $( $( $arg:expr ),+ $(,)? )? ) // Operands. - $( [ $( $( ^ $successor:ident $( ( $( $( $successor_arg:expr ),+ $(,)? )? ) )? ),+ $(,)? )? ] )? // Successors. - $( < { $( $( $prop_name:pat_param = $prop_value:expr ),+ $(,)? )? } > )? // Properties. - $( ( $( $( $region:expr ),+ $(,)? )? ) )? // Regions. - $( { $( $( $attr_name:literal = $attr_value:expr ),+ $(,)? )? } )? // Attributes. - : $args_ty:tt -> $rets_ty:tt // Signature. - )* - ) => { $( - #[allow(unused_mut)] - $( let $crate::utils::codegen_ret_decl!($($ret),+) = )? { - #[allow(unused_variables)] - let context = $context; - let mut builder = melior::ir::operation::OperationBuilder::new($op, $location); - - // Process operands. - $( let builder = builder.add_operands(&[$( $arg, )+]); )? - - // TODO: Process successors. - // TODO: Process properties. - // TODO: Process regions. - - // Process attributes. - $( $( - let builder = $crate::utils::codegen_attributes!(context, builder => $($attr_name = $attr_value),+); - )? )? - - // Process signature. - // #[cfg(debug_assertions)] - // $crate::utils::codegen_signature!( PARAMS $args_ty ); - let builder = $crate::utils::codegen_signature!( RETS builder => $rets_ty ); - - #[allow(unused_variables)] - let op = $block.append_operation(builder.build()?); - $( $crate::utils::codegen_ret_extr!(op => $($ret),+) )? - }; - )* }; -} -pub(crate) use mlir_asm; - -macro_rules! codegen_attributes { - // Macro entry points. - ( $context:ident, $builder:ident => $name:literal = $value:expr ) => { - $builder.add_attributes(&[ - $crate::utils::codegen_attributes!(INTERNAL $context, $builder => $name = $value), - ]) - }; - ( $context:ident, $builder:ident => $( $name:literal = $value:expr ),+ ) => { - $builder.add_attributes(&[ - $( $crate::utils::codegen_attributes!(INTERNAL $context, $builder => $name = $value), )+ - ]) - }; - - ( INTERNAL $context:ident, $builder:ident => $name:literal = $value:expr ) => { - ( - melior::ir::Identifier::new($context, $name), - $value, - ) - }; -} -pub(crate) use codegen_attributes; - -macro_rules! codegen_signature { - ( PARAMS ) => { - // TODO: Check operand types. - }; - - ( RETS $builder:ident => () ) => { $builder }; - ( RETS $builder:ident => $ret_ty:expr ) => { - $builder.add_results(&[$ret_ty]) - }; - ( RETS $builder:ident => $( $ret_ty:expr ),+ $(,)? ) => { - $builder.add_results(&[$($ret_ty),+]) - }; -} -pub(crate) use codegen_signature; - -macro_rules! codegen_ret_decl { - // Macro entry points. - ( $ret:ident ) => { $ret }; - ( $( $ret:ident ),+ ) => { - ( $( codegen_ret_decl!($ret) ),+ ) - }; -} -pub(crate) use codegen_ret_decl; - -macro_rules! codegen_ret_extr { - // Macro entry points. - ( $op:ident => $ret:ident ) => {{ - melior::ir::Value::from($op.result(0)?) - }}; - ( $op:ident => $( $ret:ident ),+ ) => {{ - let mut idx = 0; - ( $( codegen_ret_extr!(INTERNAL idx, $op => $ret) ),+ ) - }}; - - // Internal entry points. - ( INTERNAL $count:ident, $op:ident => $ret:ident ) => { - { - let idx = $count; - $count += 1; - melior::ir::Value::from($op.result(idx)?) - } - }; -} -pub(crate) use codegen_ret_extr; - #[cfg(test)] pub mod test { use crate::{