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: Complex(FirOpBuilder & builder,mlir::Location loc)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 /// Complex operation creation. They create MLIR operations. 36 mlir::Value createComplex(fir::KindTy kind, mlir::Value real, 37 mlir::Value imag); 38 39 /// Create a complex value. 40 mlir::Value createComplex(mlir::Type complexType, mlir::Value real, 41 mlir::Value imag); 42 43 /// Returns the Real/Imag part of \p cplx extractComplexPart(mlir::Value cplx,bool isImagPart)44 mlir::Value extractComplexPart(mlir::Value cplx, bool isImagPart) { 45 return isImagPart ? extract<Part::Imag>(cplx) : extract<Part::Real>(cplx); 46 } 47 48 /// Returns (Real, Imag) pair of \p cplx extractParts(mlir::Value cplx)49 std::pair<mlir::Value, mlir::Value> extractParts(mlir::Value cplx) { 50 return {extract<Part::Real>(cplx), extract<Part::Imag>(cplx)}; 51 } 52 insertComplexPart(mlir::Value cplx,mlir::Value part,bool isImagPart)53 mlir::Value insertComplexPart(mlir::Value cplx, mlir::Value part, 54 bool isImagPart) { 55 return isImagPart ? insert<Part::Imag>(cplx, part) 56 : insert<Part::Real>(cplx, part); 57 } 58 59 protected: 60 template <Part partId> extract(mlir::Value cplx)61 mlir::Value extract(mlir::Value cplx) { 62 return builder.create<fir::ExtractValueOp>( 63 loc, getComplexPartType(cplx), cplx, 64 builder.getArrayAttr({builder.getIntegerAttr( 65 builder.getIndexType(), static_cast<int>(partId))})); 66 } 67 68 template <Part partId> insert(mlir::Value cplx,mlir::Value part)69 mlir::Value insert(mlir::Value cplx, mlir::Value part) { 70 return builder.create<fir::InsertValueOp>( 71 loc, cplx.getType(), cplx, part, 72 builder.getArrayAttr({builder.getIntegerAttr( 73 builder.getIndexType(), static_cast<int>(partId))})); 74 } 75 76 template <Part partId> createPartId()77 mlir::Value createPartId() { 78 return builder.createIntegerConstant(loc, builder.getIndexType(), 79 static_cast<int>(partId)); 80 } 81 82 private: 83 FirOpBuilder &builder; 84 mlir::Location loc; 85 }; 86 87 } // namespace fir::factory 88 89 #endif // FORTRAN_OPTIMIZER_BUILDER_COMPLEX_H 90