https://github.com/amitamd7 created https://github.com/llvm/llvm-project/pull/183261
Initial draft >From a198499e9187be6ce8b4e2da220fe22bea952cb1 Mon Sep 17 00:00:00 2001 From: amtiwari <[email protected]> Date: Wed, 25 Feb 2026 03:48:23 -0500 Subject: [PATCH] Split node creation and registration --- clang/include/clang/AST/StmtOpenMP.h | 74 +++++++++++++++++++ clang/include/clang/Basic/StmtNodes.td | 1 + .../include/clang/Serialization/ASTBitCodes.h | 1 + clang/lib/AST/StmtOpenMP.cpp | 22 ++++++ llvm/include/llvm/Frontend/OpenMP/OMP.td | 5 ++ 5 files changed, 103 insertions(+) diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h index bc6aeaa8d143c..626c39a7b778c 100644 --- a/clang/include/clang/AST/StmtOpenMP.h +++ b/clang/include/clang/AST/StmtOpenMP.h @@ -6065,6 +6065,80 @@ class OMPFuseDirective final } }; +/// Represents the '#pragma omp split' loop transformation directive. +/// +/// \code{c} +/// #pragma omp split +/// for (int i = 0; i < n; ++i) +/// ... +/// \endcode +/// +/// This directive transforms a single loop into multiple loops based on +/// index ranges. The transformation splits the iteration space of the loop +/// into multiple contiguous ranges. +class OMPSplitDirective final + : public OMPCanonicalLoopNestTransformationDirective { + friend class ASTStmtReader; + friend class OMPExecutableDirective; + + /// Offsets of child members. + enum { + PreInitsOffset = 0, + TransformedStmtOffset, + }; + + explicit OMPSplitDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumLoops) + : OMPCanonicalLoopNestTransformationDirective( + OMPSplitDirectiveClass, llvm::omp::OMPD_split, StartLoc, EndLoc, + NumLoops) {} + + void setPreInits(Stmt *PreInits) { + Data->getChildren()[PreInitsOffset] = PreInits; + } + + void setTransformedStmt(Stmt *S) { + Data->getChildren()[TransformedStmtOffset] = S; + } + +public: + /// Create a new AST node representation for '#pragma omp split'. + /// + /// \param C Context of the AST. + /// \param StartLoc Location of the introducer (e.g. the 'omp' token). + /// \param EndLoc Location of the directive's end (e.g. the tok::eod). + /// \param NumLoops Number of affected loops (should be 1 for split). + /// \param AssociatedStmt The outermost associated loop. + /// \param TransformedStmt The loop nest after splitting, or nullptr in + /// dependent contexts. + /// \param PreInits Helper preinits statements for the loop nest. + static OMPSplitDirective *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation EndLoc, + Stmt *AssociatedStmt, unsigned NumLoops, + Stmt *TransformedStmt, Stmt *PreInits); + + /// Build an empty '#pragma omp split' AST node for deserialization. + /// + /// \param C Context of the AST. + /// \param NumLoops Number of associated loops to allocate + static OMPSplitDirective *CreateEmpty(const ASTContext &C, + unsigned NumLoops); + + /// Gets/sets the associated loops after the transformation, i.e. after + /// de-sugaring. + Stmt *getTransformedStmt() const { + return Data->getChildren()[TransformedStmtOffset]; + } + + /// Return preinits statement. + Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPSplitDirectiveClass; + } +}; + /// This represents '#pragma omp scan' directive. /// /// \code diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index cb869cc210627..77db0e6d73ca3 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -242,6 +242,7 @@ def OMPTileDirective : StmtNode<OMPCanonicalLoopNestTransformationDirective>; def OMPStripeDirective : StmtNode<OMPCanonicalLoopNestTransformationDirective>; def OMPUnrollDirective : StmtNode<OMPCanonicalLoopNestTransformationDirective>; def OMPReverseDirective : StmtNode<OMPCanonicalLoopNestTransformationDirective>; +def OMPSplitDirective : StmtNode<OMPCanonicalLoopNestTransformationDirective>; def OMPInterchangeDirective : StmtNode<OMPCanonicalLoopNestTransformationDirective>; def OMPCanonicalLoopSequenceTransformationDirective diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index d72f1f9db86b2..1786277598f8e 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1959,6 +1959,7 @@ enum StmtCode { STMP_OMP_STRIPE_DIRECTIVE, STMT_OMP_UNROLL_DIRECTIVE, STMT_OMP_REVERSE_DIRECTIVE, + STMT_OMP_SPLIT_DIRECTIVE, STMT_OMP_INTERCHANGE_DIRECTIVE, STMT_OMP_FUSE_DIRECTIVE, STMT_OMP_FOR_DIRECTIVE, diff --git a/clang/lib/AST/StmtOpenMP.cpp b/clang/lib/AST/StmtOpenMP.cpp index a5b0cd3786a28..ada4e66b280f8 100644 --- a/clang/lib/AST/StmtOpenMP.cpp +++ b/clang/lib/AST/StmtOpenMP.cpp @@ -552,6 +552,28 @@ OMPInterchangeDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, SourceLocation(), SourceLocation(), NumLoops); } +OMPSplitDirective *OMPSplitDirective::Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation EndLoc, + Stmt *AssociatedStmt, + unsigned NumLoops, + Stmt *TransformedStmt, + Stmt *PreInits) { + OMPSplitDirective *Dir = createDirective<OMPSplitDirective>( + C, {}, AssociatedStmt, TransformedStmtOffset + 1, StartLoc, EndLoc, + NumLoops); + Dir->setTransformedStmt(TransformedStmt); + Dir->setPreInits(PreInits); + return Dir; +} + +OMPSplitDirective *OMPSplitDirective::CreateEmpty(const ASTContext &C, + unsigned NumLoops) { + return createEmptyDirective<OMPSplitDirective>( + C, /*NumClauses=*/0, /*HasAssociatedStmt=*/true, + TransformedStmtOffset + 1, SourceLocation(), SourceLocation(), NumLoops); +} + OMPFuseDirective *OMPFuseDirective::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, unsigned NumGeneratedTopLevelLoops, diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td index b30c5507ecd13..23808705c174d 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -1408,6 +1408,11 @@ def OMP_Stripe : Directive<[Spelling<"stripe">]> { let association = AS_LoopNest; let category = CA_Executable; } +def OMP_Split : Directive<[Spelling<"split">]> { + // TODO: Add counts clause support (OMPC_Counts) + let association = AS_LoopNest; + let category = CA_Executable; +} def OMP_Unknown : Directive<[Spelling<"unknown">]> { let isDefault = true; let association = AS_None; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
