FLANG
FIROpsSupport.h
1//===-- Optimizer/Dialect/FIROpsSupport.h -- FIR op support -----*- 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#ifndef FORTRAN_OPTIMIZER_DIALECT_FIROPSSUPPORT_H
10#define FORTRAN_OPTIMIZER_DIALECT_FIROPSSUPPORT_H
11
12#include "flang/Optimizer/Dialect/FIROps.h"
13#include "mlir/Dialect/Func/IR/FuncOps.h"
14#include "mlir/IR/BuiltinOps.h"
15
16namespace fir {
17
25 mlir::TypeRange type,
26 llvm::SmallVectorImpl<
27 mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>>
28 &effects) {
29 for (mlir::Type t : type) {
31 effects.emplace_back(mlir::MemoryEffects::Read::get(),
32 fir::VolatileMemoryResource::get());
33 effects.emplace_back(mlir::MemoryEffects::Write::get(),
34 fir::VolatileMemoryResource::get());
35 break;
36 }
37 }
38}
39
41inline bool isaCall(mlir::Operation *op) {
42 return mlir::isa<fir::CallOp>(op) || mlir::isa<fir::DispatchOp>(op) ||
43 mlir::isa<mlir::func::CallOp>(op) ||
44 mlir::isa<mlir::func::CallIndirectOp>(op);
45}
46
50inline bool impureCall(mlir::Operation *op) {
51 // Should we also auto-detect that the called function is pure if its
52 // arguments are not references? For now, rely on a "pure" attribute.
53 return op && isaCall(op) && !op->getAttr("pure");
54}
55
59inline bool pureCall(mlir::Operation *op) {
60 // Should we also auto-detect that the called function is pure if its
61 // arguments are not references? For now, rely on a "pure" attribute.
62 return op && isaCall(op) && op->getAttr("pure");
63}
64
70mlir::func::FuncOp createFuncOp(mlir::Location loc, mlir::ModuleOp module,
71 llvm::StringRef name, mlir::FunctionType type,
73 const mlir::SymbolTable *symbolTable = nullptr);
74
77fir::GlobalOp createGlobalOp(mlir::Location loc, mlir::ModuleOp module,
78 llvm::StringRef name, mlir::Type type,
79 llvm::ArrayRef<mlir::NamedAttribute> attrs = {},
80 const mlir::SymbolTable *symbolTable = nullptr);
81
83constexpr llvm::StringRef getContiguousAttrName() { return "fir.contiguous"; }
84
86constexpr llvm::StringRef getOptionalAttrName() { return "fir.optional"; }
87
89static constexpr llvm::StringRef getTargetAttrName() { return "fir.target"; }
90
92static constexpr llvm::StringRef getAsynchronousAttrName() {
93 return "fir.asynchronous";
94}
95
97static constexpr llvm::StringRef getVolatileAttrName() {
98 return "fir.volatile";
99}
100
103static constexpr llvm::StringRef getCharacterProcedureDummyAttrName() {
104 return "fir.char_proc";
105}
106
108static constexpr llvm::StringRef getSymbolAttrName() {
109 return "fir.bindc_name";
110}
111
113static constexpr llvm::StringRef getHostAssocAttrName() {
114 return "fir.host_assoc";
115}
116
118static constexpr llvm::StringRef getHostSymbolAttrName() {
119 return "fir.host_symbol";
120}
121
124static constexpr llvm::StringRef getInternalFuncNameAttrName() {
125 return "fir.internal_name";
126}
127
130static constexpr llvm::StringRef getHasLifetimeMarkerAttrName() {
131 return "fir.has_lifetime";
132}
133
135static constexpr llvm::StringRef getAccessGroupsAttrName() {
136 return "access_groups";
137}
138
141bool hasHostAssociationArgument(mlir::func::FuncOp func);
142
146inline bool isInternalProcedure(mlir::func::FuncOp func) {
147 return func->hasAttr(fir::getHostSymbolAttrName());
148}
149
158bool valueHasFirAttribute(mlir::Value value, llvm::StringRef attributeName);
159
170bool valueMayHaveFirAttributes(mlir::Value value,
171 llvm::ArrayRef<llvm::StringRef> attributeNames);
172
176bool anyFuncArgsHaveAttr(mlir::func::FuncOp func, llvm::StringRef attr);
177
179std::optional<std::int64_t> getIntIfConstant(mlir::Value value);
180
181static constexpr llvm::StringRef getAdaptToByRefAttrName() {
182 return "adapt.valuebyref";
183}
184
185static constexpr llvm::StringRef getFuncPureAttrName() {
186 return "fir.func_pure";
187}
188
189static constexpr llvm::StringRef getFuncElementalAttrName() {
190 return "fir.func_elemental";
191}
192
193static constexpr llvm::StringRef getFuncRecursiveAttrName() {
194 return "fir.func_recursive";
195}
196
197static constexpr llvm::StringRef getFortranProcedureFlagsAttrName() {
198 return "fir.proc_attrs";
199}
200
201// Attribute for an alloca that is a trivial adaptor for converting a value to
202// pass-by-ref semantics for a VALUE parameter. The optimizer may be able to
203// eliminate these.
204// Template is used to avoid compiler errors in places that don't include
205// FIRBuilder.h
206template <typename Builder>
207inline mlir::NamedAttribute getAdaptToByRefAttr(Builder &builder) {
208 return {mlir::StringAttr::get(builder.getContext(),
209 fir::getAdaptToByRefAttrName()),
210 builder.getUnitAttr()};
211}
212
213bool isDummyArgument(mlir::Value v);
214
215template <fir::FortranProcedureFlagsEnum Flag>
216inline bool hasProcedureAttr(fir::FortranProcedureFlagsEnumAttr flags) {
217 return flags && bitEnumContainsAny(flags.getValue(), Flag);
218}
219
220template <fir::FortranProcedureFlagsEnum Flag>
221inline bool hasProcedureAttr(mlir::Operation *op) {
222 if (auto firCallOp = mlir::dyn_cast<fir::CallOp>(op))
223 return hasProcedureAttr<Flag>(firCallOp.getProcedureAttrsAttr());
224 if (auto firCallOp = mlir::dyn_cast<fir::DispatchOp>(op))
225 return hasProcedureAttr<Flag>(firCallOp.getProcedureAttrsAttr());
226 return hasProcedureAttr<Flag>(
227 op->getAttrOfType<fir::FortranProcedureFlagsEnumAttr>(
228 getFortranProcedureFlagsAttrName()));
229}
230
231inline bool hasBindcAttr(mlir::Operation *op) {
232 return hasProcedureAttr<fir::FortranProcedureFlagsEnum::bind_c>(op);
233}
234
237std::optional<int64_t> getAllocaByteSize(fir::AllocaOp alloca,
238 const mlir::DataLayout &dl,
239 const fir::KindMapping &kindMap);
240
249bool reboxPreservesContinuity(fir::ReboxOp rebox,
250 bool mayHaveNonDefaultLowerBounds = true,
251 bool checkWhole = true);
252
258bool isContiguousEmbox(fir::EmboxOp embox, bool checkWhole = true);
259
260} // namespace fir
261
262#endif // FORTRAN_OPTIMIZER_DIALECT_FIROPSSUPPORT_H
Definition FIRType.h:92
Definition AbstractConverter.h:37
bool isContiguousEmbox(fir::EmboxOp embox, bool checkWhole=true)
Definition FIROps.cpp:2161
bool anyFuncArgsHaveAttr(mlir::func::FuncOp func, llvm::StringRef attr)
Definition FIROps.cpp:5141
bool isa_volatile_type(mlir::Type t)
Definition FIRType.cpp:747
constexpr llvm::StringRef getContiguousAttrName()
Attribute to mark Fortran entities with the CONTIGUOUS attribute.
Definition FIROpsSupport.h:83
bool reboxPreservesContinuity(fir::ReboxOp rebox, bool mayHaveNonDefaultLowerBounds=true, bool checkWhole=true)
Definition FIROps.cpp:5213
fir::GlobalOp createGlobalOp(mlir::Location loc, mlir::ModuleOp module, llvm::StringRef name, mlir::Type type, llvm::ArrayRef< mlir::NamedAttribute > attrs={}, const mlir::SymbolTable *symbolTable=nullptr)
Definition FIROps.cpp:5013
bool hasHostAssociationArgument(mlir::func::FuncOp func)
Definition FIROps.cpp:5033
std::optional< int64_t > getAllocaByteSize(fir::AllocaOp alloca, const mlir::DataLayout &dl, const fir::KindMapping &kindMap)
Definition FIROps.cpp:5230
bool isInternalProcedure(mlir::func::FuncOp func)
Definition FIROpsSupport.h:146
constexpr llvm::StringRef getOptionalAttrName()
Attribute to mark Fortran entities with the OPTIONAL attribute.
Definition FIROpsSupport.h:86
bool pureCall(mlir::Operation *op)
Definition FIROpsSupport.h:59
void addVolatileMemoryEffects(mlir::TypeRange type, llvm::SmallVectorImpl< mlir::SideEffects::EffectInstance< mlir::MemoryEffects::Effect > > &effects)
Definition FIROpsSupport.h:24
std::optional< std::int64_t > getIntIfConstant(mlir::Value value)
Unwrap integer constant from an mlir::Value.
Definition FIROps.cpp:5148
bool valueHasFirAttribute(mlir::Value value, llvm::StringRef attributeName)
Definition FIROps.cpp:5134
bool valueMayHaveFirAttributes(mlir::Value value, llvm::ArrayRef< llvm::StringRef > attributeNames)
Definition FIROps.cpp:5127
bool impureCall(mlir::Operation *op)
Definition FIROpsSupport.h:50
bool isaCall(mlir::Operation *op)
Return true iff the Operation is a call.
Definition FIROpsSupport.h:41
mlir::func::FuncOp createFuncOp(mlir::Location loc, mlir::ModuleOp module, llvm::StringRef name, mlir::FunctionType type, llvm::ArrayRef< mlir::NamedAttribute > attrs={}, const mlir::SymbolTable *symbolTable=nullptr)
Definition FIROps.cpp:4991