summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp23
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(),
OpenPOWER on IntegriCloud