Warning: This file is not a C or C++ file. It does not have highlighting.

1//===-- Lower/CustomIntrinsicCall.h -----------------------------*- 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/// Custom intrinsic lowering for the few intrinsic that have optional
14/// arguments that prevents them to be handled in a more generic way in
15/// IntrinsicCall.cpp.
16/// The core principle is that this interface provides the intrinsic arguments
17/// via callbacks to generate fir::ExtendedValue (instead of a list of
18/// precomputed fir::ExtendedValue as done in the default intrinsic call
19/// lowering). This gives more flexibility to only generate references to
20/// dynamically optional arguments (pointers, allocatables, OPTIONAL dummies) in
21/// a safe way.
22//===----------------------------------------------------------------------===//
23
24#ifndef FORTRAN_LOWER_CUSTOMINTRINSICCALL_H
25#define FORTRAN_LOWER_CUSTOMINTRINSICCALL_H
26
27#include "flang/Lower/AbstractConverter.h"
28#include "flang/Optimizer/Builder/IntrinsicCall.h"
29#include <functional>
30#include <optional>
31
32namespace Fortran {
33
34namespace evaluate {
35class ProcedureRef;
36struct SpecificIntrinsic;
37} // namespace evaluate
38
39namespace lower {
40
41/// Does the call \p procRef to \p intrinsic need to be handle via this custom
42/// framework due to optional arguments. Otherwise, the tools from
43/// IntrinsicCall.cpp should be used directly.
44bool intrinsicRequiresCustomOptionalHandling(
45 const Fortran::evaluate::ProcedureRef &procRef,
46 const Fortran::evaluate::SpecificIntrinsic &intrinsic,
47 AbstractConverter &converter);
48
49/// Type of callback to be provided to prepare the arguments fetching from an
50/// actual argument expression.
51using OperandPrepare = std::function<void(const Fortran::lower::SomeExpr &)>;
52using OperandPrepareAs = std::function<void(const Fortran::lower::SomeExpr &,
53 fir::LowerIntrinsicArgAs)>;
54
55/// Type of the callback to inquire about an argument presence, once the call
56/// preparation was done. An absent optional means the argument is statically
57/// present. An mlir::Value means the presence must be checked at runtime, and
58/// that the value contains the "is present" boolean value.
59using OperandPresent = std::function<std::optional<mlir::Value>(std::size_t)>;
60
61/// Type of the callback to generate an argument reference after the call
62/// preparation was done. For optional arguments, the utility guarantees
63/// these callbacks will only be called in regions where the presence was
64/// verified. This means the getter callback can dereference the argument
65/// without any special care.
66/// For elemental intrinsics, the getter must provide the current iteration
67/// element value. If the boolean argument is true, the callback must load the
68/// argument before returning it.
69using OperandGetter = std::function<fir::ExtendedValue(std::size_t, bool)>;
70
71/// Given a callback \p prepareOptionalArgument to prepare optional
72/// arguments and a callback \p prepareOtherArgument to prepare non-optional
73/// arguments prepare the intrinsic arguments calls.
74/// It is up to the caller to decide what argument preparation means,
75/// the only contract is that it should later allow the caller to provide
76/// callbacks to generate argument reference given an argument index without
77/// any further knowledge of the argument. The function simply visits
78/// the actual arguments, deciding which ones are dynamically optional,
79/// and calling the callbacks accordingly in argument order.
80void prepareCustomIntrinsicArgument(
81 const Fortran::evaluate::ProcedureRef &procRef,
82 const Fortran::evaluate::SpecificIntrinsic &intrinsic,
83 std::optional<mlir::Type> retTy,
84 const OperandPrepare &prepareOptionalArgument,
85 const OperandPrepareAs &prepareOtherArgument, AbstractConverter &converter);
86
87/// Given a callback \p getOperand to generate a reference to the i-th argument,
88/// and a callback \p isPresentCheck to test if an argument is present, this
89/// function lowers the intrinsic calls to \p name whose argument were
90/// previously prepared with prepareCustomIntrinsicArgument. The elemental
91/// aspects must be taken into account by the caller (i.e, the function should
92/// be called during the loop nest generation for elemental intrinsics. It will
93/// not generate any implicit loop nest on its own).
94fir::ExtendedValue
95lowerCustomIntrinsic(fir::FirOpBuilder &builder, mlir::Location loc,
96 llvm::StringRef name, std::optional<mlir::Type> retTy,
97 const OperandPresent &isPresentCheck,
98 const OperandGetter &getOperand, std::size_t numOperands,
99 Fortran::lower::StatementContext &stmtCtx);
100
101/// DEPRICATED: NEW CODE SHOULD USE THE VERSION OF genIntrinsicCall WITHOUT A
102/// StatementContext, DECLARED IN IntrinsicCall.h
103/// Generate the FIR+MLIR operations for the generic intrinsic \p name
104/// with argument \p args and expected result type \p resultType.
105/// Returned fir::ExtendedValue is the returned Fortran intrinsic value.
106fir::ExtendedValue
107genIntrinsicCall(fir::FirOpBuilder &builder, mlir::Location loc,
108 llvm::StringRef name, std::optional<mlir::Type> resultType,
109 llvm::ArrayRef<fir::ExtendedValue> args,
110 StatementContext &stmtCtx,
111 Fortran::lower::AbstractConverter *converter = nullptr);
112
113} // namespace lower
114} // namespace Fortran
115
116#endif // FORTRAN_LOWER_CUSTOMINTRINSICCALL_H
117

Warning: This file is not a C or C++ file. It does not have highlighting.

source code of flang/include/flang/Lower/CustomIntrinsicCall.h