Author: erichkeane Date: 2025-08-19T07:58:11-07:00 New Revision: d0dc3799b70bb6b51ed2e90b93f8ea5d4f30cef1
URL: https://github.com/llvm/llvm-project/commit/d0dc3799b70bb6b51ed2e90b93f8ea5d4f30cef1 DIFF: https://github.com/llvm/llvm-project/commit/d0dc3799b70bb6b51ed2e90b93f8ea5d4f30cef1.diff LOG: [OpenACC][NFCI] Add AST Infrastructure for reduction recipes This patch does the bare minimum to start setting up the reduction recipe support, including adding a type to the AST to store it. No real additional work is done, and a bunch of static_asserts are left around to allow us to do this properly. Added: Modified: clang/include/clang/AST/OpenACCClause.h clang/include/clang/Sema/SemaOpenACC.h clang/lib/AST/OpenACCClause.cpp clang/lib/AST/StmtProfile.cpp clang/lib/Sema/SemaOpenACCClause.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/tools/libclang/CIndex.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/OpenACCClause.h b/clang/include/clang/AST/OpenACCClause.h index b52f7167736fe..2f4aba1cdcd90 100644 --- a/clang/include/clang/AST/OpenACCClause.h +++ b/clang/include/clang/AST/OpenACCClause.h @@ -1250,19 +1250,32 @@ class OpenACCCreateClause final SourceLocation EndLoc); }; +// A structure to stand in for the recipe on a reduction. RecipeDecl is the +// 'main' declaration used for initializaiton, which is fixed. +struct OpenACCReductionRecipe { + VarDecl *RecipeDecl; + // TODO: OpenACC: this should eventually have the operations here too. +}; + class OpenACCReductionClause final : public OpenACCClauseWithVarList, - private llvm::TrailingObjects<OpenACCReductionClause, Expr *> { + private llvm::TrailingObjects<OpenACCReductionClause, Expr *, + OpenACCReductionRecipe> { friend TrailingObjects; OpenACCReductionOperator Op; OpenACCReductionClause(SourceLocation BeginLoc, SourceLocation LParenLoc, OpenACCReductionOperator Operator, - ArrayRef<Expr *> VarList, SourceLocation EndLoc) + ArrayRef<Expr *> VarList, + ArrayRef<OpenACCReductionRecipe> Recipes, + SourceLocation EndLoc) : OpenACCClauseWithVarList(OpenACCClauseKind::Reduction, BeginLoc, LParenLoc, EndLoc), Op(Operator) { - setExprs(getTrailingObjects(VarList.size()), VarList); + assert(VarList.size() == Recipes.size()); + setExprs(getTrailingObjects<Expr *>(VarList.size()), VarList); + llvm::uninitialized_copy(Recipes, getTrailingObjects< + OpenACCReductionRecipe > ()); } public: @@ -1270,12 +1283,26 @@ class OpenACCReductionClause final return C->getClauseKind() == OpenACCClauseKind::Reduction; } + ArrayRef<OpenACCReductionRecipe> getRecipes() { + return ArrayRef<OpenACCReductionRecipe>{ + getTrailingObjects<OpenACCReductionRecipe>(), getExprs().size()}; + } + + ArrayRef<OpenACCReductionRecipe> getRecipes() const { + return ArrayRef<OpenACCReductionRecipe>{ + getTrailingObjects<OpenACCReductionRecipe>(), getExprs().size()}; + } + static OpenACCReductionClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, OpenACCReductionOperator Operator, ArrayRef<Expr *> VarList, - SourceLocation EndLoc); + ArrayRef<OpenACCReductionRecipe> Recipes, SourceLocation EndLoc); OpenACCReductionOperator getReductionOp() const { return Op; } + + size_t numTrailingObjects(OverloadToken<Expr *>) const { + return getExprs().size(); + } }; class OpenACCLinkClause final diff --git a/clang/include/clang/Sema/SemaOpenACC.h b/clang/include/clang/Sema/SemaOpenACC.h index d078de5244393..e7b62aafc060b 100644 --- a/clang/include/clang/Sema/SemaOpenACC.h +++ b/clang/include/clang/Sema/SemaOpenACC.h @@ -947,12 +947,12 @@ class SemaOpenACC : public SemaBase { ArrayRef<Expr *> IntExprs, SourceLocation EndLoc); // Does the checking for a 'reduction ' clause that needs to be done in // dependent and not dependent cases. - OpenACCClause * - CheckReductionClause(ArrayRef<const OpenACCClause *> ExistingClauses, - OpenACCDirectiveKind DirectiveKind, - SourceLocation BeginLoc, SourceLocation LParenLoc, - OpenACCReductionOperator ReductionOp, - ArrayRef<Expr *> Vars, SourceLocation EndLoc); + OpenACCClause *CheckReductionClause( + ArrayRef<const OpenACCClause *> ExistingClauses, + OpenACCDirectiveKind DirectiveKind, SourceLocation BeginLoc, + SourceLocation LParenLoc, OpenACCReductionOperator ReductionOp, + ArrayRef<Expr *> Vars, ArrayRef<OpenACCReductionRecipe> Recipes, + SourceLocation EndLoc); ExprResult BuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc); ExprResult ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc); diff --git a/clang/lib/AST/OpenACCClause.cpp b/clang/lib/AST/OpenACCClause.cpp index fe20004de6bea..9a9ede467331e 100644 --- a/clang/lib/AST/OpenACCClause.cpp +++ b/clang/lib/AST/OpenACCClause.cpp @@ -506,11 +506,13 @@ OpenACCDeviceTypeClause *OpenACCDeviceTypeClause::Create( OpenACCReductionClause *OpenACCReductionClause::Create( const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, OpenACCReductionOperator Operator, ArrayRef<Expr *> VarList, + ArrayRef<OpenACCReductionRecipe> Recipes, SourceLocation EndLoc) { void *Mem = C.Allocate( - OpenACCReductionClause::totalSizeToAlloc<Expr *>(VarList.size())); - return new (Mem) - OpenACCReductionClause(BeginLoc, LParenLoc, Operator, VarList, EndLoc); + OpenACCReductionClause::totalSizeToAlloc<Expr *, OpenACCReductionRecipe>( + VarList.size(), Recipes.size())); + return new (Mem) OpenACCReductionClause(BeginLoc, LParenLoc, Operator, + VarList, Recipes, EndLoc); } OpenACCAutoClause *OpenACCAutoClause::Create(const ASTContext &C, diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 7998d2369460b..2035fa7635f2a 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -2748,6 +2748,14 @@ void OpenACCClauseProfiler::VisitGangClause(const OpenACCGangClause &Clause) { void OpenACCClauseProfiler::VisitReductionClause( const OpenACCReductionClause &Clause) { VisitClauseWithVarList(Clause); + + for (auto &Recipe : Clause.getRecipes()) { + Profiler.VisitDecl(Recipe.RecipeDecl); + // TODO: OpenACC: Make sure we remember to update this when we figure out + // what we're adding for the operation recipe, in the meantime, a static + // assert will make sure we don't add something. + static_assert(sizeof(OpenACCReductionRecipe) == sizeof(int *)); + } } void OpenACCClauseProfiler::VisitBindClause(const OpenACCBindClause &Clause) { diff --git a/clang/lib/Sema/SemaOpenACCClause.cpp b/clang/lib/Sema/SemaOpenACCClause.cpp index aa54ff81dbba3..af5fd38ed6eb8 100644 --- a/clang/lib/Sema/SemaOpenACCClause.cpp +++ b/clang/lib/Sema/SemaOpenACCClause.cpp @@ -1774,18 +1774,27 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause( } SmallVector<Expr *> ValidVars; + SmallVector<OpenACCReductionRecipe> Recipes; for (Expr *Var : Clause.getVarList()) { ExprResult Res = SemaRef.CheckReductionVar(Clause.getDirectiveKind(), Clause.getReductionOp(), Var); - if (Res.isUsable()) + if (Res.isUsable()) { ValidVars.push_back(Res.get()); + + VarDecl *InitRecipe = + SemaRef.CreateInitRecipe(OpenACCClauseKind::Reduction, Res.get()) + .first; + // TODO: OpenACC: Create the reduction operation recipe here too. + Recipes.push_back({InitRecipe}); + } } return SemaRef.CheckReductionClause( ExistingClauses, Clause.getDirectiveKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getReductionOp(), ValidVars, + Recipes, Clause.getEndLoc()); } @@ -2158,7 +2167,8 @@ OpenACCClause *SemaOpenACC::CheckReductionClause( ArrayRef<const OpenACCClause *> ExistingClauses, OpenACCDirectiveKind DirectiveKind, SourceLocation BeginLoc, SourceLocation LParenLoc, OpenACCReductionOperator ReductionOp, - ArrayRef<Expr *> Vars, SourceLocation EndLoc) { + ArrayRef<Expr *> Vars, ArrayRef<OpenACCReductionRecipe> Recipes, + SourceLocation EndLoc) { if (DirectiveKind == OpenACCDirectiveKind::Loop || isOpenACCCombinedDirectiveKind(DirectiveKind)) { // OpenACC 3.3 2.9.11: A reduction clause may not appear on a loop directive @@ -2187,7 +2197,7 @@ OpenACCClause *SemaOpenACC::CheckReductionClause( } auto *Ret = OpenACCReductionClause::Create( - getASTContext(), BeginLoc, LParenLoc, ReductionOp, Vars, EndLoc); + getASTContext(), BeginLoc, LParenLoc, ReductionOp, Vars, Recipes, EndLoc); return Ret; } diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 3d4fc89d19bb9..7f0b24ecb7e20 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -12295,18 +12295,36 @@ void OpenACCClauseTransform<Derived>::VisitReductionClause( const OpenACCReductionClause &C) { SmallVector<Expr *> TransformedVars = VisitVarList(C.getVarList()); SmallVector<Expr *> ValidVars; + llvm::SmallVector<OpenACCReductionRecipe> Recipes; - for (Expr *Var : TransformedVars) { + for (const auto [Var, OrigRecipes] : + llvm::zip(TransformedVars, C.getRecipes())) { ExprResult Res = Self.getSema().OpenACC().CheckReductionVar( ParsedClause.getDirectiveKind(), C.getReductionOp(), Var); - if (Res.isUsable()) + if (Res.isUsable()) { ValidVars.push_back(Res.get()); + + // TODO OpenACC: When the recipe changes, make sure we get these right + // too. We probably need something similar for the operation. + static_assert(sizeof(OpenACCReductionRecipe) == sizeof(int*)); + VarDecl *InitRecipe = nullptr; + if (OrigRecipes.RecipeDecl) + InitRecipe = OrigRecipes.RecipeDecl; + else + InitRecipe = + Self.getSema() + .OpenACC() + .CreateInitRecipe(OpenACCClauseKind::Reduction, Res.get()) + .first; + + Recipes.push_back({InitRecipe}); + } } NewClause = Self.getSema().OpenACC().CheckReductionClause( ExistingClauses, ParsedClause.getDirectiveKind(), ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(), - C.getReductionOp(), ValidVars, ParsedClause.getEndLoc()); + C.getReductionOp(), ValidVars, Recipes, ParsedClause.getEndLoc()); } template <typename Derived> diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index e8dddda584a9b..b38f4944bda76 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -12996,8 +12996,16 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() { SourceLocation LParenLoc = readSourceLocation(); OpenACCReductionOperator Op = readEnum<OpenACCReductionOperator>(); llvm::SmallVector<Expr *> VarList = readOpenACCVarList(); + llvm::SmallVector<OpenACCReductionRecipe> RecipeList; + + for (unsigned I = 0; I < VarList.size(); ++I) { + VarDecl *Recipe = readDeclAs<VarDecl>(); + static_assert(sizeof(OpenACCReductionRecipe) == sizeof(int *)); + RecipeList.push_back({Recipe}); + } + return OpenACCReductionClause::Create(getContext(), BeginLoc, LParenLoc, Op, - VarList, EndLoc); + VarList, RecipeList, EndLoc); } case OpenACCClauseKind::Seq: return OpenACCSeqClause::Create(getContext(), BeginLoc, EndLoc); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 9faf107f64751..a7327397aa6d7 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -8886,6 +8886,11 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) { writeSourceLocation(RC->getLParenLoc()); writeEnum(RC->getReductionOp()); writeOpenACCVarList(RC); + + for (const OpenACCReductionRecipe &R : RC->getRecipes()) { + static_assert(sizeof(OpenACCReductionRecipe) == sizeof(int *)); + AddDeclRef(R.RecipeDecl); + } return; } case OpenACCClauseKind::Seq: diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index c446bb0331990..eb6be2b337519 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -2928,6 +2928,10 @@ void OpenACCClauseEnqueue::VisitDeviceTypeClause( void OpenACCClauseEnqueue::VisitReductionClause( const OpenACCReductionClause &C) { VisitVarList(C); + for (const OpenACCReductionRecipe &R : C.getRecipes()) { + static_assert(sizeof(OpenACCReductionRecipe) == sizeof(int *)); + Visitor.AddDecl(R.RecipeDecl); + } } void OpenACCClauseEnqueue::VisitAutoClause(const OpenACCAutoClause &C) {} void OpenACCClauseEnqueue::VisitIndependentClause( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits