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/OpenMP/Clauses.h"
17#include "flang/Optimizer/Builder/FIRBuilder.h"
18#include "flang/Optimizer/Dialect/FIRType.h"
19#include "flang/Parser/parse-tree.h"
20#include "flang/Semantics/symbol.h"
21#include "flang/Semantics/type.h"
22#include "mlir/IR/Location.h"
23#include "mlir/IR/Types.h"
24
25namespace mlir {
26namespace omp {
27class DeclareReductionOp;
28} // namespace omp
29} // namespace mlir
30
31namespace Fortran {
32namespace lower {
34} // namespace lower
35namespace semantics {
36class Scope;
38} // namespace semantics
39} // namespace Fortran
40
41namespace Fortran {
42namespace lower {
43namespace omp {
44
46public:
47 // ompOrig: mold/original variable
48 // ompPriv: private allocation (may be null for by-value reductions)
49 using GenInitValueCBTy = std::function<mlir::Value(
50 fir::FirOpBuilder &builder, mlir::Location loc, mlir::Type type,
51 mlir::Value ompOrig, mlir::Value ompPriv)>;
52 using GenCombinerCBTy = std::function<void(
53 fir::FirOpBuilder &builder, mlir::Location loc, mlir::Type type,
54 mlir::Value op1, mlir::Value op2, bool isByRef)>;
55
56 // TODO: Move this enumeration to the OpenMP dialect
57 enum ReductionIdentifier {
58 ID,
59 USER_DEF_OP,
60 ADD,
61 SUBTRACT,
62 MULTIPLY,
63 AND,
64 OR,
65 EQV,
66 NEQV,
67 MAX,
68 MIN,
69 IAND,
70 IOR,
71 IEOR
72 };
73
74 static bool doReductionByRef(mlir::Type reductionType);
75 static bool doReductionByRef(mlir::Value reductionVar);
76
77 static ReductionIdentifier
78 getReductionType(const omp::clause::ProcedureDesignator &pd);
79
80 static ReductionIdentifier
81 getReductionType(omp::clause::DefinedOperator::IntrinsicOperator intrinsicOp);
82
87 static parser::DefinedOperator::IntrinsicOperator
88 toParserIntrinsicOperator(omp::clause::DefinedOperator::IntrinsicOperator op);
89
90 static ReductionIdentifier
91 getReductionType(const fir::ReduceOperationEnum &pd);
92
93 static bool
94 supportedIntrinsicProcReduction(const omp::clause::ProcedureDesignator &pd);
95
100 const semantics::Scope &scope,
101 const omp::clause::ProcedureDesignator &reductionIntrinsic,
102 const semantics::DeclTypeSpec *type);
103
104 static const semantics::SourceName
105 getRealName(const semantics::Symbol *symbol);
106
107 static const semantics::SourceName
108 getRealName(const omp::clause::ProcedureDesignator &pd);
109
110 static std::string getReductionName(llvm::StringRef name,
111 const fir::KindMapping &kindMap,
112 mlir::Type ty, bool isByRef);
113
114 static std::string getReductionName(ReductionIdentifier redId,
115 const fir::KindMapping &kindMap,
116 mlir::Type ty, bool isByRef);
117
127 static std::string
129 const semantics::Symbol &reductionSymbol,
130 mlir::Type reductionType, bool isByRef);
131
136 static int getOperationIdentity(ReductionIdentifier redId,
137 mlir::Location loc);
138
139 static mlir::Value getReductionInitValue(mlir::Location loc, mlir::Type type,
140 ReductionIdentifier redId,
141 fir::FirOpBuilder &builder);
142
143 template <typename FloatOp, typename IntegerOp>
144 static mlir::Value getReductionOperation(fir::FirOpBuilder &builder,
145 mlir::Type type, mlir::Location loc,
146 mlir::Value op1, mlir::Value op2);
147 template <typename FloatOp, typename IntegerOp, typename ComplexOp>
148 static mlir::Value getReductionOperation(fir::FirOpBuilder &builder,
149 mlir::Type type, mlir::Location loc,
150 mlir::Value op1, mlir::Value op2);
151
152 static mlir::Value createScalarCombiner(fir::FirOpBuilder &builder,
153 mlir::Location loc,
154 ReductionIdentifier redId,
155 mlir::Type type, mlir::Value op1,
156 mlir::Value op2);
160 template <typename DeclareRedType>
161 static DeclareRedType createDeclareReductionHelper(
162 AbstractConverter &converter, llvm::StringRef reductionOpName,
163 mlir::Type type, mlir::Location loc, bool isByRef,
164 GenCombinerCBTy genCombinerCB, GenInitValueCBTy genInitValueCB,
165 const semantics::Symbol *sym = nullptr);
166
171 template <typename OpType>
172 static OpType createDeclareReduction(AbstractConverter &builder,
173 llvm::StringRef reductionOpName,
174 const ReductionIdentifier redId,
175 mlir::Type type, mlir::Location loc,
176 bool isByRef);
177
186 template <typename OpType, typename RedOperatorListTy>
187 static bool processReductionArguments(
188 mlir::Location currentLocation, lower::AbstractConverter &converter,
189 const RedOperatorListTy &redOperatorList,
191 llvm::SmallVectorImpl<bool> &reduceVarByRef,
192 llvm::SmallVectorImpl<mlir::Attribute> &reductionDeclSymbols,
194 semantics::SemanticsContext *semaCtx = nullptr,
195 llvm::DenseMap<const semantics::Symbol *, mlir::Value>
196 *reductionVarCache = nullptr);
197
198private:
208 template <typename OpType>
209 static bool processOpenMPReductionOperator(
210 mlir::Location currentLocation, lower::AbstractConverter &converter,
211 const omp::clause::ReductionOperatorList &redOperatorList,
212 llvm::SmallVectorImpl<mlir::Attribute> &reductionDeclSymbols,
213 const semantics::Symbol &reductionSymbol,
214 semantics::SemanticsContext *semaCtx, fir::ReferenceType redType,
215 bool isByRef, const fir::KindMapping &kindMap, std::string &reductionName,
216 ReductionIdentifier &redId);
217};
218
219template <typename FloatOp, typename IntegerOp>
220mlir::Value
221ReductionProcessor::getReductionOperation(fir::FirOpBuilder &builder,
222 mlir::Type type, mlir::Location loc,
223 mlir::Value op1, mlir::Value op2) {
224 type = fir::unwrapRefType(type);
225 assert(type.isIntOrIndexOrFloat() &&
226 "only integer, float and complex types are currently supported");
227 if (type.isIntOrIndex())
228 return IntegerOp::create(builder, loc, op1, op2);
229 return FloatOp::create(builder, loc, op1, op2);
230}
231
232template <typename FloatOp, typename IntegerOp, typename ComplexOp>
233mlir::Value
234ReductionProcessor::getReductionOperation(fir::FirOpBuilder &builder,
235 mlir::Type type, mlir::Location loc,
236 mlir::Value op1, mlir::Value op2) {
237 assert((type.isIntOrIndexOrFloat() || fir::isa_complex(type)) &&
238 "only integer, float and complex types are currently supported");
239 if (type.isIntOrIndex())
240 return IntegerOp::create(builder, loc, op1, op2);
241 if (fir::isa_real(type))
242 return FloatOp::create(builder, loc, op1, op2);
243 return ComplexOp::create(builder, loc, op1, op2);
244}
245
246} // namespace omp
247} // namespace lower
248} // namespace Fortran
249
250#endif // FORTRAN_LOWER_REDUCTIONPROCESSOR_H
Definition AbstractConverter.h:87
Definition ReductionProcessor.h:45
static std::string getScopedUserReductionName(AbstractConverter &converter, const semantics::Symbol &reductionSymbol, mlir::Type reductionType, bool isByRef)
Definition ReductionProcessor.cpp:281
static int getOperationIdentity(ReductionIdentifier redId, mlir::Location loc)
Definition ReductionProcessor.cpp:1482
static OpType createDeclareReduction(AbstractConverter &builder, llvm::StringRef reductionOpName, const ReductionIdentifier redId, mlir::Type type, mlir::Location loc, bool isByRef)
Definition ReductionProcessor.cpp:711
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, semantics::SemanticsContext *semaCtx=nullptr, llvm::DenseMap< const semantics::Symbol *, mlir::Value > *reductionVarCache=nullptr)
Definition ReductionProcessor.cpp:1315
static parser::DefinedOperator::IntrinsicOperator toParserIntrinsicOperator(omp::clause::DefinedOperator::IntrinsicOperator op)
Definition ReductionProcessor.cpp:129
static const semantics::Symbol * findUserDefinedReductionForIntrinsic(const semantics::Scope &scope, const omp::clause::ProcedureDesignator &reductionIntrinsic, const semantics::DeclTypeSpec *type)
Definition ReductionProcessor.cpp:199
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:649
Definition scope.h:68
Definition semantics.h:71
Definition symbol.h:916
Definition FIRBuilder.h:66
Definition KindMapping.h:48
Definition OpenACC.h:22
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:228
bool isa_real(mlir::Type t)
Is t a real type?
Definition FIRType.h:207
Definition AbstractConverter.h:32