summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGStmtOpenMP.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGStmtOpenMP.cpp')
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp31
1 files changed, 29 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 42e6a841cdf..9af74749f17 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -882,7 +882,7 @@ void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {
InlinedOpenMPRegionScopeRAII Region(*this, S);
EmitStmt(Stmt);
EnsureInsertPoint();
- }, S.getLocStart());
+ }, S.getLocStart(), llvm::None, llvm::None, llvm::None, llvm::None);
}
// Emit an implicit barrier at the end.
@@ -898,11 +898,38 @@ void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) {
}
void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) {
+ llvm::SmallVector<const Expr *, 8> CopyprivateVars;
+ llvm::SmallVector<const Expr *, 8> SrcExprs;
+ llvm::SmallVector<const Expr *, 8> DstExprs;
+ llvm::SmallVector<const Expr *, 8> AssignmentOps;
+ // Check if there are any 'copyprivate' clauses associated with this 'single'
+ // construct.
+ auto CopyprivateFilter = [](const OMPClause *C) -> bool {
+ return C->getClauseKind() == OMPC_copyprivate;
+ };
+ // Build a list of copyprivate variables along with helper expressions
+ // (<source>, <destination>, <destination>=<source> expressions)
+ typedef OMPExecutableDirective::filtered_clause_iterator<decltype(
+ CopyprivateFilter)> CopyprivateIter;
+ for (CopyprivateIter I(S.clauses(), CopyprivateFilter); I; ++I) {
+ auto *C = cast<OMPCopyprivateClause>(*I);
+ CopyprivateVars.append(C->varlists().begin(), C->varlists().end());
+ SrcExprs.append(C->source_exprs().begin(), C->source_exprs().end());
+ DstExprs.append(C->destination_exprs().begin(),
+ C->destination_exprs().end());
+ AssignmentOps.append(C->assignment_ops().begin(),
+ C->assignment_ops().end());
+ }
+ // Emit code for 'single' region along with 'copyprivate' clauses
CGM.getOpenMPRuntime().emitSingleRegion(*this, [&]() -> void {
InlinedOpenMPRegionScopeRAII Region(*this, S);
EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
EnsureInsertPoint();
- }, S.getLocStart());
+ }, S.getLocStart(), CopyprivateVars, SrcExprs, DstExprs, AssignmentOps);
+ // Emit an implicit barrier at the end.
+ if (!S.getSingleClause(OMPC_nowait))
+ CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(),
+ /*IsExplicit=*/false);
}
void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) {
OpenPOWER on IntegriCloud