| //===-- Lower/ComplexExpr.h -- lowering of complex values -------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef FORTRAN_LOWER_COMPLEXEXPR_H |
| #define FORTRAN_LOWER_COMPLEXEXPR_H |
| |
| #include "flang/Lower/FIRBuilder.h" |
| |
| namespace Fortran::lower { |
| |
| /// Helper to facilitate lowering of COMPLEX manipulations in FIR. |
| class ComplexExprHelper { |
| public: |
| explicit ComplexExprHelper(FirOpBuilder &builder, mlir::Location loc) |
| : builder(builder), loc(loc) {} |
| ComplexExprHelper(const ComplexExprHelper &) = delete; |
| |
| // The values of part enum members are meaningful for |
| // InsertValueOp and ExtractValueOp so they are explicit. |
| enum class Part { Real = 0, Imag = 1 }; |
| |
| /// Type helper. Determine the type. Do not create MLIR operations. |
| mlir::Type getComplexPartType(mlir::Value cplx); |
| mlir::Type getComplexPartType(mlir::Type complexType); |
| |
| /// Complex operation creation helper. They create MLIR operations. |
| mlir::Value createComplex(fir::KindTy kind, mlir::Value real, |
| mlir::Value imag); |
| |
| /// Create a complex value. |
| mlir::Value createComplex(mlir::Type complexType, mlir::Value real, |
| mlir::Value imag); |
| |
| mlir::Value extractComplexPart(mlir::Value cplx, bool isImagPart) { |
| return isImagPart ? extract<Part::Imag>(cplx) : extract<Part::Real>(cplx); |
| } |
| |
| /// Returns (Real, Imag) pair of \p cplx |
| std::pair<mlir::Value, mlir::Value> extractParts(mlir::Value cplx) { |
| return {extract<Part::Real>(cplx), extract<Part::Imag>(cplx)}; |
| } |
| |
| mlir::Value insertComplexPart(mlir::Value cplx, mlir::Value part, |
| bool isImagPart) { |
| return isImagPart ? insert<Part::Imag>(cplx, part) |
| : insert<Part::Real>(cplx, part); |
| } |
| |
| mlir::Value createComplexCompare(mlir::Value cplx1, mlir::Value cplx2, |
| bool eq); |
| |
| protected: |
| template <Part partId> |
| mlir::Value extract(mlir::Value cplx) { |
| return builder.create<fir::ExtractValueOp>( |
| loc, getComplexPartType(cplx), cplx, |
| builder.getArrayAttr({builder.getIntegerAttr( |
| builder.getIndexType(), static_cast<int>(partId))})); |
| } |
| |
| template <Part partId> |
| mlir::Value insert(mlir::Value cplx, mlir::Value part) { |
| return builder.create<fir::InsertValueOp>( |
| loc, cplx.getType(), cplx, part, |
| builder.getArrayAttr({builder.getIntegerAttr( |
| builder.getIndexType(), static_cast<int>(partId))})); |
| } |
| |
| template <Part partId> |
| mlir::Value createPartId() { |
| return builder.createIntegerConstant(loc, builder.getIndexType(), |
| static_cast<int>(partId)); |
| } |
| |
| private: |
| FirOpBuilder &builder; |
| mlir::Location loc; |
| }; |
| |
| } // namespace Fortran::lower |
| |
| #endif // FORTRAN_LOWER_COMPLEXEXPR_H |