@@ -27,8 +27,10 @@ void DataSharingProcessor::processStep1(
27
27
llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> *privateSyms) {
28
28
collectSymbolsForPrivatization ();
29
29
collectDefaultSymbols ();
30
+ collectImplicitSymbols ();
30
31
privatize (clauseOps, privateSyms);
31
32
defaultPrivatize (clauseOps, privateSyms);
33
+ implicitPrivatize (clauseOps, privateSyms);
32
34
insertBarrier ();
33
35
}
34
36
@@ -302,6 +304,48 @@ void DataSharingProcessor::insertLastPrivateCompare(mlir::Operation *op) {
302
304
}
303
305
}
304
306
307
+ static const Fortran::parser::CharBlock *
308
+ getSource (const Fortran::semantics::SemanticsContext &semaCtx,
309
+ const Fortran::lower::pft::Evaluation &eval) {
310
+ const Fortran::parser::CharBlock *source = nullptr ;
311
+
312
+ auto ompConsVisit = [&](const Fortran::parser::OpenMPConstruct &x) {
313
+ std::visit (Fortran::common::visitors{
314
+ [&](const Fortran::parser::OpenMPSectionsConstruct &x) {
315
+ source = &std::get<0 >(x.t ).source ;
316
+ },
317
+ [&](const Fortran::parser::OpenMPLoopConstruct &x) {
318
+ source = &std::get<0 >(x.t ).source ;
319
+ },
320
+ [&](const Fortran::parser::OpenMPBlockConstruct &x) {
321
+ source = &std::get<0 >(x.t ).source ;
322
+ },
323
+ [&](const Fortran::parser::OpenMPCriticalConstruct &x) {
324
+ source = &std::get<0 >(x.t ).source ;
325
+ },
326
+ [&](const Fortran::parser::OpenMPAtomicConstruct &x) {
327
+ std::visit ([&](const auto &x) { source = &x.source ; },
328
+ x.u );
329
+ },
330
+ [&](const auto &x) { source = &x.source ; },
331
+ },
332
+ x.u );
333
+ };
334
+
335
+ eval.visit (Fortran::common::visitors{
336
+ [&](const Fortran::parser::OpenMPConstruct &x) { ompConsVisit (x); },
337
+ [&](const Fortran::parser::OpenMPDeclarativeConstruct &x) {
338
+ source = &x.source ;
339
+ },
340
+ [&](const Fortran::parser::OmpEndLoopDirective &x) {
341
+ source = &x.source ;
342
+ },
343
+ [&](const auto &x) {},
344
+ });
345
+
346
+ return source;
347
+ }
348
+
305
349
void DataSharingProcessor::collectSymbolsInNestedRegions (
306
350
Fortran::lower::pft::Evaluation &eval,
307
351
Fortran::semantics::Symbol::Flag flag,
@@ -329,11 +373,49 @@ void DataSharingProcessor::collectSymbolsInNestedRegions(
329
373
// Later, in current context, all symbols in the set
330
374
// `defaultSymbols` - `symbolsInNestedRegions` will be privatized.
331
375
void DataSharingProcessor::collectSymbols (
332
- Fortran::semantics::Symbol::Flag flag) {
333
- converter.collectSymbolSet (eval, defaultSymbols, flag,
376
+ Fortran::semantics::Symbol::Flag flag,
377
+ llvm::SetVector<const Fortran::semantics::Symbol *> &symbols) {
378
+ // Collect all scopes associated with 'eval'.
379
+ llvm::SetVector<const Fortran::semantics::Scope *> clauseScopes;
380
+ std::function<void (const Fortran::semantics::Scope *)> collectScopes =
381
+ [&](const Fortran::semantics::Scope *scope) {
382
+ clauseScopes.insert (scope);
383
+ for (const Fortran::semantics::Scope &child : scope->children ())
384
+ collectScopes (&child);
385
+ };
386
+ const Fortran::parser::CharBlock *source =
387
+ clauses.empty () ? getSource (semaCtx, eval) : &clauses.front ().source ;
388
+ const Fortran::semantics::Scope *curScope = nullptr ;
389
+ if (source && !source->empty ()) {
390
+ curScope = &semaCtx.FindScope (*source);
391
+ collectScopes (curScope);
392
+ }
393
+ // Collect all symbols referenced in the evaluation being processed,
394
+ // that matches 'flag'.
395
+ llvm::SetVector<const Fortran::semantics::Symbol *> allSymbols;
396
+ converter.collectSymbolSet (eval, allSymbols, flag,
334
397
/* collectSymbols=*/ true ,
335
398
/* collectHostAssociatedSymbols=*/ true );
399
+ llvm::SetVector<const Fortran::semantics::Symbol *> symbolsInNestedRegions;
336
400
collectSymbolsInNestedRegions (eval, flag, symbolsInNestedRegions);
401
+ // Filter-out symbols that must not be privatized.
402
+ bool collectImplicit = flag == Fortran::semantics::Symbol::Flag::OmpImplicit;
403
+ auto isPrivatizable = [](const Fortran::semantics::Symbol &sym) -> bool {
404
+ return !Fortran::semantics::IsProcedure (sym) &&
405
+ !sym.GetUltimate ().has <Fortran::semantics::DerivedTypeDetails>() &&
406
+ !sym.GetUltimate ().has <Fortran::semantics::NamelistDetails>() &&
407
+ !Fortran::semantics::IsImpliedDoIndex (sym.GetUltimate ());
408
+ };
409
+ for (const auto *sym : allSymbols) {
410
+ assert (curScope && " couldn't find current scope" );
411
+ if (isPrivatizable (*sym) && !symbolsInNestedRegions.contains (sym) &&
412
+ !privatizedSymbols.contains (sym) &&
413
+ !sym->test (Fortran::semantics::Symbol::Flag::OmpPreDetermined) &&
414
+ (collectImplicit ||
415
+ !sym->test (Fortran::semantics::Symbol::Flag::OmpImplicit)) &&
416
+ clauseScopes.contains (&sym->owner ()))
417
+ symbols.insert (sym);
418
+ }
337
419
}
338
420
339
421
void DataSharingProcessor::collectDefaultSymbols () {
@@ -342,13 +424,22 @@ void DataSharingProcessor::collectDefaultSymbols() {
342
424
if (const auto *defaultClause =
343
425
std::get_if<omp::clause::Default>(&clause.u )) {
344
426
if (defaultClause->v == DataSharingAttribute::Private)
345
- collectSymbols (Fortran::semantics::Symbol::Flag::OmpPrivate);
427
+ collectSymbols (Fortran::semantics::Symbol::Flag::OmpPrivate,
428
+ defaultSymbols);
346
429
else if (defaultClause->v == DataSharingAttribute::Firstprivate)
347
- collectSymbols (Fortran::semantics::Symbol::Flag::OmpFirstPrivate);
430
+ collectSymbols (Fortran::semantics::Symbol::Flag::OmpFirstPrivate,
431
+ defaultSymbols);
348
432
}
349
433
}
350
434
}
351
435
436
+ void DataSharingProcessor::collectImplicitSymbols () {
437
+ // There will be no implicit symbols when a default clause is present.
438
+ if (defaultSymbols.empty ())
439
+ collectSymbols (Fortran::semantics::Symbol::Flag::OmpImplicit,
440
+ implicitSymbols);
441
+ }
442
+
352
443
void DataSharingProcessor::privatize (
353
444
mlir::omp::PrivateClauseOps *clauseOps,
354
445
llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> *privateSyms) {
@@ -378,15 +469,15 @@ void DataSharingProcessor::copyLastPrivatize(mlir::Operation *op) {
378
469
void DataSharingProcessor::defaultPrivatize (
379
470
mlir::omp::PrivateClauseOps *clauseOps,
380
471
llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> *privateSyms) {
381
- for (const Fortran::semantics::Symbol *sym : defaultSymbols) {
382
- if (! Fortran::semantics::IsProcedure (* sym) &&
383
- !sym-> GetUltimate (). has <Fortran::semantics::DerivedTypeDetails>() &&
384
- !sym-> GetUltimate (). has <Fortran::semantics::NamelistDetails>() &&
385
- ! Fortran::semantics::IsImpliedDoIndex (sym-> GetUltimate ()) &&
386
- !symbolsInNestedRegions. contains (sym) &&
387
- !privatizedSymbols. contains (sym))
388
- doPrivatize ( sym, clauseOps, privateSyms);
389
- }
472
+ for (const Fortran::semantics::Symbol *sym : defaultSymbols)
473
+ doPrivatize ( sym, clauseOps, privateSyms);
474
+ }
475
+
476
+ void DataSharingProcessor::implicitPrivatize (
477
+ mlir::omp::PrivateClauseOps *clauseOps,
478
+ llvm::SmallVectorImpl< const Fortran::semantics::Symbol *> *privateSyms) {
479
+ for ( const Fortran::semantics::Symbol * sym : implicitSymbols)
480
+ doPrivatize (sym, clauseOps, privateSyms);
390
481
}
391
482
392
483
void DataSharingProcessor::doPrivatize (
0 commit comments