FLANG
DataSharingProcessor.h
1//===-- Lower/OpenMP/DataSharingProcessor.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#ifndef FORTRAN_LOWER_DATASHARINGPROCESSOR_H
13#define FORTRAN_LOWER_DATASHARINGPROCESSOR_H
14
15#include "Clauses.h"
16#include "flang/Lower/AbstractConverter.h"
17#include "flang/Lower/OpenMP.h"
18#include "flang/Optimizer/Builder/FIRBuilder.h"
19#include "flang/Parser/parse-tree.h"
20#include "flang/Semantics/symbol.h"
21#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
22
23namespace mlir {
24namespace omp {
25struct PrivateClauseOps;
26} // namespace omp
27} // namespace mlir
28
29namespace Fortran {
30namespace lower {
31namespace omp {
32
34private:
38 struct OMPConstructSymbolVisitor {
39 template <typename T>
40 bool Pre(const T &) {
41 return true;
42 }
43 template <typename T>
44 void Post(const T &) {}
45
46 bool Pre(const parser::OpenMPConstruct &omp) {
47 // Skip constructs that may not have privatizations.
48 if (!std::holds_alternative<parser::OpenMPCriticalConstruct>(omp.u))
49 currentConstruct = &omp;
50 return true;
51 }
52
53 void Post(const parser::OpenMPConstruct &omp) {
54 currentConstruct = nullptr;
55 }
56
57 void Post(const parser::Name &name) {
58 symDefMap.try_emplace(name.symbol, currentConstruct);
59 }
60
61 const parser::OpenMPConstruct *currentConstruct = nullptr;
62 llvm::DenseMap<semantics::Symbol *, const parser::OpenMPConstruct *>
63 symDefMap;
64
67 bool isSymbolDefineBy(const semantics::Symbol *symbol,
68 lower::pft::Evaluation &eval) const;
69 };
70
71 mlir::OpBuilder::InsertPoint lastPrivIP;
73 // Symbols in private, firstprivate, and/or lastprivate clauses.
74 llvm::SetVector<const semantics::Symbol *> explicitlyPrivatizedSymbols;
75 llvm::SetVector<const semantics::Symbol *> defaultSymbols;
76 llvm::SetVector<const semantics::Symbol *> implicitSymbols;
77 llvm::SetVector<const semantics::Symbol *> preDeterminedSymbols;
78 llvm::SetVector<const semantics::Symbol *> allPrivatizedSymbols;
79
80 llvm::DenseMap<const semantics::Symbol *, mlir::omp::PrivateClauseOp>
81 symToPrivatizer;
82 lower::AbstractConverter &converter;
84 fir::FirOpBuilder &firOpBuilder;
85 omp::List<omp::Clause> clauses;
87 bool shouldCollectPreDeterminedSymbols;
88 bool useDelayedPrivatization;
89 bool callsInitClone = false;
90 lower::SymMap &symTable;
91 OMPConstructSymbolVisitor visitor;
92
93 bool needBarrier();
94 void collectSymbols(semantics::Symbol::Flag flag,
95 llvm::SetVector<const semantics::Symbol *> &symbols);
96 void collectSymbolsInNestedRegions(
97 lower::pft::Evaluation &eval, semantics::Symbol::Flag flag,
98 llvm::SetVector<const semantics::Symbol *> &symbolsInNestedRegions);
99 void collectOmpObjectListSymbol(
100 const omp::ObjectList &objects,
101 llvm::SetVector<const semantics::Symbol *> &symbolSet);
102 void collectSymbolsForPrivatization();
103 void insertBarrier();
104 void collectDefaultSymbols();
105 void collectImplicitSymbols();
106 void collectPreDeterminedSymbols();
107 void privatize(mlir::omp::PrivateClauseOps *clauseOps);
108 void doPrivatize(const semantics::Symbol *sym,
109 mlir::omp::PrivateClauseOps *clauseOps);
110 void copyLastPrivatize(mlir::Operation *op);
111 void insertLastPrivateCompare(mlir::Operation *op);
112 void cloneSymbol(const semantics::Symbol *sym);
113 void
114 copyFirstPrivateSymbol(const semantics::Symbol *sym,
115 mlir::OpBuilder::InsertPoint *copyAssignIP = nullptr);
116 void copyLastPrivateSymbol(const semantics::Symbol *sym,
117 mlir::OpBuilder::InsertPoint *lastPrivIP);
118 void insertDeallocs();
119
120public:
123 const List<Clause> &clauses,
125 bool shouldCollectPreDeterminedSymbols,
126 bool useDelayedPrivatization, lower::SymMap &symTable);
127
128 // Privatisation is split into two steps.
129 // Step1 performs cloning of all privatisation clauses and copying for
130 // firstprivates. Step1 is performed at the place where process/processStep1
131 // is called. This is usually inside the Operation corresponding to the OpenMP
132 // construct, for looping constructs this is just before the Operation. The
133 // split into two steps was performed basically to be able to call
134 // privatisation for looping constructs before the operation is created since
135 // the bounds of the MLIR OpenMP operation can be privatised.
136 // Step2 performs the copying for lastprivates and requires knowledge of the
137 // MLIR operation to insert the last private update. Step2 adds
138 // dealocation code as well.
139 void processStep1(mlir::omp::PrivateClauseOps *clauseOps = nullptr);
140 void processStep2(mlir::Operation *op, bool isLoop);
141
142 void pushLoopIV(mlir::Value iv) { loopIVs.push_back(iv); }
143
144 const llvm::SetVector<const semantics::Symbol *> &
145 getAllSymbolsToPrivatize() const {
146 return allPrivatizedSymbols;
147 }
148
149 llvm::ArrayRef<const semantics::Symbol *> getDelayedPrivSymbols() const {
150 return useDelayedPrivatization
151 ? allPrivatizedSymbols.getArrayRef()
153 }
154};
155
156} // namespace omp
157} // namespace lower
158} // namespace Fortran
159
160#endif // FORTRAN_LOWER_DATASHARINGPROCESSOR_H
Definition: AbstractConverter.h:82
Definition: SymbolMap.h:146
Definition: DataSharingProcessor.h:33
Definition: semantics.h:67
Definition: symbol.h:712
Definition: FIRBuilder.h:55
Definition: FIRType.h:77
Definition: OpenACC.h:20
Definition: bit-population-count.h:20
Definition: AbstractConverter.h:27
Definition: PFTBuilder.h:216
Definition: parse-tree.h:580
Definition: parse-tree.h:4756