22
22
namespace Fortran {
23
23
namespace lower {
24
24
namespace omp {
25
+ bool DataSharingProcessor::OMPConstructSymbolVisitor::isSymbolDefineBy (
26
+ const semantics::Symbol *symbol, lower::pft::Evaluation &eval) const {
27
+ return eval.visit (
28
+ common::visitors{[&](const parser::OpenMPConstruct &functionParserNode) {
29
+ return symDefMap.count (symbol) &&
30
+ symDefMap.at (symbol) == &functionParserNode;
31
+ },
32
+ [](const auto &functionParserNode) { return false ; }});
33
+ }
34
+
35
+ DataSharingProcessor::DataSharingProcessor (
36
+ lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx,
37
+ const List<Clause> &clauses, lower::pft::Evaluation &eval,
38
+ bool shouldCollectPreDeterminedSymbols, bool useDelayedPrivatization,
39
+ lower::SymMap *symTable)
40
+ : hasLastPrivateOp(false ), converter(converter), semaCtx(semaCtx),
41
+ firOpBuilder (converter.getFirOpBuilder()), clauses(clauses), eval(eval),
42
+ shouldCollectPreDeterminedSymbols(shouldCollectPreDeterminedSymbols),
43
+ useDelayedPrivatization(useDelayedPrivatization), symTable(symTable),
44
+ visitor() {
45
+ eval.visit ([&](const auto &functionParserNode) {
46
+ parser::Walk (functionParserNode, visitor);
47
+ });
48
+ }
25
49
26
50
void DataSharingProcessor::processStep1 (
27
51
mlir::omp::PrivateClauseOps *clauseOps,
28
52
llvm::SmallVectorImpl<const semantics::Symbol *> *privateSyms) {
29
53
collectSymbolsForPrivatization ();
30
54
collectDefaultSymbols ();
31
55
collectImplicitSymbols ();
56
+ collectPreDeterminedSymbols ();
57
+
32
58
privatize (clauseOps, privateSyms);
33
- defaultPrivatize (clauseOps, privateSyms);
34
- implicitPrivatize (clauseOps, privateSyms);
59
+
35
60
insertBarrier ();
36
61
}
37
62
@@ -57,7 +82,7 @@ void DataSharingProcessor::processStep2(mlir::Operation *op, bool isLoop) {
57
82
}
58
83
59
84
void DataSharingProcessor::insertDeallocs () {
60
- for (const semantics::Symbol *sym : privatizedSymbols )
85
+ for (const semantics::Symbol *sym : allPrivatizedSymbols )
61
86
if (semantics::IsAllocatable (sym->GetUltimate ())) {
62
87
if (!useDelayedPrivatization) {
63
88
converter.createHostAssociateVarCloneDealloc (*sym);
@@ -92,10 +117,6 @@ void DataSharingProcessor::insertDeallocs() {
92
117
}
93
118
94
119
void 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 ;
99
120
bool success = converter.createHostAssociateVarClone (*sym);
100
121
(void )success;
101
122
assert (success && " Privatization failed due to existing binding" );
@@ -126,20 +147,24 @@ void DataSharingProcessor::collectSymbolsForPrivatization() {
126
147
for (const omp::Clause &clause : clauses) {
127
148
if (const auto &privateClause =
128
149
std::get_if<omp::clause::Private>(&clause.u )) {
129
- collectOmpObjectListSymbol (privateClause->v , privatizedSymbols );
150
+ collectOmpObjectListSymbol (privateClause->v , explicitlyPrivatizedSymbols );
130
151
} else if (const auto &firstPrivateClause =
131
152
std::get_if<omp::clause::Firstprivate>(&clause.u )) {
132
- collectOmpObjectListSymbol (firstPrivateClause->v , privatizedSymbols);
153
+ collectOmpObjectListSymbol (firstPrivateClause->v ,
154
+ explicitlyPrivatizedSymbols);
133
155
} else if (const auto &lastPrivateClause =
134
156
std::get_if<omp::clause::Lastprivate>(&clause.u )) {
135
157
const ObjectList &objects = std::get<ObjectList>(lastPrivateClause->t );
136
- collectOmpObjectListSymbol (objects, privatizedSymbols );
158
+ collectOmpObjectListSymbol (objects, explicitlyPrivatizedSymbols );
137
159
hasLastPrivateOp = true ;
138
160
} else if (std::get_if<omp::clause::Collapse>(&clause.u )) {
139
161
hasCollapse = true ;
140
162
}
141
163
}
142
164
165
+ for (auto *sym : explicitlyPrivatizedSymbols)
166
+ allPrivatizedSymbols.insert (sym);
167
+
143
168
if (hasCollapse && hasLastPrivateOp)
144
169
TODO (converter.getCurrentLocation (), " Collapse clause with lastprivate" );
145
170
}
@@ -149,7 +174,7 @@ bool DataSharingProcessor::needBarrier() {
149
174
// initialization of firstprivate variables and post-update of lastprivate
150
175
// variables.
151
176
// Emit implicit barrier for linear clause. Maybe on somewhere else.
152
- for (const semantics::Symbol *sym : privatizedSymbols ) {
177
+ for (const semantics::Symbol *sym : allPrivatizedSymbols ) {
153
178
if (sym->test (semantics::Symbol::Flag::OmpFirstPrivate) &&
154
179
sym->test (semantics::Symbol::Flag::OmpLastPrivate))
155
180
return true ;
@@ -283,10 +308,11 @@ void DataSharingProcessor::collectSymbolsInNestedRegions(
283
308
if (nestedEval.isConstruct ())
284
309
// Recursively look for OpenMP constructs within `nestedEval`'s region
285
310
collectSymbolsInNestedRegions (nestedEval, flag, symbolsInNestedRegions);
286
- else
311
+ else {
287
312
converter.collectSymbolSet (nestedEval, symbolsInNestedRegions, flag,
288
313
/* collectSymbols=*/ true ,
289
314
/* collectHostAssociatedSymbols=*/ false );
315
+ }
290
316
}
291
317
}
292
318
}
@@ -322,24 +348,44 @@ void DataSharingProcessor::collectSymbols(
322
348
converter.collectSymbolSet (eval, allSymbols, flag,
323
349
/* collectSymbols=*/ true ,
324
350
/* collectHostAssociatedSymbols=*/ true );
351
+
325
352
llvm::SetVector<const semantics::Symbol *> symbolsInNestedRegions;
326
353
collectSymbolsInNestedRegions (eval, flag, symbolsInNestedRegions);
354
+
355
+ for (auto *symbol : allSymbols)
356
+ if (visitor.isSymbolDefineBy (symbol, eval))
357
+ symbolsInNestedRegions.remove (symbol);
358
+
327
359
// Filter-out symbols that must not be privatized.
328
360
bool collectImplicit = flag == semantics::Symbol::Flag::OmpImplicit;
361
+ bool collectPreDetermined = flag == semantics::Symbol::Flag::OmpPreDetermined;
362
+
329
363
auto isPrivatizable = [](const semantics::Symbol &sym) -> bool {
330
364
return !semantics::IsProcedure (sym) &&
331
365
!sym.GetUltimate ().has <semantics::DerivedTypeDetails>() &&
332
366
!sym.GetUltimate ().has <semantics::NamelistDetails>() &&
333
367
!semantics::IsImpliedDoIndex (sym.GetUltimate ());
334
368
};
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
+
335
381
for (const auto *sym : allSymbols) {
336
382
assert (curScope && " couldn't find current scope" );
337
383
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);
342
387
symbols.insert (sym);
388
+ }
343
389
}
344
390
}
345
391
@@ -363,10 +409,16 @@ void DataSharingProcessor::collectImplicitSymbols() {
363
409
collectSymbols (semantics::Symbol::Flag::OmpImplicit, implicitSymbols);
364
410
}
365
411
412
+ void DataSharingProcessor::collectPreDeterminedSymbols () {
413
+ if (shouldCollectPreDeterminedSymbols)
414
+ collectSymbols (semantics::Symbol::Flag::OmpPreDetermined,
415
+ preDeterminedSymbols);
416
+ }
417
+
366
418
void DataSharingProcessor::privatize (
367
419
mlir::omp::PrivateClauseOps *clauseOps,
368
420
llvm::SmallVectorImpl<const semantics::Symbol *> *privateSyms) {
369
- for (const semantics::Symbol *sym : privatizedSymbols ) {
421
+ for (const semantics::Symbol *sym : allPrivatizedSymbols ) {
370
422
if (const auto *commonDet =
371
423
sym->detailsIf <semantics::CommonBlockDetails>()) {
372
424
for (const auto &mem : commonDet->objects ())
@@ -378,7 +430,7 @@ void DataSharingProcessor::privatize(
378
430
379
431
void DataSharingProcessor::copyLastPrivatize (mlir::Operation *op) {
380
432
insertLastPrivateCompare (op);
381
- for (const semantics::Symbol *sym : privatizedSymbols )
433
+ for (const semantics::Symbol *sym : allPrivatizedSymbols )
382
434
if (const auto *commonDet =
383
435
sym->detailsIf <semantics::CommonBlockDetails>()) {
384
436
for (const auto &mem : commonDet->objects ()) {
@@ -389,20 +441,6 @@ void DataSharingProcessor::copyLastPrivatize(mlir::Operation *op) {
389
441
}
390
442
}
391
443
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
-
406
444
void DataSharingProcessor::doPrivatize (
407
445
const semantics::Symbol *sym, mlir::omp::PrivateClauseOps *clauseOps,
408
446
llvm::SmallVectorImpl<const semantics::Symbol *> *privateSyms) {
0 commit comments