@@ -81,30 +81,26 @@ void DataSharingProcessor::copyLastPrivateSymbol(
81
81
}
82
82
83
83
void DataSharingProcessor::collectOmpObjectListSymbol (
84
- const Fortran::parser::OmpObjectList &ompObjectList ,
84
+ const omp::ObjectList &objects ,
85
85
llvm::SetVector<const Fortran::semantics::Symbol *> &symbolSet) {
86
- for (const Fortran::parser::OmpObject &ompObject : ompObjectList.v ) {
87
- Fortran::semantics::Symbol *sym = getOmpObjectSymbol (ompObject);
88
- symbolSet.insert (sym);
89
- }
86
+ for (const omp::Object &object : objects)
87
+ symbolSet.insert (object.id ());
90
88
}
91
89
92
90
void DataSharingProcessor::collectSymbolsForPrivatization () {
93
91
bool hasCollapse = false ;
94
- for (const Fortran::parser::OmpClause &clause : opClauseList. v ) {
92
+ for (const omp::Clause &clause : clauses ) {
95
93
if (const auto &privateClause =
96
- std::get_if<Fortran::parser::OmpClause ::Private>(&clause.u )) {
94
+ std::get_if<omp::clause ::Private>(&clause.u )) {
97
95
collectOmpObjectListSymbol (privateClause->v , privatizedSymbols);
98
96
} else if (const auto &firstPrivateClause =
99
- std::get_if<Fortran::parser::OmpClause::Firstprivate>(
100
- &clause.u )) {
97
+ std::get_if<omp::clause::Firstprivate>(&clause.u )) {
101
98
collectOmpObjectListSymbol (firstPrivateClause->v , privatizedSymbols);
102
99
} else if (const auto &lastPrivateClause =
103
- std::get_if<Fortran::parser::OmpClause::Lastprivate>(
104
- &clause.u )) {
100
+ std::get_if<omp::clause::Lastprivate>(&clause.u )) {
105
101
collectOmpObjectListSymbol (lastPrivateClause->v , privatizedSymbols);
106
102
hasLastPrivateOp = true ;
107
- } else if (std::get_if<Fortran::parser::OmpClause ::Collapse>(&clause.u )) {
103
+ } else if (std::get_if<omp::clause ::Collapse>(&clause.u )) {
108
104
hasCollapse = true ;
109
105
}
110
106
}
@@ -137,138 +133,135 @@ void DataSharingProcessor::insertBarrier() {
137
133
void DataSharingProcessor::insertLastPrivateCompare (mlir::Operation *op) {
138
134
bool cmpCreated = false ;
139
135
mlir::OpBuilder::InsertPoint localInsPt = firOpBuilder.saveInsertionPoint ();
140
- for (const Fortran::parser::OmpClause &clause : opClauseList.v ) {
141
- if (std::get_if<Fortran::parser::OmpClause::Lastprivate>(&clause.u )) {
142
- // TODO: Add lastprivate support for simd construct
143
- if (mlir::isa<mlir::omp::SectionOp>(op)) {
144
- if (&eval == &eval.parentConstruct ->getLastNestedEvaluation ()) {
145
- // For `omp.sections`, lastprivatized variables occur in
146
- // lexically final `omp.section` operation. The following FIR
147
- // shall be generated for the same:
148
- //
149
- // omp.sections lastprivate(...) {
150
- // omp.section {...}
151
- // omp.section {...}
152
- // omp.section {
153
- // fir.allocate for `private`/`firstprivate`
154
- // <More operations here>
155
- // fir.if %true {
156
- // ^%lpv_update_blk
157
- // }
158
- // }
159
- // }
160
- //
161
- // To keep code consistency while handling privatization
162
- // through this control flow, add a `fir.if` operation
163
- // that always evaluates to true, in order to create
164
- // a dedicated sub-region in `omp.section` where
165
- // lastprivate FIR can reside. Later canonicalizations
166
- // will optimize away this operation.
167
- if (!eval.lowerAsUnstructured ()) {
168
- auto ifOp = firOpBuilder.create <fir::IfOp>(
169
- op->getLoc (),
170
- firOpBuilder.createIntegerConstant (
171
- op->getLoc (), firOpBuilder.getIntegerType (1 ), 0x1 ),
172
- /* else*/ false );
173
- firOpBuilder.setInsertionPointToStart (
174
- &ifOp.getThenRegion ().front ());
175
-
176
- const Fortran::parser::OpenMPConstruct *parentOmpConstruct =
177
- eval.parentConstruct ->getIf <Fortran::parser::OpenMPConstruct>();
178
- assert (parentOmpConstruct &&
179
- " Expected a valid enclosing OpenMP construct" );
180
- const Fortran::parser::OpenMPSectionsConstruct *sectionsConstruct =
181
- std::get_if<Fortran::parser::OpenMPSectionsConstruct>(
182
- &parentOmpConstruct->u );
183
- assert (sectionsConstruct &&
184
- " Expected an enclosing omp.sections construct" );
185
- const Fortran::parser::OmpClauseList §ionsEndClauseList =
186
- std::get<Fortran::parser::OmpClauseList>(
187
- std::get<Fortran::parser::OmpEndSectionsDirective>(
188
- sectionsConstruct->t )
189
- .t );
190
- for (const Fortran::parser::OmpClause &otherClause :
191
- sectionsEndClauseList.v )
192
- if (std::get_if<Fortran::parser::OmpClause::Nowait>(
193
- &otherClause.u ))
194
- // Emit implicit barrier to synchronize threads and avoid data
195
- // races on post-update of lastprivate variables when `nowait`
196
- // clause is present.
197
- firOpBuilder.create <mlir::omp::BarrierOp>(
198
- converter.getCurrentLocation ());
199
- firOpBuilder.setInsertionPointToStart (
200
- &ifOp.getThenRegion ().front ());
201
- lastPrivIP = firOpBuilder.saveInsertionPoint ();
202
- firOpBuilder.setInsertionPoint (ifOp);
203
- insPt = firOpBuilder.saveInsertionPoint ();
204
- } else {
205
- // Lastprivate operation is inserted at the end
206
- // of the lexically last section in the sections
207
- // construct
208
- mlir::OpBuilder::InsertPoint unstructuredSectionsIP =
209
- firOpBuilder.saveInsertionPoint ();
210
- mlir::Operation *lastOper = op->getRegion (0 ).back ().getTerminator ();
211
- firOpBuilder.setInsertionPoint (lastOper);
212
- lastPrivIP = firOpBuilder.saveInsertionPoint ();
213
- firOpBuilder.restoreInsertionPoint (unstructuredSectionsIP);
214
- }
215
- }
216
- } else if (mlir::isa<mlir::omp::WsLoopOp>(op)) {
217
- // Update the original variable just before exiting the worksharing
218
- // loop. Conversion as follows:
136
+ for (const omp::Clause &clause : clauses) {
137
+ if (clause.id != llvm::omp::OMPC_lastprivate)
138
+ continue ;
139
+ // TODO: Add lastprivate support for simd construct
140
+ if (mlir::isa<mlir::omp::SectionOp>(op)) {
141
+ if (&eval == &eval.parentConstruct ->getLastNestedEvaluation ()) {
142
+ // For `omp.sections`, lastprivatized variables occur in
143
+ // lexically final `omp.section` operation. The following FIR
144
+ // shall be generated for the same:
219
145
//
220
- // omp.wsloop {
221
- // omp.wsloop { ...
222
- // ... store
223
- // store ===> %v = arith.addi %iv, %step
224
- // omp.yield %cmp = %step < 0 ? %v < %ub : %v > %ub
225
- // } fir.if %cmp {
226
- // fir.store %v to %loopIV
227
- // ^%lpv_update_blk:
228
- // }
229
- // omp.yield
230
- // }
146
+ // omp.sections lastprivate(...) {
147
+ // omp.section { ...}
148
+ // omp.section { ...}
149
+ // omp.section {
150
+ // fir.allocate for `private`/`firstprivate`
151
+ // <More operations here>
152
+ // fir.if %true {
153
+ // ^%lpv_update_blk
154
+ // }
155
+ // }
156
+ // }
231
157
//
232
-
233
- // Only generate the compare once in presence of multiple LastPrivate
234
- // clauses.
235
- if (cmpCreated)
236
- continue ;
237
- cmpCreated = true ;
238
-
239
- mlir::Location loc = op->getLoc ();
240
- mlir::Operation *lastOper = op->getRegion (0 ).back ().getTerminator ();
241
- firOpBuilder.setInsertionPoint (lastOper);
242
-
243
- mlir::Value iv = op->getRegion (0 ).front ().getArguments ()[0 ];
244
- mlir::Value ub =
245
- mlir::dyn_cast<mlir::omp::WsLoopOp>(op).getUpperBound ()[0 ];
246
- mlir::Value step = mlir::dyn_cast<mlir::omp::WsLoopOp>(op).getStep ()[0 ];
247
-
248
- // v = iv + step
249
- // cmp = step < 0 ? v < ub : v > ub
250
- mlir::Value v = firOpBuilder.create <mlir::arith::AddIOp>(loc, iv, step);
251
- mlir::Value zero =
252
- firOpBuilder.createIntegerConstant (loc, step.getType (), 0 );
253
- mlir::Value negativeStep = firOpBuilder.create <mlir::arith::CmpIOp>(
254
- loc, mlir::arith::CmpIPredicate::slt, step, zero);
255
- mlir::Value vLT = firOpBuilder.create <mlir::arith::CmpIOp>(
256
- loc, mlir::arith::CmpIPredicate::slt, v, ub);
257
- mlir::Value vGT = firOpBuilder.create <mlir::arith::CmpIOp>(
258
- loc, mlir::arith::CmpIPredicate::sgt, v, ub);
259
- mlir::Value cmpOp = firOpBuilder.create <mlir::arith::SelectOp>(
260
- loc, negativeStep, vLT, vGT);
261
-
262
- auto ifOp = firOpBuilder.create <fir::IfOp>(loc, cmpOp, /* else*/ false );
263
- firOpBuilder.setInsertionPointToStart (&ifOp.getThenRegion ().front ());
264
- assert (loopIV && " loopIV was not set" );
265
- firOpBuilder.create <fir::StoreOp>(op->getLoc (), v, loopIV);
266
- lastPrivIP = firOpBuilder.saveInsertionPoint ();
267
- } else {
268
- TODO (converter.getCurrentLocation (),
269
- " lastprivate clause in constructs other than "
270
- " simd/worksharing-loop" );
158
+ // To keep code consistency while handling privatization
159
+ // through this control flow, add a `fir.if` operation
160
+ // that always evaluates to true, in order to create
161
+ // a dedicated sub-region in `omp.section` where
162
+ // lastprivate FIR can reside. Later canonicalizations
163
+ // will optimize away this operation.
164
+ if (!eval.lowerAsUnstructured ()) {
165
+ auto ifOp = firOpBuilder.create <fir::IfOp>(
166
+ op->getLoc (),
167
+ firOpBuilder.createIntegerConstant (
168
+ op->getLoc (), firOpBuilder.getIntegerType (1 ), 0x1 ),
169
+ /* else*/ false );
170
+ firOpBuilder.setInsertionPointToStart (&ifOp.getThenRegion ().front ());
171
+
172
+ const Fortran::parser::OpenMPConstruct *parentOmpConstruct =
173
+ eval.parentConstruct ->getIf <Fortran::parser::OpenMPConstruct>();
174
+ assert (parentOmpConstruct &&
175
+ " Expected a valid enclosing OpenMP construct" );
176
+ const Fortran::parser::OpenMPSectionsConstruct *sectionsConstruct =
177
+ std::get_if<Fortran::parser::OpenMPSectionsConstruct>(
178
+ &parentOmpConstruct->u );
179
+ assert (sectionsConstruct &&
180
+ " Expected an enclosing omp.sections construct" );
181
+ const Fortran::parser::OmpClauseList §ionsEndClauseList =
182
+ std::get<Fortran::parser::OmpClauseList>(
183
+ std::get<Fortran::parser::OmpEndSectionsDirective>(
184
+ sectionsConstruct->t )
185
+ .t );
186
+ for (const Fortran::parser::OmpClause &otherClause :
187
+ sectionsEndClauseList.v )
188
+ if (std::get_if<Fortran::parser::OmpClause::Nowait>(&otherClause.u ))
189
+ // Emit implicit barrier to synchronize threads and avoid data
190
+ // races on post-update of lastprivate variables when `nowait`
191
+ // clause is present.
192
+ firOpBuilder.create <mlir::omp::BarrierOp>(
193
+ converter.getCurrentLocation ());
194
+ firOpBuilder.setInsertionPointToStart (&ifOp.getThenRegion ().front ());
195
+ lastPrivIP = firOpBuilder.saveInsertionPoint ();
196
+ firOpBuilder.setInsertionPoint (ifOp);
197
+ insPt = firOpBuilder.saveInsertionPoint ();
198
+ } else {
199
+ // Lastprivate operation is inserted at the end
200
+ // of the lexically last section in the sections
201
+ // construct
202
+ mlir::OpBuilder::InsertPoint unstructuredSectionsIP =
203
+ firOpBuilder.saveInsertionPoint ();
204
+ mlir::Operation *lastOper = op->getRegion (0 ).back ().getTerminator ();
205
+ firOpBuilder.setInsertionPoint (lastOper);
206
+ lastPrivIP = firOpBuilder.saveInsertionPoint ();
207
+ firOpBuilder.restoreInsertionPoint (unstructuredSectionsIP);
208
+ }
271
209
}
210
+ } else if (mlir::isa<mlir::omp::WsLoopOp>(op)) {
211
+ // Update the original variable just before exiting the worksharing
212
+ // loop. Conversion as follows:
213
+ //
214
+ // omp.wsloop {
215
+ // omp.wsloop { ...
216
+ // ... store
217
+ // store ===> %v = arith.addi %iv, %step
218
+ // omp.yield %cmp = %step < 0 ? %v < %ub : %v > %ub
219
+ // } fir.if %cmp {
220
+ // fir.store %v to %loopIV
221
+ // ^%lpv_update_blk:
222
+ // }
223
+ // omp.yield
224
+ // }
225
+ //
226
+
227
+ // Only generate the compare once in presence of multiple LastPrivate
228
+ // clauses.
229
+ if (cmpCreated)
230
+ continue ;
231
+ cmpCreated = true ;
232
+
233
+ mlir::Location loc = op->getLoc ();
234
+ mlir::Operation *lastOper = op->getRegion (0 ).back ().getTerminator ();
235
+ firOpBuilder.setInsertionPoint (lastOper);
236
+
237
+ mlir::Value iv = op->getRegion (0 ).front ().getArguments ()[0 ];
238
+ mlir::Value ub =
239
+ mlir::dyn_cast<mlir::omp::WsLoopOp>(op).getUpperBound ()[0 ];
240
+ mlir::Value step = mlir::dyn_cast<mlir::omp::WsLoopOp>(op).getStep ()[0 ];
241
+
242
+ // v = iv + step
243
+ // cmp = step < 0 ? v < ub : v > ub
244
+ mlir::Value v = firOpBuilder.create <mlir::arith::AddIOp>(loc, iv, step);
245
+ mlir::Value zero =
246
+ firOpBuilder.createIntegerConstant (loc, step.getType (), 0 );
247
+ mlir::Value negativeStep = firOpBuilder.create <mlir::arith::CmpIOp>(
248
+ loc, mlir::arith::CmpIPredicate::slt, step, zero);
249
+ mlir::Value vLT = firOpBuilder.create <mlir::arith::CmpIOp>(
250
+ loc, mlir::arith::CmpIPredicate::slt, v, ub);
251
+ mlir::Value vGT = firOpBuilder.create <mlir::arith::CmpIOp>(
252
+ loc, mlir::arith::CmpIPredicate::sgt, v, ub);
253
+ mlir::Value cmpOp = firOpBuilder.create <mlir::arith::SelectOp>(
254
+ loc, negativeStep, vLT, vGT);
255
+
256
+ auto ifOp = firOpBuilder.create <fir::IfOp>(loc, cmpOp, /* else*/ false );
257
+ firOpBuilder.setInsertionPointToStart (&ifOp.getThenRegion ().front ());
258
+ assert (loopIV && " loopIV was not set" );
259
+ firOpBuilder.create <fir::StoreOp>(op->getLoc (), v, loopIV);
260
+ lastPrivIP = firOpBuilder.saveInsertionPoint ();
261
+ } else {
262
+ TODO (converter.getCurrentLocation (),
263
+ " lastprivate clause in constructs other than "
264
+ " simd/worksharing-loop" );
272
265
}
273
266
}
274
267
firOpBuilder.restoreInsertionPoint (localInsPt);
@@ -292,14 +285,12 @@ void DataSharingProcessor::collectSymbols(
292
285
}
293
286
294
287
void DataSharingProcessor::collectDefaultSymbols () {
295
- for (const Fortran::parser::OmpClause &clause : opClauseList.v ) {
296
- if (const auto &defaultClause =
297
- std::get_if<Fortran::parser::OmpClause::Default>(&clause.u )) {
298
- if (defaultClause->v .v ==
299
- Fortran::parser::OmpDefaultClause::Type::Private)
288
+ for (const omp::Clause &clause : clauses) {
289
+ if (const auto *defaultClause =
290
+ std::get_if<omp::clause::Default>(&clause.u )) {
291
+ if (defaultClause->v == omp::clause::Default::Type::Private)
300
292
collectSymbols (Fortran::semantics::Symbol::Flag::OmpPrivate);
301
- else if (defaultClause->v .v ==
302
- Fortran::parser::OmpDefaultClause::Type::Firstprivate)
293
+ else if (defaultClause->v == omp::clause::Default::Type::Firstprivate)
303
294
collectSymbols (Fortran::semantics::Symbol::Flag::OmpFirstPrivate);
304
295
}
305
296
}
0 commit comments