xref: /llvm-project/flang/include/flang/Optimizer/Builder/Complex.h (revision c4204c0b29a6721267b1bcbaeedd7b1118e42396)
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