r308883 - [OPENMP] Fix the restrictions for in_reduction clause.

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 24 07:52:13 PDT 2017


Author: abataev
Date: Mon Jul 24 07:52:13 2017
New Revision: 308883

URL: http://llvm.org/viewvc/llvm-project?rev=308883&view=rev
Log:
[OPENMP] Fix the restrictions for in_reduction clause.

This patch allows to use in_reduction clause even if the innermost
directive is not taskgroup.

Modified:
    cfe/trunk/lib/Sema/SemaOpenMP.cpp
    cfe/trunk/test/OpenMP/task_ast_print.cpp

Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=308883&r1=308882&r2=308883&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Mon Jul 24 07:52:13 2017
@@ -57,6 +57,10 @@ public:
     DeclRefExpr *PrivateCopy = nullptr;
     SourceLocation ImplicitDSALoc;
     DSAVarData() = default;
+    DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, Expr *RefExpr,
+               DeclRefExpr *PrivateCopy, SourceLocation ImplicitDSALoc)
+        : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
+          PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
   };
   typedef llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>
       OperatorOffsetTy;
@@ -246,12 +250,12 @@ public:
   void addReductionData(ValueDecl *D, SourceRange SR, const Expr *ReductionRef);
   /// Returns the location and reduction operation from the innermost parent
   /// region for the given \p D.
-  bool getTopMostReductionData(ValueDecl *D, SourceRange &SR,
-                               BinaryOperatorKind &BOK);
+  DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
+                                              BinaryOperatorKind &BOK);
   /// Returns the location and reduction operation from the innermost parent
   /// region for the given \p D.
-  bool getTopMostReductionData(ValueDecl *D, SourceRange &SR,
-                               const Expr *&ReductionRef);
+  DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
+                                              const Expr *&ReductionRef);
 
   /// \brief Returns data sharing attributes from top of the stack for the
   /// specified declaration.
@@ -769,48 +773,54 @@ void DSAStackTy::addReductionData(ValueD
   ReductionData.set(ReductionRef, SR);
 }
 
-bool DSAStackTy::getTopMostReductionData(ValueDecl *D, SourceRange &SR,
-                                         BinaryOperatorKind &BOK) {
+DSAStackTy::DSAVarData
+DSAStackTy::getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
+                                             BinaryOperatorKind &BOK) {
   D = getCanonicalDecl(D);
-  assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
-         "Data-sharing attributes stack is empty or has only 1 region.");
-  for (auto I = std::next(Stack.back().first.rbegin(), 0),
+  assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
+  if (Stack.back().first.empty())
+      return DSAVarData();
+  for (auto I = std::next(Stack.back().first.rbegin(), 1),
             E = Stack.back().first.rend();
        I != E; std::advance(I, 1)) {
     auto &Data = I->SharingMap[D];
-    if (Data.Attributes != OMPC_reduction)
+    if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
       continue;
     auto &ReductionData = I->ReductionMap[D];
     if (!ReductionData.ReductionOp ||
         ReductionData.ReductionOp.is<const Expr *>())
-      return false;
+      return DSAVarData();
     SR = ReductionData.ReductionRange;
     BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
-    return true;
+    return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
+                      Data.PrivateCopy, I->DefaultAttrLoc);
   }
-  return false;
+  return DSAVarData();
 }
 
-bool DSAStackTy::getTopMostReductionData(ValueDecl *D, SourceRange &SR,
-                                         const Expr *&ReductionRef) {
+DSAStackTy::DSAVarData
+DSAStackTy::getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
+                                             const Expr *&ReductionRef) {
   D = getCanonicalDecl(D);
-  assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
-         "Data-sharing attributes stack is empty or has only 1 region.");
-  for (auto I = std::next(Stack.back().first.rbegin(), 0),
+  assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
+  if (Stack.back().first.empty())
+      return DSAVarData();
+  for (auto I = std::next(Stack.back().first.rbegin(), 1),
             E = Stack.back().first.rend();
        I != E; std::advance(I, 1)) {
     auto &Data = I->SharingMap[D];
-    if (Data.Attributes != OMPC_reduction)
+    if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
       continue;
     auto &ReductionData = I->ReductionMap[D];
     if (!ReductionData.ReductionOp ||
         !ReductionData.ReductionOp.is<const Expr *>())
-      return false;
+      return DSAVarData();
     SR = ReductionData.ReductionRange;
     ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
-    return true;
+    return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
+                      Data.PrivateCopy, I->DefaultAttrLoc);
   }
