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 "flang/Lower/AbstractConverter.h"
16#include "flang/Lower/OpenMP.h"
17#include "flang/Lower/OpenMP/Clauses.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#include <variant>
23
24namespace mlir {
25namespace omp {
26struct PrivateClauseOps;
27} // namespace omp
28} // namespace mlir
29
30namespace Fortran {
31namespace lower {
32namespace omp {
33
34class DataSharingProcessor {
35private:
36 mlir::OpBuilder::InsertPoint lastPrivIP;
38 // Symbols in private, firstprivate, and/or lastprivate clauses.
39 llvm::SetVector<const semantics::Symbol *> explicitlyPrivatizedSymbols;
40 llvm::SetVector<const semantics::Symbol *> defaultSymbols;
41 llvm::SetVector<const semantics::Symbol *> allPrivatizedSymbols;
42 llvm::SetVector<const semantics::Symbol *> conditionalLastPrivatizedSymbols;
43 // When true, conditional-lastprivate list items get an ordinary private copy
44 // (their in-loop working value) plus a separate reduction struct as the
45 // conditional-last accumulator. Used by worksharing loops, where a
46 // nonmonotonic schedule can execute chunks out of order. When false the list
47 // item is bound directly to the reduction struct (used by sections, which are
48 // lexically ordered and never need the private copy).
49 bool conditionalLpUsesPrivateCopy = false;
50
51 lower::AbstractConverter &converter;
53 fir::FirOpBuilder &firOpBuilder;
54 omp::List<omp::Clause> clauses;
56 bool shouldCollectPreDeterminedSymbols;
57 bool useDelayedPrivatization;
58 bool forceHeapAllocationForPrivateDynamicArrays = false;
59 llvm::SmallPtrSet<const semantics::Symbol *, 16> mightHaveReadHostSym;
60 lower::SymMap &symTable;
61 bool isTargetPrivatization;
62 bool isMetadirectiveLoop;
63
64 bool needBarrier();
65 void collectPrivatizedSymbols(
66 std::optional<semantics::Symbol::Flag> flag,
67 const llvm::SetVector<const semantics::Symbol *> &allSymbols,
68 const llvm::SetVector<const semantics::Symbol *> &symbolsInNestedRegions,
69 llvm::SetVector<const semantics::Symbol *> *symbols = nullptr);
70 void
71 collectSymbols(semantics::Symbol::Flag flag,
72 llvm::SetVector<const semantics::Symbol *> *symbols = nullptr);
73 void collectSymbolsInNestedRegions(
74 lower::pft::Evaluation &eval, semantics::Symbol::Flag flag,
75 llvm::SetVector<const semantics::Symbol *> &symbolsInNestedRegions);
76 void collectOmpObjectListSymbol(
77 const omp::ObjectList &objects,
78 llvm::SetVector<const semantics::Symbol *> &symbolSet);
79 void collectSymbolsForPrivatization();
80 void insertBarrier(mlir::omp::PrivateClauseOps *clauseOps);
81 void collectDefaultSymbols();
82 void collectImplicitSymbols();
83 void collectPreDeterminedSymbols();
84 void collectIndirectReferences();
85 void privatize(mlir::omp::PrivateClauseOps *clauseOps,
86 std::optional<llvm::omp::Directive> dir = std::nullopt);
87 void copyLastPrivatize(mlir::Operation *op);
88 void insertLastPrivateCompare(mlir::Operation *op);
89 void cloneSymbol(const semantics::Symbol *sym);
90 void
91 copyFirstPrivateSymbol(const semantics::Symbol *sym,
92 mlir::OpBuilder::InsertPoint *copyAssignIP = nullptr);
93 void copyLastPrivateSymbol(const semantics::Symbol *sym,
94 mlir::OpBuilder::InsertPoint *lastPrivIP);
95 void insertDeallocs();
96
97 static bool isOpenMPPrivatizingConstruct(const parser::OpenMPConstruct &omp,
98 llvm::omp::Version version);
99 bool isOpenMPPrivatizingEvaluation(const pft::Evaluation &eval) const;
100
101public:
102 DataSharingProcessor(
104 const List<Clause> &clauses, lower::pft::Evaluation &eval,
105 bool shouldCollectPreDeterminedSymbols, bool useDelayedPrivatization,
106 lower::SymMap &symTable, bool isTargetPrivatization = false,
107 llvm::ArrayRef<const semantics::Symbol *> metadirectiveLoopIVs = {});
108
109 DataSharingProcessor(lower::AbstractConverter &converter,
112 bool useDelayedPrivatization, lower::SymMap &symTable,
113 bool isTargetPrivatization = false);
114
115 // Privatisation is split into two steps.
116 // Step1 performs cloning of all privatisation clauses and copying for
117 // firstprivates. Step1 is performed at the place where process/processStep1
118 // is called. This is usually inside the Operation corresponding to the OpenMP
119 // construct, for looping constructs this is just before the Operation. The
120 // split into two steps was performed basically to be able to call
121 // privatisation for looping constructs before the operation is created since
122 // the bounds of the MLIR OpenMP operation can be privatised.
123 // Step2 performs the copying for lastprivates and requires knowledge of the
124 // MLIR operation to insert the last private update. Step2 adds
125 // dealocation code as well.
126 void processStep1(mlir::omp::PrivateClauseOps *clauseOps = nullptr,
127 std::optional<llvm::omp::Directive> dir = std::nullopt);
128 void processStep2(mlir::Operation *op, bool isLoop);
129
130 void pushLoopIV(mlir::Value iv) { loopIVs.push_back(iv); }
131
132 void setForceHeapAllocationForPrivateDynamicArrays(bool value = true) {
133 forceHeapAllocationForPrivateDynamicArrays = value;
134 }
135
136 const llvm::SetVector<const semantics::Symbol *> &
137 getAllSymbolsToPrivatize() const {
138 return allPrivatizedSymbols;
139 }
140
141 llvm::ArrayRef<const semantics::Symbol *> getDelayedPrivSymbols() const {
142 return useDelayedPrivatization
143 ? allPrivatizedSymbols.getArrayRef()
145 }
146
147 void privatizeSymbol(const semantics::Symbol *symToPrivatize,
148 mlir::omp::PrivateClauseOps *clauseOps,
149 std::optional<llvm::omp::Directive> dir = std::nullopt,
150 bool isLinear = false);
151
152 bool usesDelayedPrivatization() const { return useDelayedPrivatization; }
153
154 const llvm::SetVector<const semantics::Symbol *> &
155 getConditionalLastprivateSymbols() const {
156 return conditionalLastPrivatizedSymbols;
157 }
158
159 void setConditionalLpUsesPrivateCopy(bool v) {
160 conditionalLpUsesPrivateCopy = v;
161 }
162};
163
164} // namespace omp
165} // namespace lower
166} // namespace Fortran
167
168#endif // FORTRAN_LOWER_DATASHARINGPROCESSOR_H
Definition AbstractConverter.h:87
Definition SymbolMap.h:181
Definition semantics.h:71
Definition symbol.h:916
Definition FIRBuilder.h:66
Definition FIRType.h:106
Definition OpenACC.h:20
Definition ParserActions.h:24
Definition bit-population-count.h:20
Definition AbstractConverter.h:32
Definition PFTBuilder.h:222
Definition parse-tree.h:5681