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
19inline bool nonVolatileLoad(mlir::Operation *op) {
20 if (auto load = mlir::dyn_cast<fir::LoadOp>(op))
21 return !load->getAttr("volatile");
22 if (auto arrLoad = mlir::dyn_cast<fir::ArrayLoadOp>(op))
23 return !arrLoad->getAttr("volatile");
24 return false;
25}
26
28inline bool isaCall(mlir::Operation *op) {
29 return mlir::isa<fir::CallOp>(op) || mlir::isa<fir::DispatchOp>(op) ||
30 mlir::isa<mlir::func::CallOp>(op) ||
31 mlir::isa<mlir::func::CallIndirectOp>(op);
32}
33
37inline bool impureCall(mlir::Operation *op) {
38 // Should we also auto-detect that the called function is pure if its
39 // arguments are not references? For now, rely on a "pure" attribute.
40 return op && isaCall(op) && !op->getAttr("pure");
41}
42
46inline bool pureCall(mlir::Operation *op) {
47 // Should we also auto-detect that the called function is pure if its
48 // arguments are not references? For now, rely on a "pure" attribute.
49 return op && isaCall(op) && op->getAttr("pure");
50}
51
57mlir::func::FuncOp createFuncOp(mlir::Location loc, mlir::ModuleOp module,
58 llvm::StringRef name, mlir::FunctionType type,
60 const mlir::SymbolTable *symbolTable = nullptr);
61
64fir::GlobalOp createGlobalOp(mlir::Location loc, mlir::ModuleOp module,
65 llvm::StringRef name, mlir::Type type,
67 const mlir::SymbolTable *symbolTable = nullptr);
68
70constexpr llvm::StringRef getContiguousAttrName() { return "fir.contiguous"; }
71
73constexpr llvm::StringRef getOptionalAttrName() { return "fir.optional"; }
74
76static constexpr llvm::StringRef getTargetAttrName() { return "fir.target"; }
77
79static constexpr llvm::StringRef getAsynchronousAttrName() {
80 return "fir.asynchronous";
81}
82
84static constexpr llvm::StringRef getVolatileAttrName() {
85 return "fir.volatile";
86}
87
90static constexpr llvm::StringRef getCharacterProcedureDummyAttrName() {
91 return "fir.char_proc";
92}
93
95static constexpr llvm::StringRef getSymbolAttrName() {
96 return "fir.bindc_name";
97}
98
100static constexpr llvm::StringRef getHostAssocAttrName() {
101 return "fir.host_assoc";
102}
103
105static constexpr llvm::StringRef getHostSymbolAttrName() {
106 return "fir.host_symbol";
107}
108
111static constexpr llvm::StringRef getInternalFuncNameAttrName() {
112 return "fir.internal_name";
113}
114
117bool hasHostAssociationArgument(mlir::func::FuncOp func);
118
122inline bool isInternalProcedure(mlir::func::FuncOp func) {
123 return func->hasAttr(fir::getHostSymbolAttrName());
124}
125
134bool valueHasFirAttribute(mlir::Value value, llvm::StringRef attributeName);
135
146bool valueMayHaveFirAttributes(mlir::Value value,
147 llvm::ArrayRef<llvm::StringRef> attributeNames);
148
152bool anyFuncArgsHaveAttr(mlir::func::FuncOp func, llvm::StringRef attr);
153
155std::optional<std::int64_t> getIntIfConstant(mlir::Value value);
156
157static constexpr llvm::StringRef getAdaptToByRefAttrName() {
158 return "adapt.valuebyref";
159}
160
161static constexpr llvm::StringRef getFuncPureAttrName() {
162 return "fir.func_pure";
163}
164
165static constexpr llvm::StringRef getFuncElementalAttrName() {
166 return "fir.func_elemental";
167}
168
169static constexpr llvm::StringRef getFuncRecursiveAttrName() {
170 return "fir.func_recursive";
171}
172
173static constexpr llvm::StringRef getFortranProcedureFlagsAttrName() {
174 return "fir.proc_attrs";
175}
176
177// Attribute for an alloca that is a trivial adaptor for converting a value to
178// pass-by-ref semantics for a VALUE parameter. The optimizer may be able to
179// eliminate these.
180// Template is used to avoid compiler errors in places that don't include
181// FIRBuilder.h
182template <typename Builder>
183inline mlir::NamedAttribute getAdaptToByRefAttr(Builder &builder) {
184 return {mlir::StringAttr::get(builder.getContext(),
185 fir::getAdaptToByRefAttrName()),
186 builder.getUnitAttr()};
187}
188
189bool isDummyArgument(mlir::Value v);
190
191template <fir::FortranProcedureFlagsEnum Flag>
192inline bool hasProcedureAttr(fir::FortranProcedureFlagsEnumAttr flags) {
193 return flags && bitEnumContainsAny(flags.getValue(), Flag);
194}
195
196template <fir::FortranProcedureFlagsEnum Flag>
197inline bool hasProcedureAttr(mlir::Operation *op) {
198 if (auto firCallOp = mlir::dyn_cast<fir::CallOp>(op))
199 return hasProcedureAttr<Flag>(firCallOp.getProcedureAttrsAttr());
200 if (auto firCallOp = mlir::dyn_cast<fir::DispatchOp>(op))
201 return hasProcedureAttr<Flag>(firCallOp.getProcedureAttrsAttr());
202 return hasProcedureAttr<Flag>(
203 op->getAttrOfType<fir::FortranProcedureFlagsEnumAttr>(
204 getFortranProcedureFlagsAttrName()));
205}
206
207inline bool hasBindcAttr(mlir::Operation *op) {
208 return hasProcedureAttr<fir::FortranProcedureFlagsEnum::bind_c>(op);
209}
210
211} // namespace fir
212
213#endif // FORTRAN_OPTIMIZER_DIALECT_FIROPSSUPPORT_H
Definition: FIRType.h:77
Definition: AbstractConverter.h:31
bool anyFuncArgsHaveAttr(mlir::func::FuncOp func, llvm::StringRef attr)
Definition: FIROps.cpp:4339
bool nonVolatileLoad(mlir::Operation *op)
Return true iff the Operation is a non-volatile LoadOp or ArrayLoadOp.
Definition: FIROpsSupport.h:19
constexpr llvm::StringRef getContiguousAttrName()
Attribute to mark Fortran entities with the CONTIGUOUS attribute.
Definition: FIROpsSupport.h:70
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:4211
bool hasHostAssociationArgument(mlir::func::FuncOp func)
Definition: FIROps.cpp:4231
bool isInternalProcedure(mlir::func::FuncOp func)
Definition: FIROpsSupport.h:122
constexpr llvm::StringRef getOptionalAttrName()
Attribute to mark Fortran entities with the OPTIONAL attribute.
Definition: FIROpsSupport.h:73
bool pureCall(mlir::Operation *op)
Definition: FIROpsSupport.h:46
std::optional< std::int64_t > getIntIfConstant(mlir::Value value)
Unwrap integer constant from an mlir::Value.
Definition: FIROps.cpp:4346
bool valueHasFirAttribute(mlir::Value value, llvm::StringRef attributeName)
Definition: FIROps.cpp:4332
bool valueMayHaveFirAttributes(mlir::Value value, llvm::ArrayRef< llvm::StringRef > attributeNames)
Definition: FIROps.cpp:4325
bool impureCall(mlir::Operation *op)
Definition: FIROpsSupport.h:37
bool isaCall(mlir::Operation *op)
Return true iff the Operation is a call.
Definition: FIROpsSupport.h:28
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:4189