1 //===-- Lower/ComplexExpr.h -- lowering of complex values -------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef FORTRAN_LOWER_COMPLEXEXPR_H 10 #define FORTRAN_LOWER_COMPLEXEXPR_H 11 12 #include "flang/Lower/FIRBuilder.h" 13 14 namespace Fortran::lower { 15 16 /// Helper to facilitate lowering of COMPLEX manipulations in FIR. 17 class ComplexExprHelper { 18 public: ComplexExprHelper(FirOpBuilder & builder,mlir::Location loc)19 explicit ComplexExprHelper(FirOpBuilder &builder, mlir::Location loc) 20 : builder(builder), loc(loc) {} 21 ComplexExprHelper(const ComplexExprHelper &) = delete; 22 23 // The values of part enum members are meaningful for 24 // InsertValueOp and ExtractValueOp so they are explicit. 25 enum class Part { Real = 0, Imag = 1 }; 26 27 /// Type helper. Determine the type. Do not create MLIR operations. 28 mlir::Type getComplexPartType(mlir::Value cplx); 29 mlir::Type getComplexPartType(mlir::Type complexType); 30 31 /// Complex operation creation helper. They create MLIR operations. 32 mlir::Value createComplex(fir::KindTy kind, mlir::Value real, 33 mlir::Value imag); 34 35 /// Create a complex value. 36 mlir::Value createComplex(mlir::Type complexType, mlir::Value real, 37 mlir::Value imag); 38 extractComplexPart(mlir::Value cplx,bool isImagPart)39 mlir::Value extractComplexPart(mlir::Value cplx, bool isImagPart) { 40 return isImagPart ? extract<Part::Imag>(cplx) : extract<Part::Real>(cplx); 41 } 42 43 /// Returns (Real, Imag) pair of \p cplx extractParts(mlir::Value cplx)44 std::pair<mlir::Value, mlir::Value> extractParts(mlir::Value cplx) { 45 return {extract<Part::Real>(cplx), extract<Part::Imag>(cplx)}; 46 } 47 insertComplexPart(mlir::Value cplx,mlir::Value part,bool isImagPart)48 mlir::Value insertComplexPart(mlir::Value cplx, mlir::Value part, 49 bool isImagPart) { 50 return isImagPart ? insert<Part::Imag>(cplx, part) 51 : insert<Part::Real>(cplx, part); 52 } 53 54 mlir::Value createComplexCompare(mlir::Value cplx1, mlir::Value cplx2, 55 bool eq); 56 57 protected: 58 template <Part partId> extract(mlir::Value cplx)59 mlir::Value extract(mlir::Value cplx) { 60 return builder.create<fir::ExtractValueOp>(loc, getComplexPartType(cplx), 61 cplx, createPartId<partId>()); 62 } 63 64 template <Part partId> insert(mlir::Value cplx,mlir::Value part)65 mlir::Value insert(mlir::Value cplx, mlir::Value part) { 66 return builder.create<fir::InsertValueOp>(loc, cplx.getType(), cplx, part, 67 createPartId<partId>()); 68 } 69 70 template <Part partId> createPartId()71 mlir::Value createPartId() { 72 return builder.createIntegerConstant(loc, builder.getIndexType(), 73 static_cast<int>(partId)); 74 } 75 76 private: 77 FirOpBuilder &builder; 78 mlir::Location loc; 79 }; 80 81 } // namespace Fortran::lower 82 83 #endif // FORTRAN_LOWER_COMPLEXEXPR_H 84