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