FLANG
FIROps.h
1//===-- Optimizer/Dialect/FIROps.h - FIR operations -------------*- 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_FIROPS_H
10#define FORTRAN_OPTIMIZER_DIALECT_FIROPS_H
11
12#include "flang/Optimizer/Dialect/CUF/Attributes/CUFAttr.h"
13#include "flang/Optimizer/Dialect/FIRAttr.h"
14#include "flang/Optimizer/Dialect/FIRType.h"
15#include "flang/Optimizer/Dialect/FirAliasTagOpInterface.h"
16#include "flang/Optimizer/Dialect/FortranVariableInterface.h"
17#include "flang/Optimizer/Dialect/SafeTempArrayCopyAttrInterface.h"
18#include "mlir/Dialect/Arith/IR/Arith.h"
19#include "mlir/Dialect/Func/IR/FuncOps.h"
20#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
21#include "mlir/Interfaces/SideEffectInterfaces.h"
22
23namespace fir {
24
25class FirEndOp;
26class DoLoopOp;
27class RealAttr;
28
29void buildCmpCOp(mlir::OpBuilder &builder, mlir::OperationState &result,
30 mlir::arith::CmpFPredicate predicate, mlir::Value lhs,
31 mlir::Value rhs);
32unsigned getCaseArgumentOffset(llvm::ArrayRef<mlir::Attribute> cases,
33 unsigned dest);
34DoLoopOp getForInductionVarOwner(mlir::Value val);
35mlir::ParseResult isValidCaseAttr(mlir::Attribute attr);
36mlir::ParseResult parseCmpcOp(mlir::OpAsmParser &parser,
37 mlir::OperationState &result);
38mlir::ParseResult parseSelector(mlir::OpAsmParser &parser,
39 mlir::OperationState &result,
40 mlir::OpAsmParser::UnresolvedOperand &selector,
41 mlir::Type &type);
42bool useStrictVolatileVerification();
43
44static constexpr llvm::StringRef getNormalizedLowerBoundAttrName() {
45 return "normalized.lb";
46}
47
50 : public mlir::SideEffects::Resource::Base<DebuggingResource> {
51 mlir::StringRef getName() const final { return "DebuggingResource"; }
52 bool isAddressable() const override { return false; }
53};
54
57 : public mlir::SideEffects::Resource::Base<FortranRuntimeResource> {
58 mlir::StringRef getName() const final { return "FortranRuntimeResource"; }
59 bool isAddressable() const override { return false; }
60};
61
64 : public mlir::SideEffects::Resource::Base<VolatileMemoryResource> {
65 mlir::StringRef getName() const final { return "VolatileMemoryResource"; }
66 bool isAddressable() const override { return false; }
67};
68
70using IntOrValue = llvm::PointerUnion<mlir::IntegerAttr, mlir::Value>;
71
72} // namespace fir
73
74#define GET_OP_CLASSES
75#include "flang/Optimizer/Dialect/FIROps.h.inc"
76
77namespace fir {
78class CoordinateIndicesAdaptor {
79public:
80 using value_type = IntOrValue;
81
82 CoordinateIndicesAdaptor(mlir::DenseI32ArrayAttr fieldIndices,
83 mlir::ValueRange values)
84 : fieldIndices(fieldIndices), values(values) {}
85
86 value_type operator[](size_t index) const {
87 assert(index < size() && "index out of bounds");
88 return *std::next(begin(), index);
89 }
90
91 size_t size() const {
92 return fieldIndices ? fieldIndices.size() : values.size();
93 }
94
95 bool empty() const {
96 return values.empty() && (!fieldIndices || fieldIndices.empty());
97 }
98
99 class iterator
100 : public llvm::iterator_facade_base<iterator, std::forward_iterator_tag,
101 value_type, std::ptrdiff_t,
102 value_type *, value_type> {
103 public:
104 iterator(const CoordinateIndicesAdaptor *base,
105 std::optional<llvm::ArrayRef<int32_t>::iterator> fieldIter,
106 llvm::detail::IterOfRange<const mlir::ValueRange> valuesIter)
107 : base(base), fieldIter(fieldIter), valuesIter(valuesIter) {}
108
109 value_type operator*() const {
110 if (fieldIter && **fieldIter != fir::CoordinateOp::kDynamicIndex) {
111 return mlir::IntegerAttr::get(base->fieldIndices.getElementType(),
112 **fieldIter);
113 }
114 return *valuesIter;
115 }
116
117 iterator &operator++() {
118 if (fieldIter) {
119 if (**fieldIter == fir::CoordinateOp::kDynamicIndex)
120 valuesIter++;
121 (*fieldIter)++;
122 } else {
123 valuesIter++;
124 }
125 return *this;
126 }
127
128 bool operator==(const iterator &rhs) const {
129 return base == rhs.base && fieldIter == rhs.fieldIter &&
130 valuesIter == rhs.valuesIter;
131 }
132
133 private:
134 const CoordinateIndicesAdaptor *base;
135 std::optional<llvm::ArrayRef<int32_t>::const_iterator> fieldIter;
136 llvm::detail::IterOfRange<const mlir::ValueRange> valuesIter;
137 };
138
139 iterator begin() const {
140 std::optional<llvm::ArrayRef<int32_t>::const_iterator> fieldIter;
141 if (fieldIndices)
142 fieldIter = fieldIndices.asArrayRef().begin();
143 return iterator(this, fieldIter, values.begin());
144 }
145
146 iterator end() const {
147 std::optional<llvm::ArrayRef<int32_t>::const_iterator> fieldIter;
148 if (fieldIndices)
149 fieldIter = fieldIndices.asArrayRef().end();
150 return iterator(this, fieldIter, values.end());
151 }
152
153private:
154 mlir::DenseI32ArrayAttr fieldIndices;
155 mlir::ValueRange values;
156};
157
162
165bool mayBeAbsentBox(mlir::Value val);
166
167} // namespace fir
168
169#endif // FORTRAN_OPTIMIZER_DIALECT_FIROPS_H
Definition FIROps.h:78
Definition FIRAttr.h:151
Definition FIRType.h:106
Definition OpenACC.h:20
Definition AbstractConverter.h:37
bool mayBeAbsentBox(mlir::Value val)
Definition FIROps.cpp:272
Model operations which affect global debugging information.
Definition FIROps.h:50
Runtime checks can terminate execution, but do not access user memory.
Definition FIROps.h:57
Definition FIROps.h:158
Model operations which read from/write to volatile memory.
Definition FIROps.h:64