[clang] [llvm] [Frontend] Add leaf constructs and association to OpenMP/ACC directives (PR #83625)

via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 1 13:52:54 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Krzysztof Parzyszek (kparzysz)

<details>
<summary>Changes</summary>

Add members "leafs" and "association" to .td describing OpenMP/ACC directives: "leafs" are the leaf constructs for composite/combined constructs, and "association" is the source language construct to which the directive applies (e.g. loop, block, etc.)

The tblgen-generated output then contains two additional functions
- getLeafConstructs(D), and
- getDirectiveAssociation(D) plus "enum class Association", all in namespaces "llvm::omp" and "llvm::acc".

Note: getLeafConstructs returns an empty sequence for a construct that is itself a leaf construct.

Use the new functions to simplify a few OpenMP-related functions in clang.

---

Patch is 53.90 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/83625.diff


6 Files Affected:

- (modified) clang/lib/Basic/OpenMPKinds.cpp (+34-96) 
- (modified) llvm/include/llvm/Frontend/Directive/DirectiveBase.td (+36) 
- (modified) llvm/include/llvm/Frontend/OpenACC/ACC.td (+25-2) 
- (modified) llvm/include/llvm/Frontend/OpenMP/OMP.td (+152-20) 
- (modified) llvm/include/llvm/TableGen/DirectiveEmitter.h (+12) 
- (modified) llvm/utils/TableGen/DirectiveEmitter.cpp (+232-4) 


``````````diff
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 6c31b0824eb8a4..dd1a096d178111 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -574,31 +574,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
 }
 
 bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) {
-  return DKind == OMPD_simd || DKind == OMPD_for || DKind == OMPD_for_simd ||
-         DKind == OMPD_parallel_for || DKind == OMPD_parallel_for_simd ||
-         DKind == OMPD_taskloop || DKind == OMPD_taskloop_simd ||
-         DKind == OMPD_master_taskloop || DKind == OMPD_master_taskloop_simd ||
-         DKind == OMPD_parallel_master_taskloop ||
-         DKind == OMPD_parallel_master_taskloop_simd ||
-         DKind == OMPD_masked_taskloop || DKind == OMPD_masked_taskloop_simd ||
-         DKind == OMPD_parallel_masked_taskloop || DKind == OMPD_distribute ||
-         DKind == OMPD_parallel_masked_taskloop_simd ||
-         DKind == OMPD_target_parallel_for ||
-         DKind == OMPD_distribute_parallel_for ||
-         DKind == OMPD_distribute_parallel_for_simd ||
-         DKind == OMPD_distribute_simd ||
-         DKind == OMPD_target_parallel_for_simd || DKind == OMPD_target_simd ||
-         DKind == OMPD_teams_distribute ||
-         DKind == OMPD_teams_distribute_simd ||
-         DKind == OMPD_teams_distribute_parallel_for_simd ||
-         DKind == OMPD_teams_distribute_parallel_for ||
-         DKind == OMPD_target_teams_distribute ||
-         DKind == OMPD_target_teams_distribute_parallel_for ||
-         DKind == OMPD_target_teams_distribute_parallel_for_simd ||
-         DKind == OMPD_target_teams_distribute_simd || DKind == OMPD_tile ||
-         DKind == OMPD_unroll || DKind == OMPD_loop ||
-         DKind == OMPD_teams_loop || DKind == OMPD_target_teams_loop ||
-         DKind == OMPD_parallel_loop || DKind == OMPD_target_parallel_loop;
+  return getDirectiveAssociation(DKind) == Association::Loop;
 }
 
 bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
