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" 12d0cb0d30SAlexander Belyaev #include "mlir/Dialect/Complex/IR/Complex.h" 13d0cb0d30SAlexander Belyaev #include "mlir/Dialect/LLVMIR/LLVMDialect.h" 14d0cb0d30SAlexander Belyaev 15d0cb0d30SAlexander Belyaev using namespace mlir; 16d0cb0d30SAlexander Belyaev using namespace mlir::LLVM; 17d0cb0d30SAlexander Belyaev 18d0cb0d30SAlexander Belyaev namespace { 19d0cb0d30SAlexander Belyaev 2011f4c58cSAlexander Belyaev struct AbsOpConversion : public ConvertOpToLLVMPattern<complex::AbsOp> { 2111f4c58cSAlexander Belyaev using ConvertOpToLLVMPattern<complex::AbsOp>::ConvertOpToLLVMPattern; 2211f4c58cSAlexander Belyaev 2311f4c58cSAlexander Belyaev LogicalResult 2411f4c58cSAlexander Belyaev matchAndRewrite(complex::AbsOp op, ArrayRef<Value> operands, 2511f4c58cSAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 2611f4c58cSAlexander Belyaev complex::AbsOp::Adaptor transformed(operands); 2711f4c58cSAlexander Belyaev auto loc = op.getLoc(); 2811f4c58cSAlexander Belyaev 2911f4c58cSAlexander Belyaev ComplexStructBuilder complexStruct(transformed.complex()); 3011f4c58cSAlexander Belyaev Value real = complexStruct.real(rewriter, op.getLoc()); 3111f4c58cSAlexander Belyaev Value imag = complexStruct.imaginary(rewriter, op.getLoc()); 3211f4c58cSAlexander Belyaev 33038f2a33SMehdi Amini auto fmf = LLVM::FMFAttr::get(op.getContext(), {}); 3411f4c58cSAlexander Belyaev Value sqNorm = rewriter.create<LLVM::FAddOp>( 3511f4c58cSAlexander Belyaev loc, rewriter.create<LLVM::FMulOp>(loc, real, real, fmf), 3611f4c58cSAlexander Belyaev rewriter.create<LLVM::FMulOp>(loc, imag, imag, fmf), fmf); 3711f4c58cSAlexander Belyaev 3811f4c58cSAlexander Belyaev rewriter.replaceOpWithNewOp<LLVM::SqrtOp>(op, sqNorm); 3911f4c58cSAlexander Belyaev return success(); 4011f4c58cSAlexander Belyaev } 4111f4c58cSAlexander Belyaev }; 4211f4c58cSAlexander Belyaev 43d0cb0d30SAlexander Belyaev struct CreateOpConversion : public ConvertOpToLLVMPattern<complex::CreateOp> { 44d0cb0d30SAlexander Belyaev using ConvertOpToLLVMPattern<complex::CreateOp>::ConvertOpToLLVMPattern; 45d0cb0d30SAlexander Belyaev 46d0cb0d30SAlexander Belyaev LogicalResult 47d0cb0d30SAlexander Belyaev matchAndRewrite(complex::CreateOp complexOp, ArrayRef<Value> operands, 48d0cb0d30SAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 49d0cb0d30SAlexander Belyaev complex::CreateOp::Adaptor transformed(operands); 50d0cb0d30SAlexander Belyaev 51d0cb0d30SAlexander Belyaev // Pack real and imaginary part in a complex number struct. 52d0cb0d30SAlexander Belyaev auto loc = complexOp.getLoc(); 53d0cb0d30SAlexander Belyaev auto structType = typeConverter->convertType(complexOp.getType()); 54d0cb0d30SAlexander Belyaev auto complexStruct = ComplexStructBuilder::undef(rewriter, loc, structType); 55d0cb0d30SAlexander Belyaev complexStruct.setReal(rewriter, loc, transformed.real()); 56d0cb0d30SAlexander Belyaev complexStruct.setImaginary(rewriter, loc, transformed.imaginary()); 57d0cb0d30SAlexander Belyaev 58d0cb0d30SAlexander Belyaev rewriter.replaceOp(complexOp, {complexStruct}); 59d0cb0d30SAlexander Belyaev return success(); 60d0cb0d30SAlexander Belyaev } 61d0cb0d30SAlexander Belyaev }; 62d0cb0d30SAlexander Belyaev 63d0cb0d30SAlexander Belyaev struct ReOpConversion : public ConvertOpToLLVMPattern<complex::ReOp> { 64d0cb0d30SAlexander Belyaev using ConvertOpToLLVMPattern<complex::ReOp>::ConvertOpToLLVMPattern; 65d0cb0d30SAlexander Belyaev 66d0cb0d30SAlexander Belyaev LogicalResult 67d0cb0d30SAlexander Belyaev matchAndRewrite(complex::ReOp op, ArrayRef<Value> operands, 68d0cb0d30SAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 69d0cb0d30SAlexander Belyaev complex::ReOp::Adaptor transformed(operands); 70d0cb0d30SAlexander Belyaev 71d0cb0d30SAlexander Belyaev // Extract real part from the complex number struct. 72d0cb0d30SAlexander Belyaev ComplexStructBuilder complexStruct(transformed.complex()); 73d0cb0d30SAlexander Belyaev Value real = complexStruct.real(rewriter, op.getLoc()); 74d0cb0d30SAlexander Belyaev rewriter.replaceOp(op, real); 75d0cb0d30SAlexander Belyaev 76d0cb0d30SAlexander Belyaev return success(); 77d0cb0d30SAlexander Belyaev } 78d0cb0d30SAlexander Belyaev }; 79d0cb0d30SAlexander Belyaev 80d0cb0d30SAlexander Belyaev struct ImOpConversion : public ConvertOpToLLVMPattern<complex::ImOp> { 81d0cb0d30SAlexander Belyaev using ConvertOpToLLVMPattern<complex::ImOp>::ConvertOpToLLVMPattern; 82d0cb0d30SAlexander Belyaev 83d0cb0d30SAlexander Belyaev LogicalResult 84d0cb0d30SAlexander Belyaev matchAndRewrite(complex::ImOp op, ArrayRef<Value> operands, 85d0cb0d30SAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 86d0cb0d30SAlexander Belyaev complex::ImOp::Adaptor transformed(operands); 87d0cb0d30SAlexander Belyaev 88d0cb0d30SAlexander Belyaev // Extract imaginary part from the complex number struct. 89d0cb0d30SAlexander Belyaev ComplexStructBuilder complexStruct(transformed.complex()); 90d0cb0d30SAlexander Belyaev Value imaginary = complexStruct.imaginary(rewriter, op.getLoc()); 91d0cb0d30SAlexander Belyaev rewriter.replaceOp(op, imaginary); 92d0cb0d30SAlexander Belyaev 93d0cb0d30SAlexander Belyaev return success(); 94d0cb0d30SAlexander Belyaev } 95d0cb0d30SAlexander Belyaev }; 96d0cb0d30SAlexander Belyaev 97d0cb0d30SAlexander Belyaev struct BinaryComplexOperands { 98d0cb0d30SAlexander Belyaev std::complex<Value> lhs; 99d0cb0d30SAlexander Belyaev std::complex<Value> rhs; 100d0cb0d30SAlexander Belyaev }; 101d0cb0d30SAlexander Belyaev 102d0cb0d30SAlexander Belyaev template <typename OpTy> 103d0cb0d30SAlexander Belyaev BinaryComplexOperands 104d0cb0d30SAlexander Belyaev unpackBinaryComplexOperands(OpTy op, ArrayRef<Value> operands, 105d0cb0d30SAlexander Belyaev ConversionPatternRewriter &rewriter) { 106d0cb0d30SAlexander Belyaev auto loc = op.getLoc(); 107d0cb0d30SAlexander Belyaev typename OpTy::Adaptor transformed(operands); 108d0cb0d30SAlexander Belyaev 109d0cb0d30SAlexander Belyaev // Extract real and imaginary values from operands. 110d0cb0d30SAlexander Belyaev BinaryComplexOperands unpacked; 111d0cb0d30SAlexander Belyaev ComplexStructBuilder lhs(transformed.lhs()); 112d0cb0d30SAlexander Belyaev unpacked.lhs.real(lhs.real(rewriter, loc)); 113d0cb0d30SAlexander Belyaev unpacked.lhs.imag(lhs.imaginary(rewriter, loc)); 114d0cb0d30SAlexander Belyaev ComplexStructBuilder rhs(transformed.rhs()); 115d0cb0d30SAlexander Belyaev unpacked.rhs.real(rhs.real(rewriter, loc)); 116d0cb0d30SAlexander Belyaev unpacked.rhs.imag(rhs.imaginary(rewriter, loc)); 117d0cb0d30SAlexander Belyaev 118d0cb0d30SAlexander Belyaev return unpacked; 119d0cb0d30SAlexander Belyaev } 120d0cb0d30SAlexander Belyaev 121d0cb0d30SAlexander Belyaev struct AddOpConversion : public ConvertOpToLLVMPattern<complex::AddOp> { 122d0cb0d30SAlexander Belyaev using ConvertOpToLLVMPattern<complex::AddOp>::ConvertOpToLLVMPattern; 123d0cb0d30SAlexander Belyaev 124d0cb0d30SAlexander Belyaev LogicalResult 125d0cb0d30SAlexander Belyaev matchAndRewrite(complex::AddOp op, ArrayRef<Value> operands, 126d0cb0d30SAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 127d0cb0d30SAlexander Belyaev auto loc = op.getLoc(); 128d0cb0d30SAlexander Belyaev BinaryComplexOperands arg = 129d0cb0d30SAlexander Belyaev unpackBinaryComplexOperands<complex::AddOp>(op, operands, rewriter); 130d0cb0d30SAlexander Belyaev 131d0cb0d30SAlexander Belyaev // Initialize complex number struct for result. 132d0cb0d30SAlexander Belyaev auto structType = typeConverter->convertType(op.getType()); 133d0cb0d30SAlexander Belyaev auto result = ComplexStructBuilder::undef(rewriter, loc, structType); 134d0cb0d30SAlexander Belyaev 135d0cb0d30SAlexander Belyaev // Emit IR to add complex numbers. 136038f2a33SMehdi Amini auto fmf = LLVM::FMFAttr::get(op.getContext(), {}); 137d0cb0d30SAlexander Belyaev Value real = 138d0cb0d30SAlexander Belyaev rewriter.create<LLVM::FAddOp>(loc, arg.lhs.real(), arg.rhs.real(), fmf); 139d0cb0d30SAlexander Belyaev Value imag = 140d0cb0d30SAlexander Belyaev rewriter.create<LLVM::FAddOp>(loc, arg.lhs.imag(), arg.rhs.imag(), fmf); 141d0cb0d30SAlexander Belyaev result.setReal(rewriter, loc, real); 142d0cb0d30SAlexander Belyaev result.setImaginary(rewriter, loc, imag); 143d0cb0d30SAlexander Belyaev 144d0cb0d30SAlexander Belyaev rewriter.replaceOp(op, {result}); 145d0cb0d30SAlexander Belyaev return success(); 146d0cb0d30SAlexander Belyaev } 147d0cb0d30SAlexander Belyaev }; 148d0cb0d30SAlexander Belyaev 14911f4c58cSAlexander Belyaev struct DivOpConversion : public ConvertOpToLLVMPattern<complex::DivOp> { 15011f4c58cSAlexander Belyaev using ConvertOpToLLVMPattern<complex::DivOp>::ConvertOpToLLVMPattern; 15111f4c58cSAlexander Belyaev 15211f4c58cSAlexander Belyaev LogicalResult 15311f4c58cSAlexander Belyaev matchAndRewrite(complex::DivOp op, ArrayRef<Value> operands, 15411f4c58cSAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 15511f4c58cSAlexander Belyaev auto loc = op.getLoc(); 15611f4c58cSAlexander Belyaev BinaryComplexOperands arg = 15711f4c58cSAlexander Belyaev unpackBinaryComplexOperands<complex::DivOp>(op, operands, rewriter); 15811f4c58cSAlexander Belyaev 15911f4c58cSAlexander Belyaev // Initialize complex number struct for result. 16011f4c58cSAlexander Belyaev auto structType = typeConverter->convertType(op.getType()); 16111f4c58cSAlexander Belyaev auto result = ComplexStructBuilder::undef(rewriter, loc, structType); 16211f4c58cSAlexander Belyaev 16311f4c58cSAlexander Belyaev // Emit IR to add complex numbers. 164038f2a33SMehdi Amini auto fmf = LLVM::FMFAttr::get(op.getContext(), {}); 16511f4c58cSAlexander Belyaev Value rhsRe = arg.rhs.real(); 16611f4c58cSAlexander Belyaev Value rhsIm = arg.rhs.imag(); 16711f4c58cSAlexander Belyaev Value lhsRe = arg.lhs.real(); 16811f4c58cSAlexander Belyaev Value lhsIm = arg.lhs.imag(); 16911f4c58cSAlexander Belyaev 17011f4c58cSAlexander Belyaev Value rhsSqNorm = rewriter.create<LLVM::FAddOp>( 17111f4c58cSAlexander Belyaev loc, rewriter.create<LLVM::FMulOp>(loc, rhsRe, rhsRe, fmf), 17211f4c58cSAlexander Belyaev rewriter.create<LLVM::FMulOp>(loc, rhsIm, rhsIm, fmf), fmf); 17311f4c58cSAlexander Belyaev 17411f4c58cSAlexander Belyaev Value resultReal = rewriter.create<LLVM::FAddOp>( 17511f4c58cSAlexander Belyaev loc, rewriter.create<LLVM::FMulOp>(loc, lhsRe, rhsRe, fmf), 17611f4c58cSAlexander Belyaev rewriter.create<LLVM::FMulOp>(loc, lhsIm, rhsIm, fmf), fmf); 17711f4c58cSAlexander Belyaev 17811f4c58cSAlexander Belyaev Value resultImag = rewriter.create<LLVM::FSubOp>( 17911f4c58cSAlexander Belyaev loc, rewriter.create<LLVM::FMulOp>(loc, lhsIm, rhsRe, fmf), 18011f4c58cSAlexander Belyaev rewriter.create<LLVM::FMulOp>(loc, lhsRe, rhsIm, fmf), fmf); 18111f4c58cSAlexander Belyaev 18211f4c58cSAlexander Belyaev result.setReal( 18311f4c58cSAlexander Belyaev rewriter, loc, 18411f4c58cSAlexander Belyaev rewriter.create<LLVM::FDivOp>(loc, resultReal, rhsSqNorm, fmf)); 18511f4c58cSAlexander Belyaev result.setImaginary( 18611f4c58cSAlexander Belyaev rewriter, loc, 18711f4c58cSAlexander Belyaev rewriter.create<LLVM::FDivOp>(loc, resultImag, rhsSqNorm, fmf)); 18811f4c58cSAlexander Belyaev 18911f4c58cSAlexander Belyaev rewriter.replaceOp(op, {result}); 19011f4c58cSAlexander Belyaev return success(); 19111f4c58cSAlexander Belyaev } 19211f4c58cSAlexander Belyaev }; 19311f4c58cSAlexander Belyaev 19411f4c58cSAlexander Belyaev struct MulOpConversion : public ConvertOpToLLVMPattern<complex::MulOp> { 19511f4c58cSAlexander Belyaev using ConvertOpToLLVMPattern<complex::MulOp>::ConvertOpToLLVMPattern; 19611f4c58cSAlexander Belyaev 19711f4c58cSAlexander Belyaev LogicalResult 19811f4c58cSAlexander Belyaev matchAndRewrite(complex::MulOp op, ArrayRef<Value> operands, 19911f4c58cSAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 20011f4c58cSAlexander Belyaev auto loc = op.getLoc(); 20111f4c58cSAlexander Belyaev BinaryComplexOperands arg = 20211f4c58cSAlexander Belyaev unpackBinaryComplexOperands<complex::MulOp>(op, operands, rewriter); 20311f4c58cSAlexander Belyaev 20411f4c58cSAlexander Belyaev // Initialize complex number struct for result. 20511f4c58cSAlexander Belyaev auto structType = typeConverter->convertType(op.getType()); 20611f4c58cSAlexander Belyaev auto result = ComplexStructBuilder::undef(rewriter, loc, structType); 20711f4c58cSAlexander Belyaev 20811f4c58cSAlexander Belyaev // Emit IR to add complex numbers. 209038f2a33SMehdi Amini auto fmf = LLVM::FMFAttr::get(op.getContext(), {}); 21011f4c58cSAlexander Belyaev Value rhsRe = arg.rhs.real(); 21111f4c58cSAlexander Belyaev Value rhsIm = arg.rhs.imag(); 21211f4c58cSAlexander Belyaev Value lhsRe = arg.lhs.real(); 21311f4c58cSAlexander Belyaev Value lhsIm = arg.lhs.imag(); 21411f4c58cSAlexander Belyaev 21511f4c58cSAlexander Belyaev Value real = rewriter.create<LLVM::FSubOp>( 21611f4c58cSAlexander Belyaev loc, rewriter.create<LLVM::FMulOp>(loc, rhsRe, lhsRe, fmf), 21711f4c58cSAlexander Belyaev rewriter.create<LLVM::FMulOp>(loc, rhsIm, lhsIm, fmf), fmf); 21811f4c58cSAlexander Belyaev 21911f4c58cSAlexander Belyaev Value imag = rewriter.create<LLVM::FAddOp>( 22011f4c58cSAlexander Belyaev loc, rewriter.create<LLVM::FMulOp>(loc, lhsIm, rhsRe, fmf), 22111f4c58cSAlexander Belyaev rewriter.create<LLVM::FMulOp>(loc, lhsRe, rhsIm, fmf), fmf); 22211f4c58cSAlexander Belyaev 22311f4c58cSAlexander Belyaev result.setReal(rewriter, loc, real); 22411f4c58cSAlexander Belyaev result.setImaginary(rewriter, loc, imag); 22511f4c58cSAlexander Belyaev 22611f4c58cSAlexander Belyaev rewriter.replaceOp(op, {result}); 22711f4c58cSAlexander Belyaev return success(); 22811f4c58cSAlexander Belyaev } 22911f4c58cSAlexander Belyaev }; 23011f4c58cSAlexander Belyaev 231d0cb0d30SAlexander Belyaev struct SubOpConversion : public ConvertOpToLLVMPattern<complex::SubOp> { 232d0cb0d30SAlexander Belyaev using ConvertOpToLLVMPattern<complex::SubOp>::ConvertOpToLLVMPattern; 233d0cb0d30SAlexander Belyaev 234d0cb0d30SAlexander Belyaev LogicalResult 235d0cb0d30SAlexander Belyaev matchAndRewrite(complex::SubOp op, ArrayRef<Value> operands, 236d0cb0d30SAlexander Belyaev ConversionPatternRewriter &rewriter) const override { 237d0cb0d30SAlexander Belyaev auto loc = op.getLoc(); 238d0cb0d30SAlexander Belyaev BinaryComplexOperands arg = 239d0cb0d30SAlexander Belyaev unpackBinaryComplexOperands<complex::SubOp>(op, operands, rewriter); 240d0cb0d30SAlexander Belyaev 241d0cb0d30SAlexander Belyaev // Initialize complex number struct for result. 242d0cb0d30SAlexander Belyaev auto structType = typeConverter->convertType(op.getType()); 243d0cb0d30SAlexander Belyaev auto result = ComplexStructBuilder::undef(rewriter, loc, structType); 244d0cb0d30SAlexander Belyaev 245d0cb0d30SAlexander Belyaev // Emit IR to substract complex numbers. 246038f2a33SMehdi Amini auto fmf = LLVM::FMFAttr::get(op.getContext(), {}); 247d0cb0d30SAlexander Belyaev Value real = 248d0cb0d30SAlexander Belyaev rewriter.create<LLVM::FSubOp>(loc, arg.lhs.real(), arg.rhs.real(), fmf); 249d0cb0d30SAlexander Belyaev Value imag = 250d0cb0d30SAlexander Belyaev rewriter.create<LLVM::FSubOp>(loc, arg.lhs.imag(), arg.rhs.imag(), fmf); 251d0cb0d30SAlexander Belyaev result.setReal(rewriter, loc, real); 252d0cb0d30SAlexander Belyaev result.setImaginary(rewriter, loc, imag); 253d0cb0d30SAlexander Belyaev 254d0cb0d30SAlexander Belyaev rewriter.replaceOp(op, {result}); 255d0cb0d30SAlexander Belyaev return success(); 256d0cb0d30SAlexander Belyaev } 257d0cb0d30SAlexander Belyaev }; 258d0cb0d30SAlexander Belyaev } // namespace 259d0cb0d30SAlexander Belyaev 260d0cb0d30SAlexander Belyaev void mlir::populateComplexToLLVMConversionPatterns( 261*dc4e913bSChris Lattner LLVMTypeConverter &converter, RewritePatternSet &patterns) { 262d0cb0d30SAlexander Belyaev // clang-format off 263*dc4e913bSChris Lattner patterns.add< 26411f4c58cSAlexander Belyaev AbsOpConversion, 265d0cb0d30SAlexander Belyaev AddOpConversion, 266d0cb0d30SAlexander Belyaev CreateOpConversion, 26711f4c58cSAlexander Belyaev DivOpConversion, 268d0cb0d30SAlexander Belyaev ImOpConversion, 26911f4c58cSAlexander Belyaev MulOpConversion, 270d0cb0d30SAlexander Belyaev ReOpConversion, 271d0cb0d30SAlexander Belyaev SubOpConversion 272d0cb0d30SAlexander Belyaev >(converter); 273d0cb0d30SAlexander Belyaev // clang-format on 274d0cb0d30SAlexander Belyaev } 275d0cb0d30SAlexander Belyaev 276d0cb0d30SAlexander Belyaev namespace { 277d0cb0d30SAlexander Belyaev struct ConvertComplexToLLVMPass 278d0cb0d30SAlexander Belyaev : public ConvertComplexToLLVMBase<ConvertComplexToLLVMPass> { 279d0cb0d30SAlexander Belyaev void runOnOperation() override; 280d0cb0d30SAlexander Belyaev }; 281d0cb0d30SAlexander Belyaev } // namespace 282d0cb0d30SAlexander Belyaev 283d0cb0d30SAlexander Belyaev void ConvertComplexToLLVMPass::runOnOperation() { 284d0cb0d30SAlexander Belyaev auto module = getOperation(); 285d0cb0d30SAlexander Belyaev 286d0cb0d30SAlexander Belyaev // Convert to the LLVM IR dialect using the converter defined above. 287*dc4e913bSChris Lattner RewritePatternSet patterns(&getContext()); 288d0cb0d30SAlexander Belyaev LLVMTypeConverter converter(&getContext()); 289d0cb0d30SAlexander Belyaev populateComplexToLLVMConversionPatterns(converter, patterns); 290d0cb0d30SAlexander Belyaev 291d0cb0d30SAlexander Belyaev LLVMConversionTarget target(getContext()); 292d6be2773SAlex Zinenko target.addLegalOp<ModuleOp, FuncOp>(); 293d6be2773SAlex Zinenko target.addLegalOp<LLVM::DialectCastOp>(); 294d6be2773SAlex Zinenko target.addIllegalDialect<complex::ComplexDialect>(); 295d6be2773SAlex Zinenko if (failed(applyPartialConversion(module, target, std::move(patterns)))) 296d0cb0d30SAlexander Belyaev signalPassFailure(); 297d0cb0d30SAlexander Belyaev } 298d0cb0d30SAlexander Belyaev 299d0cb0d30SAlexander Belyaev std::unique_ptr<OperationPass<ModuleOp>> 300d0cb0d30SAlexander Belyaev mlir::createConvertComplexToLLVMPass() { 301d0cb0d30SAlexander Belyaev return std::make_unique<ConvertComplexToLLVMPass>(); 302d0cb0d30SAlexander Belyaev } 303