diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2014-10-21 03:16:40 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2014-10-21 03:16:40 +0000 |
commit | 03b340a3a5608eecf447bdbcb0a3b64714e4efd7 (patch) | |
tree | 230ba545e88bcc01901ab44644ff0e79dd2d450b /clang/lib/CodeGen | |
parent | 322d0df309b5a01612e3a2dbc194e300d2cd5176 (diff) | |
download | bcm5719-llvm-03b340a3a5608eecf447bdbcb0a3b64714e4efd7.tar.gz bcm5719-llvm-03b340a3a5608eecf447bdbcb0a3b64714e4efd7.zip |
[OPENMP] Codegen for 'private' clause in 'parallel' directive.
This patch generates some helper variables which used as a private copies of the corresponding original variables inside an OpenMP 'parallel' directive. These generated variables are initialized by default (with the default constructor, if any). In outlined function references to original variables are replaced by the references to these private helper variables. At the end of the initialization of the private variables and implicit barier is set by calling __kmpc_barrier(...) runtime function to be sure that all threads were initialized using original values of the variables.
Differential Revision: http://reviews.llvm.org/D4752
llvm-svn: 220262
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGOpenMPRuntime.cpp | 9 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGStmtOpenMP.cpp | 27 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 3 |
3 files changed, 37 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 1a50c94bc7d..06dd680bc7b 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -71,6 +71,7 @@ LValue CGOpenMPRegionInfo::getThreadIDVariableLValue(CodeGenFunction &CGF) { void CGOpenMPRegionInfo::EmitBody(CodeGenFunction &CGF, Stmt *S) { CodeGenFunction::OMPPrivateScope PrivateScope(CGF); + CGF.EmitOMPPrivateClause(Directive, PrivateScope); CGF.EmitOMPFirstprivateClause(Directive, PrivateScope); if (PrivateScope.Privatize()) { // Emit implicit barrier to synchronize threads and avoid data races. @@ -200,7 +201,10 @@ llvm::Value *CGOpenMPRuntime::GetOpenMPThreadID(CodeGenFunction &CGF, OpenMPLocThreadIDMapTy::iterator I = OpenMPLocThreadIDMap.find(CGF.CurFn); if (I != OpenMPLocThreadIDMap.end()) { ThreadID = I->second.ThreadID; - } else if (auto OMPRegionInfo = + if (ThreadID != nullptr) + return ThreadID; + } + if (auto OMPRegionInfo = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) { // Check if this an outlined function with thread id passed as argument. auto ThreadIDVar = OMPRegionInfo->getThreadIDVariable(); @@ -233,7 +237,8 @@ llvm::Value *CGOpenMPRuntime::GetOpenMPThreadID(CodeGenFunction &CGF, void CGOpenMPRuntime::FunctionFinished(CodeGenFunction &CGF) { assert(CGF.CurFn && "No function in current CodeGenFunction."); - OpenMPLocThreadIDMap.erase(CGF.CurFn); + if (OpenMPLocThreadIDMap.count(CGF.CurFn)) + OpenMPLocThreadIDMap.erase(CGF.CurFn); } llvm::Type *CGOpenMPRuntime::getIdentTyPointerTy() { diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 2b0fb043be0..0e55993f924 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -183,6 +183,33 @@ void CodeGenFunction::EmitOMPFirstprivateClause( } } +void CodeGenFunction::EmitOMPPrivateClause( + const OMPExecutableDirective &D, + CodeGenFunction::OMPPrivateScope &PrivateScope) { + auto PrivateFilter = [](const OMPClause *C) -> bool { + return C->getClauseKind() == OMPC_private; + }; + for (OMPExecutableDirective::filtered_clause_iterator<decltype(PrivateFilter)> + I(D.clauses(), PrivateFilter); I; ++I) { + auto *C = cast<OMPPrivateClause>(*I); + auto IRef = C->varlist_begin(); + for (auto IInit : C->private_copies()) { + auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); + auto VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl()); + bool IsRegistered = + PrivateScope.addPrivate(OrigVD, [&]() -> llvm::Value * { + // Emit private VarDecl with copy init. + EmitDecl(*VD); + return GetAddrOfLocalVar(VD); + }); + assert(IsRegistered && "counter already registered as private"); + // Silence the warning about unused variable. + (void)IsRegistered; + ++IRef; + } + } +} + /// \brief Emits code for OpenMP parallel directive in the parallel region. static void EmitOMPParallelCall(CodeGenFunction &CGF, const OMPParallelDirective &S, diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 49810a8700e..a31cd1bf7af 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -113,6 +113,7 @@ class CodeGenFunction : public CodeGenTypeCache { void operator=(const CodeGenFunction &) LLVM_DELETED_FUNCTION; friend class CGCXXABI; + friend class CGOpenMPRegionInfo; public: /// A jump destination is an abstract label, branching to which may /// require a jump out through normal cleanups. @@ -2012,6 +2013,8 @@ public: const VarDecl *VDInit); void EmitOMPFirstprivateClause(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope); + void EmitOMPPrivateClause(const OMPExecutableDirective &D, + OMPPrivateScope &PrivateScope); void EmitOMPParallelDirective(const OMPParallelDirective &S); void EmitOMPSimdDirective(const OMPSimdDirective &S); |