diff --git a/mlir/include/mlir/Dialect/Complex/IR/CMakeLists.txt b/mlir/include/mlir/Dialect/Complex/IR/CMakeLists.txt --- a/mlir/include/mlir/Dialect/Complex/IR/CMakeLists.txt +++ b/mlir/include/mlir/Dialect/Complex/IR/CMakeLists.txt @@ -1,2 +1,7 @@ add_mlir_dialect(ComplexOps complex) add_mlir_doc(ComplexOps ComplexOps Dialects/ -gen-dialect-doc) + +set(LLVM_TARGET_DEFINITIONS ComplexAttributes.td) +mlir_tablegen(ComplexAttributes.h.inc -gen-attrdef-decls) +mlir_tablegen(ComplexAttributes.cpp.inc -gen-attrdef-defs) +add_public_tablegen_target(MLIRComplexAttributesIncGen) diff --git a/mlir/include/mlir/Dialect/Complex/IR/Complex.h b/mlir/include/mlir/Dialect/Complex/IR/Complex.h --- a/mlir/include/mlir/Dialect/Complex/IR/Complex.h +++ b/mlir/include/mlir/Dialect/Complex/IR/Complex.h @@ -27,4 +27,7 @@ #define GET_OP_CLASSES #include "mlir/Dialect/Complex/IR/ComplexOps.h.inc" +#define GET_ATTRDEF_CLASSES +#include "mlir/Dialect/Complex/IR/ComplexAttributes.h.inc" + #endif // MLIR_DIALECT_COMPLEX_IR_COMPLEX_H_ diff --git a/mlir/include/mlir/Dialect/Complex/IR/ComplexAttributes.td b/mlir/include/mlir/Dialect/Complex/IR/ComplexAttributes.td new file mode 100644 --- /dev/null +++ b/mlir/include/mlir/Dialect/Complex/IR/ComplexAttributes.td @@ -0,0 +1,43 @@ +//===- ComplexAttributes.td - Definitions for complex attributes -*- tablegen -*-=// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef COMPLEX_ATTRIBUTE +#define COMPLEX_ATTRIBUTE + +include "mlir/IR/AttrTypeBase.td" +include "mlir/Dialect/Complex/IR/ComplexBase.td" + +//===----------------------------------------------------------------------===// +// Complex Attributes. +//===----------------------------------------------------------------------===// + +class Complex_Attr + : AttrDef { + let mnemonic = attrMnemonic; +} + +def Complex_NumberAttr : Complex_Attr<"Number", "number"> { + let summary = "A complex number attribute"; + + let description = [{ + A complex number attribute. + + Example: + + ```mlir + #complex.number<:f64 1.0, 2.0> + ``` + }]; + + let parameters = (ins APFloatParameter<"">:$real, APFloatParameter<"">:$imag, AttributeSelfTypeParameter<"">:$type); + + let genVerifyDecl = 1; + let hasCustomAssemblyFormat = 1; +} + +#endif // COMPLEX_ATTRIBUTE diff --git a/mlir/include/mlir/Dialect/Complex/IR/ComplexBase.td b/mlir/include/mlir/Dialect/Complex/IR/ComplexBase.td --- a/mlir/include/mlir/Dialect/Complex/IR/ComplexBase.td +++ b/mlir/include/mlir/Dialect/Complex/IR/ComplexBase.td @@ -22,6 +22,7 @@ let dependentDialects = ["arith::ArithmeticDialect"]; let hasConstantMaterializer = 1; let emitAccessorPrefix = kEmitAccessorPrefix_Prefixed; + let useDefaultAttributePrinterParser = 1; } #endif // COMPLEX_BASE diff --git a/mlir/lib/Dialect/Complex/IR/CMakeLists.txt b/mlir/lib/Dialect/Complex/IR/CMakeLists.txt --- a/mlir/lib/Dialect/Complex/IR/CMakeLists.txt +++ b/mlir/lib/Dialect/Complex/IR/CMakeLists.txt @@ -7,6 +7,7 @@ DEPENDS MLIRComplexOpsIncGen + MLIRComplexAttributesIncGen LINK_LIBS PUBLIC MLIRArithmeticDialect diff --git a/mlir/lib/Dialect/Complex/IR/ComplexDialect.cpp b/mlir/lib/Dialect/Complex/IR/ComplexDialect.cpp --- a/mlir/lib/Dialect/Complex/IR/ComplexDialect.cpp +++ b/mlir/lib/Dialect/Complex/IR/ComplexDialect.cpp @@ -8,6 +8,10 @@ #include "mlir/Dialect/Arithmetic/IR/Arithmetic.h" #include "mlir/Dialect/Complex/IR/Complex.h" +#include "mlir/IR/Builders.h" +#include "mlir/IR/DialectImplementation.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/TypeSwitch.h" using namespace mlir; @@ -18,6 +22,10 @@ #define GET_OP_LIST #include "mlir/Dialect/Complex/IR/ComplexOps.cpp.inc" >(); + addAttributes< +#define GET_ATTRDEF_LIST +#include "mlir/Dialect/Complex/IR/ComplexAttributes.cpp.inc" + >(); } Operation *complex::ComplexDialect::materializeConstant(OpBuilder &builder, @@ -32,3 +40,71 @@ return builder.create(loc, type, value); return nullptr; } + +#define GET_ATTRDEF_CLASSES +#include "mlir/Dialect/Complex/IR/ComplexAttributes.cpp.inc" + +LogicalResult complex::NumberAttr::verify( + ::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError, + ::llvm::APFloat real, ::llvm::APFloat imag, ::mlir::Type type) { + + if (!type.isa()) + return emitError() + << "element of the complex attribute must be float like type."; + + const auto &typeFloatSemantics = type.cast().getFloatSemantics(); + if (&real.getSemantics() != &typeFloatSemantics) + return emitError() + << "type doesn't match the type implied by its `real` value"; + if (&imag.getSemantics() != &typeFloatSemantics) + return emitError() + << "type doesn't match the type implied by its `imag` value"; + + return success(); +} + +void complex::NumberAttr::print(AsmPrinter &printer) const { + printer << "<:"; + printer.printType(getType()); + printer << " "; + printer.printFloat(getReal()); + printer << ", "; + printer.printFloat(getImag()); + printer << ">"; +} + +Attribute complex::NumberAttr::parse(AsmParser &parser, Type odsType) { + if (failed(parser.parseLess())) + return {}; + + if (failed(parser.parseColon())) + return {}; + + Type type; + if (failed(parser.parseType(type))) + return {}; + + double real; + if (failed(parser.parseFloat(real))) + return {}; + + if (failed(parser.parseComma())) + return {}; + + double imag; + if (failed(parser.parseFloat(imag))) + return {}; + + if (failed(parser.parseGreater())) + return {}; + + bool unused = false; + auto realFloat = APFloat(real); + realFloat.convert(type.cast().getFloatSemantics(), + APFloat::rmNearestTiesToEven, &unused); + auto imagFloat = APFloat(imag); + imagFloat.convert(type.cast().getFloatSemantics(), + APFloat::rmNearestTiesToEven, &unused); + + return NumberAttr::get(parser.getContext(), realFloat, imagFloat, type); +} diff --git a/mlir/test/Dialect/Complex/attribute.mlir b/mlir/test/Dialect/Complex/attribute.mlir new file mode 100644 --- /dev/null +++ b/mlir/test/Dialect/Complex/attribute.mlir @@ -0,0 +1,19 @@ +// RUN: mlir-opt %s -split-input-file -allow-unregistered-dialect -verify-diagnostics | FileCheck %s + +func.func @number_attr_f64() { + "test.number_attr"() { + // CHECK: attr = #complex.number<:f64 1.000000e+00, 0.000000e+00> : f64 + attr = #complex.number<:f64 1.0, 0.0> + } : () -> () + + return +} + +func.func @number_attr_f32() { + "test.number_attr"() { + // CHECK: attr = #complex.number<:f32 1.000000e+00, 0.000000e+00> : f32 + attr = #complex.number<:f32 1.0, 0.0> + } : () -> () + + return +}