Author: erichkeane Date: 2025-08-05T09:26:47-07:00 New Revision: 258997c16e4d5438207377d6ce4f9d608860d7ae
URL: https://github.com/llvm/llvm-project/commit/258997c16e4d5438207377d6ce4f9d608860d7ae DIFF: https://github.com/llvm/llvm-project/commit/258997c16e4d5438207377d6ce4f9d608860d7ae.diff LOG: [OpenACC][NFCI] Add 'InitRecipes' to 'firstprivate' AST node This patch adds the 'init recipes' to firstprivate like I did for 'private', so that we can properly init these types. At the moment, the recipe init isn't generated (just the VarDecl), and this isn't really used anywhere as it will be used exclusively in Codegen. 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/SemaOpenACC.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 32a06bc84ad20..8c848a10d40ad 100644 --- a/clang/include/clang/AST/OpenACCClause.h +++ b/clang/include/clang/AST/OpenACCClause.h @@ -878,23 +878,46 @@ class OpenACCPrivateClause final class OpenACCFirstPrivateClause final : public OpenACCClauseWithVarList, - private llvm::TrailingObjects<OpenACCFirstPrivateClause, Expr *> { + private llvm::TrailingObjects<OpenACCFirstPrivateClause, Expr *, + VarDecl *> { friend TrailingObjects; OpenACCFirstPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc, - ArrayRef<Expr *> VarList, SourceLocation EndLoc) + ArrayRef<Expr *> VarList, + ArrayRef<VarDecl *> InitRecipes, + SourceLocation EndLoc) : OpenACCClauseWithVarList(OpenACCClauseKind::FirstPrivate, BeginLoc, LParenLoc, EndLoc) { - setExprs(getTrailingObjects(VarList.size()), VarList); + assert(VarList.size() == InitRecipes.size()); + setExprs(getTrailingObjects<Expr *>(VarList.size()), VarList); + llvm::uninitialized_copy(InitRecipes, getTrailingObjects<VarDecl *>()); } public: static bool classof(const OpenACCClause *C) { return C->getClauseKind() == OpenACCClauseKind::FirstPrivate; } + + // Gets a list of 'made up' `VarDecl` objects that can be used by codegen to + // ensure that we properly initialize each of these variables. + ArrayRef<VarDecl *> getInitRecipes() { + return ArrayRef<VarDecl *>{getTrailingObjects<VarDecl *>(), + getExprs().size()}; + } + + ArrayRef<VarDecl *> getInitRecipes() const { + return ArrayRef<VarDecl *>{getTrailingObjects<VarDecl *>(), + getExprs().size()}; + } + static OpenACCFirstPrivateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, - ArrayRef<Expr *> VarList, SourceLocation EndLoc); + ArrayRef<Expr *> VarList, ArrayRef<VarDecl *> InitRecipes, + SourceLocation EndLoc); + + size_t numTrailingObjects(OverloadToken<Expr *>) const { + return getExprs().size(); + } }; class OpenACCDevicePtrClause final diff --git a/clang/include/clang/Sema/SemaOpenACC.h b/clang/include/clang/Sema/SemaOpenACC.h index e9e4e6c2b380c..964749c2fd627 100644 --- a/clang/include/clang/Sema/SemaOpenACC.h +++ b/clang/include/clang/Sema/SemaOpenACC.h @@ -238,8 +238,9 @@ class SemaOpenACC : public SemaBase { ArrayRef<const OpenACCClause *> Clauses); // Creates a VarDecl with a proper default init for the purposes of a - // `private` clause, so it can be used to generate a recipe later. - VarDecl *CreateInitRecipe(const Expr *VarExpr); + // `private`/'firstprivate'/'reduction' clause, so it can be used to generate + // a recipe later. + VarDecl *CreateInitRecipe(OpenACCClauseKind CK, const Expr *VarExpr); public: ComputeConstructInfo &getActiveComputeConstructInfo() { diff --git a/clang/lib/AST/OpenACCClause.cpp b/clang/lib/AST/OpenACCClause.cpp index f21e645697656..f7a98bd92190b 100644 --- a/clang/lib/AST/OpenACCClause.cpp +++ b/clang/lib/AST/OpenACCClause.cpp @@ -329,11 +329,13 @@ OpenACCPrivateClause::Create(const ASTContext &C, SourceLocation BeginLoc, OpenACCFirstPrivateClause *OpenACCFirstPrivateClause::Create( const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, - ArrayRef<Expr *> VarList, SourceLocation EndLoc) { - void *Mem = C.Allocate( - OpenACCFirstPrivateClause::totalSizeToAlloc<Expr *>(VarList.size())); - return new (Mem) - OpenACCFirstPrivateClause(BeginLoc, LParenLoc, VarList, EndLoc); + ArrayRef<Expr *> VarList, ArrayRef<VarDecl *> InitRecipes, + SourceLocation EndLoc) { + void *Mem = + C.Allocate(OpenACCFirstPrivateClause::totalSizeToAlloc<Expr *, VarDecl *>( + VarList.size(), InitRecipes.size())); + return new (Mem) OpenACCFirstPrivateClause(BeginLoc, LParenLoc, VarList, + InitRecipes, EndLoc); } OpenACCAttachClause *OpenACCAttachClause::Create(const ASTContext &C, diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 57834ca4a89ca..4c36f2473ce25 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -2644,6 +2644,9 @@ void OpenACCClauseProfiler::VisitPrivateClause( void OpenACCClauseProfiler::VisitFirstPrivateClause( const OpenACCFirstPrivateClause &Clause) { VisitClauseWithVarList(Clause); + + for (auto *VD : Clause.getInitRecipes()) + Profiler.VisitDecl(VD); } void OpenACCClauseProfiler::VisitAttachClause( diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp index 8c6c9c70f8e2c..62fe3d1836ab5 100644 --- a/clang/lib/Sema/SemaOpenACC.cpp +++ b/clang/lib/Sema/SemaOpenACC.cpp @@ -2575,7 +2575,8 @@ SemaOpenACC::ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) { return BuildOpenACCAsteriskSizeExpr(AsteriskLoc); } -VarDecl *SemaOpenACC::CreateInitRecipe(const Expr *VarExpr) { +VarDecl *SemaOpenACC::CreateInitRecipe(OpenACCClauseKind CK, + const Expr *VarExpr) { // Strip off any array subscripts/array section exprs to get to the type of // the variable. while (isa_and_present<ArraySectionExpr, ArraySubscriptExpr>(VarExpr)) { @@ -2602,7 +2603,7 @@ VarDecl *SemaOpenACC::CreateInitRecipe(const Expr *VarExpr) { ExprResult Init; - { + if (CK == OpenACCClauseKind::Private) { // Trap errors so we don't get weird ones here. If we can't init, we'll just // swallow the errors. Sema::TentativeAnalysisScope Trap{SemaRef}; @@ -2612,6 +2613,12 @@ VarDecl *SemaOpenACC::CreateInitRecipe(const Expr *VarExpr) { InitializationSequence InitSeq(SemaRef.SemaRef, Entity, Kind, {}); Init = InitSeq.Perform(SemaRef.SemaRef, Entity, Kind, {}); + } else if (CK == OpenACCClauseKind::FirstPrivate) { + // TODO: OpenACC: Implement this to do a 'copy' operation. + } else if (CK == OpenACCClauseKind::Reduction) { + // TODO: OpenACC: Implement this for whatever reduction needs. + } else { + llvm_unreachable("Unknown clause kind in CreateInitRecipe"); } if (Init.get()) { diff --git a/clang/lib/Sema/SemaOpenACCClause.cpp b/clang/lib/Sema/SemaOpenACCClause.cpp index 9f1a6177b945c..88d217f2c8d25 100644 --- a/clang/lib/Sema/SemaOpenACCClause.cpp +++ b/clang/lib/Sema/SemaOpenACCClause.cpp @@ -799,7 +799,8 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitPrivateClause( // Assemble the recipes list. for (const Expr *VarExpr : Clause.getVarList()) - InitRecipes.push_back(SemaRef.CreateInitRecipe(VarExpr)); + InitRecipes.push_back( + SemaRef.CreateInitRecipe(OpenACCClauseKind::Private, VarExpr)); return OpenACCPrivateClause::Create( Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(), @@ -812,9 +813,16 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitFirstPrivateClause( // really isn't anything to do here. GCC does some duplicate-finding, though // it isn't apparent in the standard where this is justified. + llvm::SmallVector<VarDecl *> InitRecipes; + + // Assemble the recipes list. + for (const Expr *VarExpr : Clause.getVarList()) + InitRecipes.push_back( + SemaRef.CreateInitRecipe(OpenACCClauseKind::FirstPrivate, VarExpr)); + return OpenACCFirstPrivateClause::Create( Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(), - Clause.getEndLoc()); + InitRecipes, Clause.getEndLoc()); } OpenACCClause *SemaOpenACCClauseVisitor::VisitNoCreateClause( diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 5ff5fbf52ae25..6ce5535c7f3f7 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -11901,8 +11901,8 @@ void OpenACCClauseTransform<Derived>::VisitPrivateClause( if (InitRecipe) InitRecipes.push_back(InitRecipe); else - InitRecipes.push_back( - Self.getSema().OpenACC().CreateInitRecipe(VarRef.get())); + InitRecipes.push_back(Self.getSema().OpenACC().CreateInitRecipe( + OpenACCClauseKind::Private, VarRef.get())); } } ParsedClause.setVarListDetails(InstantiatedVarList, @@ -11941,12 +11941,31 @@ void OpenACCClauseTransform<Derived>::VisitDeviceClause( template <typename Derived> void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause( const OpenACCFirstPrivateClause &C) { - ParsedClause.setVarListDetails(VisitVarList(C.getVarList()), + llvm::SmallVector<Expr *> InstantiatedVarList; + llvm::SmallVector<VarDecl *> InitRecipes; + + for (const auto [RefExpr, InitRecipe] : + llvm::zip(C.getVarList(), C.getInitRecipes())) { + ExprResult VarRef = VisitVar(RefExpr); + + if (VarRef.isUsable()) { + InstantiatedVarList.push_back(VarRef.get()); + + // We only have to create a new one if it is dependent, and Sema won't + // make one of these unless the type is non-dependent. + if (InitRecipe) + InitRecipes.push_back(InitRecipe); + else + InitRecipes.push_back(Self.getSema().OpenACC().CreateInitRecipe( + OpenACCClauseKind::FirstPrivate, VarRef.get())); + } + } + ParsedClause.setVarListDetails(InstantiatedVarList, OpenACCModifierKind::Invalid); NewClause = OpenACCFirstPrivateClause::Create( Self.getSema().getASTContext(), ParsedClause.getBeginLoc(), - ParsedClause.getLParenLoc(), ParsedClause.getVarList(), + ParsedClause.getLParenLoc(), ParsedClause.getVarList(), InitRecipes, ParsedClause.getEndLoc()); } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 95e92cf6790d7..1402f40894ab8 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -12877,8 +12877,12 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() { case OpenACCClauseKind::FirstPrivate: { SourceLocation LParenLoc = readSourceLocation(); llvm::SmallVector<Expr *> VarList = readOpenACCVarList(); + llvm::SmallVector<VarDecl *> RecipeList; + for (unsigned I = 0; I < VarList.size(); ++I) + RecipeList.push_back(readDeclAs<VarDecl>()); + return OpenACCFirstPrivateClause::Create(getContext(), BeginLoc, LParenLoc, - VarList, EndLoc); + VarList, RecipeList, EndLoc); } case OpenACCClauseKind::Attach: { SourceLocation LParenLoc = readSourceLocation(); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 955f7b914f5db..c038d4dd5c942 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -8761,6 +8761,9 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) { const auto *FPC = cast<OpenACCFirstPrivateClause>(C); writeSourceLocation(FPC->getLParenLoc()); writeOpenACCVarList(FPC); + + for (VarDecl *VD : FPC->getInitRecipes()) + AddDeclRef(VD); return; } case OpenACCClauseKind::Attach: { diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 9c2724f17cf8b..95cda674a5895 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -2895,6 +2895,8 @@ void OpenACCClauseEnqueue::VisitDeviceClause(const OpenACCDeviceClause &C) { void OpenACCClauseEnqueue::VisitFirstPrivateClause( const OpenACCFirstPrivateClause &C) { VisitVarList(C); + for (VarDecl *V : C.getInitRecipes()) + Visitor.AddDecl(V); } void OpenACCClauseEnqueue::VisitPresentClause(const OpenACCPresentClause &C) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits