diff --git a/clang/include/clang/AST/OpenACCClause.h b/clang/include/clang/AST/OpenACCClause.h index 58ba8d91f1277..79cffeb4dade9 100644 --- a/clang/include/clang/AST/OpenACCClause.h +++ b/clang/include/clang/AST/OpenACCClause.h @@ -1280,13 +1280,31 @@ class OpenACCCreateClause final // 'main' declaration used for initializaiton, which is fixed. struct OpenACCReductionRecipe { VarDecl *AllocaDecl; - // TODO: OpenACC: this should eventually have the operations here too. - OpenACCReductionRecipe(VarDecl *A) : AllocaDecl(A) {} + // A combiner recipe is represented by an operation expression. However, in + // order to generate these properly, we have to make up a LHS and a RHS + // expression for the purposes of generation. + struct CombinerRecipe { + VarDecl *LHS; + VarDecl *RHS; + Expr *Op; + }; + + // Contains a collection of the recipe elements we need for the combiner: + // -For Scalars, there will be 1 element, just the combiner for that scalar. + // -For a struct with a valid operator, this will be 1 element, just that + // call. + // -For a struct without the operator, this will be 1 element per field, which + // should be the combiner for that element. + // -For an array of any of the above, it will be the above for the element. + llvm::SmallVector CombinerRecipes; + + OpenACCReductionRecipe(VarDecl *A, llvm::ArrayRef Combiners) + : AllocaDecl(A), CombinerRecipes(Combiners) {} bool isSet() const { return AllocaDecl; } static OpenACCReductionRecipe Empty() { - return OpenACCReductionRecipe(/*AllocaDecl=*/nullptr); + return OpenACCReductionRecipe(/*AllocaDecl=*/nullptr, {}); } }; diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index f3b5478222488..3cd033e73800f 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -2769,10 +2769,19 @@ void OpenACCClauseProfiler::VisitReductionClause( for (auto &Recipe : Clause.getRecipes()) { Profiler.VisitDecl(Recipe.AllocaDecl); + // 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 *)); + static_assert(sizeof(OpenACCReductionRecipe::CombinerRecipe) == + 3 * sizeof(int *)); + for (auto &CombinerRecipe : Recipe.CombinerRecipes) { + if (CombinerRecipe.Op) { + Profiler.VisitDecl(CombinerRecipe.LHS); + Profiler.VisitDecl(CombinerRecipe.RHS); + Profiler.VisitStmt(CombinerRecipe.Op); + } + } } } diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp index 8471f02f323d6..4824b5a3082a4 100644 --- a/clang/lib/Sema/SemaOpenACC.cpp +++ b/clang/lib/Sema/SemaOpenACC.cpp @@ -2946,5 +2946,5 @@ OpenACCReductionRecipe SemaOpenACC::CreateReductionInitRecipe( AllocaDecl->setInit(Init.get()); AllocaDecl->setInitStyle(VarDecl::CallInit); } - return OpenACCReductionRecipe(AllocaDecl); + return OpenACCReductionRecipe(AllocaDecl, {}); } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 6acf79acea111..868f0cc8b1da7 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -13009,9 +13009,22 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() { llvm::SmallVector RecipeList; for (unsigned I = 0; I < VarList.size(); ++I) { - static_assert(sizeof(OpenACCReductionRecipe) == sizeof(int *)); VarDecl *Recipe = readDeclAs(); - RecipeList.push_back({Recipe}); + + static_assert(sizeof(OpenACCReductionRecipe::CombinerRecipe) == + 3 * sizeof(int *)); + + llvm::SmallVector Combiners; + unsigned NumCombiners = readInt(); + for (unsigned I = 0; I < NumCombiners; ++I) { + VarDecl *LHS = readDeclAs(); + VarDecl *RHS = readDeclAs(); + Expr *Op = readExpr(); + + Combiners.push_back({LHS, RHS, Op}); + } + + RecipeList.push_back({Recipe, Combiners}); } return OpenACCReductionClause::Create(getContext(), BeginLoc, LParenLoc, Op, diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 09b1e58ef220c..82ccde84de37d 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -8925,8 +8925,17 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) { writeOpenACCVarList(RC); for (const OpenACCReductionRecipe &R : RC->getRecipes()) { - static_assert(sizeof(OpenACCReductionRecipe) == 1 * sizeof(int *)); AddDeclRef(R.AllocaDecl); + + static_assert(sizeof(OpenACCReductionRecipe::CombinerRecipe) == + 3 * sizeof(int *)); + writeUInt32(R.CombinerRecipes.size()); + + for (auto &CombinerRecipe : R.CombinerRecipes) { + AddDeclRef(CombinerRecipe.LHS); + AddDeclRef(CombinerRecipe.RHS); + AddStmt(CombinerRecipe.Op); + } } return; }