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" 1275e5f0aaSAlex Zinenko #include "mlir/Conversion/LLVMCommon/ConversionTarget.h" 1375e5f0aaSAlex 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 61*ef976337SRiver Riddle matchAndRewrite(complex::AbsOp op, OpAdaptor adaptor, 6211f4c58cSAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 6311f4c58cSAlexander Belyaev auto loc = op.getLoc(); 6411f4c58cSAlexander Belyaev 65*ef976337SRiver Riddle ComplexStructBuilder complexStruct(adaptor.complex()); 6611f4c58cSAlexander Belyaev Value real = complexStruct.real(rewriter, op.getLoc()); 6711f4c58cSAlexander Belyaev Value imag = complexStruct.imaginary(rewriter, op.getLoc()); 6811f4c58cSAlexander Belyaev 69038f2a33SMehdi Amini auto fmf = LLVM::FMFAttr::get(op.getContext(), {}); 7011f4c58cSAlexander Belyaev Value sqNorm = rewriter.create<LLVM::FAddOp>( 7111f4c58cSAlexander Belyaev loc, rewriter.create<LLVM::FMulOp>(loc, real, real, fmf), 7211f4c58cSAlexander Belyaev rewriter.create<LLVM::FMulOp>(loc, imag, imag, fmf), fmf); 7311f4c58cSAlexander Belyaev 7411f4c58cSAlexander Belyaev rewriter.replaceOpWithNewOp<LLVM::SqrtOp>(op, sqNorm); 7511f4c58cSAlexander Belyaev return success(); 7611f4c58cSAlexander Belyaev } 7711f4c58cSAlexander Belyaev }; 7811f4c58cSAlexander Belyaev 79d0cb0d30SAlexander Belyaev struct CreateOpConversion : public ConvertOpToLLVMPattern<complex::CreateOp> { 80d0cb0d30SAlexander Belyaev using ConvertOpToLLVMPattern<complex::CreateOp>::ConvertOpToLLVMPattern; 81d0cb0d30SAlexander Belyaev 82d0cb0d30SAlexander Belyaev LogicalResult 83*ef976337SRiver Riddle matchAndRewrite(complex::CreateOp complexOp, OpAdaptor adaptor, 84d0cb0d30SAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 85d0cb0d30SAlexander Belyaev // Pack real and imaginary part in a complex number struct. 86d0cb0d30SAlexander Belyaev auto loc = complexOp.getLoc(); 87d0cb0d30SAlexander Belyaev auto structType = typeConverter->convertType(complexOp.getType()); 88d0cb0d30SAlexander Belyaev auto complexStruct = ComplexStructBuilder::undef(rewriter, loc, structType); 89*ef976337SRiver Riddle complexStruct.setReal(rewriter, loc, adaptor.real()); 90*ef976337SRiver Riddle complexStruct.setImaginary(rewriter, loc, adaptor.imaginary()); 91d0cb0d30SAlexander Belyaev 92d0cb0d30SAlexander Belyaev rewriter.replaceOp(complexOp, {complexStruct}); 93d0cb0d30SAlexander Belyaev return success(); 94d0cb0d30SAlexander Belyaev } 95d0cb0d30SAlexander Belyaev }; 96d0cb0d30SAlexander Belyaev 97d0cb0d30SAlexander Belyaev struct ReOpConversion : public ConvertOpToLLVMPattern<complex::ReOp> { 98d0cb0d30SAlexander Belyaev using ConvertOpToLLVMPattern<complex::ReOp>::ConvertOpToLLVMPattern; 99d0cb0d30SAlexander Belyaev 100d0cb0d30SAlexander Belyaev LogicalResult 101*ef976337SRiver Riddle matchAndRewrite(complex::ReOp op, OpAdaptor adaptor, 102d0cb0d30SAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 103d0cb0d30SAlexander Belyaev // Extract real part from the complex number struct. 104*ef976337SRiver Riddle ComplexStructBuilder complexStruct(adaptor.complex()); 105d0cb0d30SAlexander Belyaev Value real = complexStruct.real(rewriter, op.getLoc()); 106d0cb0d30SAlexander Belyaev rewriter.replaceOp(op, real); 107d0cb0d30SAlexander Belyaev 108d0cb0d30SAlexander Belyaev return success(); 109d0cb0d30SAlexander Belyaev } 110d0cb0d30SAlexander Belyaev }; 111d0cb0d30SAlexander Belyaev 112d0cb0d30SAlexander Belyaev struct ImOpConversion : public ConvertOpToLLVMPattern<complex::ImOp> { 113d0cb0d30SAlexander Belyaev using ConvertOpToLLVMPattern<complex::ImOp>::ConvertOpToLLVMPattern; 114d0cb0d30SAlexander Belyaev 115d0cb0d30SAlexander Belyaev LogicalResult 116*ef976337SRiver Riddle matchAndRewrite(complex::ImOp op, OpAdaptor adaptor, 117d0cb0d30SAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 118d0cb0d30SAlexander Belyaev // Extract imaginary part from the complex number struct. 119*ef976337SRiver Riddle ComplexStructBuilder complexStruct(adaptor.complex()); 120d0cb0d30SAlexander Belyaev Value imaginary = complexStruct.imaginary(rewriter, op.getLoc()); 121d0cb0d30SAlexander Belyaev rewriter.replaceOp(op, imaginary); 122d0cb0d30SAlexander Belyaev 123d0cb0d30SAlexander Belyaev return success(); 124d0cb0d30SAlexander Belyaev } 125d0cb0d30SAlexander Belyaev }; 126d0cb0d30SAlexander Belyaev 127d0cb0d30SAlexander Belyaev struct BinaryComplexOperands { 128d0cb0d30SAlexander Belyaev std::complex<Value> lhs; 129d0cb0d30SAlexander Belyaev std::complex<Value> rhs; 130d0cb0d30SAlexander Belyaev }; 131d0cb0d30SAlexander Belyaev 132d0cb0d30SAlexander Belyaev template <typename OpTy> 133d0cb0d30SAlexander Belyaev BinaryComplexOperands 134*ef976337SRiver Riddle unpackBinaryComplexOperands(OpTy op, typename OpTy::Adaptor adaptor, 135d0cb0d30SAlexander Belyaev ConversionPatternRewriter &rewriter) { 136d0cb0d30SAlexander Belyaev auto loc = op.getLoc(); 137d0cb0d30SAlexander Belyaev 138d0cb0d30SAlexander Belyaev // Extract real and imaginary values from operands. 139d0cb0d30SAlexander Belyaev BinaryComplexOperands unpacked; 140*ef976337SRiver Riddle ComplexStructBuilder lhs(adaptor.lhs()); 141d0cb0d30SAlexander Belyaev unpacked.lhs.real(lhs.real(rewriter, loc)); 142d0cb0d30SAlexander Belyaev unpacked.lhs.imag(lhs.imaginary(rewriter, loc)); 143*ef976337SRiver Riddle ComplexStructBuilder rhs(adaptor.rhs()); 144d0cb0d30SAlexander Belyaev unpacked.rhs.real(rhs.real(rewriter, loc)); 145d0cb0d30SAlexander Belyaev unpacked.rhs.imag(rhs.imaginary(rewriter, loc)); 146d0cb0d30SAlexander Belyaev 147d0cb0d30SAlexander Belyaev return unpacked; 148d0cb0d30SAlexander Belyaev } 149d0cb0d30SAlexander Belyaev 150d0cb0d30SAlexander Belyaev struct AddOpConversion : public ConvertOpToLLVMPattern<complex::AddOp> { 151d0cb0d30SAlexander Belyaev using ConvertOpToLLVMPattern<complex::AddOp>::ConvertOpToLLVMPattern; 152d0cb0d30SAlexander Belyaev 153d0cb0d30SAlexander Belyaev LogicalResult 154*ef976337SRiver Riddle matchAndRewrite(complex::AddOp op, OpAdaptor adaptor, 155d0cb0d30SAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 156d0cb0d30SAlexander Belyaev auto loc = op.getLoc(); 157d0cb0d30SAlexander Belyaev BinaryComplexOperands arg = 158*ef976337SRiver Riddle unpackBinaryComplexOperands<complex::AddOp>(op, adaptor, rewriter); 159d0cb0d30SAlexander Belyaev 160d0cb0d30SAlexander Belyaev // Initialize complex number struct for result. 161d0cb0d30SAlexander Belyaev auto structType = typeConverter->convertType(op.getType()); 162d0cb0d30SAlexander Belyaev auto result = ComplexStructBuilder::undef(rewriter, loc, structType); 163d0cb0d30SAlexander Belyaev 164d0cb0d30SAlexander Belyaev // Emit IR to add complex numbers. 165038f2a33SMehdi Amini auto fmf = LLVM::FMFAttr::get(op.getContext(), {}); 166d0cb0d30SAlexander Belyaev Value real = 167d0cb0d30SAlexander Belyaev rewriter.create<LLVM::FAddOp>(loc, arg.lhs.real(), arg.rhs.real(), fmf); 168d0cb0d30SAlexander Belyaev Value imag = 169d0cb0d30SAlexander Belyaev rewriter.create<LLVM::FAddOp>(loc, arg.lhs.imag(), arg.rhs.imag(), fmf); 170d0cb0d30SAlexander Belyaev result.setReal(rewriter, loc, real); 171d0cb0d30SAlexander Belyaev result.setImaginary(rewriter, loc, imag); 172d0cb0d30SAlexander Belyaev 173d0cb0d30SAlexander Belyaev rewriter.replaceOp(op, {result}); 174d0cb0d30SAlexander Belyaev return success(); 175d0cb0d30SAlexander Belyaev } 176d0cb0d30SAlexander Belyaev }; 177d0cb0d30SAlexander Belyaev 17811f4c58cSAlexander Belyaev struct DivOpConversion : public ConvertOpToLLVMPattern<complex::DivOp> { 17911f4c58cSAlexander Belyaev using ConvertOpToLLVMPattern<complex::DivOp>::ConvertOpToLLVMPattern; 18011f4c58cSAlexander Belyaev 18111f4c58cSAlexander Belyaev LogicalResult 182*ef976337SRiver Riddle matchAndRewrite(complex::DivOp op, OpAdaptor adaptor, 18311f4c58cSAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 18411f4c58cSAlexander Belyaev auto loc = op.getLoc(); 18511f4c58cSAlexander Belyaev BinaryComplexOperands arg = 186*ef976337SRiver Riddle unpackBinaryComplexOperands<complex::DivOp>(op, adaptor, rewriter); 18711f4c58cSAlexander Belyaev 18811f4c58cSAlexander Belyaev // Initialize complex number struct for result. 18911f4c58cSAlexander Belyaev auto structType = typeConverter->convertType(op.getType()); 19011f4c58cSAlexander Belyaev auto result = ComplexStructBuilder::undef(rewriter, loc, structType); 19111f4c58cSAlexander Belyaev 19211f4c58cSAlexander Belyaev // Emit IR to add complex numbers. 193038f2a33SMehdi Amini auto fmf = LLVM::FMFAttr::get(op.getContext(), {}); 19411f4c58cSAlexander Belyaev Value rhsRe = arg.rhs.real(); 19511f4c58cSAlexander Belyaev Value rhsIm = arg.rhs.imag(); 19611f4c58cSAlexander Belyaev Value lhsRe = arg.lhs.real(); 19711f4c58cSAlexander Belyaev Value lhsIm = arg.lhs.imag(); 19811f4c58cSAlexander Belyaev 19911f4c58cSAlexander Belyaev Value rhsSqNorm = rewriter.create<LLVM::FAddOp>( 20011f4c58cSAlexander Belyaev loc, rewriter.create<LLVM::FMulOp>(loc, rhsRe, rhsRe, fmf), 20111f4c58cSAlexander Belyaev rewriter.create<LLVM::FMulOp>(loc, rhsIm, rhsIm, fmf), fmf); 20211f4c58cSAlexander Belyaev 20311f4c58cSAlexander Belyaev Value resultReal = rewriter.create<LLVM::FAddOp>( 20411f4c58cSAlexander Belyaev loc, rewriter.create<LLVM::FMulOp>(loc, lhsRe, rhsRe, fmf), 20511f4c58cSAlexander Belyaev rewriter.create<LLVM::FMulOp>(loc, lhsIm, rhsIm, fmf), fmf); 20611f4c58cSAlexander Belyaev 20711f4c58cSAlexander Belyaev Value resultImag = rewriter.create<LLVM::FSubOp>( 20811f4c58cSAlexander Belyaev loc, rewriter.create<LLVM::FMulOp>(loc, lhsIm, rhsRe, fmf), 20911f4c58cSAlexander Belyaev rewriter.create<LLVM::FMulOp>(loc, lhsRe, rhsIm, fmf), fmf); 21011f4c58cSAlexander Belyaev 21111f4c58cSAlexander Belyaev result.setReal( 21211f4c58cSAlexander Belyaev rewriter, loc, 21311f4c58cSAlexander Belyaev rewriter.create<LLVM::FDivOp>(loc, resultReal, rhsSqNorm, fmf)); 21411f4c58cSAlexander Belyaev result.setImaginary( 21511f4c58cSAlexander Belyaev rewriter, loc, 21611f4c58cSAlexander Belyaev rewriter.create<LLVM::FDivOp>(loc, resultImag, rhsSqNorm, fmf)); 21711f4c58cSAlexander Belyaev 21811f4c58cSAlexander Belyaev rewriter.replaceOp(op, {result}); 21911f4c58cSAlexander Belyaev return success(); 22011f4c58cSAlexander Belyaev } 22111f4c58cSAlexander Belyaev }; 22211f4c58cSAlexander Belyaev 22311f4c58cSAlexander Belyaev struct MulOpConversion : public ConvertOpToLLVMPattern<complex::MulOp> { 22411f4c58cSAlexander Belyaev using ConvertOpToLLVMPattern<complex::MulOp>::ConvertOpToLLVMPattern; 22511f4c58cSAlexander Belyaev 22611f4c58cSAlexander Belyaev LogicalResult 227*ef976337SRiver Riddle matchAndRewrite(complex::MulOp op, OpAdaptor adaptor, 22811f4c58cSAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 22911f4c58cSAlexander Belyaev auto loc = op.getLoc(); 23011f4c58cSAlexander Belyaev BinaryComplexOperands arg = 231*ef976337SRiver Riddle unpackBinaryComplexOperands<complex::MulOp>(op, adaptor, rewriter); 23211f4c58cSAlexander Belyaev 23311f4c58cSAlexander Belyaev // Initialize complex number struct for result. 23411f4c58cSAlexander Belyaev auto structType = typeConverter->convertType(op.getType()); 23511f4c58cSAlexander Belyaev auto result = ComplexStructBuilder::undef(rewriter, loc, structType); 23611f4c58cSAlexander Belyaev 23711f4c58cSAlexander Belyaev // Emit IR to add complex numbers. 238038f2a33SMehdi Amini auto fmf = LLVM::FMFAttr::get(op.getContext(), {}); 23911f4c58cSAlexander Belyaev Value rhsRe = arg.rhs.real(); 24011f4c58cSAlexander Belyaev Value rhsIm = arg.rhs.imag(); 24111f4c58cSAlexander Belyaev Value lhsRe = arg.lhs.real(); 24211f4c58cSAlexander Belyaev Value lhsIm = arg.lhs.imag(); 24311f4c58cSAlexander Belyaev 24411f4c58cSAlexander Belyaev Value real = rewriter.create<LLVM::FSubOp>( 24511f4c58cSAlexander Belyaev loc, rewriter.create<LLVM::FMulOp>(loc, rhsRe, lhsRe, fmf), 24611f4c58cSAlexander Belyaev rewriter.create<LLVM::FMulOp>(loc, rhsIm, lhsIm, fmf), fmf); 24711f4c58cSAlexander Belyaev 24811f4c58cSAlexander Belyaev Value imag = rewriter.create<LLVM::FAddOp>( 24911f4c58cSAlexander Belyaev loc, rewriter.create<LLVM::FMulOp>(loc, lhsIm, rhsRe, fmf), 25011f4c58cSAlexander Belyaev rewriter.create<LLVM::FMulOp>(loc, lhsRe, rhsIm, fmf), fmf); 25111f4c58cSAlexander Belyaev 25211f4c58cSAlexander Belyaev result.setReal(rewriter, loc, real); 25311f4c58cSAlexander Belyaev result.setImaginary(rewriter, loc, imag); 25411f4c58cSAlexander Belyaev 25511f4c58cSAlexander Belyaev rewriter.replaceOp(op, {result}); 25611f4c58cSAlexander Belyaev return success(); 25711f4c58cSAlexander Belyaev } 25811f4c58cSAlexander Belyaev }; 25911f4c58cSAlexander Belyaev 260d0cb0d30SAlexander Belyaev struct SubOpConversion : public ConvertOpToLLVMPattern<complex::SubOp> { 261d0cb0d30SAlexander Belyaev using ConvertOpToLLVMPattern<complex::SubOp>::ConvertOpToLLVMPattern; 262d0cb0d30SAlexander Belyaev 263d0cb0d30SAlexander Belyaev LogicalResult 264*ef976337SRiver Riddle matchAndRewrite(complex::SubOp op, OpAdaptor adaptor, 265d0cb0d30SAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 266d0cb0d30SAlexander Belyaev auto loc = op.getLoc(); 267d0cb0d30SAlexander Belyaev BinaryComplexOperands arg = 268*ef976337SRiver Riddle unpackBinaryComplexOperands<complex::SubOp>(op, adaptor, rewriter); 269d0cb0d30SAlexander Belyaev 270d0cb0d30SAlexander Belyaev // Initialize complex number struct for result. 271d0cb0d30SAlexander Belyaev auto structType = typeConverter->convertType(op.getType()); 272d0cb0d30SAlexander Belyaev auto result = ComplexStructBuilder::undef(rewriter, loc, structType); 273d0cb0d30SAlexander Belyaev 274d0cb0d30SAlexander Belyaev // Emit IR to substract complex numbers. 275038f2a33SMehdi Amini auto fmf = LLVM::FMFAttr::get(op.getContext(), {}); 276d0cb0d30SAlexander Belyaev Value real = 277d0cb0d30SAlexander Belyaev rewriter.create<LLVM::FSubOp>(loc, arg.lhs.real(), arg.rhs.real(), fmf); 278d0cb0d30SAlexander Belyaev Value imag = 279d0cb0d30SAlexander Belyaev rewriter.create<LLVM::FSubOp>(loc, arg.lhs.imag(), arg.rhs.imag(), fmf); 280d0cb0d30SAlexander Belyaev result.setReal(rewriter, loc, real); 281d0cb0d30SAlexander Belyaev result.setImaginary(rewriter, loc, imag); 282d0cb0d30SAlexander Belyaev 283d0cb0d30SAlexander Belyaev rewriter.replaceOp(op, {result}); 284d0cb0d30SAlexander Belyaev return success(); 285d0cb0d30SAlexander Belyaev } 286d0cb0d30SAlexander Belyaev }; 287d0cb0d30SAlexander Belyaev } // namespace 288d0cb0d30SAlexander Belyaev 289d0cb0d30SAlexander Belyaev void mlir::populateComplexToLLVMConversionPatterns( 290dc4e913bSChris Lattner LLVMTypeConverter &converter, RewritePatternSet &patterns) { 291d0cb0d30SAlexander Belyaev // clang-format off 292dc4e913bSChris Lattner patterns.add< 29311f4c58cSAlexander Belyaev AbsOpConversion, 294d0cb0d30SAlexander Belyaev AddOpConversion, 295d0cb0d30SAlexander Belyaev CreateOpConversion, 29611f4c58cSAlexander Belyaev DivOpConversion, 297d0cb0d30SAlexander Belyaev ImOpConversion, 29811f4c58cSAlexander Belyaev MulOpConversion, 299d0cb0d30SAlexander Belyaev ReOpConversion, 300d0cb0d30SAlexander Belyaev SubOpConversion 301d0cb0d30SAlexander Belyaev >(converter); 302d0cb0d30SAlexander Belyaev // clang-format on 303d0cb0d30SAlexander Belyaev } 304d0cb0d30SAlexander Belyaev 305d0cb0d30SAlexander Belyaev namespace { 306d0cb0d30SAlexander Belyaev struct ConvertComplexToLLVMPass 307d0cb0d30SAlexander Belyaev : public ConvertComplexToLLVMBase<ConvertComplexToLLVMPass> { 308d0cb0d30SAlexander Belyaev void runOnOperation() override; 309d0cb0d30SAlexander Belyaev }; 310d0cb0d30SAlexander Belyaev } // namespace 311d0cb0d30SAlexander Belyaev 312d0cb0d30SAlexander Belyaev void ConvertComplexToLLVMPass::runOnOperation() { 313d0cb0d30SAlexander Belyaev auto module = getOperation(); 314d0cb0d30SAlexander Belyaev 315d0cb0d30SAlexander Belyaev // Convert to the LLVM IR dialect using the converter defined above. 316dc4e913bSChris Lattner RewritePatternSet patterns(&getContext()); 317d0cb0d30SAlexander Belyaev LLVMTypeConverter converter(&getContext()); 318d0cb0d30SAlexander Belyaev populateComplexToLLVMConversionPatterns(converter, patterns); 319d0cb0d30SAlexander Belyaev 320d0cb0d30SAlexander Belyaev LLVMConversionTarget target(getContext()); 321d6be2773SAlex Zinenko target.addLegalOp<ModuleOp, FuncOp>(); 322d6be2773SAlex Zinenko target.addIllegalDialect<complex::ComplexDialect>(); 323d6be2773SAlex Zinenko if (failed(applyPartialConversion(module, target, std::move(patterns)))) 324d0cb0d30SAlexander Belyaev signalPassFailure(); 325d0cb0d30SAlexander Belyaev } 326d0cb0d30SAlexander Belyaev 327d0cb0d30SAlexander Belyaev std::unique_ptr<OperationPass<ModuleOp>> 328d0cb0d30SAlexander Belyaev mlir::createConvertComplexToLLVMPass() { 329d0cb0d30SAlexander Belyaev return std::make_unique<ConvertComplexToLLVMPass>(); 330d0cb0d30SAlexander Belyaev } 331