[PATCH] D11395: [OpenMP] Add capture for threadprivate variables used in copyin clause

Alexey Bataev a.bataev at hotmail.com
Fri Jul 24 01:48:45 PDT 2015


ABataev added inline comments.

================
Comment at: lib/Sema/SemaOpenMP.cpp:663
@@ -651,3 +662,3 @@
 
-bool Sema::IsOpenMPCapturedVar(VarDecl *VD) {
+bool Sema::IsOpenMPCapturedVar(VarDecl *VD, bool &PropagateCapture) {
   assert(LangOpts.OpenMP && "OpenMP is not allowed");
----------------
sfantao wrote:
> That was my initial approach, however that will not do what is required. Let me explain with an example:
> 
> ```
> int A = 0, B = 0, C = 0;
> #pragma omp threadprivate(A,B,C)
> 
> foo(){
>   ++A; ++B; ++C;
>   #pragma omp parallel copyin(A,B,C)
>   {
>     ++B;
>     #pragma omp some_other_directive
>     {
>        ++C;
>        bar(); // Uses A 
>     }
>   }
> }
> ```
> If we just change `IsOpenMPCapturedVar` as you say, this is what happens:
>  - A will not be captured so bar() will not get the right value of A
>  - C will be captured by some_other_directive, and that is not necessary, and will pose an avoidable overhead.
>  - Only B would be captured properly.
> 
> I am not saying that there is no better way of doing, but after testing several cases this is the best solution I was able to get. Let me know if you have something different to propose or if you need me to clarify anything.
Try this one:
%%% patch
Index: SemaOpenMP.cpp
===================================================================
--- SemaOpenMP.cpp      (revision 243097)
+++ SemaOpenMP.cpp      (working copy)
@@ -120,6 +120,7 @@
   /// from current directive.
   OpenMPClauseKind ClauseKindMode;
   Sema &SemaRef;
+  bool ForceCapturing;

   typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator;

@@ -130,7 +131,8 @@

 public:
   explicit DSAStackTy(Sema &S)
-      : Stack(1), ClauseKindMode(OMPC_unknown), SemaRef(S) {}
+      : Stack(1), ClauseKindMode(OMPC_unknown), SemaRef(S),
+        ForceCapturing(false) {}

   bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
   void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
@@ -146,6 +148,9 @@
     Stack.pop_back();
   }

+  void forceVarCapturing(bool V) { ForceCapturing = V; }
+  bool isForceVarCapturing() const { return ForceCapturing; }
+
   /// \brief If 'aligned' declaration for given variable \a D was not seen yet,
   /// add it and return NULL; otherwise return previous occurrence's expression
   /// for diagnostics.
@@ -655,7 +660,8 @@
   if (DSAStack->getCurrentDirective() != OMPD_unknown) {
     if (DSAStack->isLoopControlVariable(VD) ||
         (VD->hasLocalStorage() &&
-         isParallelOrTaskRegion(DSAStack->getCurrentDirective())))
+         isParallelOrTaskRegion(DSAStack->getCurrentDirective())) ||
+        DSAStack->isForceVarCapturing())
       return true;
     auto DVarPrivate = DSAStack->getTopDSA(VD, DSAStack->isClauseParsingMode());
     if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
@@ -1351,13 +1357,18 @@
   // This is required for proper codegen.
   for (auto *Clause : Clauses) {
     if (isOpenMPPrivate(Clause->getClauseKind()) ||
-        Clause->getClauseKind() == OMPC_copyprivate) {
+        Clause->getClauseKind() == OMPC_copyprivate ||
+        (getLangOpts().OpenMPUseTLS &&
+         getASTContext().getTargetInfo().isTLSSupported() &&
+         Clause->getClauseKind() == OMPC_copyin)) {
+      DSAStack->forceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
       // Mark all variables in private list clauses as used in inner region.
       for (auto *VarRef : Clause->children()) {
         if (auto *E = cast_or_null<Expr>(VarRef)) {
           MarkDeclarationsReferencedInExpr(E);
         }
       }
+      DSAStack->forceVarCapturing(/*V=*/false);
     } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective()) &&
                Clause->getClauseKind() == OMPC_schedule) {
       // Mark all variables in private list clauses as used in inner region.
%%%


http://reviews.llvm.org/D11395







More information about the cfe-commits mailing list