19 #define GEN_PASS_DEF_CONVERTCOMPLEXTOLLVM
20 #include "mlir/Conversion/Passes.h.inc"
35 Value val = builder.
create<LLVM::UndefOp>(loc, type);
67 matchAndRewrite(complex::AbsOp op, OpAdaptor adaptor,
69 auto loc = op.getLoc();
72 Value real = complexStruct.real(rewriter, op.getLoc());
73 Value imag = complexStruct.imaginary(rewriter, op.getLoc());
75 auto fmf = LLVM::FastmathFlagsAttr::get(op.getContext(), {});
77 loc, rewriter.
create<LLVM::FMulOp>(loc, real, real, fmf),
78 rewriter.
create<LLVM::FMulOp>(loc, imag, imag, fmf), fmf);
89 matchAndRewrite(complex::ConstantOp op, OpAdaptor adaptor,
92 op, LLVM::ConstantOp::getOperationName(), adaptor.getOperands(),
93 op->getAttrs(), *getTypeConverter(), rewriter);
101 matchAndRewrite(complex::CreateOp complexOp, OpAdaptor adaptor,
104 auto loc = complexOp.getLoc();
105 auto structType = typeConverter->convertType(complexOp.getType());
107 complexStruct.setReal(rewriter, loc, adaptor.getReal());
108 complexStruct.setImaginary(rewriter, loc, adaptor.getImaginary());
110 rewriter.
replaceOp(complexOp, {complexStruct});
119 matchAndRewrite(complex::ReOp op, OpAdaptor adaptor,
123 Value real = complexStruct.real(rewriter, op.getLoc());
134 matchAndRewrite(complex::ImOp op, OpAdaptor adaptor,
138 Value imaginary = complexStruct.imaginary(rewriter, op.getLoc());
145 struct BinaryComplexOperands {
146 std::complex<Value> lhs;
147 std::complex<Value> rhs;
150 template <
typename OpTy>
151 BinaryComplexOperands
152 unpackBinaryComplexOperands(OpTy op,
typename OpTy::Adaptor adaptor,
154 auto loc = op.getLoc();
157 BinaryComplexOperands unpacked;
159 unpacked.lhs.real(lhs.real(rewriter, loc));
160 unpacked.lhs.imag(lhs.imaginary(rewriter, loc));
162 unpacked.rhs.real(rhs.real(rewriter, loc));
163 unpacked.rhs.imag(rhs.imaginary(rewriter, loc));
172 matchAndRewrite(complex::AddOp op, OpAdaptor adaptor,
174 auto loc = op.getLoc();
175 BinaryComplexOperands arg =
176 unpackBinaryComplexOperands<complex::AddOp>(op, adaptor, rewriter);
179 auto structType = typeConverter->convertType(op.getType());
183 auto fmf = LLVM::FastmathFlagsAttr::get(op.getContext(), {});
185 rewriter.
create<LLVM::FAddOp>(loc, arg.lhs.real(), arg.rhs.real(), fmf);
187 rewriter.
create<LLVM::FAddOp>(loc, arg.lhs.imag(), arg.rhs.imag(), fmf);
188 result.setReal(rewriter, loc, real);
189 result.setImaginary(rewriter, loc, imag);
200 matchAndRewrite(complex::DivOp op, OpAdaptor adaptor,
202 auto loc = op.getLoc();
203 BinaryComplexOperands arg =
204 unpackBinaryComplexOperands<complex::DivOp>(op, adaptor, rewriter);
207 auto structType = typeConverter->convertType(op.getType());
211 auto fmf = LLVM::FastmathFlagsAttr::get(op.getContext(), {});
212 Value rhsRe = arg.rhs.real();
213 Value rhsIm = arg.rhs.imag();
214 Value lhsRe = arg.lhs.real();
215 Value lhsIm = arg.lhs.imag();
218 loc, rewriter.
create<LLVM::FMulOp>(loc, rhsRe, rhsRe, fmf),
219 rewriter.
create<LLVM::FMulOp>(loc, rhsIm, rhsIm, fmf), fmf);
222 loc, rewriter.
create<LLVM::FMulOp>(loc, lhsRe, rhsRe, fmf),
223 rewriter.
create<LLVM::FMulOp>(loc, lhsIm, rhsIm, fmf), fmf);
226 loc, rewriter.
create<LLVM::FMulOp>(loc, lhsIm, rhsRe, fmf),
227 rewriter.
create<LLVM::FMulOp>(loc, lhsRe, rhsIm, fmf), fmf);
231 rewriter.
create<LLVM::FDivOp>(loc, resultReal, rhsSqNorm, fmf));
234 rewriter.
create<LLVM::FDivOp>(loc, resultImag, rhsSqNorm, fmf));
245 matchAndRewrite(complex::MulOp op, OpAdaptor adaptor,
247 auto loc = op.getLoc();
248 BinaryComplexOperands arg =
249 unpackBinaryComplexOperands<complex::MulOp>(op, adaptor, rewriter);
252 auto structType = typeConverter->convertType(op.getType());
256 auto fmf = LLVM::FastmathFlagsAttr::get(op.getContext(), {});
257 Value rhsRe = arg.rhs.real();
258 Value rhsIm = arg.rhs.imag();
259 Value lhsRe = arg.lhs.real();
260 Value lhsIm = arg.lhs.imag();
263 loc, rewriter.
create<LLVM::FMulOp>(loc, rhsRe, lhsRe, fmf),
264 rewriter.
create<LLVM::FMulOp>(loc, rhsIm, lhsIm, fmf), fmf);
267 loc, rewriter.
create<LLVM::FMulOp>(loc, lhsIm, rhsRe, fmf),
268 rewriter.
create<LLVM::FMulOp>(loc, lhsRe, rhsIm, fmf), fmf);
270 result.setReal(rewriter, loc, real);
271 result.setImaginary(rewriter, loc, imag);
282 matchAndRewrite(complex::SubOp op, OpAdaptor adaptor,
284 auto loc = op.getLoc();
285 BinaryComplexOperands arg =
286 unpackBinaryComplexOperands<complex::SubOp>(op, adaptor, rewriter);
289 auto structType = typeConverter->convertType(op.getType());
293 auto fmf = LLVM::FastmathFlagsAttr::get(op.getContext(), {});
295 rewriter.
create<LLVM::FSubOp>(loc, arg.lhs.real(), arg.rhs.real(), fmf);
297 rewriter.
create<LLVM::FSubOp>(loc, arg.lhs.imag(), arg.rhs.imag(), fmf);
298 result.setReal(rewriter, loc, real);
299 result.setImaginary(rewriter, loc, imag);
325 struct ConvertComplexToLLVMPass
326 :
public impl::ConvertComplexToLLVMBase<ConvertComplexToLLVMPass> {
327 void runOnOperation()
override;
331 void ConvertComplexToLLVMPass::runOnOperation() {
338 target.addIllegalDialect<complex::ComplexDialect>();
345 return std::make_unique<ConvertComplexToLLVMPass>();
static constexpr unsigned kRealPosInComplexNumberStruct
static constexpr unsigned kImaginaryPosInComplexNumberStruct
static ComplexStructBuilder undef(OpBuilder &builder, Location loc, Type type)
Build IR creating an undef value of the complex number type.
Value imaginary(OpBuilder &builder, Location loc)
void setImaginary(OpBuilder &builder, Location loc, Value imaginary)
void setReal(OpBuilder &builder, Location loc, Value real)
Value real(OpBuilder &builder, Location loc)
This class implements a pattern rewriter for use with ConversionPatterns.
void replaceOp(Operation *op, ValueRange newValues) override
PatternRewriter hook for replacing the results of an operation.
Utility class for operation conversions targeting the LLVM dialect that match exactly one source oper...
ConvertOpToLLVMPattern(LLVMTypeConverter &typeConverter, PatternBenefit benefit=1)
Derived class that automatically populates legalization information for different LLVM ops.
Conversion from types to the LLVM IR dialect.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
This class helps build Operations.
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
RewritePatternSet & add(ConstructorArg &&arg, ConstructorArgs &&...args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments.
OpTy replaceOpWithNewOp(Operation *op, Args &&...args)
Replaces the result op with a new op that is created without verification.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
LogicalResult oneToOneRewrite(Operation *op, StringRef targetOp, ValueRange operands, ArrayRef< NamedAttribute > targetAttrs, LLVMTypeConverter &typeConverter, ConversionPatternRewriter &rewriter)
Replaces the given operation "op" with a new operation of type "targetOp" and given operands.
Include the generated interface declarations.
LogicalResult applyPartialConversion(ArrayRef< Operation * > ops, ConversionTarget &target, const FrozenRewritePatternSet &patterns, DenseSet< Operation * > *unconvertedOps=nullptr)
Below we define several entry points for operation conversion.
std::unique_ptr< Pass > createConvertComplexToLLVMPass()
Create a pass to convert Complex operations to the LLVMIR dialect.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
void populateComplexToLLVMConversionPatterns(LLVMTypeConverter &converter, RewritePatternSet &patterns)
Populate the given list with patterns that convert from Complex to LLVM.
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
This class represents an efficient way to signal success or failure.