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 | |
32 | namespace Fortran { |
33 | |
34 | namespace evaluate { |
35 | class ProcedureRef; |
36 | struct SpecificIntrinsic; |
37 | } // namespace evaluate |
38 | |
39 | namespace 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. |
44 | bool 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. |
51 | using OperandPrepare = std::function<void(const Fortran::lower::SomeExpr &)>; |
52 | using 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. |
59 | using 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. |
69 | using 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. |
80 | void 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). |
94 | fir::ExtendedValue |
95 | lowerCustomIntrinsic(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. |
106 | fir::ExtendedValue |
107 | genIntrinsicCall(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.