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 | |
22 | namespace mlir { |
23 | namespace omp { |
24 | struct PrivateClauseOps; |
25 | } // namespace omp |
26 | } // namespace mlir |
27 | |
28 | namespace Fortran { |
29 | namespace lower { |
30 | namespace omp { |
31 | |
32 | class DataSharingProcessor { |
33 | private: |
34 | bool hasLastPrivateOp; |
35 | mlir::OpBuilder::InsertPoint lastPrivIP; |
36 | mlir::OpBuilder::InsertPoint insPt; |
37 | mlir::Value loopIV; |
38 | // Symbols in private, firstprivate, and/or lastprivate clauses. |
39 | llvm::SetVector<const Fortran::semantics::Symbol *> privatizedSymbols; |
40 | llvm::SetVector<const Fortran::semantics::Symbol *> defaultSymbols; |
41 | llvm::SetVector<const Fortran::semantics::Symbol *> symbolsInNestedRegions; |
42 | llvm::SetVector<const Fortran::semantics::Symbol *> symbolsInParentRegions; |
43 | Fortran::lower::AbstractConverter &converter; |
44 | fir::FirOpBuilder &firOpBuilder; |
45 | omp::List<omp::Clause> clauses; |
46 | Fortran::lower::pft::Evaluation &eval; |
47 | bool useDelayedPrivatization; |
48 | Fortran::lower::SymMap *symTable; |
49 | |
50 | bool needBarrier(); |
51 | void collectSymbols(Fortran::semantics::Symbol::Flag flag); |
52 | void collectOmpObjectListSymbol( |
53 | const omp::ObjectList &objects, |
54 | llvm::SetVector<const Fortran::semantics::Symbol *> &symbolSet); |
55 | void collectSymbolsForPrivatization(); |
56 | void insertBarrier(); |
57 | void collectDefaultSymbols(); |
58 | void privatize( |
59 | mlir::omp::PrivateClauseOps *clauseOps, |
60 | llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> *privateSyms); |
61 | void defaultPrivatize( |
62 | mlir::omp::PrivateClauseOps *clauseOps, |
63 | llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> *privateSyms); |
64 | void doPrivatize( |
65 | const Fortran::semantics::Symbol *sym, |
66 | mlir::omp::PrivateClauseOps *clauseOps, |
67 | llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> *privateSyms); |
68 | void copyLastPrivatize(mlir::Operation *op); |
69 | void insertLastPrivateCompare(mlir::Operation *op); |
70 | void cloneSymbol(const Fortran::semantics::Symbol *sym); |
71 | void |
72 | copyFirstPrivateSymbol(const Fortran::semantics::Symbol *sym, |
73 | mlir::OpBuilder::InsertPoint *copyAssignIP = nullptr); |
74 | void copyLastPrivateSymbol(const Fortran::semantics::Symbol *sym, |
75 | mlir::OpBuilder::InsertPoint *lastPrivIP); |
76 | void insertDeallocs(); |
77 | |
78 | public: |
79 | DataSharingProcessor(Fortran::lower::AbstractConverter &converter, |
80 | Fortran::semantics::SemanticsContext &semaCtx, |
81 | const List<Clause> &clauses, |
82 | Fortran::lower::pft::Evaluation &eval, |
83 | bool useDelayedPrivatization = false, |
84 | Fortran::lower::SymMap *symTable = nullptr) |
85 | : hasLastPrivateOp(false), converter(converter), |
86 | firOpBuilder(converter.getFirOpBuilder()), clauses(clauses), eval(eval), |
87 | useDelayedPrivatization(useDelayedPrivatization), symTable(symTable) {} |
88 | |
89 | // Privatisation is split into two steps. |
90 | // Step1 performs cloning of all privatisation clauses and copying for |
91 | // firstprivates. Step1 is performed at the place where process/processStep1 |
92 | // is called. This is usually inside the Operation corresponding to the OpenMP |
93 | // construct, for looping constructs this is just before the Operation. The |
94 | // split into two steps was performed basically to be able to call |
95 | // privatisation for looping constructs before the operation is created since |
96 | // the bounds of the MLIR OpenMP operation can be privatised. |
97 | // Step2 performs the copying for lastprivates and requires knowledge of the |
98 | // MLIR operation to insert the last private update. Step2 adds |
99 | // dealocation code as well. |
100 | void processStep1(mlir::omp::PrivateClauseOps *clauseOps = nullptr, |
101 | llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> |
102 | *privateSyms = nullptr); |
103 | void processStep2(mlir::Operation *op, bool isLoop); |
104 | |
105 | void setLoopIV(mlir::Value iv) { |
106 | assert(!loopIV && "Loop iteration variable already set" ); |
107 | loopIV = iv; |
108 | } |
109 | }; |
110 | |
111 | } // namespace omp |
112 | } // namespace lower |
113 | } // namespace Fortran |
114 | |
115 | #endif // FORTRAN_LOWER_DATASHARINGPROCESSOR_H |
116 | |