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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits