Skip to main content

pliron_math/
mlir.rs

1//! MLIR textual export for `math` operations.
2//!
3//! Every operation implements [`ToMlirOp`] and prints in MLIR's generic form.
4//! The `math_fastmath` storage key becomes the upstream `fastmath` property
5//! (`#arith.fastmath<..>`) and is omitted when `none`.
6
7use crate::ops::*;
8use pliron::{
9    attribute::Attribute, context::Context, derive::op_interface_impl, op::Op, printable::State,
10    result::Result,
11};
12use pliron_arith::{attributes::FastMathFlagsAttr, mlir::print_generic};
13use pliron_mlir_interop::ToMlirOp;
14use std::fmt;
15
16/// Translates one `math`-owned storage key to an MLIR property.
17///
18/// Returns `Ok(None)` for keys `math` does not own and `Ok(Some((name, None)))`
19/// when the property equals its default and is omitted.
20///
21/// # Errors
22///
23/// Returns an error when a `math` key holds an attribute of the wrong type.
24pub fn property(
25    _ctx: &Context,
26    key: &str,
27    attr: &dyn Attribute,
28) -> Result<Option<(&'static str, Option<String>)>> {
29    if key != "math_fastmath" {
30        return Ok(None);
31    }
32    let flags = attr
33        .downcast_ref::<FastMathFlagsAttr>()
34        .ok_or_else(|| {
35            pliron::input_error_noloc!(pliron_mlir_interop::Error::Untranslatable(format!(
36                "attribute {key} has an unexpected type"
37            )))
38        })?
39        .value;
40    Ok(Some((
41        "fastmath",
42        (!flags.is_none()).then(|| format!("#arith.fastmath<{}>", flags.mlir_spelling())),
43    )))
44}
45
46macro_rules! operations {
47    ($($ty:ty),* $(,)?) => {$(
48        #[op_interface_impl]
49        impl ToMlirOp for $ty {
50            fn to_mlir(&self, ctx: &Context, state: &State, f: &mut fmt::Formatter<'_>) -> Result<()> {
51                let name = self.get_opid().to_string();
52                print_generic(ctx, self.get_operation(), state, f, &|ctx, key, attr| {
53                    if matches!(name.as_str(), "math.absi" | "math.ctlz" | "math.cttz"
54                        | "math.ctpop" | "math.ipowi" | "math.isnan" | "math.isinf"
55                        | "math.isfinite" | "math.isnormal")
56                    {
57                        return Err(pliron::input_error_noloc!(
58                            pliron_mlir_interop::Error::Untranslatable(
59                                format!("attribute {key} is not a property of {name}")
60                            )
61                        ));
62                    }
63                    property(ctx, key, attr)
64                })
65            }
66        }
67    )*};
68}
69
70operations!(
71    AbsFOp,
72    CeilOp,
73    FloorOp,
74    RoundOp,
75    RoundEvenOp,
76    TruncOp,
77    ExpOp,
78    Exp2Op,
79    ExpM1Op,
80    LogOp,
81    Log2Op,
82    Log10Op,
83    Log1pOp,
84    SqrtOp,
85    RsqrtOp,
86    CbrtOp,
87    SinOp,
88    CosOp,
89    TanOp,
90    AsinOp,
91    AcosOp,
92    AtanOp,
93    SinhOp,
94    CoshOp,
95    TanhOp,
96    AsinhOp,
97    AcoshOp,
98    AtanhOp,
99    ErfOp,
100    ErfcOp,
101    Atan2Op,
102    PowFOp,
103    CopySignOp,
104    FmaOp,
105    ClampFOp,
106    SincosOp,
107    FPowIOp,
108    AbsIOp,
109    CountLeadingZerosOp,
110    CountTrailingZerosOp,
111    CtPopOp,
112    IPowIOp,
113    IsNaNOp,
114    IsInfOp,
115    IsFiniteOp,
116    IsNormalOp,
117);