[clang] [clang][OpenMP] Implement `isOpenMPCapturingDirective` (PR #97090)

Krzysztof Parzyszek via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 1 06:38:00 PDT 2024


https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/97090

>From 789ec614d285e3fe632aae6280f6c4cf01746cdf Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Fri, 28 Jun 2024 12:27:10 -0500
Subject: [PATCH 1/5] [clang][OpenMP] Implement `isOpenMPExecutableDirective`

What is considered "executable" in clang differs slightly from the
OpenMP's "executable" category. In addition to the executable
category, subsidiary directives, and OMPD_error are considered
executable.

Implement a function that performs that check.
---
 clang/include/clang/Basic/OpenMPKinds.h | 8 ++++++++
 clang/lib/Basic/OpenMPKinds.cpp         | 7 +++++++
 clang/lib/Parse/ParseOpenMP.cpp         | 6 ++----
 clang/lib/Sema/SemaOpenMP.cpp           | 2 ++
 4 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h
index d127498774c7f..6d9d6ebc58e2c 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -368,6 +368,14 @@ bool needsTaskBasedThreadLimit(OpenMPDirectiveKind DKind);
 /// is restricted only to memory order clauses of "OMPC_acquire",
 /// "OMPC_relaxed" and "OMPC_seq_cst".
 bool checkFailClauseParameter(OpenMPClauseKind FailClauseParameter);
+
+/// Checks if the specified directive is considered as "executable". This
+/// combines the OpenMP categories of "executable" and "subsidiary", plus
+/// any other directives that are should be treated as executable.
+/// \param DKind Specified directive.
+/// \return true - if the above condition is met for this directive
+/// otherwise - false.
+bool isOpenMPExecutableDirective(OpenMPDirectiveKind DKind);
 }
 
 #endif
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index b3e9affbb3e58..7c8990880fae3 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -702,6 +702,13 @@ bool clang::needsTaskBasedThreadLimit(OpenMPDirectiveKind DKind) {
          DKind == OMPD_target_parallel_loop;
 }
 
