blob: 337294587cf5649c77402688d6c27fc23b3441f3 [file] [log] [blame]
//===-- 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