@@ -619,44 +595,22 @@ bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
 }
 
 bool clang::isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind) {
-  return DKind == OMPD_taskloop || DKind == OMPD_taskloop_simd ||
-         DKind == OMPD_master_taskloop || DKind == OMPD_master_taskloop_simd ||
-         DKind == OMPD_parallel_master_taskloop ||
-         DKind == OMPD_masked_taskloop || DKind == OMPD_masked_taskloop_simd ||
-         DKind == OMPD_parallel_masked_taskloop ||
-         DKind == OMPD_parallel_masked_taskloop_simd ||
-         DKind == OMPD_parallel_master_taskloop_simd;
+  return DKind == OMPD_taskloop ||
+         llvm::is_contained(getLeafConstructs(DKind), OMPD_taskloop);
 }
 
 bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) {
-  return DKind == OMPD_parallel || DKind == OMPD_parallel_for ||
-         DKind == OMPD_parallel_for_simd || DKind == OMPD_parallel_sections ||
-         DKind == OMPD_target_parallel || DKind == OMPD_target_parallel_for ||
-         DKind == OMPD_distribute_parallel_for ||
-         DKind == OMPD_distribute_parallel_for_simd ||
-         DKind == OMPD_target_parallel_for_simd ||
-         DKind == OMPD_teams_distribute_parallel_for ||
-         DKind == OMPD_teams_distribute_parallel_for_simd ||
-         DKind == OMPD_target_teams_distribute_parallel_for ||
-         DKind == OMPD_target_teams_distribute_parallel_for_simd ||
-         DKind == OMPD_parallel_master || DKind == OMPD_parallel_masked ||
-         DKind == OMPD_parallel_master_taskloop ||
-         DKind == OMPD_parallel_master_taskloop_simd ||
-         DKind == OMPD_parallel_masked_taskloop ||
-         DKind == OMPD_parallel_masked_taskloop_simd ||
-         DKind == OMPD_parallel_loop || DKind == OMPD_target_parallel_loop ||
-         DKind == OMPD_teams_loop;
+  if (DKind == OMPD_parallel_workshare)
+    return false;
+  if (DKind == OMPD_teams_loop)
+    return true;
+  return DKind == OMPD_parallel ||
+         llvm::is_contained(getLeafConstructs(DKind), OMPD_parallel);
 }
 
 bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) {
-  return DKind == OMPD_target || DKind == OMPD_target_parallel ||
-         DKind == OMPD_target_parallel_for ||
-         DKind == OMPD_target_parallel_for_simd || DKind == OMPD_target_simd ||
-         DKind == OMPD_target_teams || DKind == OMPD_target_teams_distribute ||
-         DKind == OMPD_target_teams_distribute_parallel_for ||
-         DKind == OMPD_target_teams_distribute_parallel_for_simd ||
-         DKind == OMPD_target_teams_distribute_simd ||
-         DKind == OMPD_target_teams_loop || DKind == OMPD_target_parallel_loop;
+  return DKind == OMPD_target ||
+         llvm::is_contained(getLeafConstructs(DKind), OMPD_target);
 }
 
 bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) {
@@ -665,60 +619,44 @@ bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) {
 }
 
 bool clang::isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind) {
-  return DKind == OMPD_teams || DKind == OMPD_teams_distribute ||
-         DKind == OMPD_teams_distribute_simd ||
-         DKind == OMPD_teams_distribute_parallel_for_simd ||
-         DKind == OMPD_teams_distribute_parallel_for ||
-         DKind == OMPD_teams_loop;
+  if (DKind == OMPD_teams)
+    return true;
+  auto leafs = getLeafConstructs(DKind);
+  return !leafs.empty() && leafs.front() == OMPD_teams;
 }
 
 bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) {
-  return isOpenMPNestingTeamsDirective(DKind) || DKind == OMPD_target_teams ||
-         DKind == OMPD_target_teams_distribute ||
-         DKind == OMPD_target_teams_distribute_parallel_for ||
-         DKind == OMPD_target_teams_distribute_parallel_for_simd ||
-         DKind == OMPD_target_teams_distribute_simd ||
-         DKind == OMPD_target_teams_loop;
+  return DKind == OMPD_teams ||
+         llvm::is_contained(getLeafConstructs(DKind), OMPD_teams);
 }
 
 bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) {
-  return DKind == OMPD_simd || DKind == OMPD_for_simd ||
-         DKind == OMPD_parallel_for_simd || DKind == OMPD_taskloop_simd ||
-         DKind == OMPD_master_taskloop_simd ||
-         DKind == OMPD_masked_taskloop_simd ||
-         DKind == OMPD_parallel_master_taskloop_simd ||
-         DKind == OMPD_parallel_masked_taskloop_simd ||
-         DKind == OMPD_distribute_parallel_for_simd ||
-         DKind == OMPD_distribute_simd || DKind == OMPD_target_simd ||
-         DKind == OMPD_teams_distribute_simd ||
-         DKind == OMPD_teams_distribute_parallel_for_simd ||
-         DKind == OMPD_target_teams_distribute_parallel_for_simd ||
-         DKind == OMPD_target_teams_distribute_simd ||
-         DKind == OMPD_target_parallel_for_simd;
+  // Avoid OMPD_declare_simd
+  if (DKind == OMPD_end_do_simd ||
+      getDirectiveAssociation(DKind) != Association::Loop)
+    return false;
+
+  return DKind == OMPD_simd ||
+         llvm::is_contained(getLeafConstructs(DKind), OMPD_simd);
 }
 
 bool clang::isOpenMPNestingDistributeDirective(OpenMPDirectiveKind Kind) {
-  return Kind == OMPD_distribute || Kind == OMPD_distribute_parallel_for ||
-         Kind == OMPD_distribute_parallel_for_simd ||
-         Kind == OMPD_distribute_simd;
-  // TODO add next directives.
+  if (Kind == OMPD_distribute)
+    return true;
+  auto leafs = getLeafConstructs(Kind);
+  return !leafs.empty() && leafs.front() == OMPD_distribute;
 }
 
 bool clang::isOpenMPDistributeDirective(OpenMPDirectiveKind Kind) {
-  return isOpenMPNestingDistributeDirective(Kind) ||
-         Kind == OMPD_teams_distribute || Kind == OMPD_teams_distribute_simd ||
-         Kind == OMPD_teams_distribute_parallel_for_simd ||
-         Kind == OMPD_teams_distribute_parallel_for ||
-         Kind == OMPD_target_teams_distribute ||
-         Kind == OMPD_target_teams_distribute_parallel_for ||
-         Kind == OMPD_target_teams_distribute_parallel_for_simd ||
-         Kind == OMPD_target_teams_distribute_simd;
+  return Kind == OMPD_distribute ||
+         llvm::is_contained(getLeafConstructs(Kind), OMPD_distribute);
 }
 
 bool clang::isOpenMPGenericLoopDirective(OpenMPDirectiveKind Kind) {
-  return Kind == OMPD_loop || Kind == OMPD_teams_loop ||
-         Kind == OMPD_target_teams_loop || Kind == OMPD_parallel_loop ||
-         Kind == OMPD_target_parallel_loop;
+  if (Kind == OMPD_loop)
+    return true;
+  auto leafs = getLeafConstructs(Kind);
+  return !leafs.empty() && leafs.back() == OMPD_loop;
 }
 
 bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) {
diff --git a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td
index 31578710365b21..4d5201aabe8afb 100644
--- a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td
+++ b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td
@@ -127,6 +127,35 @@ class VersionedClause<Clause c, int min = 1, int max = 0x7FFFFFFF> {
   int maxVersion = max;
 }
 
+// Kinds of directive associations.
+class Association<string n> {
+  string name = n;  // Name of the enum value in enum class Association.
+}
+// All of the AS_Xyz names are recognized by TableGen in order to calculate
+// the association in the AS_FromLeafs case.
+def AS_None : Association<"None"> {}              // No association
+def AS_Block : Association<"Block"> {}            // Block (incl. single
+                                                  // statement)
+def AS_Declaration : Association<"Declaration"> {}   // Declaration
+def AS_Delimited : Association<"Delimited"> {}    // Region delimited with
+                                                  // begin/end
+def AS_Loop : Association<"Loop"> {}              // Loop
+def AS_Separating : Association<"Separating"> {}  // Separates parts of a
+                                                  // construct
+
+def AS_FromLeafs : Association<"FromLeafs"> {}    // See below
+// AS_FromLeafs can be used for combined/composite directives, and the actual
+// association will be computed based on associations of the leaf constructs:
+//   (x + y) + z = x + (y + z)
+//   x + y = y + x
+//   x + x = x
+//   AS_None + x = x
+//   AS_Block + AS_Loop = AS_Loop
+// Other combinations are not allowed.
+// This association is not valid for leaf constructs.
+// The name "AS_FromLeafs" is recognized by TableGen, and there is no enum
+// generated for it.
+
 // Information about a specific directive.
 class Directive<string d> {
   // Name of the directive. Can be composite directive sepearted by whitespace.
@@ -152,6 +181,13 @@ class Directive<string d> {
   // List of clauses that are required.
   list<VersionedClause> requiredClauses = [];
 
+  // List of leaf constituent directives in the order in which they appear
+  // in the combined/composite directive.
+  list<Directive> leafs = [];
+
   // Set directive used by default when unknown.
   bit isDefault = false;
+
+  // What the directive is associated with.
+  Association association = AS_FromLeafs;
 }
diff --git a/llvm/include/llvm/Frontend/OpenACC/ACC.td b/llvm/include/llvm/Frontend/OpenACC/ACC.td
index 0dbd934d83f064..3c8cc1af0518b1 100644
--- a/llvm/include/llvm/Frontend/OpenACC/ACC.td
+++ b/llvm/include/llvm/Frontend/OpenACC/ACC.td
@@ -266,7 +266,9 @@ def ACCC_Unknown : Clause<"unknown"> {
 //===----------------------------------------------------------------------===//
 
 // 2.12
-def ACC_Atomic : Directive<"atomic"> {}
+def ACC_Atomic : Directive<"atomic"> {
+  let association = AS_Block;
+}
 
 // 2.6.5
 def ACC_Data : Directive<"data"> {
@@ -290,6 +292,7 @@ def ACC_Data : Directive<"data"> {
     VersionedClause<ACCC_NoCreate>,
     VersionedClause<ACCC_Present>
   ];
+  let association = AS_Block;
 }
 
 // 2.13
@@ -304,6 +307,7 @@ def ACC_Declare : Directive<"declare"> {
     VersionedClause<ACCC_DeviceResident>,
     VersionedClause<ACCC_Link>
   ];
+  let association = AS_None;
 }
 
 // 2.5.3
@@ -329,6 +333,7 @@ def ACC_Kernels : Directive<"kernels"> {
     VersionedClause<ACCC_Self>,
     VersionedClause<ACCC_VectorLength>
   ];
+  let association = AS_Block;
 }
 
 // 2.5.1
@@ -357,6 +362,7 @@ def ACC_Parallel : Directive<"parallel"> {
     VersionedClause<ACCC_If>,
     VersionedClause<ACCC_Self>
   ];
+  let association = AS_Block;
 }
 
 // 2.5.2