+bool clang::isOpenMPExecutableDirective(OpenMPDirectiveKind DKind) {
+  if (DKind == OMPD_error)
+    return true;
+  Category Cat = getDirectiveCategory(DKind);
+  return Cat == Category::Executable || Cat == Category::Subsidiary;
+}
+
 void clang::getOpenMPCaptureRegions(
     SmallVectorImpl<OpenMPDirectiveKind> &CaptureRegions,
     OpenMPDirectiveKind DKind) {
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 00f9ebb65d876..326cd22ff9005 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2397,10 +2397,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
 StmtResult Parser::ParseOpenMPExecutableDirective(
     ParsedStmtContext StmtCtx, OpenMPDirectiveKind DKind, SourceLocation Loc,
     bool ReadDirectiveWithinMetadirective) {
-  assert((DKind == OMPD_error ||
-          getDirectiveCategory(DKind) == Category::Executable ||
-          getDirectiveCategory(DKind) == Category::Subsidiary) &&
-         "Directive with an unexpected category");
+  assert(isOpenMPExecutableDirective(DKind) && "Unexpected directive category");
+
   bool HasAssociatedStatement = true;
   Association Assoc = getDirectiveAssociation(DKind);
 
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 29104b2c0de94..b17c7e2be968e 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -6357,6 +6357,8 @@ StmtResult SemaOpenMP::ActOnOpenMPExecutableDirective(
     OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc,
     OpenMPDirectiveKind PrevMappedDirective) {
+  assert(isOpenMPExecutableDirective(Kind) && "Unexpected directive category");
+
   StmtResult Res = StmtError();
   OpenMPBindClauseKind BindKind = OMPC_BIND_unknown;
   llvm::SmallVector<OMPClause *> ClausesWithoutBind;

>From 0ee7c0154dee86e25c05f09828637eaf9bb8ec27 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Fri, 28 Jun 2024 12:31:35 -0500
Subject: [PATCH 2/5] [clang][OpenMP] Implement `isOpenMPCapturingDirective`

Check if the given directive can capture variables, and thus needs
a captured statement.

Simplify some code using this function.
---
 clang/include/clang/Basic/OpenMPKinds.h |  6 +++
 clang/lib/Basic/OpenMPKinds.cpp         | 66 +++++++++++++------------
 clang/lib/Sema/SemaOpenMP.cpp           | 14 +-----
 3 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h
index 6d9d6ebc58e2c..3f21766f392cf 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -376,6 +376,12 @@ bool checkFailClauseParameter(OpenMPClauseKind FailClauseParameter);
 /// \return true - if the above condition is met for this directive
 /// otherwise - false.
 bool isOpenMPExecutableDirective(OpenMPDirectiveKind DKind);
+
+/// Checks if the specified directive need to capture variables.
+/// \param DKind Specified directive.
+/// \return true - if the above condition is met for this directive
+/// otherwise - false.
+bool isOpenMPCapturingDirective(OpenMPDirectiveKind DKind);
 }
 
 #endif
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 7c8990880fae3..30c34c207ae23 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -709,10 +709,44 @@ bool clang::isOpenMPExecutableDirective(OpenMPDirectiveKind DKind) {
   return Cat == Category::Executable || Cat == Category::Subsidiary;
 }
 
+bool clang::isOpenMPCapturingDirective(OpenMPDirectiveKind DKind) {
+  if (isOpenMPExecutableDirective(DKind)) {
+    switch (DKind) {
+    case OMPD_atomic:
+    case OMPD_barrier:
+    case OMPD_cancel:
+    case OMPD_cancellation_point:
+    case OMPD_critical:
+    case OMPD_depobj:
+    case OMPD_error:
+    case OMPD_flush:
+    case OMPD_masked:
+    case OMPD_master:
+    case OMPD_section:
+    case OMPD_taskwait:
+    case OMPD_taskyield:
+      return false;
+    default:
+      return !isOpenMPLoopTransformationDirective(DKind);
+    }
+  }
+  // Non-executable directives.
+  switch (DKind) {
+  case OMPD_metadirective:
+  case OMPD_nothing:
+    return true;
+  default:
+    break;
+  }
+  return false;
+}
+
 void clang::getOpenMPCaptureRegions(
     SmallVectorImpl<OpenMPDirectiveKind> &CaptureRegions,
     OpenMPDirectiveKind DKind) {
   assert(unsigned(DKind) < llvm::omp::Directive_enumSize);
+  assert(isOpenMPCapturingDirective(DKind));
+
   switch (DKind) {
   case OMPD_metadirective:
     CaptureRegions.push_back(OMPD_metadirective);
@@ -799,48 +833,18 @@ void clang::getOpenMPCaptureRegions(
   case OMPD_for:
   case OMPD_for_simd:
   case OMPD_sections:
-  case OMPD_section:
   case OMPD_single:
-  case OMPD_master:
-  case OMPD_critical:
   case OMPD_taskgroup:
   case OMPD_distribute:
   case OMPD_ordered:
-  case OMPD_atomic:
   case OMPD_target_data:
   case OMPD_distribute_simd:
   case OMPD_scope:
   case OMPD_dispatch:
     CaptureRegions.push_back(OMPD_unknown);
     break;
-  case OMPD_tile:
-  case OMPD_unroll:
-    // loop transformations do not introduce captures.
-    break;
-  case OMPD_threadprivate:
-  case OMPD_allocate:
-  case OMPD_taskyield:
-  case OMPD_barrier:
-  case OMPD_error:
-  case OMPD_taskwait:
-  case OMPD_cancellation_point:
-  case OMPD_cancel:
-  case OMPD_flush:
-  case OMPD_depobj:
-  case OMPD_scan:
-  case OMPD_declare_reduction:
-  case OMPD_declare_mapper:
-  case OMPD_declare_simd:
-  case OMPD_declare_target:
-  case OMPD_end_declare_target:
-  case OMPD_requires:
-  case OMPD_declare_variant:
-  case OMPD_begin_declare_variant:
-  case OMPD_end_declare_variant:
-    llvm_unreachable("OpenMP Directive is not allowed");
-  case OMPD_unknown:
   default:
-    llvm_unreachable("Unknown OpenMP directive");
+    llvm_unreachable("Unhandled OpenMP directive");
   }
 }
 
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index b17c7e2be968e..a741339a7d669 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -4862,11 +4862,7 @@ StmtResult SemaOpenMP::ActOnOpenMPRegionEnd(StmtResult S,
                                             ArrayRef<OMPClause *> Clauses) {
   handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(),
                                      /* ScopeEntry */ false);
-  if (DSAStack->getCurrentDirective() == OMPD_atomic ||
-      DSAStack->getCurrentDirective() == OMPD_critical ||
-      DSAStack->getCurrentDirective() == OMPD_section ||
-      DSAStack->getCurrentDirective() == OMPD_master ||
-      DSAStack->getCurrentDirective() == OMPD_masked)
+  if (!isOpenMPCapturingDirective(DSAStack->getCurrentDirective()))
     return S;
 
   bool ErrorFound = false;
@@ -4909,10 +4905,6 @@ StmtResult SemaOpenMP::ActOnOpenMPRegionEnd(StmtResult S,
         }
       }
       DSAStack->setForceVarCapturing(/*V=*/false);
-    } else if (isOpenMPLoopTransformationDirective(
-                   DSAStack->getCurrentDirective())) {
-      assert(CaptureRegions.empty() &&
-             "No captured regions in loop transformation directives.");
     } else if (CaptureRegions.size() > 1 ||
                CaptureRegions.back() != OMPD_unknown) {
       if (auto *C = OMPClauseWithPreInit::get(Clause))
@@ -6400,9 +6392,7 @@ StmtResult SemaOpenMP::ActOnOpenMPExecutableDirective(
     ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
   }
   if (AStmt && !SemaRef.CurContext->isDependentContext() &&
-      Kind != OMPD_atomic && Kind != OMPD_critical && Kind != OMPD_section &&
-      Kind != OMPD_master && Kind != OMPD_masked &&
-      !isOpenMPLoopTransformationDirective(Kind)) {
+      isOpenMPCapturingDirective(Kind)) {
     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
 
     // Check default data sharing attributes for referenced variables.

>From c9015325dcf0444907fa5b94cb37c5f7f42020a7 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Fri, 28 Jun 2024 13:00:41 -0500
Subject: [PATCH 3/5] fix typo

---
 clang/include/clang/Basic/OpenMPKinds.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h
index 3f21766f392cf..123f8fe9f2d1c 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -377,7 +377,7 @@ bool checkFailClauseParameter(OpenMPClauseKind FailClauseParameter);
 /// otherwise - false.
 bool isOpenMPExecutableDirective(OpenMPDirectiveKind DKind);
 
-/// Checks if the specified directive need to capture variables.
+/// Checks if the specified directive can capture variables.
 /// \param DKind Specified directive.
 /// \return true - if the above condition is met for this directive
 /// otherwise - false.

>From 1d5ca2e5309924bc9d4e1bf1f382b08ad6b20805 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Fri, 28 Jun 2024 13:22:11 -0500
Subject: [PATCH 4/5] Fix wording

---
 clang/include/clang/Basic/OpenMPKinds.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h
index 6d9d6ebc58e2c..29a852d666511 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -371,7 +371,7 @@ bool checkFailClauseParameter(OpenMPClauseKind FailClauseParameter);
 
 /// Checks if the specified directive is considered as "executable". This
 /// combines the OpenMP categories of "executable" and "subsidiary", plus
-/// any other directives that are should be treated as executable.
+/// any other directives that should be treated as executable.
 /// \param DKind Specified directive.
 /// \return true - if the above condition is met for this directive
 /// otherwise - false.

>From 3753e4cdf8e2aa9b1af2ba7a88cfecae842d2e7f Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Mon, 1 Jul 2024 08:17:30 -0500
Subject: [PATCH 5/5] Add assertion message

---
 clang/lib/Basic/OpenMPKinds.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 30c34c207ae23..df172dce30058 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -745,7 +745,7 @@ void clang::getOpenMPCaptureRegions(
     SmallVectorImpl<OpenMPDirectiveKind> &CaptureRegions,
     OpenMPDirectiveKind DKind) {
   assert(unsigned(DKind) < llvm::omp::Directive_enumSize);
-  assert(isOpenMPCapturingDirective(DKind));
+  assert(isOpenMPCapturingDirective(DKind) && "Expecting capturing directive");
 
   switch (DKind) {
   case OMPD_metadirective:



More information about the cfe-commits mailing list