11 #include "../PassDetail.h" 30 Value val = builder.
create<LLVM::UndefOp>(loc, type);
62 matchAndRewrite(complex::AbsOp op, OpAdaptor adaptor,
64 auto loc = op.getLoc();
67 Value real = complexStruct.real(rewriter, op.getLoc());
68 Value imag = complexStruct.imaginary(rewriter, op.getLoc());
70 auto fmf = LLVM::FMFAttr::get(op.getContext(), {});
72 loc, rewriter.
create<LLVM::FMulOp>(loc, real, real, fmf),
73 rewriter.
create<LLVM::FMulOp>(loc, imag, imag, fmf), fmf);
84 matchAndRewrite(complex::ConstantOp op, OpAdaptor adaptor,
87 op, LLVM::ConstantOp::getOperationName(), adaptor.getOperands(),
88 *getTypeConverter(), rewriter);
96 matchAndRewrite(complex::CreateOp complexOp, OpAdaptor adaptor,
99 auto loc = complexOp.getLoc();
100 auto structType = typeConverter->convertType(complexOp.getType());
102 complexStruct.setReal(rewriter, loc, adaptor.getReal());
103 complexStruct.setImaginary(rewriter, loc, adaptor.getImaginary());
105 rewriter.
replaceOp(complexOp, {complexStruct});
114 matchAndRewrite(complex::ReOp op, OpAdaptor adaptor,
118 Value real = complexStruct.real(rewriter, op.getLoc());
129 matchAndRewrite(complex::ImOp op, OpAdaptor adaptor,
133 Value imaginary = complexStruct.imaginary(rewriter, op.getLoc());
140 struct BinaryComplexOperands {
141 std::complex<Value> lhs;
142 std::complex<Value> rhs;
145 template <
typename OpTy>
146 BinaryComplexOperands
147 unpackBinaryComplexOperands(OpTy op,
typename OpTy::Adaptor adaptor,
152 BinaryComplexOperands unpacked;
154 unpacked.lhs.real(lhs.real(rewriter, loc));
155 unpacked.lhs.imag(lhs.imaginary(rewriter, loc));
157 unpacked.rhs.real(rhs.real(rewriter, loc));
158 unpacked.rhs.imag(rhs.imaginary(rewriter, loc));
167 matchAndRewrite(complex::AddOp op, OpAdaptor adaptor,
169 auto loc = op.getLoc();
170 BinaryComplexOperands arg =
171 unpackBinaryComplexOperands<complex::AddOp>(op, adaptor, rewriter);
174 auto structType = typeConverter->convertType(op.getType());
178 auto fmf = LLVM::FMFAttr::get(op.getContext(), {});
180 rewriter.
create<LLVM::FAddOp>(loc, arg.lhs.real(), arg.rhs.real(), fmf);
182 rewriter.
create<LLVM::FAddOp>(loc, arg.lhs.imag(), arg.rhs.imag(), fmf);
183 result.setReal(rewriter, loc, real);
184 result.setImaginary(rewriter, loc, imag);
195 matchAndRewrite(complex::DivOp op, OpAdaptor adaptor,
197 auto loc = op.getLoc();
198 BinaryComplexOperands arg =
199 unpackBinaryComplexOperands<complex::DivOp>(op, adaptor, rewriter);
202 auto structType = typeConverter->convertType(op.getType());
206 auto fmf = LLVM::FMFAttr::get(op.getContext(), {});
207 Value rhsRe = arg.rhs.real();
208 Value rhsIm = arg.rhs.imag();
209 Value lhsRe = arg.lhs.real();
210 Value lhsIm = arg.lhs.imag();
213 loc, rewriter.
create<LLVM::FMulOp>(loc, rhsRe, rhsRe, fmf),
214 rewriter.
create<LLVM::FMulOp>(loc, rhsIm, rhsIm, fmf), fmf);
217 loc, rewriter.
create<LLVM::FMulOp>(loc, lhsRe, rhsRe, fmf),
218 rewriter.
create<LLVM::FMulOp>(loc, lhsIm, rhsIm, fmf), fmf);
221 loc, rewriter.
create<LLVM::FMulOp>(loc, lhsIm, rhsRe, fmf),
222 rewriter.
create<LLVM::FMulOp>(loc, lhsRe, rhsIm, fmf), fmf);
226 rewriter.
create<LLVM::FDivOp>(loc, resultReal, rhsSqNorm, fmf));
229 rewriter.
create<LLVM::FDivOp>(loc, resultImag, rhsSqNorm, fmf));
240 matchAndRewrite(complex::MulOp op, OpAdaptor adaptor,
242 auto loc = op.getLoc();
243 BinaryComplexOperands arg =
244 unpackBinaryComplexOperands<complex::MulOp>(op, adaptor, rewriter);
247 auto structType = typeConverter->convertType(op.getType());
251 auto fmf = LLVM::FMFAttr::get(op.getContext(), {});
252 Value rhsRe = arg.rhs.real();
253 Value rhsIm = arg.rhs.imag();
254 Value lhsRe = arg.lhs.real();
255 Value lhsIm = arg.lhs.imag();
258 loc, rewriter.
create<LLVM::FMulOp>(loc, rhsRe, lhsRe, fmf),
259 rewriter.
create<LLVM::FMulOp>(loc, rhsIm, lhsIm, fmf), fmf);
262 loc, rewriter.
create<LLVM::FMulOp>(loc, lhsIm, rhsRe, fmf),
263 rewriter.
create<LLVM::FMulOp>(loc, lhsRe, rhsIm, fmf), fmf);
265 result.setReal(rewriter, loc, real);
266 result.setImaginary(rewriter, loc, imag);
277 matchAndRewrite(complex::SubOp op, OpAdaptor adaptor,
279 auto loc = op.getLoc();
280 BinaryComplexOperands arg =
281 unpackBinaryComplexOperands<complex::SubOp>(op, adaptor, rewriter);
284 auto structType = typeConverter->convertType(op.getType());
288 auto fmf = LLVM::FMFAttr::get(op.getContext(), {});
290 rewriter.
create<LLVM::FSubOp>(loc, arg.lhs.real(), arg.rhs.real(), fmf);
292 rewriter.
create<LLVM::FSubOp>(loc, arg.lhs.imag(), arg.rhs.imag(), fmf);
293 result.setReal(rewriter, loc, real);
294 result.setImaginary(rewriter, loc, imag);
320 struct ConvertComplexToLLVMPass
321 :
public ConvertComplexToLLVMBase<ConvertComplexToLLVMPass> {
322 void runOnOperation()
override;
326 void ConvertComplexToLLVMPass::runOnOperation() {
340 return std::make_unique<ConvertComplexToLLVMPass>();
Include the generated interface declarations.
void populateComplexToLLVMConversionPatterns(LLVMTypeConverter &converter, RewritePatternSet &patterns)
Populate the given list with patterns that convert from Complex to LLVM.
Utility class for operation conversions targeting the LLVM dialect that match exactly one source oper...
RewritePatternSet & add(ConstructorArg &&arg, ConstructorArgs &&...args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments...
void setReal(OpBuilder &builder, Location loc, Value real)
LogicalResult applyPartialConversion(ArrayRef< Operation *> ops, ConversionTarget &target, const FrozenRewritePatternSet &patterns, DenseSet< Operation *> *unconvertedOps=nullptr)
Below we define several entry points for operation conversion.
ConvertOpToLLVMPattern(LLVMTypeConverter &typeConverter, PatternBenefit benefit=1)
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value...
static constexpr unsigned kImaginaryPosInComplexNumberStruct
static ComplexStructBuilder undef(OpBuilder &builder, Location loc, Type type)
Build IR creating an undef value of the complex number type.
Derived class that automatically populates legalization information for different LLVM ops...
void replaceOp(Operation *op, ValueRange newValues) override
PatternRewriter hook for replacing the results of an operation.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Value imaginary(OpBuilder &builder, Location loc)
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
This class represents an efficient way to signal success or failure.
Value real(OpBuilder &builder, Location loc)
Location getLoc() const
Return the location of this value.
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...
std::unique_ptr< Pass > createConvertComplexToLLVMPass()
Create a pass to convert Complex operations to the LLVMIR dialect.
void addIllegalDialect(StringRef name, Names... names)
Register the operations of the given dialects as illegal, i.e.
OpTy replaceOpWithNewOp(Operation *op, Args &&...args)
Replaces the result op with a new op that is created without verification.
Conversion from types to the LLVM IR dialect.
static constexpr unsigned kRealPosInComplexNumberStruct
This class implements a pattern rewriter for use with ConversionPatterns.
LogicalResult oneToOneRewrite(Operation *op, StringRef targetOp, ValueRange operands, LLVMTypeConverter &typeConverter, ConversionPatternRewriter &rewriter)
Replaces the given operation "op" with a new operation of type "targetOp" and given operands...
This class helps build Operations.
void setImaginary(OpBuilder &builder, Location loc, Value imaginary)