@@ -384,6 +390,7 @@ def ACC_Serial : Directive<"serial"> {
     VersionedClause<ACCC_If>,
     VersionedClause<ACCC_Self>
   ];
+  let association = AS_Block;
 }
 
 // 2.9
@@ -403,10 +410,13 @@ def ACC_Loop : Directive<"loop"> {
     VersionedClause<ACCC_Independent>,
     VersionedClause<ACCC_Seq>
   ];
+  let association = AS_Loop;
 }
 
 // 2.10
-def ACC_Cache : Directive<"cache"> {}
+def ACC_Cache : Directive<"cache"> {
+  let association = AS_None;
+}
 
 // 2.14.1
 def ACC_Init : Directive<"init"> {
@@ -415,6 +425,7 @@ def ACC_Init : Directive<"init"> {
     VersionedClause<ACCC_DeviceType>,
     VersionedClause<ACCC_If>
   ];
+  let association = AS_None;
 }
 
 // 2.15.1
@@ -430,6 +441,7 @@ def ACC_Routine : Directive<"routine"> {
   let allowedOnceClauses = [
     VersionedClause<ACCC_NoHost>
   ];
+  let association = AS_Declaration;
 }
 
 // 2.14.3
@@ -448,6 +460,7 @@ def ACC_Set : Directive<"set"> {
     VersionedClause<ACCC_DeviceNum>,
     VersionedClause<ACCC_DeviceType>
   ];
