[clang] [llvm] Draft/wip/preview of using leaf constructs in clang (PR #84817)

Krzysztof Parzyszek via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 11 12:49:33 PDT 2024


https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/84817

This doesn't do anything with clauses yet.  It's just hooking things up to handle leaf constructs, and it's not even trying to cover all cases.

>From 45859d3b1fb914d26831086fb7f7e6decdec9010 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Mon, 11 Mar 2024 12:55:38 -0500
Subject: [PATCH 1/2] [Frontend][OpenMP] Add isCompositeConstruct and
 isCombinedConstruct

Implement helper functions to identify composite and combined constructs.
---
 llvm/include/llvm/Frontend/OpenMP/OMP.h |  5 +++++
 llvm/lib/Frontend/OpenMP/OMP.cpp        | 21 +++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.h b/llvm/include/llvm/Frontend/OpenMP/OMP.h
index a85cd9d344c6d7..59737417b4b014 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.h
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.h
@@ -15,4 +15,9 @@
 
 #include "llvm/Frontend/OpenMP/OMP.h.inc"
 
+namespace llvm::omp {
+bool isCompositeConstruct(Directive D);
+bool isCombinedConstruct(Directive D);
+} // namespace llvm::omp
+
 #endif // LLVM_FRONTEND_OPENMP_OMP_H
diff --git a/llvm/lib/Frontend/OpenMP/OMP.cpp b/llvm/lib/Frontend/OpenMP/OMP.cpp
index 4f2f95392648b3..19327277d22ad8 100644
--- a/llvm/lib/Frontend/OpenMP/OMP.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMP.cpp
@@ -8,6 +8,7 @@
 
 #include "llvm/Frontend/OpenMP/OMP.h"
 
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -17,3 +18,23 @@ using namespace omp;
 
 #define GEN_DIRECTIVES_IMPL
 #include "llvm/Frontend/OpenMP/OMP.inc"
+
+namespace llvm::omp {
+bool isCompositeConstruct(Directive D) {
+  // OpenMP Spec 5.2: [17.3, 8-9]
+  // If directive-name-A and directive-name-B both correspond to loop-
+  // associated constructs then directive-name is a composite construct
+  size_t numLoopConstructs =
+      llvm::count_if(getLeafConstructs(D), [](Directive L) {
+        return getDirectiveAssociation(L) == Association::Loop;
+      });
+  return numLoopConstructs > 1;
+}
+
+bool isCombinedConstruct(Directive D) {
+  // OpenMP Spec 5.2: [17.3, 9-10]
+  // Otherwise directive-name is a combined construct.
+  return !getLeafConstructs(D).empty() && !isCompositeConstruct(D);
+}
+
+} // namespace llvm::omp

>From 0f4bf060d080b156708ff6e9d3fa7987e7652b9c Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 7 Mar 2024 07:10:20 -0600
Subject: [PATCH 2/2] Draft/wip/preview of using leaf constructs

---
 clang/include/clang/Sema/Sema.h |  3 ++
 clang/lib/Basic/OpenMPKinds.cpp | 35 ++++++++++++---------
 clang/lib/Parse/ParseOpenMP.cpp | 28 ++++++++++++++---
 clang/lib/Sema/SemaOpenMP.cpp   | 54 ++++++++++++++++++++-------------
 4 files changed, 79 insertions(+), 41 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 267c79cc057cba..e5e62d5ea5e8ac 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -13718,6 +13718,9 @@ class Sema final {
   ///
   /// \returns Statement for finished OpenMP region.
   StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef<OMPClause *> Clauses);
+  StmtResult ActOnOpenMPRegionEnd(
+      StmtResult S, ArrayRef<OMPClause *> Clauses,
+      std::function<StmtResult(StmtResult)> callback);
   StmtResult ActOnOpenMPExecutableDirective(
       OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
       OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index b3e9affbb3e58a..289da880400c80 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -706,6 +706,11 @@ void clang::getOpenMPCaptureRegions(
     SmallVectorImpl<OpenMPDirectiveKind> &CaptureRegions,
     OpenMPDirectiveKind DKind) {
   assert(unsigned(DKind) < llvm::omp::Directive_enumSize);
+  if (isCombinedConstruct(DKind)) {
+    for (OpenMPDirectiveKind Leaf : getLeafConstructs(DKind))
+      getOpenMPCaptureRegions(CaptureRegions, Leaf);
+    return;
+  }
   switch (DKind) {
   case OMPD_metadirective:
     CaptureRegions.push_back(OMPD_metadirective);
@@ -713,15 +718,15 @@ void clang::getOpenMPCaptureRegions(
   case OMPD_parallel:
   case OMPD_parallel_for:
   case OMPD_parallel_for_simd:
-  case OMPD_parallel_master:
-  case OMPD_parallel_masked:
-  case OMPD_parallel_sections:
+  // case OMPD_parallel_master:
+  // case OMPD_parallel_masked:
+  // case OMPD_parallel_sections:
   case OMPD_distribute_parallel_for:
   case OMPD_distribute_parallel_for_simd:
-  case OMPD_parallel_loop:
+  // case OMPD_parallel_loop:
     CaptureRegions.push_back(OMPD_parallel);
     break;
-  case OMPD_target_teams:
+  // case OMPD_target_teams:
   case OMPD_target_teams_distribute:
   case OMPD_target_teams_distribute_simd:
     CaptureRegions.push_back(OMPD_task);
@@ -729,8 +734,8 @@ void clang::getOpenMPCaptureRegions(
     CaptureRegions.push_back(OMPD_teams);
     break;
   case OMPD_teams:
-  case OMPD_teams_distribute:
-  case OMPD_teams_distribute_simd:
+  // case OMPD_teams_distribute:
+  // case OMPD_teams_distribute_simd:
     CaptureRegions.push_back(OMPD_teams);
     break;
   case OMPD_target:
@@ -738,16 +743,16 @@ void clang::getOpenMPCaptureRegions(
     CaptureRegions.push_back(OMPD_task);
     CaptureRegions.push_back(OMPD_target);
     break;
-  case OMPD_teams_loop:
+  // case OMPD_teams_loop:
   case OMPD_teams_distribute_parallel_for:
   case OMPD_teams_distribute_parallel_for_simd:
     CaptureRegions.push_back(OMPD_teams);
     CaptureRegions.push_back(OMPD_parallel);
     break;
-  case OMPD_target_parallel:
+  // case OMPD_target_parallel:
   case OMPD_target_parallel_for:
   case OMPD_target_parallel_for_simd:
-  case OMPD_target_parallel_loop:
+  // case OMPD_target_parallel_loop:
     CaptureRegions.push_back(OMPD_task);
     CaptureRegions.push_back(OMPD_target);
     CaptureRegions.push_back(OMPD_parallel);
@@ -760,20 +765,20 @@ void clang::getOpenMPCaptureRegions(
     break;
   case OMPD_taskloop:
   case OMPD_taskloop_simd:
-  case OMPD_master_taskloop:
+  // case OMPD_master_taskloop:
   case OMPD_master_taskloop_simd:
-  case OMPD_masked_taskloop:
+  // case OMPD_masked_taskloop:
   case OMPD_masked_taskloop_simd:
     CaptureRegions.push_back(OMPD_taskloop);
     break;
-  case OMPD_parallel_masked_taskloop:
+  // case OMPD_parallel_masked_taskloop:
   case OMPD_parallel_masked_taskloop_simd:
-  case OMPD_parallel_master_taskloop:
+  // case OMPD_parallel_master_taskloop:
   case OMPD_parallel_master_taskloop_simd:
     CaptureRegions.push_back(OMPD_parallel);
     CaptureRegions.push_back(OMPD_taskloop);
     break;
-  case OMPD_target_teams_loop:
+  // case OMPD_target_teams_loop:
   case OMPD_target_teams_distribute_parallel_for:
   case OMPD_target_teams_distribute_parallel_for_simd:
     CaptureRegions.push_back(OMPD_task);
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 814126e321d3bc..711c3fb2ba9c1a 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2952,8 +2952,14 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
 
     StmtResult AssociatedStmt;
     if (HasAssociatedStatement) {
+      ArrayRef<OpenMPDirectiveKind> Leaves = getLeafConstructs(DKind);
       // The body is a block scope like in Lambdas and Blocks.
-      Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
+      if (isCombinedConstruct(DKind)) {
+        for (OpenMPDirectiveKind Leaf : Leaves)
+          Actions.ActOnOpenMPRegionStart(Leaf, getCurScope());
+      } else {
+        Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
+      }
       // FIXME: We create a bogus CompoundStmt scope to hold the contents of
       // the captured region. Code elsewhere assumes that any FunctionScopeInfo
       // should have at least one compound statement scope within it.
@@ -2966,7 +2972,17 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
             getLangOpts().OpenMPIRBuilder)
           AssociatedStmt = Actions.ActOnOpenMPLoopnest(AssociatedStmt.get());
       }
-      AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
+      if (!Leaves.empty()) {
+        size_t i = Leaves.size() - 1;
+        AssociatedStmt = Actions.ActOnOpenMPRegionEnd(
+            AssociatedStmt, Clauses, [&](StmtResult S) {
+              return Actions.ActOnOpenMPExecutableDirective(
+                  Leaves[i--], DirName, CancelRegion, Clauses, S.get(),
+                  Loc, EndLoc);
+            });
+      } else {
+        AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
+      }
     } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
                DKind == OMPD_target_exit_data) {
       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
@@ -2975,9 +2991,11 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
                                                   /*isStmtExpr=*/false));
       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
     }
-    Directive = Actions.ActOnOpenMPExecutableDirective(
-        DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
-        EndLoc);
+    if (!isCombinedConstruct(DKind)) {
+      Directive = Actions.ActOnOpenMPExecutableDirective(
+          DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
+          EndLoc);
+    }
 
     // Exit scope.
     Actions.EndOpenMPDSABlock(Directive.get());
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 0cc0cbacb37548..f9edacb7cc782b 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -4194,16 +4194,21 @@ static void handleDeclareVariantConstructTrait(DSAStackTy *Stack,
 }
 
 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
+  if (isCombinedConstruct(DKind)) {
+    for (OpenMPDirectiveKind Leaf : getLeafConstructs(DKind))
+      ActOnOpenMPRegionStart(Leaf, CurScope);
+    return;
+  }
   switch (DKind) {
   case OMPD_parallel:
-  case OMPD_parallel_for:
+  // case OMPD_parallel_for:
   case OMPD_parallel_for_simd:
-  case OMPD_parallel_sections:
-  case OMPD_parallel_master:
-  case OMPD_parallel_masked:
-  case OMPD_parallel_loop:
+  // case OMPD_parallel_sections:
+  // case OMPD_parallel_master:
+  // case OMPD_parallel_masked:
+  // case OMPD_parallel_loop:
   case OMPD_teams:
-  case OMPD_teams_distribute:
+  // case OMPD_teams_distribute:
   case OMPD_teams_distribute_simd: {
     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
     QualType KmpInt32PtrTy =
@@ -4217,12 +4222,12 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
                              Params);
     break;
   }
-  case OMPD_target_teams:
-  case OMPD_target_parallel:
-  case OMPD_target_parallel_for:
+  // case OMPD_target_teams:
+  // case OMPD_target_parallel:
+  // case OMPD_target_parallel_for:
   case OMPD_target_parallel_for_simd:
-  case OMPD_target_parallel_loop:
-  case OMPD_target_teams_distribute:
+  // case OMPD_target_parallel_loop:
+  // case OMPD_target_teams_distribute:
   case OMPD_target_teams_distribute_simd: {
     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
@@ -4269,8 +4274,8 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
                              ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
     break;
   }
-  case OMPD_target:
-  case OMPD_target_simd: {
+  case OMPD_target: {
+  // case OMPD_target_simd: {
     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
     QualType KmpInt32PtrTy =
@@ -4366,8 +4371,8 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
   }
   case OMPD_taskloop:
   case OMPD_taskloop_simd:
-  case OMPD_master_taskloop:
-  case OMPD_masked_taskloop:
+  // case OMPD_master_taskloop:
+  // case OMPD_masked_taskloop:
   case OMPD_masked_taskloop_simd:
   case OMPD_master_taskloop_simd: {
     QualType KmpInt32Ty =
@@ -4410,9 +4415,9 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
     break;
   }
-  case OMPD_parallel_masked_taskloop:
+  // case OMPD_parallel_masked_taskloop:
   case OMPD_parallel_masked_taskloop_simd:
-  case OMPD_parallel_master_taskloop:
+  // case OMPD_parallel_master_taskloop:
   case OMPD_parallel_master_taskloop_simd: {
     QualType KmpInt32Ty =
         Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
@@ -4478,7 +4483,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
                              Params);
     break;
   }
-  case OMPD_target_teams_loop:
+  // case OMPD_target_teams_loop:
   case OMPD_target_teams_distribute_parallel_for:
   case OMPD_target_teams_distribute_parallel_for_simd: {
     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
@@ -4539,7 +4544,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
     break;
   }
 
-  case OMPD_teams_loop:
+  // case OMPD_teams_loop:
   case OMPD_teams_distribute_parallel_for:
   case OMPD_teams_distribute_parallel_for_simd: {
     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
@@ -4802,8 +4807,14 @@ static bool checkOrderedOrderSpecified(Sema &S,
   return false;
 }
 
-StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
-                                      ArrayRef<OMPClause *> Clauses) {
+StmtResult
+Sema::ActOnOpenMPRegionEnd(StmtResult S, ArrayRef<OMPClause *> Clauses) {
+  return ActOnOpenMPRegionEnd(S, Clauses, [](StmtResult S) { return S; });
+}
+
+StmtResult
+Sema::ActOnOpenMPRegionEnd(StmtResult S, ArrayRef<OMPClause *> Clauses,
+                           std::function<StmtResult(StmtResult)> callback) {
   handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(),
                                      /* ScopeEntry */ false);
   if (DSAStack->getCurrentDirective() == OMPD_atomic ||
@@ -4974,6 +4985,7 @@ StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
     if (++CompletedRegions == CaptureRegions.size())
       DSAStack->setBodyComplete();
     SR = ActOnCapturedRegionEnd(SR.get());
+    SR = callback(SR);
   }
   return SR;
 }



More information about the cfe-commits mailing list