1 //===-- Complex.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 // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef FORTRAN_OPTIMIZER_BUILDER_COMPLEX_H 14 #define FORTRAN_OPTIMIZER_BUILDER_COMPLEX_H 15 16 #include "flang/Optimizer/Builder/FIRBuilder.h" 17 18 namespace fir::factory { 19 20 /// Helper to facilitate lowering of COMPLEX manipulations in FIR. 21 class Complex { 22 public: 23 explicit Complex(FirOpBuilder &builder, mlir::Location loc) 24 : builder(builder), loc(loc) {} 25 Complex(const Complex &) = delete; 26 27 // The values of part enum members are meaningful for 28 // InsertValueOp and ExtractValueOp so they are explicit. 29 enum class Part { Real = 0, Imag = 1 }; 30 31 /// Get the Complex Type. Determine the type. Do not create MLIR operations. 32 mlir::Type getComplexPartType(mlir::Value cplx) const; 33 mlir::Type getComplexPartType(mlir::Type complexType) const; 34 35 /// Create a complex value. 36 mlir::Value createComplex(mlir::Type complexType, mlir::Value real, 37 mlir::Value imag); 38 /// Create a complex value given the real and imag parts real type (which 39 /// must be the same). 40 mlir::Value createComplex(mlir::Value real, mlir::Value imag); 41 42 /// Returns the Real/Imag part of \p cplx 43 mlir::Value extractComplexPart(mlir::Value cplx, bool isImagPart) { 44 return isImagPart ? extract<Part::Imag>(cplx) : extract<Part::Real>(cplx); 45 } 46 47 /// Returns (Real, Imag) pair of \p cplx 48 std::pair<mlir::Value, mlir::Value> extractParts(mlir::Value cplx) { 49 return {extract<Part::Real>(cplx), extract<Part::Imag>(cplx)}; 50 } 51 52 mlir::Value insertComplexPart(mlir::Value cplx, mlir::Value part, 53 bool isImagPart) { 54 return isImagPart ? insert<Part::Imag>(cplx, part) 55 : insert<Part::Real>(cplx, part); 56 } 57 58 protected: 59 template <Part partId> 60 mlir::Value extract(mlir::Value cplx) { 61 return builder.create<fir::ExtractValueOp>( 62 loc, getComplexPartType(cplx), cplx, 63 builder.getArrayAttr({builder.getIntegerAttr( 64 builder.getIndexType(), static_cast<int>(partId))})); 65 } 66 67 template <Part partId> 68 mlir::Value insert(mlir::Value cplx, mlir::Value part) { 69 return builder.create<fir::InsertValueOp>( 70 loc, cplx.getType(), cplx, part, 71 builder.getArrayAttr({builder.getIntegerAttr( 72 builder.getIndexType(), static_cast<int>(partId))})); 73 } 74 75 template <Part partId> 76 mlir::Value createPartId() { 77 return builder.createIntegerConstant(loc, builder.getIndexType(), 78 static_cast<int>(partId)); 79 } 80 81 private: 82 FirOpBuilder &builder; 83 mlir::Location loc; 84 }; 85 86 } // namespace fir::factory 87 88 #endif // FORTRAN_OPTIMIZER_BUILDER_COMPLEX_H 89