[clang] Inital support for privavate variable reduction (PR #127740)

CHANDRA GHALE via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 18 19:26:04 PST 2025


https://github.com/chandraghale created https://github.com/llvm/llvm-project/pull/127740

None

>From cf392f05f9499fd0621ffec91a3b852d4b91820b Mon Sep 17 00:00:00 2001
From: Chandra Ghale <ghale at pe31.hpc.amslabs.hpecorp.net>
Date: Tue, 18 Feb 2025 21:24:22 -0600
Subject: [PATCH] Inital support for privavate variable reduction

---
 clang/include/clang/Basic/OpenMPKinds.def |  7 +++
 clang/include/clang/Basic/OpenMPKinds.h   |  7 +++
 clang/include/clang/Sema/SemaOpenMP.h     |  5 +-
 clang/lib/Parse/ParseOpenMP.cpp           | 27 ++++++++++
 clang/lib/Sema/SemaOpenMP.cpp             | 65 +++++++++++++++++++----
 5 files changed, 101 insertions(+), 10 deletions(-)

diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def
index 3f25e7aafe23b..4f8396dc34ea8 100644
--- a/clang/include/clang/Basic/OpenMPKinds.def
+++ b/clang/include/clang/Basic/OpenMPKinds.def
@@ -71,6 +71,9 @@
 #ifndef OPENMP_REDUCTION_MODIFIER
 #define OPENMP_REDUCTION_MODIFIER(Name)
 #endif
+#ifndef OPENMP_ORIGINAL_SHARING_MODIFIER
+#define OPENMP_ORIGINAL_SHARING_MODIFIER(Name)
+#endif
 #ifndef OPENMP_ADJUST_ARGS_KIND
 #define OPENMP_ADJUST_ARGS_KIND(Name)
 #endif
@@ -202,6 +205,9 @@ OPENMP_REDUCTION_MODIFIER(default)
 OPENMP_REDUCTION_MODIFIER(inscan)
 OPENMP_REDUCTION_MODIFIER(task)
 
+OPENMP_ORIGINAL_SHARING_MODIFIER(shared)
+OPENMP_ORIGINAL_SHARING_MODIFIER(private)
+
 // Adjust-op kinds for the 'adjust_args' clause.
 OPENMP_ADJUST_ARGS_KIND(nothing)
 OPENMP_ADJUST_ARGS_KIND(need_device_ptr)
@@ -231,6 +237,7 @@ OPENMP_DOACROSS_MODIFIER(source_omp_cur_iteration)
 #undef OPENMP_BIND_KIND
 #undef OPENMP_ADJUST_ARGS_KIND
 #undef OPENMP_REDUCTION_MODIFIER
+#undef OPENMP_ORIGINAL_SHARING_MODIFIER
 #undef OPENMP_DEVICE_MODIFIER
 #undef OPENMP_ORDER_KIND
 #undef OPENMP_ORDER_MODIFIER
diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h
index 900ad6ca6d66f..bbadda9fb03b4 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -190,6 +190,13 @@ enum OpenMPReductionClauseModifier {
   OMPC_REDUCTION_unknown,
 };
 
+/// OpenMP original sharing modifiers
+enum OpenMPOriginalSharingModifier {
+#define OPENMP_ORIGINAL_SHARING_MODIFIER(Name) OMPC_ORIGINAL_SHARING_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+  OMPC_ORIGINAL_SHARING_default,
+};
+
 /// OpenMP adjust-op kinds for 'adjust_args' clause.
 enum OpenMPAdjustArgsOpKind {
 #define OPENMP_ADJUST_ARGS_KIND(Name) OMPC_ADJUST_ARGS_##Name,
diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h
index 3d1cc4fab1c10..40e300f099826 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -1136,6 +1136,7 @@ class SemaOpenMP : public SemaBase {
     DeclarationNameInfo ReductionOrMapperId;
     int ExtraModifier = -1; ///< Additional modifier for linear, map, depend or
                             ///< lastprivate clause.
+    int OriginalSharingModifier = 0;  // Default is shared
     SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
         MapTypeModifiers;
     SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
@@ -1145,6 +1146,7 @@ class SemaOpenMP : public SemaBase {
     SmallVector<SourceLocation, NumberOfOMPMotionModifiers> MotionModifiersLoc;
     bool IsMapTypeImplicit = false;
     SourceLocation ExtraModifierLoc;
+    SourceLocation OriginalSharingModifierLoc;
     SourceLocation OmpAllMemoryLoc;
     SourceLocation
         StepModifierLoc; /// 'step' modifier location for linear clause
@@ -1197,7 +1199,8 @@ class SemaOpenMP : public SemaBase {
       SourceLocation ModifierLoc, SourceLocation ColonLoc,
       SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
       const DeclarationNameInfo &ReductionId,
-      ArrayRef<Expr *> UnresolvedReductions = {});
+      ArrayRef<Expr *> UnresolvedReductions = {}, 
+      OpenMPOriginalSharingModifier OriginalShareModifier = OMPC_ORIGINAL_SHARING_default);
   /// Called on well-formed 'task_reduction' clause.
   OMPClause *ActOnOpenMPTaskReductionClause(
       ArrayRef<Expr *> VarList, SourceLocation StartLoc,
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index b4e973bc84a7b..f59ecd93de6d3 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -4594,6 +4594,33 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
       assert(Tok.is(tok::comma) && "Expected comma.");
       (void)ConsumeToken();
     }
+    // Handle original(private / shared) Modifier
+    if (Kind == OMPC_reduction && getLangOpts().OpenMP >= 60  &&
+        Tok.is(tok::identifier) && PP.getSpelling(Tok) == "original" &&
+        NextToken().is(tok::l_paren)) {
+      // Parse original(private) modifier.
+      ConsumeToken(); 
+      BalancedDelimiterTracker ParenT(*this, tok::l_paren, tok::r_paren);
+      ParenT.consumeOpen();
+      if (Tok.is(tok::kw_private)) {
+        Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_private;
+        Data.OriginalSharingModifierLoc = Tok.getLocation();
+        ConsumeToken(); 
+      }    
+      else if (Tok.is(tok::identifier) &&  PP.getSpelling(Tok) == "shared") {
+        Data.OriginalSharingModifier = OMPC_ORIGINAL_SHARING_shared;
+        Data.OriginalSharingModifierLoc = Tok.getLocation();
+        ConsumeToken(); 
+      } else {
+        Diag(Tok.getLocation(), diag::err_expected) << "'private or shared'";
+        SkipUntil(tok::r_paren);
+        return false;
+      }    
+      ParenT.consumeClose();
+      assert(Tok.is(tok::comma) && "Expected comma.");
+      (void)ConsumeToken();
+    } 
+    
     ColonProtectionRAIIObject ColonRAII(*this);
     if (getLangOpts().CPlusPlus)
       ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 66ff92f554fc4..4daaf44d7c163 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -17054,6 +17054,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
   SourceLocation EndLoc = Locs.EndLoc;
   OMPClause *Res = nullptr;
   int ExtraModifier = Data.ExtraModifier;
+  int OriginalSharingModifier = Data.OriginalSharingModifier;
   SourceLocation ExtraModifierLoc = Data.ExtraModifierLoc;
   SourceLocation ColonLoc = Data.ColonLoc;
   switch (Kind) {
@@ -17079,7 +17080,8 @@ OMPClause *SemaOpenMP::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
     Res = ActOnOpenMPReductionClause(
         VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
         StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
-        Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
+        Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, {},
+        static_cast<OpenMPOriginalSharingModifier>(OriginalSharingModifier));
     break;
   case OMPC_task_reduction:
     Res = ActOnOpenMPTaskReductionClause(
@@ -18220,6 +18222,8 @@ namespace {
 struct ReductionData {
   /// List of original reduction items.
   SmallVector<Expr *, 8> Vars;
+  /// OpenMP 6.0 List of internal shared private reduction items
+  SmallVector<Expr *, 8> VarsTmp;
   /// List of private copies of the reduction items.
   SmallVector<Expr *, 8> Privates;
   /// LHS expressions for the reduction_op expressions.
@@ -18243,9 +18247,12 @@ struct ReductionData {
   SmallVector<Expr *, 4> ExprPostUpdates;
   /// Reduction modifier.
   unsigned RedModifier = 0;
+  /// OpenMP 6.9  Original sharing modifier
+  unsigned OrigSharingModifier = 0;
   ReductionData() = delete;
   /// Reserves required memory for the reduction data.
-  ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
+  ReductionData(unsigned Size, unsigned Modifier = 0, unsigned OrgModifier = 0) : RedModifier(Modifier),
+   OrigSharingModifier(OrgModifier) {
     Vars.reserve(Size);
     Privates.reserve(Size);
     LHSs.reserve(Size);
@@ -18256,6 +18263,9 @@ struct ReductionData {
       InscanCopyArrayTemps.reserve(Size);
       InscanCopyArrayElems.reserve(Size);
     }
+    if( OrigSharingModifier == OMPC_ORIGINAL_SHARING_private){
+      VarsTmp.reserve(Size);
+    }
     TaskgroupDescriptors.reserve(Size);
     ExprCaptures.reserve(Size);
     ExprPostUpdates.reserve(Size);
@@ -18274,6 +18284,10 @@ struct ReductionData {
       InscanCopyArrayTemps.push_back(nullptr);
       InscanCopyArrayElems.push_back(nullptr);
     }
+     // To be analyze later
+    if( OrigSharingModifier == OMPC_ORIGINAL_SHARING_private){
+      VarsTmp.emplace_back(Item);
+    }
   }
   /// Stores reduction data.
   void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
@@ -18599,7 +18613,7 @@ static bool actOnOMPReductionKindClause(
           S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
         continue;
       }
-      if (DVar.CKind != OMPC_unknown) {
+      if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
         S.Diag(ELoc, diag::err_omp_wrong_dsa)
             << getOpenMPClauseName(DVar.CKind)
             << getOpenMPClauseName(OMPC_reduction);
@@ -18611,7 +18625,7 @@ static bool actOnOMPReductionKindClause(
       //  A list item that appears in a reduction clause of a worksharing
       //  construct must be shared in the parallel regions to which any of the
       //  worksharing regions arising from the worksharing construct bind.
-      if (isOpenMPWorksharingDirective(CurrDir) &&
+      if (RD.OrigSharingModifier !=OMPC_ORIGINAL_SHARING_private && isOpenMPWorksharingDirective(CurrDir) &&
           !isOpenMPParallelDirective(CurrDir) &&
           !isOpenMPTeamsDirective(CurrDir)) {
         DVar = Stack->getImplicitDSA(D, true);
@@ -19117,7 +19131,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPReductionClause(
     SourceLocation StartLoc, SourceLocation LParenLoc,
     SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
-    ArrayRef<Expr *> UnresolvedReductions) {
+    ArrayRef<Expr *> UnresolvedReductions, OpenMPOriginalSharingModifier OriginalSharingMod  ) {
   if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
     Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
         << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
@@ -19130,7 +19144,8 @@ OMPClause *SemaOpenMP::ActOnOpenMPReductionClause(
   // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
   // construct, a parallel worksharing-loop construct or a parallel
   // worksharing-loop SIMD construct.
-  if (Modifier == OMPC_REDUCTION_inscan &&
+  if ((Modifier == OMPC_REDUCTION_inscan || OriginalSharingMod  == OMPC_ORIGINAL_SHARING_private
+        || OriginalSharingMod  == OMPC_ORIGINAL_SHARING_shared )   &&
       (DSAStack->getCurrentDirective() != OMPD_for &&
        DSAStack->getCurrentDirective() != OMPD_for_simd &&
        DSAStack->getCurrentDirective() != OMPD_simd &&
@@ -19139,9 +19154,41 @@ OMPClause *SemaOpenMP::ActOnOpenMPReductionClause(
     Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
     return nullptr;
   }
-
-  ReductionData RD(VarList.size(), Modifier);
-  if (actOnOMPReductionKindClause(SemaRef, DSAStack, OMPC_reduction, VarList,
+  
+  SmallVector<Expr *, 4> ProcessedVarList;
+  for (Expr *E : VarList) {
+    DeclRefExpr *OrigDRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts());
+    if( !OrigDRE ){
+      ProcessedVarList.push_back(E);
+      continue;
+     }
+     ValueDecl *OrigDecl = OrigDRE->getDecl();
+     DSAStackTy::DSAVarData DVar  = DSAStack->getImplicitDSA(OrigDecl, true);
+     if (DVar.CKind == OMPC_private || DVar.CKind == OMPC_firstprivate || 
+        OriginalSharingMod == OMPC_ORIGINAL_SHARING_private )
+     {
+       
+       VarDecl *SharedVar = buildVarDecl(SemaRef, E->getExprLoc(), E->getType(),
+                                                     ".omp.reduction.shared.tmp", nullptr, nullptr);
+       SemaRef.getCurScope()->AddDecl(SharedVar);
+       SharedVar->setImplicit();
+       DeclRefExpr* SharedRef = buildDeclRefExpr(SemaRef, SharedVar,
+                                                                 SharedVar->getType(),
+                                                                 E->getExprLoc());
+       DSAStack->addDSA(SharedVar, nullptr, OMPC_shared);
+       ExprResult Init = SemaRef.BuildBinOp( SemaRef.getCurScope(), OrigDRE->getBeginLoc(), BO_Assign, static_cast<Expr*>(SharedRef), E);
+       if (!Init.isInvalid())
+        SemaRef.AddInitializerToDecl(SharedVar, Init.get(), false);
+
+       ProcessedVarList.push_back(static_cast<Expr*>(SharedRef));
+      } 
+     else 
+     {
+        ProcessedVarList.push_back(E);
+     }
+  }
+  ReductionData RD(ProcessedVarList.size(), Modifier, OriginalSharingMod );
+  if (actOnOMPReductionKindClause(SemaRef, DSAStack, OMPC_reduction, ProcessedVarList,
                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
                                   ReductionIdScopeSpec, ReductionId,
                                   UnresolvedReductions, RD))



More information about the cfe-commits mailing list