+  let association = AS_None;
 }
 
 // 2.14.2
@@ -457,6 +470,7 @@ def ACC_Shutdown : Directive<"shutdown"> {
     VersionedClause<ACCC_DeviceType>,
     VersionedClause<ACCC_If>
   ];
+  let association = AS_None;
 }
 
 // 2.14.4
@@ -475,6 +489,7 @@ def ACC_Update : Directive<"update"> {
     VersionedClause<ACCC_Host>,
     VersionedClause<ACCC_Self>
   ];
+  let association = AS_None;
 }
 
 // 2.16.3
@@ -483,6 +498,7 @@ def ACC_Wait : Directive<"wait"> {
     VersionedClause<ACCC_Async>,
     VersionedClause<ACCC_If>
   ];
+  let association = AS_None;
 }
 
 // 2.14.6
@@ -499,6 +515,7 @@ def ACC_EnterData : Directive<"enter data"> {
     VersionedClause<ACCC_Create>,
     VersionedClause<ACCC_Copyin>
   ];
+  let association = AS_None;
 }
 
 // 2.14.7
@@ -516,6 +533,7 @@ def ACC_ExitData : Directive<"exit data"> {
     VersionedClause<ACCC_Delete>,
     VersionedClause<ACCC_Detach>
   ];
+  let association = AS_None;
 }
 
 // 2.8
