[PATCH] D11395: [OpenMP] Add capture for threadprivate variables used in copyin clause
Samuel Antao
sfantao at us.ibm.com
Thu Jul 23 15:00:27 PDT 2015
sfantao added inline comments.
================
Comment at: lib/CodeGen/CGStmtOpenMP.cpp:230-246
@@ -229,7 +229,19 @@
if (CopiedVars.insert(VD->getCanonicalDecl()).second) {
- // Get the address of the master variable.
- auto *MasterAddr = VD->isStaticLocal()
- ? CGM.getStaticLocalDeclAddress(VD)
- : CGM.GetAddrOfGlobal(VD);
+
+ // Get the address of the master variable. If we are emitting code with
+ // TLS support, the address is passed from the master as field in the
+ // captured declaration.
+ llvm::Value *MasterAddr;
+ if (getLangOpts().OpenMPUseTLS &&
+ getContext().getTargetInfo().isTLSSupported()) {
+ assert(CapturedStmtInfo->lookup(VD) &&
+ "Copyin threadprivates should have been captured!");
+ DeclRefExpr DRE(const_cast<VarDecl *>(VD), true, (*IRef)->getType(),
+ VK_LValue, (*IRef)->getExprLoc());
+ MasterAddr = EmitLValue(&DRE).getAddress();
+ } else {
+ MasterAddr = VD->isStaticLocal() ? CGM.getStaticLocalDeclAddress(VD)
+ : CGM.GetAddrOfGlobal(VD);
+ }
// Get the address of the threadprivate variable.
auto *PrivateAddr = EmitLValue(*IRef).getAddress();
----------------
Done with a small modification: the implementation always expect the `CapturedStmtInfo` to contain a valid lookup.
================
Comment at: lib/Sema/SemaOpenMP.cpp:160-667
@@ -159,4 +159,8 @@
+ /// \brief Check if the specified variable is a 'copyin' variable for current
+ /// region.
+ bool isCopyinVariable(VarDecl *D);
+
/// \brief Adds explicit data sharing attribute to the specified declaration.
void addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A);
@@ -412,6 +416,12 @@
return Stack.back().LCVSet.count(D) > 0;
}
+bool DSAStackTy::isCopyinVariable(VarDecl *D){
+ assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");
+ D = D->getCanonicalDecl();
+ DSAInfo I = Stack.back().SharingMap.lookup(D);
+ return I.Attributes == OMPC_copyin;
+}
void DSAStackTy::addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A) {
D = D->getCanonicalDecl();
if (A == OMPC_threadprivate) {
@@ -653,4 +663,6 @@
assert(LangOpts.OpenMP && "OpenMP is not allowed");
VD = VD->getCanonicalDecl();
if (DSAStack->getCurrentDirective() != OMPD_unknown) {
+ if (DSAStack->isCopyinVariable(VD) && !DSAStack->isClauseParsingMode())
+ return true;
if (DSAStack->isLoopControlVariable(VD) ||
----------------
ABataev wrote:
> ABataev wrote:
> > I'd better write a new function isOpenMPPrivateOrCopyin() function and used it instead of isOpenMPPrivate() in Sema::IsOpenMPCapturedVar(). Besides, note, that copyin variables must be captured only if TLS mode is on, if we're using runtime calls we don't need to capture threadprivates.
> If you want to capture copyin variable only in closely nested OpenMP region, it is enough just to make next changes in Sema::IsOpenMPCapturedVar():
> ...
> auto DVarPrivate = DSAStack->getTopDSA(VD, DSAStack->isClauseParsingMode());
> if (DVarPrivate.CKind != OMPC_unknown && (isOpenMPPrivate(DVarPrivate.CKind) || (getLangOpts().OpenMPTLS && DVarPrivate.CKind == OMPC_copyin))
> ...
The TLS check is now implemented in `IsOpenMPCapturedVar`. However I am not combining private with copyin because the action takes is slightly different.
================
Comment at: lib/Sema/SemaOpenMP.cpp:160-667
@@ -159,4 +159,8 @@
+ /// \brief Check if the specified variable is a 'copyin' variable for current
+ /// region.
+ bool isCopyinVariable(VarDecl *D);
+
/// \brief Adds explicit data sharing attribute to the specified declaration.
void addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A);
@@ -412,6 +416,12 @@
return Stack.back().LCVSet.count(D) > 0;
}
+bool DSAStackTy::isCopyinVariable(VarDecl *D){
+ assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");
+ D = D->getCanonicalDecl();
+ DSAInfo I = Stack.back().SharingMap.lookup(D);
+ return I.Attributes == OMPC_copyin;
+}
void DSAStackTy::addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A) {
D = D->getCanonicalDecl();
if (A == OMPC_threadprivate) {
@@ -653,4 +663,6 @@
assert(LangOpts.OpenMP && "OpenMP is not allowed");
VD = VD->getCanonicalDecl();
if (DSAStack->getCurrentDirective() != OMPD_unknown) {
+ if (DSAStack->isCopyinVariable(VD) && !DSAStack->isClauseParsingMode())
+ return true;
if (DSAStack->isLoopControlVariable(VD) ||
----------------
sfantao wrote:
> ABataev wrote:
> > ABataev wrote:
> > > I'd better write a new function isOpenMPPrivateOrCopyin() function and used it instead of isOpenMPPrivate() in Sema::IsOpenMPCapturedVar(). Besides, note, that copyin variables must be captured only if TLS mode is on, if we're using runtime calls we don't need to capture threadprivates.
> > If you want to capture copyin variable only in closely nested OpenMP region, it is enough just to make next changes in Sema::IsOpenMPCapturedVar():
> > ...
> > auto DVarPrivate = DSAStack->getTopDSA(VD, DSAStack->isClauseParsingMode());
> > if (DVarPrivate.CKind != OMPC_unknown && (isOpenMPPrivate(DVarPrivate.CKind) || (getLangOpts().OpenMPTLS && DVarPrivate.CKind == OMPC_copyin))
> > ...
> The TLS check is now implemented in `IsOpenMPCapturedVar`. However I am not combining private with copyin because the action takes is slightly different.
Capturing in the closely nested region is not sufficient: declarations have to be captured even if no uses are found. Please, take a look at the last patch and let me know your thoughts.
http://reviews.llvm.org/D11395
More information about the cfe-commits
mailing list