1d0cb0d30SAlexander Belyaev //===- ComplexToLLVM.cpp - conversion from Complex to LLVM 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 9d0cb0d30SAlexander Belyaev #include "mlir/Conversion/ComplexToLLVM/ComplexToLLVM.h" 10d0cb0d30SAlexander Belyaev 11d0cb0d30SAlexander Belyaev #include "../PassDetail.h" 12*75e5f0aaSAlex Zinenko #include "mlir/Conversion/LLVMCommon/ConversionTarget.h" 13*75e5f0aaSAlex Zinenko #include "mlir/Conversion/LLVMCommon/Pattern.h" 14d0cb0d30SAlexander Belyaev #include "mlir/Dialect/Complex/IR/Complex.h" 15d0cb0d30SAlexander Belyaev #include "mlir/Dialect/LLVMIR/LLVMDialect.h" 16d0cb0d30SAlexander Belyaev 17d0cb0d30SAlexander Belyaev using namespace mlir; 18d0cb0d30SAlexander Belyaev using namespace mlir::LLVM; 19d0cb0d30SAlexander Belyaev 20b5d847b1SAlex Zinenko //===----------------------------------------------------------------------===// 21b5d847b1SAlex Zinenko // ComplexStructBuilder implementation. 22b5d847b1SAlex Zinenko //===----------------------------------------------------------------------===// 23b5d847b1SAlex Zinenko 24b5d847b1SAlex Zinenko static constexpr unsigned kRealPosInComplexNumberStruct = 0; 25b5d847b1SAlex Zinenko static constexpr unsigned kImaginaryPosInComplexNumberStruct = 1; 26b5d847b1SAlex Zinenko 27b5d847b1SAlex Zinenko ComplexStructBuilder ComplexStructBuilder::undef(OpBuilder &builder, 28b5d847b1SAlex Zinenko Location loc, Type type) { 29b5d847b1SAlex Zinenko Value val = builder.create<LLVM::UndefOp>(loc, type); 30b5d847b1SAlex Zinenko return ComplexStructBuilder(val); 31b5d847b1SAlex Zinenko } 32b5d847b1SAlex Zinenko 33b5d847b1SAlex Zinenko void ComplexStructBuilder::setReal(OpBuilder &builder, Location loc, 34b5d847b1SAlex Zinenko Value real) { 35b5d847b1SAlex Zinenko setPtr(builder, loc, kRealPosInComplexNumberStruct, real); 36b5d847b1SAlex Zinenko } 37b5d847b1SAlex Zinenko 38b5d847b1SAlex Zinenko Value ComplexStructBuilder::real(OpBuilder &builder, Location loc) { 39b5d847b1SAlex Zinenko return extractPtr(builder, loc, kRealPosInComplexNumberStruct); 40b5d847b1SAlex Zinenko } 41b5d847b1SAlex Zinenko 42b5d847b1SAlex Zinenko void ComplexStructBuilder::setImaginary(OpBuilder &builder, Location loc, 43b5d847b1SAlex Zinenko Value imaginary) { 44b5d847b1SAlex Zinenko setPtr(builder, loc, kImaginaryPosInComplexNumberStruct, imaginary); 45b5d847b1SAlex Zinenko } 46b5d847b1SAlex Zinenko 47b5d847b1SAlex Zinenko Value ComplexStructBuilder::imaginary(OpBuilder &builder, Location loc) { 48b5d847b1SAlex Zinenko return extractPtr(builder, loc, kImaginaryPosInComplexNumberStruct); 49b5d847b1SAlex Zinenko } 50b5d847b1SAlex Zinenko 51b5d847b1SAlex Zinenko //===----------------------------------------------------------------------===// 52b5d847b1SAlex Zinenko // Conversion patterns. 53b5d847b1SAlex Zinenko //===----------------------------------------------------------------------===// 54b5d847b1SAlex Zinenko 55d0cb0d30SAlexander Belyaev namespace { 56d0cb0d30SAlexander Belyaev 5711f4c58cSAlexander Belyaev struct AbsOpConversion : public ConvertOpToLLVMPattern<complex::AbsOp> { 5811f4c58cSAlexander Belyaev using ConvertOpToLLVMPattern<complex::AbsOp>::ConvertOpToLLVMPattern; 5911f4c58cSAlexander Belyaev 6011f4c58cSAlexander Belyaev LogicalResult 6111f4c58cSAlexander Belyaev matchAndRewrite(complex::AbsOp op, ArrayRef<Value> operands, 6211f4c58cSAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 6311f4c58cSAlexander Belyaev complex::AbsOp::Adaptor transformed(operands); 6411f4c58cSAlexander Belyaev auto loc = op.getLoc(); 6511f4c58cSAlexander Belyaev 6611f4c58cSAlexander Belyaev ComplexStructBuilder complexStruct(transformed.complex()); 6711f4c58cSAlexander Belyaev Value real = complexStruct.real(rewriter, op.getLoc()); 6811f4c58cSAlexander Belyaev Value imag = complexStruct.imaginary(rewriter, op.getLoc()); 6911f4c58cSAlexander Belyaev 70038f2a33SMehdi Amini auto fmf = LLVM::FMFAttr::get(op.getContext(), {}); 7111f4c58cSAlexander Belyaev Value sqNorm = rewriter.create<LLVM::FAddOp>( 7211f4c58cSAlexander Belyaev loc, rewriter.create<LLVM::FMulOp>(loc, real, real, fmf), 7311f4c58cSAlexander Belyaev rewriter.create<LLVM::FMulOp>(loc, imag, imag, fmf), fmf); 7411f4c58cSAlexander Belyaev 7511f4c58cSAlexander Belyaev rewriter.replaceOpWithNewOp<LLVM::SqrtOp>(op, sqNorm); 7611f4c58cSAlexander Belyaev return success(); 7711f4c58cSAlexander Belyaev } 7811f4c58cSAlexander Belyaev }; 7911f4c58cSAlexander Belyaev 80d0cb0d30SAlexander Belyaev struct CreateOpConversion : public ConvertOpToLLVMPattern<complex::CreateOp> { 81d0cb0d30SAlexander Belyaev using ConvertOpToLLVMPattern<complex::CreateOp>::ConvertOpToLLVMPattern; 82d0cb0d30SAlexander Belyaev 83d0cb0d30SAlexander Belyaev LogicalResult 84d0cb0d30SAlexander Belyaev matchAndRewrite(complex::CreateOp complexOp, ArrayRef<Value> operands, 85d0cb0d30SAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 86d0cb0d30SAlexander Belyaev complex::CreateOp::Adaptor transformed(operands); 87d0cb0d30SAlexander Belyaev 88d0cb0d30SAlexander Belyaev // Pack real and imaginary part in a complex number struct. 89d0cb0d30SAlexander Belyaev auto loc = complexOp.getLoc(); 90d0cb0d30SAlexander Belyaev auto structType = typeConverter->convertType(complexOp.getType()); 91d0cb0d30SAlexander Belyaev auto complexStruct = ComplexStructBuilder::undef(rewriter, loc, structType); 92d0cb0d30SAlexander Belyaev complexStruct.setReal(rewriter, loc, transformed.real()); 93d0cb0d30SAlexander Belyaev complexStruct.setImaginary(rewriter, loc, transformed.imaginary()); 94d0cb0d30SAlexander Belyaev 95d0cb0d30SAlexander Belyaev rewriter.replaceOp(complexOp, {complexStruct}); 96d0cb0d30SAlexander Belyaev return success(); 97d0cb0d30SAlexander Belyaev } 98d0cb0d30SAlexander Belyaev }; 99d0cb0d30SAlexander Belyaev 100d0cb0d30SAlexander Belyaev struct ReOpConversion : public ConvertOpToLLVMPattern<complex::ReOp> { 101d0cb0d30SAlexander Belyaev using ConvertOpToLLVMPattern<complex::ReOp>::ConvertOpToLLVMPattern; 102d0cb0d30SAlexander Belyaev 103d0cb0d30SAlexander Belyaev LogicalResult 104d0cb0d30SAlexander Belyaev matchAndRewrite(complex::ReOp op, ArrayRef<Value> operands, 105d0cb0d30SAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 106d0cb0d30SAlexander Belyaev complex::ReOp::Adaptor transformed(operands); 107d0cb0d30SAlexander Belyaev 108d0cb0d30SAlexander Belyaev // Extract real part from the complex number struct. 109d0cb0d30SAlexander Belyaev ComplexStructBuilder complexStruct(transformed.complex()); 110d0cb0d30SAlexander Belyaev Value real = complexStruct.real(rewriter, op.getLoc()); 111d0cb0d30SAlexander Belyaev rewriter.replaceOp(op, real); 112d0cb0d30SAlexander Belyaev 113d0cb0d30SAlexander Belyaev return success(); 114d0cb0d30SAlexander Belyaev } 115d0cb0d30SAlexander Belyaev }; 116d0cb0d30SAlexander Belyaev 117d0cb0d30SAlexander Belyaev struct ImOpConversion : public ConvertOpToLLVMPattern<complex::ImOp> { 118d0cb0d30SAlexander Belyaev using ConvertOpToLLVMPattern<complex::ImOp>::ConvertOpToLLVMPattern; 119d0cb0d30SAlexander Belyaev 120d0cb0d30SAlexander Belyaev LogicalResult 121d0cb0d30SAlexander Belyaev matchAndRewrite(complex::ImOp op, ArrayRef<Value> operands, 122d0cb0d30SAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 123d0cb0d30SAlexander Belyaev complex::ImOp::Adaptor transformed(operands); 124d0cb0d30SAlexander Belyaev 125d0cb0d30SAlexander Belyaev // Extract imaginary part from the complex number struct. 126d0cb0d30SAlexander Belyaev ComplexStructBuilder complexStruct(transformed.complex()); 127d0cb0d30SAlexander Belyaev Value imaginary = complexStruct.imaginary(rewriter, op.getLoc()); 128d0cb0d30SAlexander Belyaev rewriter.replaceOp(op, imaginary); 129d0cb0d30SAlexander Belyaev 130d0cb0d30SAlexander Belyaev return success(); 131d0cb0d30SAlexander Belyaev } 132d0cb0d30SAlexander Belyaev }; 133d0cb0d30SAlexander Belyaev 134d0cb0d30SAlexander Belyaev struct BinaryComplexOperands { 135d0cb0d30SAlexander Belyaev std::complex<Value> lhs; 136d0cb0d30SAlexander Belyaev std::complex<Value> rhs; 137d0cb0d30SAlexander Belyaev }; 138d0cb0d30SAlexander Belyaev 139d0cb0d30SAlexander Belyaev template <typename OpTy> 140d0cb0d30SAlexander Belyaev BinaryComplexOperands 141d0cb0d30SAlexander Belyaev unpackBinaryComplexOperands(OpTy op, ArrayRef<Value> operands, 142d0cb0d30SAlexander Belyaev ConversionPatternRewriter &rewriter) { 143d0cb0d30SAlexander Belyaev auto loc = op.getLoc(); 144d0cb0d30SAlexander Belyaev typename OpTy::Adaptor transformed(operands); 145d0cb0d30SAlexander Belyaev 146d0cb0d30SAlexander Belyaev // Extract real and imaginary values from operands. 147d0cb0d30SAlexander Belyaev BinaryComplexOperands unpacked; 148d0cb0d30SAlexander Belyaev ComplexStructBuilder lhs(transformed.lhs()); 149d0cb0d30SAlexander Belyaev unpacked.lhs.real(lhs.real(rewriter, loc)); 150d0cb0d30SAlexander Belyaev unpacked.lhs.imag(lhs.imaginary(rewriter, loc)); 151d0cb0d30SAlexander Belyaev ComplexStructBuilder rhs(transformed.rhs()); 152d0cb0d30SAlexander Belyaev unpacked.rhs.real(rhs.real(rewriter, loc)); 153d0cb0d30SAlexander Belyaev unpacked.rhs.imag(rhs.imaginary(rewriter, loc)); 154d0cb0d30SAlexander Belyaev 155d0cb0d30SAlexander Belyaev return unpacked; 156d0cb0d30SAlexander Belyaev } 157d0cb0d30SAlexander Belyaev 158d0cb0d30SAlexander Belyaev struct AddOpConversion : public ConvertOpToLLVMPattern<complex::AddOp> { 159d0cb0d30SAlexander Belyaev using ConvertOpToLLVMPattern<complex::AddOp>::ConvertOpToLLVMPattern; 160d0cb0d30SAlexander Belyaev 161d0cb0d30SAlexander Belyaev LogicalResult 162d0cb0d30SAlexander Belyaev matchAndRewrite(complex::AddOp op, ArrayRef<Value> operands, 163d0cb0d30SAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 164d0cb0d30SAlexander Belyaev auto loc = op.getLoc(); 165d0cb0d30SAlexander Belyaev BinaryComplexOperands arg = 166d0cb0d30SAlexander Belyaev unpackBinaryComplexOperands<complex::AddOp>(op, operands, rewriter); 167d0cb0d30SAlexander Belyaev 168d0cb0d30SAlexander Belyaev // Initialize complex number struct for result. 169d0cb0d30SAlexander Belyaev auto structType = typeConverter->convertType(op.getType()); 170d0cb0d30SAlexander Belyaev auto result = ComplexStructBuilder::undef(rewriter, loc, structType); 171d0cb0d30SAlexander Belyaev 172d0cb0d30SAlexander Belyaev // Emit IR to add complex numbers. 173038f2a33SMehdi Amini auto fmf = LLVM::FMFAttr::get(op.getContext(), {}); 174d0cb0d30SAlexander Belyaev Value real = 175d0cb0d30SAlexander Belyaev rewriter.create<LLVM::FAddOp>(loc, arg.lhs.real(), arg.rhs.real(), fmf); 176d0cb0d30SAlexander Belyaev Value imag = 177d0cb0d30SAlexander Belyaev rewriter.create<LLVM::FAddOp>(loc, arg.lhs.imag(), arg.rhs.imag(), fmf); 178d0cb0d30SAlexander Belyaev result.setReal(rewriter, loc, real); 179d0cb0d30SAlexander Belyaev result.setImaginary(rewriter, loc, imag); 180d0cb0d30SAlexander Belyaev 181d0cb0d30SAlexander Belyaev rewriter.replaceOp(op, {result}); 182d0cb0d30SAlexander Belyaev return success(); 183d0cb0d30SAlexander Belyaev } 184d0cb0d30SAlexander Belyaev }; 185d0cb0d30SAlexander Belyaev 18611f4c58cSAlexander Belyaev struct DivOpConversion : public ConvertOpToLLVMPattern<complex::DivOp> { 18711f4c58cSAlexander Belyaev using ConvertOpToLLVMPattern<complex::DivOp>::ConvertOpToLLVMPattern; 18811f4c58cSAlexander Belyaev 18911f4c58cSAlexander Belyaev LogicalResult 19011f4c58cSAlexander Belyaev matchAndRewrite(complex::DivOp op, ArrayRef<Value> operands, 19111f4c58cSAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 19211f4c58cSAlexander Belyaev auto loc = op.getLoc(); 19311f4c58cSAlexander Belyaev BinaryComplexOperands arg = 19411f4c58cSAlexander Belyaev unpackBinaryComplexOperands<complex::DivOp>(op, operands, rewriter); 19511f4c58cSAlexander Belyaev 19611f4c58cSAlexander Belyaev // Initialize complex number struct for result. 19711f4c58cSAlexander Belyaev auto structType = typeConverter->convertType(op.getType()); 19811f4c58cSAlexander Belyaev auto result = ComplexStructBuilder::undef(rewriter, loc, structType); 19911f4c58cSAlexander Belyaev 20011f4c58cSAlexander Belyaev // Emit IR to add complex numbers. 201038f2a33SMehdi Amini auto fmf = LLVM::FMFAttr::get(op.getContext(), {}); 20211f4c58cSAlexander Belyaev Value rhsRe = arg.rhs.real(); 20311f4c58cSAlexander Belyaev Value rhsIm = arg.rhs.imag(); 20411f4c58cSAlexander Belyaev Value lhsRe = arg.lhs.real(); 20511f4c58cSAlexander Belyaev Value lhsIm = arg.lhs.imag(); 20611f4c58cSAlexander Belyaev 20711f4c58cSAlexander Belyaev Value rhsSqNorm = rewriter.create<LLVM::FAddOp>( 20811f4c58cSAlexander Belyaev loc, rewriter.create<LLVM::FMulOp>(loc, rhsRe, rhsRe, fmf), 20911f4c58cSAlexander Belyaev rewriter.create<LLVM::FMulOp>(loc, rhsIm, rhsIm, fmf), fmf); 21011f4c58cSAlexander Belyaev 21111f4c58cSAlexander Belyaev Value resultReal = rewriter.create<LLVM::FAddOp>( 21211f4c58cSAlexander Belyaev loc, rewriter.create<LLVM::FMulOp>(loc, lhsRe, rhsRe, fmf), 21311f4c58cSAlexander Belyaev rewriter.create<LLVM::FMulOp>(loc, lhsIm, rhsIm, fmf), fmf); 21411f4c58cSAlexander Belyaev 21511f4c58cSAlexander Belyaev Value resultImag = rewriter.create<LLVM::FSubOp>( 21611f4c58cSAlexander Belyaev loc, rewriter.create<LLVM::FMulOp>(loc, lhsIm, rhsRe, fmf), 21711f4c58cSAlexander Belyaev rewriter.create<LLVM::FMulOp>(loc, lhsRe, rhsIm, fmf), fmf); 21811f4c58cSAlexander Belyaev 21911f4c58cSAlexander Belyaev result.setReal( 22011f4c58cSAlexander Belyaev rewriter, loc, 22111f4c58cSAlexander Belyaev rewriter.create<LLVM::FDivOp>(loc, resultReal, rhsSqNorm, fmf)); 22211f4c58cSAlexander Belyaev result.setImaginary( 22311f4c58cSAlexander Belyaev rewriter, loc, 22411f4c58cSAlexander Belyaev rewriter.create<LLVM::FDivOp>(loc, resultImag, rhsSqNorm, fmf)); 22511f4c58cSAlexander Belyaev 22611f4c58cSAlexander Belyaev rewriter.replaceOp(op, {result}); 22711f4c58cSAlexander Belyaev return success(); 22811f4c58cSAlexander Belyaev } 22911f4c58cSAlexander Belyaev }; 23011f4c58cSAlexander Belyaev 23111f4c58cSAlexander Belyaev struct MulOpConversion : public ConvertOpToLLVMPattern<complex::MulOp> { 23211f4c58cSAlexander Belyaev using ConvertOpToLLVMPattern<complex::MulOp>::ConvertOpToLLVMPattern; 23311f4c58cSAlexander Belyaev 23411f4c58cSAlexander Belyaev LogicalResult 23511f4c58cSAlexander Belyaev matchAndRewrite(complex::MulOp op, ArrayRef<Value> operands, 23611f4c58cSAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 23711f4c58cSAlexander Belyaev auto loc = op.getLoc(); 23811f4c58cSAlexander Belyaev BinaryComplexOperands arg = 23911f4c58cSAlexander Belyaev unpackBinaryComplexOperands<complex::MulOp>(op, operands, rewriter); 24011f4c58cSAlexander Belyaev 24111f4c58cSAlexander Belyaev // Initialize complex number struct for result. 24211f4c58cSAlexander Belyaev auto structType = typeConverter->convertType(op.getType()); 24311f4c58cSAlexander Belyaev auto result = ComplexStructBuilder::undef(rewriter, loc, structType); 24411f4c58cSAlexander Belyaev 24511f4c58cSAlexander Belyaev // Emit IR to add complex numbers. 246038f2a33SMehdi Amini auto fmf = LLVM::FMFAttr::get(op.getContext(), {}); 24711f4c58cSAlexander Belyaev Value rhsRe = arg.rhs.real(); 24811f4c58cSAlexander Belyaev Value rhsIm = arg.rhs.imag(); 24911f4c58cSAlexander Belyaev Value lhsRe = arg.lhs.real(); 25011f4c58cSAlexander Belyaev Value lhsIm = arg.lhs.imag(); 25111f4c58cSAlexander Belyaev 25211f4c58cSAlexander Belyaev Value real = rewriter.create<LLVM::FSubOp>( 25311f4c58cSAlexander Belyaev loc, rewriter.create<LLVM::FMulOp>(loc, rhsRe, lhsRe, fmf), 25411f4c58cSAlexander Belyaev rewriter.create<LLVM::FMulOp>(loc, rhsIm, lhsIm, fmf), fmf); 25511f4c58cSAlexander Belyaev 25611f4c58cSAlexander Belyaev Value imag = rewriter.create<LLVM::FAddOp>( 25711f4c58cSAlexander Belyaev loc, rewriter.create<LLVM::FMulOp>(loc, lhsIm, rhsRe, fmf), 25811f4c58cSAlexander Belyaev rewriter.create<LLVM::FMulOp>(loc, lhsRe, rhsIm, fmf), fmf); 25911f4c58cSAlexander Belyaev 26011f4c58cSAlexander Belyaev result.setReal(rewriter, loc, real); 26111f4c58cSAlexander Belyaev result.setImaginary(rewriter, loc, imag); 26211f4c58cSAlexander Belyaev 26311f4c58cSAlexander Belyaev rewriter.replaceOp(op, {result}); 26411f4c58cSAlexander Belyaev return success(); 26511f4c58cSAlexander Belyaev } 26611f4c58cSAlexander Belyaev }; 26711f4c58cSAlexander Belyaev 268d0cb0d30SAlexander Belyaev struct SubOpConversion : public ConvertOpToLLVMPattern<complex::SubOp> { 269d0cb0d30SAlexander Belyaev using ConvertOpToLLVMPattern<complex::SubOp>::ConvertOpToLLVMPattern; 270d0cb0d30SAlexander Belyaev 271d0cb0d30SAlexander Belyaev LogicalResult 272d0cb0d30SAlexander Belyaev matchAndRewrite(complex::SubOp op, ArrayRef<Value> operands, 273d0cb0d30SAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 274d0cb0d30SAlexander Belyaev auto loc = op.getLoc(); 275d0cb0d30SAlexander Belyaev BinaryComplexOperands arg = 276d0cb0d30SAlexander Belyaev unpackBinaryComplexOperands<complex::SubOp>(op, operands, rewriter); 277d0cb0d30SAlexander Belyaev 278d0cb0d30SAlexander Belyaev // Initialize complex number struct for result. 279d0cb0d30SAlexander Belyaev auto structType = typeConverter->convertType(op.getType()); 280d0cb0d30SAlexander Belyaev auto result = ComplexStructBuilder::undef(rewriter, loc, structType); 281d0cb0d30SAlexander Belyaev 282d0cb0d30SAlexander Belyaev // Emit IR to substract complex numbers. 283038f2a33SMehdi Amini auto fmf = LLVM::FMFAttr::get(op.getContext(), {}); 284d0cb0d30SAlexander Belyaev Value real = 285d0cb0d30SAlexander Belyaev rewriter.create<LLVM::FSubOp>(loc, arg.lhs.real(), arg.rhs.real(), fmf); 286d0cb0d30SAlexander Belyaev Value imag = 287d0cb0d30SAlexander Belyaev rewriter.create<LLVM::FSubOp>(loc, arg.lhs.imag(), arg.rhs.imag(), fmf); 288d0cb0d30SAlexander Belyaev result.setReal(rewriter, loc, real); 289d0cb0d30SAlexander Belyaev result.setImaginary(rewriter, loc, imag); 290d0cb0d30SAlexander Belyaev 291d0cb0d30SAlexander Belyaev rewriter.replaceOp(op, {result}); 292d0cb0d30SAlexander Belyaev return success(); 293d0cb0d30SAlexander Belyaev } 294d0cb0d30SAlexander Belyaev }; 295d0cb0d30SAlexander Belyaev } // namespace 296d0cb0d30SAlexander Belyaev 297d0cb0d30SAlexander Belyaev void mlir::populateComplexToLLVMConversionPatterns( 298dc4e913bSChris Lattner LLVMTypeConverter &converter, RewritePatternSet &patterns) { 299d0cb0d30SAlexander Belyaev // clang-format off 300dc4e913bSChris Lattner patterns.add< 30111f4c58cSAlexander Belyaev AbsOpConversion, 302d0cb0d30SAlexander Belyaev AddOpConversion, 303d0cb0d30SAlexander Belyaev CreateOpConversion, 30411f4c58cSAlexander Belyaev DivOpConversion, 305d0cb0d30SAlexander Belyaev ImOpConversion, 30611f4c58cSAlexander Belyaev MulOpConversion, 307d0cb0d30SAlexander Belyaev ReOpConversion, 308d0cb0d30SAlexander Belyaev SubOpConversion 309d0cb0d30SAlexander Belyaev >(converter); 310d0cb0d30SAlexander Belyaev // clang-format on 311d0cb0d30SAlexander Belyaev } 312d0cb0d30SAlexander Belyaev 313d0cb0d30SAlexander Belyaev namespace { 314d0cb0d30SAlexander Belyaev struct ConvertComplexToLLVMPass 315d0cb0d30SAlexander Belyaev : public ConvertComplexToLLVMBase<ConvertComplexToLLVMPass> { 316d0cb0d30SAlexander Belyaev void runOnOperation() override; 317d0cb0d30SAlexander Belyaev }; 318d0cb0d30SAlexander Belyaev } // namespace 319d0cb0d30SAlexander Belyaev 320d0cb0d30SAlexander Belyaev void ConvertComplexToLLVMPass::runOnOperation() { 321d0cb0d30SAlexander Belyaev auto module = getOperation(); 322d0cb0d30SAlexander Belyaev 323d0cb0d30SAlexander Belyaev // Convert to the LLVM IR dialect using the converter defined above. 324dc4e913bSChris Lattner RewritePatternSet patterns(&getContext()); 325d0cb0d30SAlexander Belyaev LLVMTypeConverter converter(&getContext()); 326d0cb0d30SAlexander Belyaev populateComplexToLLVMConversionPatterns(converter, patterns); 327d0cb0d30SAlexander Belyaev 328d0cb0d30SAlexander Belyaev LLVMConversionTarget target(getContext()); 329d6be2773SAlex Zinenko target.addLegalOp<ModuleOp, FuncOp>(); 330d6be2773SAlex Zinenko target.addLegalOp<LLVM::DialectCastOp>(); 331d6be2773SAlex Zinenko target.addIllegalDialect<complex::ComplexDialect>(); 332d6be2773SAlex Zinenko if (failed(applyPartialConversion(module, target, std::move(patterns)))) 333d0cb0d30SAlexander Belyaev signalPassFailure(); 334d0cb0d30SAlexander Belyaev } 335d0cb0d30SAlexander Belyaev 336d0cb0d30SAlexander Belyaev std::unique_ptr<OperationPass<ModuleOp>> 337d0cb0d30SAlexander Belyaev mlir::createConvertComplexToLLVMPass() { 338d0cb0d30SAlexander Belyaev return std::make_unique<ConvertComplexToLLVMPass>(); 339d0cb0d30SAlexander Belyaev } 340