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