@@ -29,9 +29,10 @@ void DataSharingProcessor::processStep1(
2929 collectSymbolsForPrivatization ();
3030 collectDefaultSymbols ();
3131 collectImplicitSymbols ();
32+ collectPreDeterminedSymbols ();
33+
3234 privatize (clauseOps, privateSyms);
33- defaultPrivatize (clauseOps, privateSyms);
34- implicitPrivatize (clauseOps, privateSyms);
35+
3536 insertBarrier ();
3637}
3738
@@ -57,7 +58,7 @@ void DataSharingProcessor::processStep2(mlir::Operation *op, bool isLoop) {
5758}
5859
5960void DataSharingProcessor::insertDeallocs () {
60- for (const semantics::Symbol *sym : privatizedSymbols )
61+ for (const semantics::Symbol *sym : allPrivatizedSymbols )
6162 if (semantics::IsAllocatable (sym->GetUltimate ())) {
6263 if (!useDelayedPrivatization) {
6364 converter.createHostAssociateVarCloneDealloc (*sym);
@@ -92,10 +93,6 @@ void DataSharingProcessor::insertDeallocs() {
9293}
9394
9495void DataSharingProcessor::cloneSymbol (const semantics::Symbol *sym) {
95- // Privatization for symbols which are pre-determined (like loop index
96- // variables) happen separately, for everything else privatize here.
97- if (sym->test (semantics::Symbol::Flag::OmpPreDetermined))
98- return ;
9996 bool success = converter.createHostAssociateVarClone (*sym);
10097 (void )success;
10198 assert (success && " Privatization failed due to existing binding" );
@@ -126,20 +123,24 @@ void DataSharingProcessor::collectSymbolsForPrivatization() {
126123 for (const omp::Clause &clause : clauses) {
127124 if (const auto &privateClause =
128125 std::get_if<omp::clause::Private>(&clause.u )) {
129- collectOmpObjectListSymbol (privateClause->v , privatizedSymbols );
126+ collectOmpObjectListSymbol (privateClause->v , explicitlyPrivatizedSymbols );
130127 } else if (const auto &firstPrivateClause =
131128 std::get_if<omp::clause::Firstprivate>(&clause.u )) {
132- collectOmpObjectListSymbol (firstPrivateClause->v , privatizedSymbols);
129+ collectOmpObjectListSymbol (firstPrivateClause->v ,
130+ explicitlyPrivatizedSymbols);
133131 } else if (const auto &lastPrivateClause =
134132 std::get_if<omp::clause::Lastprivate>(&clause.u )) {
135133 const ObjectList &objects = std::get<ObjectList>(lastPrivateClause->t );
136- collectOmpObjectListSymbol (objects, privatizedSymbols );
134+ collectOmpObjectListSymbol (objects, explicitlyPrivatizedSymbols );
137135 hasLastPrivateOp = true ;
138136 } else if (std::get_if<omp::clause::Collapse>(&clause.u )) {
139137 hasCollapse = true ;
140138 }
141139 }
142140
141+ for (auto *sym : explicitlyPrivatizedSymbols)
142+ allPrivatizedSymbols.insert (sym);
143+
143144 if (hasCollapse && hasLastPrivateOp)
144145 TODO (converter.getCurrentLocation (), " Collapse clause with lastprivate" );
145146}
@@ -149,7 +150,7 @@ bool DataSharingProcessor::needBarrier() {
149150 // initialization of firstprivate variables and post-update of lastprivate
150151 // variables.
151152 // Emit implicit barrier for linear clause. Maybe on somewhere else.
152- for (const semantics::Symbol *sym : privatizedSymbols ) {
153+ for (const semantics::Symbol *sym : allPrivatizedSymbols ) {
153154 if (sym->test (semantics::Symbol::Flag::OmpFirstPrivate) &&
154155 sym->test (semantics::Symbol::Flag::OmpLastPrivate))
155156 return true ;
@@ -283,10 +284,40 @@ void DataSharingProcessor::collectSymbolsInNestedRegions(
283284 if (nestedEval.isConstruct ())
284285 // Recursively look for OpenMP constructs within `nestedEval`'s region
285286 collectSymbolsInNestedRegions (nestedEval, flag, symbolsInNestedRegions);
286- else
287- converter.collectSymbolSet (nestedEval, symbolsInNestedRegions, flag,
288- /* collectSymbols=*/ true ,
289- /* collectHostAssociatedSymbols=*/ false );
287+ else {
288+ bool isOrderedConstruct = [&]() {
289+ if (auto *ompConstruct =
290+ nestedEval.getIf <parser::OpenMPConstruct>()) {
291+ if (auto *ompBlockConstruct =
292+ std::get_if<parser::OpenMPBlockConstruct>(
293+ &ompConstruct->u )) {
294+ const auto &beginBlockDirective =
295+ std::get<parser::OmpBeginBlockDirective>(
296+ ompBlockConstruct->t );
297+ const auto origDirective =
298+ std::get<parser::OmpBlockDirective>(beginBlockDirective.t ).v ;
299+
300+ return origDirective == llvm::omp::Directive::OMPD_ordered;
301+ }
302+ }
303+
304+ return false ;
305+ }();
306+
307+ bool isCriticalConstruct = [&]() {
308+ if (auto *ompConstruct =
309+ nestedEval.getIf <parser::OpenMPConstruct>()) {
310+ return std::get_if<parser::OpenMPCriticalConstruct>(
311+ &ompConstruct->u ) != nullptr ;
312+ }
313+ return false ;
314+ }();
315+
316+ if (!isOrderedConstruct && !isCriticalConstruct)
317+ converter.collectSymbolSet (nestedEval, symbolsInNestedRegions, flag,
318+ /* collectSymbols=*/ true ,
319+ /* collectHostAssociatedSymbols=*/ false );
320+ }
290321 }
291322 }
292323}
@@ -322,24 +353,39 @@ void DataSharingProcessor::collectSymbols(
322353 converter.collectSymbolSet (eval, allSymbols, flag,
323354 /* collectSymbols=*/ true ,
324355 /* collectHostAssociatedSymbols=*/ true );
356+
325357 llvm::SetVector<const semantics::Symbol *> symbolsInNestedRegions;
326358 collectSymbolsInNestedRegions (eval, flag, symbolsInNestedRegions);
327359 // Filter-out symbols that must not be privatized.
328360 bool collectImplicit = flag == semantics::Symbol::Flag::OmpImplicit;
361+ bool collectPreDetermined = flag == semantics::Symbol::Flag::OmpPreDetermined;
362+
329363 auto isPrivatizable = [](const semantics::Symbol &sym) -> bool {
330364 return !semantics::IsProcedure (sym) &&
331365 !sym.GetUltimate ().has <semantics::DerivedTypeDetails>() &&
332366 !sym.GetUltimate ().has <semantics::NamelistDetails>() &&
333367 !semantics::IsImpliedDoIndex (sym.GetUltimate ());
334368 };
369+
370+ auto shouldCollectSymbol = [&](const semantics::Symbol *sym) {
371+ if (collectImplicit)
372+ return sym->test (semantics::Symbol::Flag::OmpImplicit);
373+
374+ if (collectPreDetermined)
375+ return sym->test (semantics::Symbol::Flag::OmpPreDetermined);
376+
377+ return !sym->test (semantics::Symbol::Flag::OmpImplicit) &&
378+ !sym->test (semantics::Symbol::Flag::OmpPreDetermined);
379+ };
380+
335381 for (const auto *sym : allSymbols) {
336382 assert (curScope && " couldn't find current scope" );
337383 if (isPrivatizable (*sym) && !symbolsInNestedRegions.contains (sym) &&
338- !privatizedSymbols.contains (sym) &&
339- !sym->test (semantics::Symbol::Flag::OmpPreDetermined) &&
340- (collectImplicit || !sym->test (semantics::Symbol::Flag::OmpImplicit)) &&
341- clauseScopes.contains (&sym->owner ()))
384+ !explicitlyPrivatizedSymbols.contains (sym) &&
385+ shouldCollectSymbol (sym) && clauseScopes.contains (&sym->owner ())) {
386+ allPrivatizedSymbols.insert (sym);
342387 symbols.insert (sym);
388+ }
343389 }
344390}
345391
@@ -363,10 +409,16 @@ void DataSharingProcessor::collectImplicitSymbols() {
363409 collectSymbols (semantics::Symbol::Flag::OmpImplicit, implicitSymbols);
364410}
365411
412+ void DataSharingProcessor::collectPreDeterminedSymbols () {
413+ if (shouldCollectPreDeterminedSymbols)
414+ collectSymbols (semantics::Symbol::Flag::OmpPreDetermined,
415+ preDeterminedSymbols);
416+ }
417+
366418void DataSharingProcessor::privatize (
367419 mlir::omp::PrivateClauseOps *clauseOps,
368420 llvm::SmallVectorImpl<const semantics::Symbol *> *privateSyms) {
369- for (const semantics::Symbol *sym : privatizedSymbols ) {
421+ for (const semantics::Symbol *sym : allPrivatizedSymbols ) {
370422 if (const auto *commonDet =
371423 sym->detailsIf <semantics::CommonBlockDetails>()) {
372424 for (const auto &mem : commonDet->objects ())
@@ -378,7 +430,7 @@ void DataSharingProcessor::privatize(
378430
379431void DataSharingProcessor::copyLastPrivatize (mlir::Operation *op) {
380432 insertLastPrivateCompare (op);
381- for (const semantics::Symbol *sym : privatizedSymbols )
433+ for (const semantics::Symbol *sym : allPrivatizedSymbols )
382434 if (const auto *commonDet =
383435 sym->detailsIf <semantics::CommonBlockDetails>()) {
384436 for (const auto &mem : commonDet->objects ()) {
@@ -389,20 +441,6 @@ void DataSharingProcessor::copyLastPrivatize(mlir::Operation *op) {
389441 }
390442}
391443
392- void DataSharingProcessor::defaultPrivatize (
393- mlir::omp::PrivateClauseOps *clauseOps,
394- llvm::SmallVectorImpl<const semantics::Symbol *> *privateSyms) {
395- for (const semantics::Symbol *sym : defaultSymbols)
396- doPrivatize (sym, clauseOps, privateSyms);
397- }
398-
399- void DataSharingProcessor::implicitPrivatize (
400- mlir::omp::PrivateClauseOps *clauseOps,
401- llvm::SmallVectorImpl<const semantics::Symbol *> *privateSyms) {
402- for (const semantics::Symbol *sym : implicitSymbols)
403- doPrivatize (sym, clauseOps, privateSyms);
404- }
405-
406444void DataSharingProcessor::doPrivatize (
407445 const semantics::Symbol *sym, mlir::omp::PrivateClauseOps *clauseOps,
408446 llvm::SmallVectorImpl<const semantics::Symbol *> *privateSyms) {
0 commit comments