@@ -29,7 +29,7 @@ getDesignatorNameIfDataRef(const Fortran::parser::Designator &designator) {
29
29
return dataRef ? std::get_if<Fortran::parser::Name>(&dataRef->u ) : nullptr ;
30
30
}
31
31
32
- static void privatiseVars (Fortran::lower::AbstractConverter &converter,
32
+ static void privatizeVars (Fortran::lower::AbstractConverter &converter,
33
33
const Fortran::parser::OmpClauseList &opClauseList) {
34
34
auto &firOpBuilder = converter.getFirOpBuilder ();
35
35
Fortran::semantics::Symbol *sym = nullptr ;
@@ -50,9 +50,13 @@ static void privatiseVars(Fortran::lower::AbstractConverter &converter,
50
50
},
51
51
[&](const Fortran::parser::Name &name) { sym = name.symbol ; }},
52
52
ompObject.u );
53
- [[maybe_unused]] bool success =
54
- converter.createHostAssociateVarClone (*sym);
55
- assert (success && " Privatisation failed due to existing binding" );
53
+ // Privatization for symbols which are pre-determined (like loop index
54
+ // variables) happen separately, for everything else privatize here
55
+ if (!sym->test (Fortran::semantics::Symbol::Flag::OmpPreDetermined)) {
56
+ [[maybe_unused]] bool success =
57
+ converter.createHostAssociateVarClone (*sym);
58
+ assert (success && " Privatization failed due to existing binding" );
59
+ }
56
60
}
57
61
}
58
62
}
@@ -128,7 +132,7 @@ static void createBodyOfOp(
128
132
// Reset the insertion point to the start of the first block.
129
133
firOpBuilder.setInsertionPointToStart (&block);
130
134
if (clauses)
131
- privatiseVars (converter, *clauses);
135
+ privatizeVars (converter, *clauses);
132
136
}
133
137
134
138
static void genOMP (Fortran::lower::AbstractConverter &converter,
@@ -199,7 +203,7 @@ genOMP(Fortran::lower::AbstractConverter &converter,
199
203
standaloneConstruct.u );
200
204
}
201
205
202
- template <typename Directive>
206
+ template <typename Directive, bool isCombined >
203
207
static void createParallelOp (Fortran::lower::AbstractConverter &converter,
204
208
Fortran::lower::pft::Evaluation &eval,
205
209
const Directive &directive) {
@@ -317,8 +321,11 @@ static void createParallelOp(Fortran::lower::AbstractConverter &converter,
317
321
}
318
322
}
319
323
324
+ // Avoid multiple privatization: If Parallel is part of a combined construct
325
+ // then privatization will be performed later when the other part of the
326
+ // combined construct is processed.
320
327
createBodyOfOp<omp::ParallelOp>(parallelOp, converter, currentLocation,
321
- &opClauseList);
328
+ isCombined ? nullptr : &opClauseList);
322
329
}
323
330
324
331
static void
@@ -331,7 +338,7 @@ genOMP(Fortran::lower::AbstractConverter &converter,
331
338
std::get<Fortran::parser::OmpBlockDirective>(beginBlockDirective.t );
332
339
333
340
if (blockDirective.v == llvm::omp::OMPD_parallel) {
334
- createParallelOp<Fortran::parser::OmpBeginBlockDirective>(
341
+ createParallelOp<Fortran::parser::OmpBeginBlockDirective, false >(
335
342
converter, eval,
336
343
std::get<Fortran::parser::OmpBeginBlockDirective>(blockConstruct.t ));
337
344
} else if (blockDirective.v == llvm::omp::OMPD_master) {
@@ -436,7 +443,7 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
436
443
std::get<Fortran::parser::OmpLoopDirective>(
437
444
std::get<Fortran::parser::OmpBeginLoopDirective>(loopConstruct.t ).t )
438
445
.v ) {
439
- createParallelOp<Fortran::parser::OmpBeginLoopDirective>(
446
+ createParallelOp<Fortran::parser::OmpBeginLoopDirective, true >(
440
447
converter, eval,
441
448
std::get<Fortran::parser::OmpBeginLoopDirective>(loopConstruct.t ));
442
449
} else {
0 commit comments