https://github.com/loopacino updated https://github.com/llvm/llvm-project/pull/206977
>From 0fb5bd42f1e127faea963c359b1e3c69cb969c60 Mon Sep 17 00:00:00 2001 From: amtiwari <[email protected]> Date: Wed, 1 Jul 2026 09:06:58 -0400 Subject: [PATCH 1/9] add OMPFlattenDirective ast node --- clang/include/clang/AST/RecursiveASTVisitor.h | 3 + clang/include/clang/AST/StmtOpenMP.h | 75 ++++++++++++++++++- clang/include/clang/Basic/StmtNodes.td | 1 + clang/lib/AST/StmtOpenMP.cpp | 20 +++++ clang/lib/AST/StmtPrinter.cpp | 5 ++ clang/lib/AST/StmtProfile.cpp | 4 + clang/lib/Basic/OpenMPKinds.cpp | 2 +- 7 files changed, 108 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index b000a34043696..e425f7a31f59c 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -3227,6 +3227,9 @@ DEF_TRAVERSE_STMT(OMPFuseDirective, DEF_TRAVERSE_STMT(OMPInterchangeDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) +DEF_TRAVERSE_STMT(OMPFlattenDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + DEF_TRAVERSE_STMT(OMPSplitDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h index dbc76e7df8ecd..1420331f37c1f 100644 --- a/clang/include/clang/AST/StmtOpenMP.h +++ b/clang/include/clang/AST/StmtOpenMP.h @@ -1041,7 +1041,7 @@ class OMPCanonicalLoopNestTransformationDirective Stmt::StmtClass C = T->getStmtClass(); return C == OMPTileDirectiveClass || C == OMPUnrollDirectiveClass || C == OMPReverseDirectiveClass || C == OMPInterchangeDirectiveClass || - C == OMPStripeDirectiveClass; + C == OMPStripeDirectiveClass || C == OMPFlattenDirectiveClass; } }; @@ -5959,6 +5959,79 @@ class OMPInterchangeDirective final } }; +/// Represents the '#pragma omp flatten' loop transformation directive. +/// +/// \code{c} +/// #pragma omp flatten +/// for (int i = 0; i < m; ++i) +/// for (int j = 0; j < n; ++j) +/// .. +/// \endcode +class OMPFlattenDirective final + : public OMPCanonicalLoopNestTransformationDirective { + friend class ASTStmtReader; + friend class OMPExecutableDirective; + + /// Offsets of child members. + enum { + PreInitsOffset = 0, + TransformedStmtOffset, + }; + + explicit OMPFlattenDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumLoops) + : OMPCanonicalLoopNestTransformationDirective( + OMPFlattenDirectiveClass, llvm::omp::OMPD_flatten, 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 flatten'. + /// + /// \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 Clauses The directive's clauses. + /// \param NumLoops Number of affected loops (the flatten depth, currently + /// always 2). + /// \param AssociatedStmt The outermost associated loop. + /// \param TransformedStmt The flattened loop, or nullptr in dependent + /// contexts. + /// \param PreInits Helper preinits statements for the loop nest. + static OMPFlattenDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, unsigned NumLoops, Stmt *AssociatedStmt, + Stmt *TransformedStmt, Stmt *PreInits); + + /// Build an empty '#pragma omp flatten' AST node for deserialization. + /// + /// \param C Context of the AST. + /// \param NumClauses Number of clauses to allocate. + /// \param NumLoops Number of associated loops to allocate. + static OMPFlattenDirective * + CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned NumLoops); + + /// Gets the flattened loop after the transformation. This is the de-sugared + /// replacement or nullptr in dependent contexts. + 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() == OMPFlattenDirectiveClass; + } +}; + /// The base class for all transformation directives of canonical loop /// sequences (currently only 'fuse') class OMPCanonicalLoopSequenceTransformationDirective diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index e166894ea024b..0d7a0c1490a1e 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -247,6 +247,7 @@ def OMPReverseDirective : StmtNode<OMPCanonicalLoopNestTransformationDirective>; def OMPSplitDirective : StmtNode<OMPCanonicalLoopNestTransformationDirective>; def OMPInterchangeDirective : StmtNode<OMPCanonicalLoopNestTransformationDirective>; +def OMPFlattenDirective : StmtNode<OMPCanonicalLoopNestTransformationDirective>; def OMPCanonicalLoopSequenceTransformationDirective : StmtNode<OMPExecutableDirective, 1>; def OMPFuseDirective diff --git a/clang/lib/AST/StmtOpenMP.cpp b/clang/lib/AST/StmtOpenMP.cpp index 9d6b315effb41..477604ef3dafb 100644 --- a/clang/lib/AST/StmtOpenMP.cpp +++ b/clang/lib/AST/StmtOpenMP.cpp @@ -552,6 +552,26 @@ OMPInterchangeDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, SourceLocation(), SourceLocation(), NumLoops); } +OMPFlattenDirective *OMPFlattenDirective::Create( + const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, unsigned NumLoops, Stmt *AssociatedStmt, + Stmt *TransformedStmt, Stmt *PreInits) { + OMPFlattenDirective *Dir = createDirective<OMPFlattenDirective>( + C, Clauses, AssociatedStmt, TransformedStmtOffset + 1, StartLoc, EndLoc, + NumLoops); + Dir->setTransformedStmt(TransformedStmt); + Dir->setPreInits(PreInits); + return Dir; +} + +OMPFlattenDirective *OMPFlattenDirective::CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned NumLoops) { + return createEmptyDirective<OMPFlattenDirective>( + C, NumClauses, /*HasAssociatedStmt=*/true, TransformedStmtOffset + 1, + SourceLocation(), SourceLocation(), NumLoops); +} + OMPSplitDirective * OMPSplitDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 6c3294573e9d4..0bacb79ed86e3 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -800,6 +800,11 @@ void StmtPrinter::VisitOMPInterchangeDirective(OMPInterchangeDirective *Node) { PrintOMPExecutableDirective(Node); } +void StmtPrinter::VisitOMPFlattenDirective(OMPFlattenDirective *Node) { + Indent() << "#pragma omp flatten"; + PrintOMPExecutableDirective(Node); +} + void StmtPrinter::VisitOMPSplitDirective(OMPSplitDirective *Node) { Indent() << "#pragma omp split"; PrintOMPExecutableDirective(Node); diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 90eab530e0c2e..de7ed322d7424 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -1071,6 +1071,10 @@ void StmtProfiler::VisitOMPInterchangeDirective( VisitOMPCanonicalLoopNestTransformationDirective(S); } +void StmtProfiler::VisitOMPFlattenDirective(const OMPFlattenDirective *S) { + VisitOMPCanonicalLoopNestTransformationDirective(S); +} + void StmtProfiler::VisitOMPSplitDirective(const OMPSplitDirective *S) { VisitOMPCanonicalLoopNestTransformationDirective(S); } diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 675d86349c933..57e0347f8ea77 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -818,7 +818,7 @@ bool clang::isOpenMPCanonicalLoopNestTransformationDirective( OpenMPDirectiveKind DKind) { return DKind == OMPD_tile || DKind == OMPD_unroll || DKind == OMPD_reverse || DKind == OMPD_split || DKind == OMPD_interchange || - DKind == OMPD_stripe; + DKind == OMPD_stripe || DKind == OMPD_flatten; } bool clang::isOpenMPCanonicalLoopSequenceTransformationDirective( >From 933007b6333584fb358adc4f89a61db1ae15d4cb Mon Sep 17 00:00:00 2001 From: amtiwari <[email protected]> Date: Wed, 8 Jul 2026 16:02:27 -0400 Subject: [PATCH 2/9] add OMPDepthClause ast node --- clang/include/clang/AST/OpenMPClause.h | 68 +++++++++++++++++++ clang/include/clang/AST/RecursiveASTVisitor.h | 6 ++ clang/lib/AST/OpenMPClause.cpp | 25 +++++++ clang/lib/AST/StmtProfile.cpp | 5 ++ clang/lib/Parse/ParseOpenMP.cpp | 1 + llvm/include/llvm/Frontend/OpenMP/OMP.td | 1 + 6 files changed, 106 insertions(+) diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index 8ceafc4669297..50d1364a9726d 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -1380,6 +1380,74 @@ class OMPPartialClause final : public OMPClause { } }; +/// This represents the 'depth' clause on the '#pragma omp flatten' (and +/// '#pragma omp fuse') loop-transformation directives. +/// +/// \code +/// #pragma omp flatten depth(3) +/// \endcode +/// In this example the 'flatten' directive has a 'depth' clause whose argument +/// '3' specifies how many perfectly nested loops are combined into one. +/// The argument must be a positive integer constant expression that evaluates +/// to at most the loop nest depth of the associated loop nest. +class OMPDepthClause final : public OMPClause { + friend class OMPClauseReader; + + /// Location of '('. + SourceLocation LParenLoc; + + /// The depth expression (number of loops to flatten). + Stmt *Depth = nullptr; + + /// Build an empty clause. + explicit OMPDepthClause() : OMPClause(llvm::omp::OMPC_depth, {}, {}) {} + + /// Set the depth expression. + void setDepth(Expr *E) { Depth = E; } + + /// Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + +public: + /// Build an AST node for a 'depth' clause. + /// + /// \param C Context of the AST. + /// \param StartLoc Location of the 'depth' identifier. + /// \param LParenLoc Location of '('. + /// \param EndLoc Location of ')'. + /// \param Depth The depth expression. + static OMPDepthClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc, + Expr *Depth); + + /// Build an empty 'depth' AST node for deserialization. + /// + /// \param C Context of the AST. + static OMPDepthClause *CreateEmpty(const ASTContext &C); + + /// Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// Returns the depth expression or nullptr if not set. + Expr *getDepth() const { return cast_or_null<Expr>(Depth); } + + child_range children() { return child_range(&Depth, &Depth + 1); } + const_child_range children() const { + return const_child_range(&Depth, &Depth + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_depth; + } +}; + /// This represents 'collapse' clause in the '#pragma omp ...' /// directive. /// diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index e425f7a31f59c..da55e97fdfcb5 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -3568,6 +3568,12 @@ bool RecursiveASTVisitor<Derived>::VisitOMPPartialClause(OMPPartialClause *C) { return true; } +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPDepthClause(OMPDepthClause *C) { + TRY_TO(TraverseStmt(C->getDepth())); + return true; +} + template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) { diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index ed00e80144c25..7b2f67a31cad9 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -1057,6 +1057,22 @@ OMPPartialClause *OMPPartialClause::CreateEmpty(const ASTContext &C) { return new (C) OMPPartialClause(); } +OMPDepthClause *OMPDepthClause::Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, Expr *Depth) { + OMPDepthClause *Clause = CreateEmpty(C); + Clause->setLocStart(StartLoc); + Clause->setLParenLoc(LParenLoc); + Clause->setLocEnd(EndLoc); + Clause->setDepth(Depth); + return Clause; +} + +OMPDepthClause *OMPDepthClause::CreateEmpty(const ASTContext &C) { + return new (C) OMPDepthClause(); +} + OMPLoopRangeClause * OMPLoopRangeClause::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation FirstLoc, @@ -2069,6 +2085,15 @@ void OMPClausePrinter::VisitOMPPermutationClause(OMPPermutationClause *Node) { void OMPClausePrinter::VisitOMPFullClause(OMPFullClause *Node) { OS << "full"; } +void OMPClausePrinter::VisitOMPDepthClause(OMPDepthClause *Node) { + OS << "depth"; + if (Expr *Depth = Node->getDepth()) { + OS << '('; + Depth->printPretty(OS, nullptr, Policy, 0); + OS << ')'; + } +} + void OMPClausePrinter::VisitOMPPartialClause(OMPPartialClause *Node) { OS << "partial"; diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index de7ed322d7424..838d6d02f7446 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -521,6 +521,11 @@ void OMPClauseProfiler::VisitOMPPartialClause(const OMPPartialClause *C) { Profiler->VisitExpr(Factor); } +void OMPClauseProfiler::VisitOMPDepthClause(const OMPDepthClause *C) { + if (const Expr *Depth = C->getDepth()) + Profiler->VisitExpr(Depth); +} + void OMPClauseProfiler::VisitOMPLoopRangeClause(const OMPLoopRangeClause *C) { if (const Expr *First = C->getFirst()) Profiler->VisitExpr(First); diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index af52295df2d8b..952a517205381 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -3247,6 +3247,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_nocontext: case OMPC_filter: case OMPC_partial: + case OMPC_depth: case OMPC_align: case OMPC_message: case OMPC_ompx_dyn_cgroup_mem: diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td index 679a944fc4358..d49c5ee1a0db3 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -161,6 +161,7 @@ def OMPC_Depobj : Clause<[Spelling<"depobj">]> { let isImplicit = true; } def OMPC_Depth : Clause<[Spelling<"depth">]> { + let clangClass = "OMPDepthClause"; let flangClass = "ScalarIntConstantExpr"; } def OMPC_Destroy : Clause<[Spelling<"destroy">]> { >From b63024e1e342cd168ef128a3f6a24909df2a82db Mon Sep 17 00:00:00 2001 From: amtiwari <[email protected]> Date: Wed, 8 Jul 2026 16:04:44 -0400 Subject: [PATCH 3/9] template-transform support for flatten directive & depth clause --- clang/lib/Sema/TreeTransform.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 3b99ff4bb9e23..865622ad50f1c 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1804,6 +1804,14 @@ class TreeTransform { LParenLoc, EndLoc); } + /// Build a new OpenMP 'depth' clause. + OMPClause *RebuildOMPDepthClause(Expr *Depth, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc) { + return getSema().OpenMP().ActOnOpenMPDepthClause(Depth, StartLoc, LParenLoc, + EndLoc); + } + OMPClause * RebuildOMPLoopRangeClause(Expr *First, Expr *Count, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation FirstLoc, @@ -9791,6 +9799,17 @@ TreeTransform<Derived>::TransformOMPSplitDirective(OMPSplitDirective *D) { return Res; } +template <typename Derived> +StmtResult +TreeTransform<Derived>::TransformOMPFlattenDirective(OMPFlattenDirective *D) { + DeclarationNameInfo DirName; + getDerived().getSema().OpenMP().StartOpenMPDSABlock( + D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc()); + StmtResult Res = getDerived().TransformOMPExecutableDirective(D); + getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get()); + return Res; +} + template <typename Derived> StmtResult TreeTransform<Derived>::TransformOMPFuseDirective(OMPFuseDirective *D) { @@ -10717,6 +10736,20 @@ TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) { C->getEndLoc()); } +template <typename Derived> +OMPClause *TreeTransform<Derived>::TransformOMPDepthClause(OMPDepthClause *C) { + ExprResult T = getDerived().TransformExpr(C->getDepth()); + if (T.isInvalid()) + return nullptr; + Expr *Depth = T.get(); + bool Changed = Depth != C->getDepth(); + + if (!Changed && !getDerived().AlwaysRebuild()) + return C; + return RebuildOMPDepthClause(Depth, C->getBeginLoc(), C->getLParenLoc(), + C->getEndLoc()); +} + template <typename Derived> OMPClause * TreeTransform<Derived>::TransformOMPLoopRangeClause(OMPLoopRangeClause *C) { >From deafb222a7d251069c68a44fa267e58e750f1064 Mon Sep 17 00:00:00 2001 From: amtiwari <[email protected]> Date: Wed, 8 Jul 2026 16:08:12 -0400 Subject: [PATCH 4/9] serialize flatten --- clang/include/clang/Serialization/ASTBitCodes.h | 1 + clang/lib/Serialization/ASTReaderStmt.cpp | 11 +++++++++++ clang/lib/Serialization/ASTWriterStmt.cpp | 5 +++++ 3 files changed, 17 insertions(+) diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 279380de2f7fe..93a0e0a454b68 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1970,6 +1970,7 @@ enum StmtCode { STMT_OMP_REVERSE_DIRECTIVE, STMT_OMP_SPLIT_DIRECTIVE, STMT_OMP_INTERCHANGE_DIRECTIVE, + STMT_OMP_FLATTEN_DIRECTIVE, STMT_OMP_FUSE_DIRECTIVE, STMT_OMP_FOR_DIRECTIVE, STMT_OMP_FOR_SIMD_DIRECTIVE, diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 02ccf8d4d41c2..8c2debd6cdf32 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -2537,6 +2537,10 @@ void ASTStmtReader::VisitOMPInterchangeDirective(OMPInterchangeDirective *D) { VisitOMPCanonicalLoopNestTransformationDirective(D); } +void ASTStmtReader::VisitOMPFlattenDirective(OMPFlattenDirective *D) { + VisitOMPCanonicalLoopNestTransformationDirective(D); +} + void ASTStmtReader::VisitOMPSplitDirective(OMPSplitDirective *D) { VisitOMPCanonicalLoopNestTransformationDirective(D); } @@ -3719,6 +3723,13 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; } + case STMT_OMP_FLATTEN_DIRECTIVE: { + unsigned NumLoops = Record[ASTStmtReader::NumStmtFields]; + unsigned NumClauses = Record[ASTStmtReader::NumStmtFields + 1]; + S = OMPFlattenDirective::CreateEmpty(Context, NumClauses, NumLoops); + break; + } + case STMT_OMP_FOR_DIRECTIVE: { unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields]; unsigned NumClauses = Record[ASTStmtReader::NumStmtFields + 1]; diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 4e9eadd730a56..dfe28a9b915e3 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -2547,6 +2547,11 @@ void ASTStmtWriter::VisitOMPInterchangeDirective(OMPInterchangeDirective *D) { Code = serialization::STMT_OMP_INTERCHANGE_DIRECTIVE; } +void ASTStmtWriter::VisitOMPFlattenDirective(OMPFlattenDirective *D) { + VisitOMPCanonicalLoopNestTransformationDirective(D); + Code = serialization::STMT_OMP_FLATTEN_DIRECTIVE; +} + void ASTStmtWriter::VisitOMPSplitDirective(OMPSplitDirective *D) { VisitOMPCanonicalLoopNestTransformationDirective(D); Code = serialization::STMT_OMP_SPLIT_DIRECTIVE; >From 3e2dfeb99230057b7cb9c484182ae33befbe1e41 Mon Sep 17 00:00:00 2001 From: amtiwari <[email protected]> Date: Wed, 8 Jul 2026 16:09:03 -0400 Subject: [PATCH 5/9] serialize depth --- clang/lib/Serialization/ASTReader.cpp | 8 ++++++++ clang/lib/Serialization/ASTWriter.cpp | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index f8a6a38bb9b5c..4f51d79a52105 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -11495,6 +11495,9 @@ OMPClause *OMPClauseReader::readClause() { case llvm::omp::OMPC_partial: C = OMPPartialClause::CreateEmpty(Context); break; + case llvm::omp::OMPC_depth: + C = OMPDepthClause::CreateEmpty(Context); + break; case llvm::omp::OMPC_looprange: C = OMPLoopRangeClause::CreateEmpty(Context); break; @@ -11924,6 +11927,11 @@ void OMPClauseReader::VisitOMPPartialClause(OMPPartialClause *C) { C->setLParenLoc(Record.readSourceLocation()); } +void OMPClauseReader::VisitOMPDepthClause(OMPDepthClause *C) { + C->setDepth(Record.readSubExpr()); + C->setLParenLoc(Record.readSourceLocation()); +} + void OMPClauseReader::VisitOMPLoopRangeClause(OMPLoopRangeClause *C) { C->setFirst(Record.readSubExpr()); C->setCount(Record.readSubExpr()); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 357a7f7e95fa0..cbfeaa9e6638a 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -8106,6 +8106,11 @@ void OMPClauseWriter::VisitOMPPartialClause(OMPPartialClause *C) { Record.AddSourceLocation(C->getLParenLoc()); } +void OMPClauseWriter::VisitOMPDepthClause(OMPDepthClause *C) { + Record.AddStmt(C->getDepth()); + Record.AddSourceLocation(C->getLParenLoc()); +} + void OMPClauseWriter::VisitOMPLoopRangeClause(OMPLoopRangeClause *C) { Record.AddStmt(C->getFirst()); Record.AddStmt(C->getCount()); >From 4ae746ca1eeaf11db10e859572a4500029d01cce Mon Sep 17 00:00:00 2001 From: amtiwari <[email protected]> Date: Wed, 8 Jul 2026 16:17:29 -0400 Subject: [PATCH 6/9] add analysis traversal support for flatten directive --- clang/lib/Sema/SemaExceptionSpec.cpp | 1 + clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index 40d530a1f3925..995b5b6010978 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1508,6 +1508,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) { case Stmt::OMPUnrollDirectiveClass: case Stmt::OMPReverseDirectiveClass: case Stmt::OMPInterchangeDirectiveClass: + case Stmt::OMPFlattenDirectiveClass: case Stmt::OMPSplitDirectiveClass: case Stmt::OMPFuseDirectiveClass: case Stmt::OMPSingleDirectiveClass: diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index cfb294736ee02..3f666be00cc24 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1783,6 +1783,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::OMPStripeDirectiveClass: case Stmt::OMPTileDirectiveClass: case Stmt::OMPInterchangeDirectiveClass: + case Stmt::OMPFlattenDirectiveClass: case Stmt::OMPSplitDirectiveClass: case Stmt::OMPFuseDirectiveClass: case Stmt::OMPInteropDirectiveClass: >From 415eba88ad0af63c552b4c5c2eabd660bcb29c02 Mon Sep 17 00:00:00 2001 From: amtiwari <[email protected]> Date: Wed, 8 Jul 2026 16:21:25 -0400 Subject: [PATCH 7/9] codegen flatten directive --- clang/lib/CodeGen/CGStmt.cpp | 3 +++ clang/lib/CodeGen/CGStmtOpenMP.cpp | 8 ++++++++ clang/lib/CodeGen/CodeGenFunction.h | 1 + 3 files changed, 12 insertions(+) diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 232094777f233..27f48cb63b553 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -236,6 +236,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) { case Stmt::OMPInterchangeDirectiveClass: EmitOMPInterchangeDirective(cast<OMPInterchangeDirective>(*S)); break; + case Stmt::OMPFlattenDirectiveClass: + EmitOMPFlattenDirective(cast<OMPFlattenDirective>(*S)); + break; case Stmt::OMPFuseDirectiveClass: EmitOMPFuseDirective(cast<OMPFuseDirective>(*S)); break; diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 95fd6694437fe..25da3430a23fe 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -218,6 +218,8 @@ class OMPLoopScope : public CodeGenFunction::RunCleanupsScope { } else if (const auto *Interchange = dyn_cast<OMPInterchangeDirective>(&S)) { PreInits = Interchange->getPreInits(); + } else if (const auto *Flatten = dyn_cast<OMPFlattenDirective>(&S)) { + PreInits = Flatten->getPreInits(); } else { llvm_unreachable("Unknown loop-based directive kind."); } @@ -3248,6 +3250,12 @@ void CodeGenFunction::EmitOMPInterchangeDirective( EmitStmt(S.getTransformedStmt()); } +void CodeGenFunction::EmitOMPFlattenDirective(const OMPFlattenDirective &S) { + // Emit the de-sugared statement. + OMPTransformDirectiveScopeRAII FlattenScope(*this, &S); + EmitStmt(S.getTransformedStmt()); +} + void CodeGenFunction::EmitOMPFuseDirective(const OMPFuseDirective &S) { // Emit the de-sugared statement OMPTransformDirectiveScopeRAII FuseScope(*this, &S); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 6d0718c243812..eea0163422cd3 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -3934,6 +3934,7 @@ class CodeGenFunction : public CodeGenTypeCache { void EmitOMPReverseDirective(const OMPReverseDirective &S); void EmitOMPSplitDirective(const OMPSplitDirective &S); void EmitOMPInterchangeDirective(const OMPInterchangeDirective &S); + void EmitOMPFlattenDirective(const OMPFlattenDirective &S); void EmitOMPFuseDirective(const OMPFuseDirective &S); void EmitOMPForDirective(const OMPForDirective &S); void EmitOMPForSimdDirective(const OMPForSimdDirective &S); >From 814e2e9fe9bf4e28e4557999fbc16beec144cc39 Mon Sep 17 00:00:00 2001 From: amtiwari <[email protected]> Date: Wed, 8 Jul 2026 16:24:42 -0400 Subject: [PATCH 8/9] add NYI CIR stub --- clang/lib/CIR/CodeGen/CIRGenFunction.h | 1 + clang/lib/CIR/CodeGen/CIRGenStmt.cpp | 2 ++ clang/lib/CIR/CodeGen/CIRGenStmtOpenMP.cpp | 5 +++++ 3 files changed, 8 insertions(+) diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index 322355fde3957..8374583ffd4d0 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -2559,6 +2559,7 @@ class CIRGenFunction : public CIRGenTypeCache { mlir::LogicalResult emitOMPSplitDirective(const OMPSplitDirective &s); mlir::LogicalResult emitOMPInterchangeDirective(const OMPInterchangeDirective &s); + mlir::LogicalResult emitOMPFlattenDirective(const OMPFlattenDirective &s); mlir::LogicalResult emitOMPAssumeDirective(const OMPAssumeDirective &s); mlir::LogicalResult emitOMPMaskedDirective(const OMPMaskedDirective &s); mlir::LogicalResult emitOMPStripeDirective(const OMPStripeDirective &s); diff --git a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp index d3acac5801e74..33d425b22d61a 100644 --- a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp @@ -408,6 +408,8 @@ mlir::LogicalResult CIRGenFunction::emitStmt(const Stmt *s, return emitOMPSplitDirective(cast<OMPSplitDirective>(*s)); case Stmt::OMPInterchangeDirectiveClass: return emitOMPInterchangeDirective(cast<OMPInterchangeDirective>(*s)); + case Stmt::OMPFlattenDirectiveClass: + return emitOMPFlattenDirective(cast<OMPFlattenDirective>(*s)); case Stmt::OMPAssumeDirectiveClass: return emitOMPAssumeDirective(cast<OMPAssumeDirective>(*s)); case Stmt::OMPMaskedDirectiveClass: diff --git a/clang/lib/CIR/CodeGen/CIRGenStmtOpenMP.cpp b/clang/lib/CIR/CodeGen/CIRGenStmtOpenMP.cpp index 17a1fb8090f5c..4fffd17b25a16 100644 --- a/clang/lib/CIR/CodeGen/CIRGenStmtOpenMP.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenStmtOpenMP.cpp @@ -587,6 +587,11 @@ CIRGenFunction::emitOMPInterchangeDirective(const OMPInterchangeDirective &s) { return mlir::failure(); } mlir::LogicalResult +CIRGenFunction::emitOMPFlattenDirective(const OMPFlattenDirective &s) { + getCIRGenModule().errorNYI(s.getSourceRange(), "OpenMP OMPFlattenDirective"); + return mlir::failure(); +} +mlir::LogicalResult CIRGenFunction::emitOMPAssumeDirective(const OMPAssumeDirective &s) { getCIRGenModule().errorNYI(s.getSourceRange(), "OpenMP OMPAssumeDirective"); return mlir::failure(); >From 0027ec6ab982a83766bd65f3e1bc45d9a671fc62 Mon Sep 17 00:00:00 2001 From: amtiwari <[email protected]> Date: Wed, 8 Jul 2026 16:26:31 -0400 Subject: [PATCH 9/9] add libclang traversal support for depth clause --- clang/tools/libclang/CIndex.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index ac2fad38a1348..f8ab63e3e0dae 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -2378,6 +2378,10 @@ void OMPClauseEnqueue::VisitOMPLoopRangeClause(const OMPLoopRangeClause *C) { Visitor->AddStmt(C->getCount()); } +void OMPClauseEnqueue::VisitOMPDepthClause(const OMPDepthClause *C) { + Visitor->AddStmt(C->getDepth()); +} + void OMPClauseEnqueue::VisitOMPAllocatorClause(const OMPAllocatorClause *C) { Visitor->AddStmt(C->getAllocator()); } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
