1d0cb0d30SAlexander Belyaev //===- ComplexDialect.cpp - MLIR Complex Dialect --------------------------===//
2d0cb0d30SAlexander Belyaev //
3d0cb0d30SAlexander Belyaev // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4d0cb0d30SAlexander Belyaev // See https://llvm.org/LICENSE.txt for license information.
5d0cb0d30SAlexander Belyaev // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d0cb0d30SAlexander Belyaev //
7d0cb0d30SAlexander Belyaev //===----------------------------------------------------------------------===//
8d0cb0d30SAlexander Belyaev
9b43c5049SJustin Fargnoli #include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"
10abc362a1SJakub Kuderski #include "mlir/Dialect/Arith/IR/Arith.h"
11d0cb0d30SAlexander Belyaev #include "mlir/Dialect/Complex/IR/Complex.h"
125caa941fSlewuathe #include "mlir/IR/Builders.h"
135caa941fSlewuathe #include "mlir/IR/DialectImplementation.h"
147cc9ae95SOkwan Kwon #include "mlir/Transforms/InliningUtils.h"
155caa941fSlewuathe #include "llvm/ADT/StringExtras.h"
165caa941fSlewuathe #include "llvm/ADT/TypeSwitch.h"
17a54f4eaeSMogball
18a54f4eaeSMogball using namespace mlir;
19d0cb0d30SAlexander Belyaev
20485cc55eSStella Laurenzo #include "mlir/Dialect/Complex/IR/ComplexOpsDialect.cpp.inc"
21485cc55eSStella Laurenzo
227cc9ae95SOkwan Kwon namespace {
237cc9ae95SOkwan Kwon /// This class defines the interface for handling inlining for complex
247cc9ae95SOkwan Kwon /// dialect operations.
257cc9ae95SOkwan Kwon struct ComplexInlinerInterface : public DialectInlinerInterface {
267cc9ae95SOkwan Kwon using DialectInlinerInterface::DialectInlinerInterface;
277cc9ae95SOkwan Kwon /// All complex dialect ops can be inlined.
isLegalToInline__anonba7833e00111::ComplexInlinerInterface287cc9ae95SOkwan Kwon bool isLegalToInline(Operation *, Region *, bool, IRMapping &) const final {
297cc9ae95SOkwan Kwon return true;
307cc9ae95SOkwan Kwon }
317cc9ae95SOkwan Kwon };
327cc9ae95SOkwan Kwon } // namespace
337cc9ae95SOkwan Kwon
initialize()34a54f4eaeSMogball void complex::ComplexDialect::initialize() {
35d0cb0d30SAlexander Belyaev addOperations<
36d0cb0d30SAlexander Belyaev #define GET_OP_LIST
37d0cb0d30SAlexander Belyaev #include "mlir/Dialect/Complex/IR/ComplexOps.cpp.inc"
38d0cb0d30SAlexander Belyaev >();
395caa941fSlewuathe addAttributes<
405caa941fSlewuathe #define GET_ATTRDEF_LIST
415caa941fSlewuathe #include "mlir/Dialect/Complex/IR/ComplexAttributes.cpp.inc"
425caa941fSlewuathe >();
43*35d55f28SJustin Fargnoli declarePromisedInterface<ConvertToLLVMPatternInterface, ComplexDialect>();
447cc9ae95SOkwan Kwon addInterfaces<ComplexInlinerInterface>();
45d0cb0d30SAlexander Belyaev }
46a54f4eaeSMogball
materializeConstant(OpBuilder & builder,Attribute value,Type type,Location loc)47a54f4eaeSMogball Operation *complex::ComplexDialect::materializeConstant(OpBuilder &builder,
48a54f4eaeSMogball Attribute value,
49a54f4eaeSMogball Type type,
50a54f4eaeSMogball Location loc) {
51480cd4cbSRiver Riddle if (complex::ConstantOp::isBuildableWith(value, type)) {
52480cd4cbSRiver Riddle return builder.create<complex::ConstantOp>(loc, type,
53c1fa60b4STres Popp llvm::cast<ArrayAttr>(value));
54480cd4cbSRiver Riddle }
5500e3566dSRahul Kayaith return arith::ConstantOp::materialize(builder, value, type, loc);
56a54f4eaeSMogball }
575caa941fSlewuathe
585caa941fSlewuathe #define GET_ATTRDEF_CLASSES
595caa941fSlewuathe #include "mlir/Dialect/Complex/IR/ComplexAttributes.cpp.inc"
605caa941fSlewuathe
verify(::llvm::function_ref<::mlir::InFlightDiagnostic ()> emitError,::llvm::APFloat real,::llvm::APFloat imag,::mlir::Type type)615caa941fSlewuathe LogicalResult complex::NumberAttr::verify(
625caa941fSlewuathe ::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError,
635caa941fSlewuathe ::llvm::APFloat real, ::llvm::APFloat imag, ::mlir::Type type) {
645caa941fSlewuathe
65c1fa60b4STres Popp if (!llvm::isa<ComplexType>(type))
6623c3eb7cSAdrian Kuegel return emitError() << "complex attribute must be a complex type.";
675caa941fSlewuathe
68c1fa60b4STres Popp Type elementType = llvm::cast<ComplexType>(type).getElementType();
69c1fa60b4STres Popp if (!llvm::isa<FloatType>(elementType))
7023c3eb7cSAdrian Kuegel return emitError()
7123c3eb7cSAdrian Kuegel << "element type of the complex attribute must be float like type.";
7223c3eb7cSAdrian Kuegel
7323c3eb7cSAdrian Kuegel const auto &typeFloatSemantics =
74c1fa60b4STres Popp llvm::cast<FloatType>(elementType).getFloatSemantics();
755caa941fSlewuathe if (&real.getSemantics() != &typeFloatSemantics)
765caa941fSlewuathe return emitError()
775caa941fSlewuathe << "type doesn't match the type implied by its `real` value";
785caa941fSlewuathe if (&imag.getSemantics() != &typeFloatSemantics)
795caa941fSlewuathe return emitError()
805caa941fSlewuathe << "type doesn't match the type implied by its `imag` value";
815caa941fSlewuathe
825caa941fSlewuathe return success();
835caa941fSlewuathe }
845caa941fSlewuathe
print(AsmPrinter & printer) const855caa941fSlewuathe void complex::NumberAttr::print(AsmPrinter &printer) const {
86c1fa60b4STres Popp printer << "<:" << llvm::cast<ComplexType>(getType()).getElementType() << " "
8723c3eb7cSAdrian Kuegel << getReal() << ", " << getImag() << ">";
885caa941fSlewuathe }
895caa941fSlewuathe
parse(AsmParser & parser,Type odsType)905caa941fSlewuathe Attribute complex::NumberAttr::parse(AsmParser &parser, Type odsType) {
915caa941fSlewuathe Type type;
92824954a8SAlexander Belyaev double real, imag;
93824954a8SAlexander Belyaev if (parser.parseLess() || parser.parseColon() || parser.parseType(type) ||
94824954a8SAlexander Belyaev parser.parseFloat(real) || parser.parseComma() ||
95824954a8SAlexander Belyaev parser.parseFloat(imag) || parser.parseGreater())
965caa941fSlewuathe return {};
975caa941fSlewuathe
986e951b3eSAdrian Kuegel return NumberAttr::get(ComplexType::get(type), real, imag);
995caa941fSlewuathe }
100