FLANG
HlfirIntrinsics.h
1//===-- HlfirIntrinsics.h -- lowering to HLFIR intrinsic ops ----*- 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//===----------------------------------------------------------------------===//
16//===----------------------------------------------------------------------===//
17
18#ifndef FORTRAN_LOWER_HLFIRINTRINSICS_H
19#define FORTRAN_LOWER_HLFIRINTRINSICS_H
20
21#include "flang/Optimizer/Builder/HLFIRTools.h"
22#include "flang/Optimizer/Builder/Todo.h"
23#include "flang/Optimizer/HLFIR/HLFIROps.h"
24#include "llvm/ADT/SmallVector.h"
25#include <cassert>
26#include <optional>
27#include <string>
28
29namespace mlir {
30class Location;
31class Type;
32class Value;
33class ValueRange;
34} // namespace mlir
35
36namespace fir {
37class FirOpBuilder;
39} // namespace fir
40
41namespace Fortran::lower {
42
46struct PreparedActualArgument {
47
48 PreparedActualArgument(hlfir::Entity actual,
49 std::optional<mlir::Value> isPresent)
50 : actual{actual}, isPresent{isPresent} {}
51 PreparedActualArgument(hlfir::ElementalAddrOp vectorSubscriptedActual)
52 : actual{vectorSubscriptedActual}, isPresent{std::nullopt} {}
53 void setElementalIndices(mlir::ValueRange &indices) {
54 oneBasedElementalIndices = &indices;
55 }
56
59 hlfir::Entity getActual(mlir::Location loc, fir::FirOpBuilder &builder) const;
60
61 mlir::Type getFortranElementType() {
62 if (auto *actualEntity = std::get_if<hlfir::Entity>(&actual))
63 return hlfir::getFortranElementType(actualEntity->getType());
64 mlir::Value entity =
65 std::get<hlfir::ElementalAddrOp>(actual).getElementEntity();
66 return hlfir::getFortranElementType(entity.getType());
67 }
68
69 void derefPointersAndAllocatables(mlir::Location loc,
70 fir::FirOpBuilder &builder) {
71 if (auto *actualEntity = std::get_if<hlfir::Entity>(&actual))
72 actual = hlfir::derefPointersAndAllocatables(loc, builder, *actualEntity);
73 }
74
75 void loadTrivialScalar(mlir::Location loc, fir::FirOpBuilder &builder) {
76 if (auto *actualEntity = std::get_if<hlfir::Entity>(&actual))
77 actual = hlfir::loadTrivialScalar(loc, builder, *actualEntity);
78 }
79
82 hlfir::AssociateOp associateIfArrayExpr(mlir::Location loc,
83 fir::FirOpBuilder &builder) {
84 if (auto *actualEntity = std::get_if<hlfir::Entity>(&actual)) {
85 if (!actualEntity->isVariable() && actualEntity->isArray()) {
86 mlir::Type storageType = actualEntity->getType();
87 hlfir::AssociateOp associate = hlfir::genAssociateExpr(
88 loc, builder, *actualEntity, storageType, "adapt.impure_arg_eval");
89 actual = hlfir::Entity{associate};
90 return associate;
91 }
92 }
93 return {};
94 }
95
96 bool isArray() const {
97 return std::holds_alternative<hlfir::ElementalAddrOp>(actual) ||
98 std::get<hlfir::Entity>(actual).isArray();
99 }
100
101 mlir::Value genShape(mlir::Location loc, fir::FirOpBuilder &builder) {
102 if (auto *actualEntity = std::get_if<hlfir::Entity>(&actual))
103 return hlfir::genShape(loc, builder, *actualEntity);
104 return std::get<hlfir::ElementalAddrOp>(actual).getShape();
105 }
106
107 mlir::Value genCharLength(mlir::Location loc, fir::FirOpBuilder &builder) {
108 if (auto *actualEntity = std::get_if<hlfir::Entity>(&actual))
109 return hlfir::genCharLength(loc, builder, *actualEntity);
110 auto typeParams = std::get<hlfir::ElementalAddrOp>(actual).getTypeparams();
111 assert(typeParams.size() == 1 &&
112 "failed to retrieve vector subscripted character length");
113 return typeParams[0];
114 }
115
116 void genLengthParameters(mlir::Location loc, fir::FirOpBuilder &builder,
117 llvm::SmallVectorImpl<mlir::Value> &result) {
118 if (auto *actualEntity = std::get_if<hlfir::Entity>(&actual)) {
119 hlfir::genLengthParameters(loc, builder, *actualEntity, result);
120 return;
121 }
122 for (mlir::Value len :
123 std::get<hlfir::ElementalAddrOp>(actual).getTypeparams())
124 result.push_back(len);
125 }
126
129 mlir::Value getPolymorphicMold(mlir::Location loc) const {
130 if (auto *actualEntity = std::get_if<hlfir::Entity>(&actual))
131 return *actualEntity;
132 TODO(loc, "polymorphic vector subscripts");
133 }
134
135 bool handleDynamicOptional() const { return isPresent.has_value(); }
136 mlir::Value getIsPresent() const {
137 assert(handleDynamicOptional() && "not a dynamic optional");
138 return *isPresent;
139 }
140
141 void resetOptionalAspect() { isPresent = std::nullopt; }
142
143private:
144 std::variant<hlfir::Entity, hlfir::ElementalAddrOp> actual;
145 mlir::ValueRange *oneBasedElementalIndices{nullptr};
146 // When the actual may be dynamically optional, "isPresent"
147 // holds a boolean value indicating the presence of the
148 // actual argument at runtime.
149 std::optional<mlir::Value> isPresent;
150};
151
156
157std::optional<hlfir::EntityWithAttributes> lowerHlfirIntrinsic(
158 fir::FirOpBuilder &builder, mlir::Location loc, const std::string &name,
159 const Fortran::lower::PreparedActualArguments &loweredActuals,
160 const fir::IntrinsicArgumentLoweringRules *argLowering,
161 mlir::Type stmtResultType);
162
163} // namespace Fortran::lower
164#endif // FORTRAN_LOWER_HLFIRINTRINSICS_H
Definition FIRBuilder.h:55
Definition HLFIRTools.h:52
Definition OpenACC.h:20
Definition ParserActions.h:24
llvm::SmallVector< std::optional< PreparedActualArgument > > PreparedActualArguments
Definition HlfirIntrinsics.h:154
Definition AbstractConverter.h:34
Definition AbstractConverter.h:29
mlir::Value getPolymorphicMold(mlir::Location loc) const
Definition HlfirIntrinsics.h:129
hlfir::Entity getActual(mlir::Location loc, fir::FirOpBuilder &builder) const
Definition ConvertCall.cpp:3039
hlfir::AssociateOp associateIfArrayExpr(mlir::Location loc, fir::FirOpBuilder &builder)
Definition HlfirIntrinsics.h:82
This is shared by intrinsics and intrinsic module procedures.
Definition IntrinsicCall.h:591