-  return false;
+  return DSAVarData();
 }
 
 bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) {
@@ -9550,20 +9560,20 @@ static bool ActOnOMPReductionKindClause(
     // condition must specify the same reduction-identifier as the in_reduction
     // clause.
     if (ClauseKind == OMPC_in_reduction) {
-      DVar = Stack->hasDSA(
-          D, [](OpenMPClauseKind K) { return K != OMPC_unknown; },
-          [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; },
-          /*FromParent=*/true);
-      if (DVar.CKind != OMPC_reduction || DVar.DKind != OMPD_taskgroup) {
-        S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
-        continue;
-      }
       SourceRange ParentSR;
       BinaryOperatorKind ParentBOK;
       const Expr *ParentReductionOp;
-      bool IsParentBOK = Stack->getTopMostReductionData(D, ParentSR, ParentBOK);
-      bool IsParentReductionOp =
-          Stack->getTopMostReductionData(D, ParentSR, ParentReductionOp);
+      DSAStackTy::DSAVarData ParentBOKDSA =
+          Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK);
+      DSAStackTy::DSAVarData ParentReductionOpDSA =
+          Stack->getTopMostTaskgroupReductionData(D, ParentSR,
+                                                  ParentReductionOp);
+      bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
+      bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
+      if (!IsParentBOK && !IsParentReductionOp) {
+        S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
+        continue;
+      }
       if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
           (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK ||
           IsParentReductionOp) {
@@ -9581,7 +9591,10 @@ static bool ActOnOMPReductionKindClause(
               << ReductionIdRange << RefExpr->getSourceRange();
           S.Diag(ParentSR.getBegin(),
                  diag::note_omp_previous_reduction_identifier)
-              << ParentSR << DVar.RefExpr->getSourceRange();
+              << ParentSR
+              << (IsParentBOK ? ParentBOKDSA.RefExpr
+                              : ParentReductionOpDSA.RefExpr)
+                     ->getSourceRange();
           continue;
         }
       }
@@ -9624,10 +9637,12 @@ static bool ActOnOMPReductionKindClause(
     // All reduction items are still marked as reduction (to do not increase
     // code base size).
     Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
-    if (DeclareReductionRef.isUsable())
-      Stack->addReductionData(D, ReductionIdRange, DeclareReductionRef.get());
-    else
-      Stack->addReductionData(D, ReductionIdRange, BOK);
+    if (CurrDir == OMPD_taskgroup) {
+      if (DeclareReductionRef.isUsable())
+        Stack->addReductionData(D, ReductionIdRange, DeclareReductionRef.get());
+      else
+        Stack->addReductionData(D, ReductionIdRange, BOK);
+    }
     RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get());
   }
   return RD.Vars.empty();

Modified: cfe/trunk/test/OpenMP/task_ast_print.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/task_ast_print.cpp?rev=308883&r1=308882&r2=308883&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/task_ast_print.cpp (original)
+++ cfe/trunk/test/OpenMP/task_ast_print.cpp Mon Jul 24 07:52:13 2017
@@ -155,6 +155,14 @@ int main(int argc, char **argv) {
   // CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) if(argc > 0) final(a > 0) depend(inout : a,argv[:argc],arr[:a]) priority(23) in_reduction(min: arr1)
   foo();
   // CHECK-NEXT: foo();
+#pragma omp taskgroup task_reduction(min: arr1)
+#pragma omp parallel reduction(+:arr1)
+#pragma omp task in_reduction(min: arr1)
+  // CHECK-NEXT: #pragma omp taskgroup task_reduction(min: arr1)
+  // CHECK-NEXT: #pragma omp parallel reduction(+: arr1)
+  // CHECK-NEXT: #pragma omp task in_reduction(min: arr1)
+  foo();
+  // CHECK-NEXT: foo();
   return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x);
 }
 




More information about the cfe-commits mailing list