https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/168934
OpenMP 6.0 introduced a `fuse` directive, and with it a "loop sequence" as the associated code. What used to be "loop association" has become "loop-nest association". Rename Association::Loop to LoopNest, add Association::LoopSeq to represent the "loop sequence" association. Change the association of fuse from "block" to "loop sequence". >From 01a417701b5a758910d17ecfb1f4e99fca0f5e9d Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek <[email protected]> Date: Thu, 20 Nov 2025 13:14:16 -0600 Subject: [PATCH] [OpenMP] Introduce "loop sequence" as directive association OpenMP 6.0 introduced a `fuse` directive, and with it a "loop sequence" as the associated code. What used to be "loop association" has become "loop-nest association". Rename Association::Loop to LoopNest, add Association::LoopSeq to represent the "loop sequence" association. Change the association of fuse from "block" to "loop sequence". --- clang/lib/Basic/OpenMPKinds.cpp | 4 ++-- flang/lib/Lower/OpenMP/OpenMP.cpp | 4 ++-- .../llvm/Frontend/Directive/DirectiveBase.td | 5 ++-- llvm/include/llvm/Frontend/OpenACC/ACC.td | 2 +- llvm/include/llvm/Frontend/OpenMP/OMP.td | 24 +++++++++---------- llvm/lib/Frontend/OpenMP/OMP.cpp | 4 ++-- llvm/test/TableGen/directive1.td | 5 ++-- llvm/test/TableGen/directive2.td | 5 ++-- .../utils/TableGen/Basic/DirectiveEmitter.cpp | 19 ++++++++------- 9 files changed, 38 insertions(+), 34 deletions(-) diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 8e60fc26a7947..03485b7e81abc 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -680,7 +680,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, } bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) { - return getDirectiveAssociation(DKind) == Association::Loop; + return getDirectiveAssociation(DKind) == Association::LoopNest; } bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) { @@ -741,7 +741,7 @@ bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) { bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) { // Avoid OMPD_declare_simd - if (getDirectiveAssociation(DKind) != Association::Loop) + if (getDirectiveAssociation(DKind) != Association::LoopNest) return false; // Formally, OMPD_end_do_simd also has a loop association, but // it's a Fortran-specific directive. diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index c6487349c4056..2e43e3d94cb8c 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -1202,7 +1202,7 @@ static void createBodyOfOp(mlir::Operation &op, const OpWithBodyGenInfo &info, // Start with privatization, so that the lowering of the nested // code will use the right symbols. bool isLoop = llvm::omp::getDirectiveAssociation(info.dir) == - llvm::omp::Association::Loop; + llvm::omp::Association::LoopNest; bool privatize = info.clauses && info.privatize; firOpBuilder.setInsertionPoint(marker); @@ -3398,7 +3398,7 @@ static void genOMPDispatch(lower::AbstractConverter &converter, }; bool loopLeaf = llvm::omp::getDirectiveAssociation(item->id) == - llvm::omp::Association::Loop; + llvm::omp::Association::LoopNest; if (loopLeaf) { symTable.pushScope(); if (genOMPCompositeDispatch(converter, symTable, stmtCtx, semaCtx, eval, diff --git a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td index 301a7cce59627..2aa0649479023 100644 --- a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td +++ b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td @@ -162,7 +162,8 @@ def AS_Block : Association<"Block"> {} // Block (incl. single def AS_Declaration : Association<"Declaration"> {} // Declaration def AS_Delimited : Association<"Delimited"> {} // Region delimited with // begin/end -def AS_Loop : Association<"Loop"> {} // Loop +def AS_LoopNest : Association<"LoopNest"> {} // Loop nest +def AS_LoopSeq : Association<"LoopSeq"> {} // Loop sequence def AS_Separating : Association<"Separating"> {} // Separates parts of a // construct @@ -173,7 +174,7 @@ def AS_FromLeaves : Association<"FromLeaves"> {} // See below // x + y = y + x // x + x = x // AS_None + x = x -// AS_Block + AS_Loop = AS_Loop +// AS_Block + AS_Loop{Nest|Seq} = AS_Loop{Nest|Seq} // Other combinations are not allowed. // This association is not valid for leaf constructs. // The name "AS_FromLeaves" is recognized by TableGen, and there is no enum diff --git a/llvm/include/llvm/Frontend/OpenACC/ACC.td b/llvm/include/llvm/Frontend/OpenACC/ACC.td index 65751839ceb09..7381ec7bff0c4 100644 --- a/llvm/include/llvm/Frontend/OpenACC/ACC.td +++ b/llvm/include/llvm/Frontend/OpenACC/ACC.td @@ -419,7 +419,7 @@ def ACC_Loop : Directive<[Spelling<"loop">]> { VersionedClause<ACCC_Independent>, VersionedClause<ACCC_Seq> ]; - let association = AS_Loop; + let association = AS_LoopNest; let category = CA_Executable; } diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td index a01858fb220f1..ade00e7ca27d5 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -859,7 +859,7 @@ def OMP_Distribute : Directive<[Spelling<"distribute">]> { VersionedClause<OMPC_DistSchedule>, VersionedClause<OMPC_Order, 50>, ]; - let association = AS_Loop; + let association = AS_LoopNest; let category = CA_Executable; } def OMP_Do : Directive<[Spelling<"do">]> { @@ -877,7 +877,7 @@ def OMP_Do : Directive<[Spelling<"do">]> { VersionedClause<OMPC_Ordered>, VersionedClause<OMPC_Schedule>, ]; - let association = AS_Loop; + let association = AS_LoopNest; let category = CA_Executable; let languages = [L_Fortran]; } @@ -926,7 +926,7 @@ def OMP_For : Directive<[Spelling<"for">]> { VersionedClause<OMPC_Reduction>, VersionedClause<OMPC_Schedule>, ]; - let association = AS_Loop; + let association = AS_LoopNest; let category = CA_Executable; let languages = [L_C]; } @@ -940,14 +940,14 @@ def OMP_Groupprivate : Directive<[Spelling<"groupprivate">]> { } def OMP_Fuse : Directive<[Spelling<"fuse">]> { let allowedOnceClauses = [VersionedClause<OMPC_LoopRange, 60>]; - let association = AS_Block; + let association = AS_LoopSeq; let category = CA_Executable; } def OMP_Interchange : Directive<[Spelling<"interchange">]> { let allowedOnceClauses = [ VersionedClause<OMPC_Permutation>, ]; - let association = AS_Loop; + let association = AS_LoopNest; let category = CA_Executable; } def OMP_interop : Directive<[Spelling<"interop">]> { @@ -973,7 +973,7 @@ def OMP_loop : Directive<[Spelling<"loop">]> { VersionedClause<OMPC_Collapse>, VersionedClause<OMPC_Order, 50>, ]; - let association = AS_Loop; + let association = AS_LoopNest; let category = CA_Executable; } def OMP_masked : Directive<[Spelling<"masked">]> { @@ -1056,7 +1056,7 @@ def OMP_Requires : Directive<[Spelling<"requires">]> { let category = CA_Informational; } def OMP_Reverse : Directive<[Spelling<"reverse">]> { - let association = AS_Loop; + let association = AS_LoopNest; let category = CA_Executable; } def OMP_Scan : Directive<[Spelling<"scan">]> { @@ -1131,7 +1131,7 @@ def OMP_Simd : Directive<[Spelling<"simd">]> { VersionedClause<OMPC_SafeLen>, VersionedClause<OMPC_SimdLen>, ]; - let association = AS_Loop; + let association = AS_LoopNest; let category = CA_Executable; } def OMP_Single : Directive<[Spelling<"single">]> { @@ -1323,7 +1323,7 @@ def OMP_TaskLoop : Directive<[Spelling<"taskloop">]> { VersionedClause<OMPC_GrainSize>, VersionedClause<OMPC_NumTasks>, ]; - let association = AS_Loop; + let association = AS_LoopNest; let category = CA_Executable; } def OMP_TaskWait : Directive<[Spelling<"taskwait">]> { @@ -1371,14 +1371,14 @@ def OMP_Tile : Directive<[Spelling<"tile">]> { let requiredClauses = [ VersionedClause<OMPC_Sizes, 51>, ]; - let association = AS_Loop; + let association = AS_LoopNest; let category = CA_Executable; } def OMP_Stripe : Directive<[Spelling<"stripe">]> { let allowedOnceClauses = [ VersionedClause<OMPC_Sizes, 60>, ]; - let association = AS_Loop; + let association = AS_LoopNest; let category = CA_Executable; } def OMP_Unknown : Directive<[Spelling<"unknown">]> { @@ -1391,7 +1391,7 @@ def OMP_Unroll : Directive<[Spelling<"unroll">]> { VersionedClause<OMPC_Full, 51>, VersionedClause<OMPC_Partial, 51>, ]; - let association = AS_Loop; + let association = AS_LoopNest; let category = CA_Executable; } def OMP_Workshare : Directive<[Spelling<"workshare">]> { diff --git a/llvm/lib/Frontend/OpenMP/OMP.cpp b/llvm/lib/Frontend/OpenMP/OMP.cpp index f12941492547e..97aecf92ca5f3 100644 --- a/llvm/lib/Frontend/OpenMP/OMP.cpp +++ b/llvm/lib/Frontend/OpenMP/OMP.cpp @@ -53,7 +53,7 @@ getFirstCompositeRange(iterator_range<ArrayRef<Directive>::iterator> Leafs) { auto firstLoopAssociated = [](iterator_range<ArrayRef<Directive>::iterator> List) { for (auto It = List.begin(), End = List.end(); It != End; ++It) { - if (getDirectiveAssociation(*It) == Association::Loop) + if (getDirectiveAssociation(*It) == Association::LoopNest) return It; } return List.end(); @@ -71,7 +71,7 @@ getFirstCompositeRange(iterator_range<ArrayRef<Directive>::iterator> Leafs) { return Empty; for (; End != Leafs.end(); ++End) { - if (getDirectiveAssociation(*End) != Association::Loop) + if (getDirectiveAssociation(*End) != Association::LoopNest) break; } return llvm::make_range(Begin, End); diff --git a/llvm/test/TableGen/directive1.td b/llvm/test/TableGen/directive1.td index 5bd7890e0ddd1..3a9e8701c06eb 100644 --- a/llvm/test/TableGen/directive1.td +++ b/llvm/test/TableGen/directive1.td @@ -71,13 +71,14 @@ def TDL_DirA : Directive<[Spelling<"dira">]> { // CHECK-NEXT: First_ = Block, // CHECK-NEXT: Declaration, // CHECK-NEXT: Delimited, -// CHECK-NEXT: Loop, +// CHECK-NEXT: LoopNest, +// CHECK-NEXT: LoopSeq, // CHECK-NEXT: None, // CHECK-NEXT: Separating, // CHECK-NEXT: Last_ = Separating, // CHECK-NEXT: }; // CHECK-EMPTY: -// CHECK-NEXT: static constexpr std::size_t Association_enumSize = 6; +// CHECK-NEXT: static constexpr std::size_t Association_enumSize = 7; // CHECK-EMPTY: // CHECK-NEXT: enum class Category { // CHECK-NEXT: Declarative, diff --git a/llvm/test/TableGen/directive2.td b/llvm/test/TableGen/directive2.td index eaaf82ddaaf41..392423faed36f 100644 --- a/llvm/test/TableGen/directive2.td +++ b/llvm/test/TableGen/directive2.td @@ -62,13 +62,14 @@ def TDL_DirA : Directive<[Spelling<"dira">]> { // CHECK-NEXT: First_ = Block, // CHECK-NEXT: Declaration, // CHECK-NEXT: Delimited, -// CHECK-NEXT: Loop, +// CHECK-NEXT: LoopNest, +// CHECK-NEXT: LoopSeq, // CHECK-NEXT: None, // CHECK-NEXT: Separating, // CHECK-NEXT: Last_ = Separating, // CHECK-NEXT: }; // CHECK-EMPTY: -// CHECK-NEXT: static constexpr std::size_t Association_enumSize = 6; +// CHECK-NEXT: static constexpr std::size_t Association_enumSize = 7; // CHECK-EMPTY: // CHECK-NEXT: enum class Category { // CHECK-NEXT: Declarative, diff --git a/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp b/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp index 3a488ed952210..1126c83034b54 100644 --- a/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp +++ b/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp @@ -729,11 +729,12 @@ static void emitLeafTable(const DirectiveLanguage &DirLang, raw_ostream &OS, static void generateGetDirectiveAssociation(const DirectiveLanguage &DirLang, raw_ostream &OS) { enum struct Association { - None = 0, // None should be the smallest value. - Block, // The values of the rest don't matter. - Declaration, + None = 0, // None should be the smallest value. + Block, // If the order of the rest of these changes, update the + Declaration, // 'Reduce' function below. Delimited, - Loop, + LoopNest, + LoopSeq, Separating, FromLeaves, Invalid, @@ -746,7 +747,8 @@ static void generateGetDirectiveAssociation(const DirectiveLanguage &DirLang, .Case("AS_Block", Association::Block) .Case("AS_Declaration", Association::Declaration) .Case("AS_Delimited", Association::Delimited) - .Case("AS_Loop", Association::Loop) + .Case("AS_LoopNest", Association::LoopNest) + .Case("AS_LoopSeq", Association::LoopSeq) .Case("AS_None", Association::None) .Case("AS_Separating", Association::Separating) .Case("AS_FromLeaves", Association::FromLeaves) @@ -777,13 +779,12 @@ static void generateGetDirectiveAssociation(const DirectiveLanguage &DirLang, // Calculate the result using the following rules: // x + x = x // AS_None + x = x - // AS_Block + AS_Loop = AS_Loop + // AS_Block + AS_Loop{Nest|Seq} = AS_Loop{Nest|Seq} if (A == Association::None || A == B) return B; - if (A == Association::Block && B == Association::Loop) + if (A == Association::Block && + (B == Association::LoopNest || B == Association::LoopSeq)) return B; - if (A == Association::Loop && B == Association::Block) - return A; return Association::Invalid; }; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