@@ -527,6 +545,7 @@ def ACC_HostData : Directive<"host_data"> {
   let requiredClauses = [
     VersionedClause<ACCC_UseDevice>
   ];
+  let association = AS_Block;
 }
 
 // 2.11
@@ -564,6 +583,7 @@ def ACC_KernelsLoop : Directive<"kernels loop"> {
     VersionedClause<ACCC_Independent>,
     VersionedClause<ACCC_Seq>
   ];
+  let leafs = [ACC_Kernels, ACC_Loop];
 }
 
 // 2.11
@@ -602,6 +622,7 @@ def ACC_ParallelLoop : Directive<"parallel loop"> {
     VersionedClause<ACCC_Independent>,
     VersionedClause<ACCC_Seq>
   ];
+  let leafs = [ACC_Parallel, ACC_Loop];
 }
 
 // 2.11
@@ -637,8 +658,10 @@ def ACC_SerialLoop : Directive<"serial loop"> {
     VersionedClause<ACCC_Independent>,
     VersionedClause<ACCC_Seq>
   ];
+  let leafs = [ACC_Serial, ACC_Loop];
 }
 
 def ACC_Unknown : Directive<"unknown"> {
   let isDefault = true;
+  let association = AS_None;
 }
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 77d207f2b10a83..fecc49e888a454 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -463,7 +463,9 @@ def OMPC_OMX_Bare : Clause<"ompx_bare"> {
 // Definition of OpenMP directives
 //===----------------------------------------------------------------------===//
 
-def OMP_ThreadPrivate : Directive<"threadprivate"> {}
+def OMP_ThreadPrivate : Directive<"threadprivate"> {
+  let association = AS_None;
+}
 def OMP_Parallel : Directive<"parallel"> {
   let allowedClauses = [
     VersionedClause<OMPC_Private>,
@@ -480,6 +482,7 @@ def OMP_Parallel : Directive<"parallel"> {
     VersionedClause<OMPC_NumThreads>,
     VersionedClause<OMPC_ProcBind>,
   ];
+  let association = AS_Block;
 }
 def OMP_Task : Directive<"task"> {
   let allowedClauses = [
@@ -500,6 +503,7 @@ def OMP_Task : Directive<"task"> {
     VersionedClause<OMPC_Final>,
     VersionedClause<OMPC_Priority>
   ];
+  let association = AS_Block;
 }
 def OMP_Simd : Directive<"simd"> {
   let allowedClauses = [
@@ -518,17 +522,20 @@ def OMP_Simd : Directive<"simd"> {
     VersionedClause<OMPC_If, 50>,
     VersionedClause<OMPC_Order, 50>
   ];
+  let association = AS_Loop;
 }
 def OMP_Tile : Directive<"tile"> {
   let allowedOnceClauses = [
     VersionedClause<OMPC_Sizes, 51>,
   ];
+  let association = AS_Loop;
 }
 def OMP_Unroll : Directive<"unroll"> {
   let allowedOnceClauses = [
     VersionedClause<OMPC_Full, 51>,
     VersionedClause<OMPC_Partial, 51>,
   ];
+  let association = AS_Loop;
 }
 def OMP_For : Directive<"for"> {
   let allowedClauses = [
@@ -544,6 +551,7 @@ def OMP_For : Directive<"for"> {
     VersionedClause<OMPC_Allocate>,
     VersionedClause<OMPC_Order, 50>
   ];
+  let association = AS_Loop;
 }
 def OMP_Do : Directive<"do"> {
   let allowedClauses = [
@@ -560,6 +568,7 @@ def OMP_Do : Directive<"do"> {
     VersionedClause<OMPC_NoWait>,
     VersionedClause<OMPC_Order, 50>
   ];
+  let association = AS_Loop;
 }
 def OMP_Sections : Directive<"sections"> {
   let allowedClauses = [
@@ -570,8 +579,11 @@ def OMP_Sections : Directive<"sections"> {
     VersionedClause<OMPC_NoWait>,
     VersionedClause<OMPC_Allocate>
   ];
+  let association = AS_Block;
+}
+def OMP_Section : Directive<"section"> {
+  let association = AS_Separating;
 }
-def OMP_Section : Directive<"section"> {}
 def OMP_Single : Directive<"single"> {
   let allowedClauses = [
     VersionedClause<OMPC_Private>,
@@ -580,33 +592,44 @@ def OMP_Single : Directive<"single"> {
     VersionedClause<OMPC_NoWait>,
     VersionedClause<OMPC_Allocate>
   ];
+  let association = AS_Block;
+}
+def OMP_Master : Directive<"master"> {
+  let association = AS_Block;
 }
-def OMP_Master : Directive<"master"> {}
 def OMP_Critical : Directive<"critical"> {
   let allowedClauses = [
     VersionedClause<OMPC_Hint>
   ];
+  let association = AS_Block;
+}
+def OMP_TaskYield : Directive<"taskyield"> {
+  let association = AS_None;
+}
+def OMP_Barrier : Directive<"barrier"> {
+  let association = AS_None;
 }
-def OMP_TaskYield : Directive<"taskyield"> {}
-def OMP_Barrier : Directive<"barrier"> {}
 def OMP_Error : Directive<"error"> {
   let allowedClauses = [
     VersionedClause<OMPC_At, 51>,
     VersionedClause<OMPC_Severity, 51>,
     VersionedClause<OMPC_Message, 51>
   ];
+  let association = AS_None;
 }
 def OMP_TaskWait : Directive<"taskwait"> {
   let allowedClauses = [
     VersionedClause<OMPC_Depend, 50>,
     VersionedClause<OMPC_NoWait, 51>
   ];
+  let association = AS_None;
 }
 def OMP_TaskGroup : Directive<"taskgroup"> {
   let allowedClauses = [
     VersionedClause<OMPC_TaskReduction, 50>,
     VersionedClause<OMPC_Allocate, 50>
   ];
+  let association = AS_Block;
 }
 def OMP_Flush : Directive<"flush"> {
   let allowedOnceClauses = [
@@ -617,6 +640,7 @@ def OMP_Flush : Directive<"flush"> {
     // OMPKinds.def.
     VersionedClause<OMPC_Flush>
   ];
+  let association = AS_None;
 }
 def OMP_Ordered : Directive<"ordered"> {
   let allowedClauses = [
@@ -627,6 +651,8 @@ def OMP_Ordered : Directive<"ordered"> {
     VersionedClause<OMPC_Threads>,
     VersionedClause<OMPC_Simd>
   ];
+  let association = AS_None;
+  // There is also a block-associated "ordered" directive.
 }
 def OMP_Atomic : Directive<"atomic"> {
   let allowedClauses = [
@@ -646,6 +672,7 @@ def OMP_Atomic : Directive<"atomic"> {
     VersionedClause<OMPC_Fail, 51>,
     VersionedClause<OMPC_Weak, 51>
   ];
+  let association = AS_Block;
 }
 def OMP_Target : Directive<"target"> {
   let allowedClauses = [
@@ -669,6 +696,7 @@ def OMP_Target : Directive<"target"> {
     VersionedClause<OMPC_NoWait>,
     VersionedClause<OMPC_OMPX_DynCGroupMem>,
   ];
+  let association = AS_Block;
 }
 def OMP_Teams : Directive<"teams"> {
   let allowedClauses = [
@@ -685,11 +713,13 @@ def OMP_Teams : Directive<"teams"> {
     VersionedClause<OMPC_NumTeams>,
     VersionedClause<OMPC_ThreadLimit>
   ];
+  let association = AS_Block;
 }
 def OMP_Cancel : Directive<"cancel"> {
   let allowedOnceClauses = [
     VersionedClause<OMPC_If>
   ];
+  let association = AS_None;
 }
 def OMP_Req...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/83625


More information about the cfe-commits mailing list