diff options
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGStmtOpenMP.cpp | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 62fe4bcd1f2..22f6c3432a0 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -1175,6 +1175,7 @@ static OpenMPDirectiveKind emitSections(CodeGenFunction &CGF, } CGF.EmitOMPPrivateClause(S, LoopScope); HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope); + CGF.EmitOMPReductionClauseInit(S, LoopScope); (void)LoopScope.Privatize(); // Emit static non-chunked loop. @@ -1194,6 +1195,7 @@ static OpenMPDirectiveKind emitSections(CodeGenFunction &CGF, [](CodeGenFunction &) {}); // Tell the runtime we are done. CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocStart()); + CGF.EmitOMPReductionClauseFinal(S); // Emit final copy of the lastprivate variables if IsLastIter != 0. if (HasLastprivates) @@ -1217,6 +1219,14 @@ static OpenMPDirectiveKind emitSections(CodeGenFunction &CGF, // If only one section is found - no need to generate loop, emit as a single // region. bool HasFirstprivates; + // No need to generate reductions for sections with single section region, we + // can use original shared variables for all operations. + auto ReductionFilter = [](const OMPClause *C) -> bool { + return C->getClauseKind() == OMPC_reduction; + }; + OMPExecutableDirective::filtered_clause_iterator<decltype(ReductionFilter)> I( + S.clauses(), ReductionFilter); + bool HasReductions = I; // No need to generate lastprivates for sections with single section region, // we can use original shared variable for all calculations with barrier at // the end of the sections. @@ -1224,8 +1234,8 @@ static OpenMPDirectiveKind emitSections(CodeGenFunction &CGF, return C->getClauseKind() == OMPC_lastprivate; }; OMPExecutableDirective::filtered_clause_iterator<decltype(LastprivateFilter)> - I(S.clauses(), LastprivateFilter); - bool HasLastprivates = I; + I1(S.clauses(), LastprivateFilter); + bool HasLastprivates = I1; auto &&CodeGen = [Stmt, &S, &HasFirstprivates](CodeGenFunction &CGF) { CodeGenFunction::OMPPrivateScope SingleScope(CGF); HasFirstprivates = CGF.EmitOMPFirstprivateClause(S, SingleScope); @@ -1238,10 +1248,11 @@ static OpenMPDirectiveKind emitSections(CodeGenFunction &CGF, CGF.CGM.getOpenMPRuntime().emitSingleRegion(CGF, CodeGen, S.getLocStart(), llvm::None, llvm::None, llvm::None, llvm::None); - // Emit barrier for firstprivates or lastprivates only if 'sections' directive - // has 'nowait' clause. Otherwise the barrier will be generated by the codegen - // for the directive. - if ((HasFirstprivates || HasLastprivates) && S.getSingleClause(OMPC_nowait)) { + // Emit barrier for firstprivates, lastprivates or reductions only if + // 'sections' directive has 'nowait' clause. Otherwise the barrier will be + // generated by the codegen for the directive. + if ((HasFirstprivates || HasLastprivates || HasReductions) && + S.getSingleClause(OMPC_nowait)) { // Emit implicit barrier to synchronize threads and avoid data races on // initialization of firstprivate variables. CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), |

