FLANG
ReductionProcessor.h
1//===-- Lower/OpenMP/ReductionProcessor.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#ifndef FORTRAN_LOWER_REDUCTIONPROCESSOR_H
14#define FORTRAN_LOWER_REDUCTIONPROCESSOR_H
15
16#include "flang/Lower/AbstractConverter.h"
17#include "flang/Lower/OpenMP/Clauses.h"
18#include "flang/Optimizer/Builder/FIRBuilder.h"
19#include "flang/Optimizer/Dialect/FIRType.h"
20#include "flang/Parser/parse-tree.h"
21#include "flang/Semantics/symbol.h"
22#include "flang/Semantics/type.h"
23#include "mlir/IR/Location.h"
24#include "mlir/IR/Types.h"
25#include "llvm/ADT/ArrayRef.h"
26
27namespace mlir {
28namespace omp {
29class DeclareReductionOp;
30} // namespace omp
31} // namespace mlir
32
33namespace Fortran {
34namespace lower {
36} // namespace lower
37namespace semantics {
39} // namespace semantics
40} // namespace Fortran
41
42namespace Fortran {
43namespace lower {
44namespace omp {
45
47public:
48 // ompOrig: mold/original variable
49 // ompPriv: private allocation (may be null for by-value reductions)
50 using GenInitValueCBTy = std::function<mlir::Value(
51 fir::FirOpBuilder &builder, mlir::Location loc, mlir::Type type,
52 mlir::Value ompOrig, mlir::Value ompPriv)>;
53 using GenCombinerCBTy = std::function<void(
54 fir::FirOpBuilder &builder, mlir::Location loc, mlir::Type type,
55 mlir::Value op1, mlir::Value op2, bool isByRef)>;
56
57 // TODO: Move this enumeration to the OpenMP dialect
58 enum ReductionIdentifier {
59 ID,
60 USER_DEF_OP,
61 ADD,
62 SUBTRACT,
63 MULTIPLY,
64 AND,
65 OR,
66 EQV,
67 NEQV,
68 MAX,
69 MIN,
70 IAND,
71 IOR,
72 IEOR
73 };
74
75 static bool doReductionByRef(mlir::Type reductionType);
76 static bool doReductionByRef(mlir::Value reductionVar);
77
78 static ReductionIdentifier
79 getReductionType(const omp::clause::ProcedureDesignator &pd);
80
81 static ReductionIdentifier
82 getReductionType(omp::clause::DefinedOperator::IntrinsicOperator intrinsicOp);
83
89 static parser::DefinedOperator::IntrinsicOperator
90 toParserIntrinsicOperator(omp::clause::DefinedOperator::IntrinsicOperator op);
91
92 static ReductionIdentifier
93 getReductionType(const fir::ReduceOperationEnum &pd);
94
95 static bool
96 supportedIntrinsicProcReduction(const omp::clause::ProcedureDesignator &pd);
97
98 static const semantics::SourceName
99 getRealName(const semantics::Symbol *symbol);
100
101 static const semantics::SourceName
102 getRealName(const omp::clause::ProcedureDesignator &pd);
103
104 static std::string getReductionName(llvm::StringRef name,
105 const fir::KindMapping &kindMap,
106 mlir::Type ty, bool isByRef);
107
108 static std::string getReductionName(ReductionIdentifier redId,
109 const fir::KindMapping &kindMap,
110 mlir::Type ty, bool isByRef);
111
121 static std::string
123 const semantics::Symbol &reductionSymbol,
124 mlir::Type reductionType, bool isByRef);
125
130 static int getOperationIdentity(ReductionIdentifier redId,
131 mlir::Location loc);
132
133 static mlir::Value getReductionInitValue(mlir::Location loc, mlir::Type type,
134 ReductionIdentifier redId,
135 fir::FirOpBuilder &builder);
136
137 template <typename FloatOp, typename IntegerOp>
138 static mlir::Value getReductionOperation(fir::FirOpBuilder &builder,
139 mlir::Type type, mlir::Location loc,
140 mlir::Value op1, mlir::Value op2);
141 template <typename FloatOp, typename IntegerOp, typename ComplexOp>
142 static mlir::Value getReductionOperation(fir::FirOpBuilder &builder,
143 mlir::Type type, mlir::Location loc,
144 mlir::Value op1, mlir::Value op2);
145
146 static mlir::Value createScalarCombiner(fir::FirOpBuilder &builder,
147 mlir::Location loc,
148 ReductionIdentifier redId,
149 mlir::Type type, mlir::Value op1,
150 mlir::Value op2);
154 template <typename DeclareRedType>
155 static DeclareRedType createDeclareReductionHelper(
156 AbstractConverter &converter, llvm::StringRef reductionOpName,
157 mlir::Type type, mlir::Location loc, bool isByRef,
158 GenCombinerCBTy genCombinerCB, GenInitValueCBTy genInitValueCB,
159 const semantics::Symbol *sym = nullptr);
160
165 template <typename OpType>
166 static OpType createDeclareReduction(AbstractConverter &builder,
167 llvm::StringRef reductionOpName,
168 const ReductionIdentifier redId,
169 mlir::Type type, mlir::Location loc,
170 bool isByRef);
171
180 template <typename OpType, typename RedOperatorListTy>
181 static bool processReductionArguments(
182 mlir::Location currentLocation, lower::AbstractConverter &converter,
183 const RedOperatorListTy &redOperatorList,
184 llvm::SmallVectorImpl<mlir::Value> &reductionVars,
185 llvm::SmallVectorImpl<bool> &reduceVarByRef,
186 llvm::SmallVectorImpl<mlir::Attribute> &reductionDeclSymbols,
187 const llvm::SmallVectorImpl<const semantics::Symbol *> &reductionSymbols,
188 llvm::ArrayRef<Object> reductionObjects, lower::SymMap &symMap,
189 semantics::SemanticsContext *semaCtx = nullptr,
190 llvm::DenseMap<const semantics::Symbol *, mlir::Value>
191 *reductionVarCache = nullptr);
192
196 // TODO support more types of objects
197 // to avoid Reduction clauses being represented in FIR as full arrays.
198 static bool isExpressionLoweredAsReductionObject(const Object *object);
199};
200
201template <typename FloatOp, typename IntegerOp>
202mlir::Value
203ReductionProcessor::getReductionOperation(fir::FirOpBuilder &builder,
204 mlir::Type type, mlir::Location loc,
205 mlir::Value op1, mlir::Value op2) {
206 type = fir::unwrapRefType(type);
207 assert(type.isIntOrIndexOrFloat() &&
208 "only integer, float and complex types are currently supported");
209 if (type.isIntOrIndex())
210 return IntegerOp::create(builder, loc, op1, op2);
211 return FloatOp::create(builder, loc, op1, op2);
212}
213
214template <typename FloatOp, typename IntegerOp, typename ComplexOp>
215mlir::Value
216ReductionProcessor::getReductionOperation(fir::FirOpBuilder &builder,
217 mlir::Type type, mlir::Location loc,
218 mlir::Value op1, mlir::Value op2) {
219 assert((type.isIntOrIndexOrFloat() || fir::isa_complex(type)) &&
220 "only integer, float and complex types are currently supported");
221 if (type.isIntOrIndex())
222 return IntegerOp::create(builder, loc, op1, op2);
223 if (fir::isa_real(type))
224 return FloatOp::create(builder, loc, op1, op2);
225 return ComplexOp::create(builder, loc, op1, op2);
226}
227
228} // namespace omp
229} // namespace lower
230} // namespace Fortran
231
232#endif // FORTRAN_LOWER_REDUCTIONPROCESSOR_H
Definition AbstractConverter.h:87
Definition SymbolMap.h:181
Definition ReductionProcessor.h:46
static std::string getScopedUserReductionName(AbstractConverter &converter, const semantics::Symbol &reductionSymbol, mlir::Type reductionType, bool isByRef)
Definition ReductionProcessor.cpp:254
static int getOperationIdentity(ReductionIdentifier redId, mlir::Location loc)
Definition ReductionProcessor.cpp:1274
static OpType createDeclareReduction(AbstractConverter &builder, llvm::StringRef reductionOpName, const ReductionIdentifier redId, mlir::Type type, mlir::Location loc, bool isByRef)
Definition ReductionProcessor.cpp:696
static parser::DefinedOperator::IntrinsicOperator toParserIntrinsicOperator(omp::clause::DefinedOperator::IntrinsicOperator op)
Definition ReductionProcessor.cpp:123
static bool isExpressionLoweredAsReductionObject(const Object *object)
Definition ReductionProcessor.cpp:430
static bool processReductionArguments(mlir::Location currentLocation, lower::AbstractConverter &converter, const RedOperatorListTy &redOperatorList, llvm::SmallVectorImpl< mlir::Value > &reductionVars, llvm::SmallVectorImpl< bool > &reduceVarByRef, llvm::SmallVectorImpl< mlir::Attribute > &reductionDeclSymbols, const llvm::SmallVectorImpl< const semantics::Symbol * > &reductionSymbols, llvm::ArrayRef< Object > reductionObjects, lower::SymMap &symMap, semantics::SemanticsContext *semaCtx=nullptr, llvm::DenseMap< const semantics::Symbol *, mlir::Value > *reductionVarCache=nullptr)
Definition ReductionProcessor.cpp:742
static DeclareRedType createDeclareReductionHelper(AbstractConverter &converter, llvm::StringRef reductionOpName, mlir::Type type, mlir::Location loc, bool isByRef, GenCombinerCBTy genCombinerCB, GenInitValueCBTy genInitValueCB, const semantics::Symbol *sym=nullptr)
Definition ReductionProcessor.cpp:634
Definition semantics.h:67
Definition symbol.h:896
Definition FIRBuilder.h:59
Definition KindMapping.h:48
Definition FIRType.h:106
Definition ParserActions.h:24
Definition bit-population-count.h:20
bool isa_complex(mlir::Type t)
Is t a floating point complex type?
Definition FIRType.h:221
bool isa_real(mlir::Type t)
Is t a real type?
Definition FIRType.h:200
Definition AbstractConverter.h:32