Skip to content

Commit 258997c

Browse files
committed
[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.
1 parent e8a87da commit 258997c

File tree

10 files changed

+92
-20
lines changed

10 files changed

+92
-20
lines changed

clang/include/clang/AST/OpenACCClause.h

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -878,23 +878,46 @@ class OpenACCPrivateClause final
878878

879879
class OpenACCFirstPrivateClause final
880880
: public OpenACCClauseWithVarList,
881-
private llvm::TrailingObjects<OpenACCFirstPrivateClause, Expr *> {
881+
private llvm::TrailingObjects<OpenACCFirstPrivateClause, Expr *,
882+
VarDecl *> {
882883
friend TrailingObjects;
883884

884885
OpenACCFirstPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
885-
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
886+
ArrayRef<Expr *> VarList,
887+
ArrayRef<VarDecl *> InitRecipes,
888+
SourceLocation EndLoc)
886889
: OpenACCClauseWithVarList(OpenACCClauseKind::FirstPrivate, BeginLoc,
887890
LParenLoc, EndLoc) {
888-
setExprs(getTrailingObjects(VarList.size()), VarList);
891+
assert(VarList.size() == InitRecipes.size());
892+
setExprs(getTrailingObjects<Expr *>(VarList.size()), VarList);
893+
llvm::uninitialized_copy(InitRecipes, getTrailingObjects<VarDecl *>());
889894
}
890895

891896
public:
892897
static bool classof(const OpenACCClause *C) {
893898
return C->getClauseKind() == OpenACCClauseKind::FirstPrivate;
894899
}
900+
901+
// Gets a list of 'made up' `VarDecl` objects that can be used by codegen to
902+
// ensure that we properly initialize each of these variables.
903+
ArrayRef<VarDecl *> getInitRecipes() {
904+
return ArrayRef<VarDecl *>{getTrailingObjects<VarDecl *>(),
905+
getExprs().size()};
906+
}
907+
908+
ArrayRef<VarDecl *> getInitRecipes() const {
909+
return ArrayRef<VarDecl *>{getTrailingObjects<VarDecl *>(),
910+
getExprs().size()};
911+
}
912+
895913
static OpenACCFirstPrivateClause *
896914
Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
897-
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
915+
ArrayRef<Expr *> VarList, ArrayRef<VarDecl *> InitRecipes,
916+
SourceLocation EndLoc);
917+
918+
size_t numTrailingObjects(OverloadToken<Expr *>) const {
919+
return getExprs().size();
920+
}
898921
};
899922

900923
class OpenACCDevicePtrClause final

clang/include/clang/Sema/SemaOpenACC.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,9 @@ class SemaOpenACC : public SemaBase {
238238
ArrayRef<const OpenACCClause *> Clauses);
239239

240240
// Creates a VarDecl with a proper default init for the purposes of a
241-
// `private` clause, so it can be used to generate a recipe later.
242-
VarDecl *CreateInitRecipe(const Expr *VarExpr);
241+
// `private`/'firstprivate'/'reduction' clause, so it can be used to generate
242+
// a recipe later.
243+
VarDecl *CreateInitRecipe(OpenACCClauseKind CK, const Expr *VarExpr);
243244

244245
public:
245246
ComputeConstructInfo &getActiveComputeConstructInfo() {

clang/lib/AST/OpenACCClause.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -329,11 +329,13 @@ OpenACCPrivateClause::Create(const ASTContext &C, SourceLocation BeginLoc,
329329

330330
OpenACCFirstPrivateClause *OpenACCFirstPrivateClause::Create(
331331
const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
332-
ArrayRef<Expr *> VarList, SourceLocation EndLoc) {
333-
void *Mem = C.Allocate(
334-
OpenACCFirstPrivateClause::totalSizeToAlloc<Expr *>(VarList.size()));
335-
return new (Mem)
336-
OpenACCFirstPrivateClause(BeginLoc, LParenLoc, VarList, EndLoc);
332+
ArrayRef<Expr *> VarList, ArrayRef<VarDecl *> InitRecipes,
333+
SourceLocation EndLoc) {
334+
void *Mem =
335+
C.Allocate(OpenACCFirstPrivateClause::totalSizeToAlloc<Expr *, VarDecl *>(
336+
VarList.size(), InitRecipes.size()));
337+
return new (Mem) OpenACCFirstPrivateClause(BeginLoc, LParenLoc, VarList,
338+
InitRecipes, EndLoc);
337339
}
338340

339341
OpenACCAttachClause *OpenACCAttachClause::Create(const ASTContext &C,

clang/lib/AST/StmtProfile.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2644,6 +2644,9 @@ void OpenACCClauseProfiler::VisitPrivateClause(
26442644
void OpenACCClauseProfiler::VisitFirstPrivateClause(
26452645
const OpenACCFirstPrivateClause &Clause) {
26462646
VisitClauseWithVarList(Clause);
2647+
2648+
for (auto *VD : Clause.getInitRecipes())
2649+
Profiler.VisitDecl(VD);
26472650
}
26482651

26492652
void OpenACCClauseProfiler::VisitAttachClause(

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2575,7 +2575,8 @@ SemaOpenACC::ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
25752575
return BuildOpenACCAsteriskSizeExpr(AsteriskLoc);
25762576
}
25772577

2578-
VarDecl *SemaOpenACC::CreateInitRecipe(const Expr *VarExpr) {
2578+
VarDecl *SemaOpenACC::CreateInitRecipe(OpenACCClauseKind CK,
2579+
const Expr *VarExpr) {
25792580
// Strip off any array subscripts/array section exprs to get to the type of
25802581
// the variable.
25812582
while (isa_and_present<ArraySectionExpr, ArraySubscriptExpr>(VarExpr)) {
@@ -2602,7 +2603,7 @@ VarDecl *SemaOpenACC::CreateInitRecipe(const Expr *VarExpr) {
26022603

26032604
ExprResult Init;
26042605

2605-
{
2606+
if (CK == OpenACCClauseKind::Private) {
26062607
// Trap errors so we don't get weird ones here. If we can't init, we'll just
26072608
// swallow the errors.
26082609
Sema::TentativeAnalysisScope Trap{SemaRef};
@@ -2612,6 +2613,12 @@ VarDecl *SemaOpenACC::CreateInitRecipe(const Expr *VarExpr) {
26122613

26132614
InitializationSequence InitSeq(SemaRef.SemaRef, Entity, Kind, {});
26142615
Init = InitSeq.Perform(SemaRef.SemaRef, Entity, Kind, {});
2616+
} else if (CK == OpenACCClauseKind::FirstPrivate) {
2617+
// TODO: OpenACC: Implement this to do a 'copy' operation.
2618+
} else if (CK == OpenACCClauseKind::Reduction) {
2619+
// TODO: OpenACC: Implement this for whatever reduction needs.
2620+
} else {
2621+
llvm_unreachable("Unknown clause kind in CreateInitRecipe");
26152622
}
26162623

26172624
if (Init.get()) {

clang/lib/Sema/SemaOpenACCClause.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,8 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitPrivateClause(
799799

800800
// Assemble the recipes list.
801801
for (const Expr *VarExpr : Clause.getVarList())
802-
InitRecipes.push_back(SemaRef.CreateInitRecipe(VarExpr));
802+
InitRecipes.push_back(
803+
SemaRef.CreateInitRecipe(OpenACCClauseKind::Private, VarExpr));
803804

804805
return OpenACCPrivateClause::Create(
805806
Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(),
@@ -812,9 +813,16 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitFirstPrivateClause(
812813
// really isn't anything to do here. GCC does some duplicate-finding, though
813814
// it isn't apparent in the standard where this is justified.
814815

816+
llvm::SmallVector<VarDecl *> InitRecipes;
817+
818+
// Assemble the recipes list.
819+
for (const Expr *VarExpr : Clause.getVarList())
820+
InitRecipes.push_back(
821+
SemaRef.CreateInitRecipe(OpenACCClauseKind::FirstPrivate, VarExpr));
822+
815823
return OpenACCFirstPrivateClause::Create(
816824
Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(),
817-
Clause.getEndLoc());
825+
InitRecipes, Clause.getEndLoc());
818826
}
819827

820828
OpenACCClause *SemaOpenACCClauseVisitor::VisitNoCreateClause(

clang/lib/Sema/TreeTransform.h

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11901,8 +11901,8 @@ void OpenACCClauseTransform<Derived>::VisitPrivateClause(
1190111901
if (InitRecipe)
1190211902
InitRecipes.push_back(InitRecipe);
1190311903
else
11904-
InitRecipes.push_back(
11905-
Self.getSema().OpenACC().CreateInitRecipe(VarRef.get()));
11904+
InitRecipes.push_back(Self.getSema().OpenACC().CreateInitRecipe(
11905+
OpenACCClauseKind::Private, VarRef.get()));
1190611906
}
1190711907
}
1190811908
ParsedClause.setVarListDetails(InstantiatedVarList,
@@ -11941,12 +11941,31 @@ void OpenACCClauseTransform<Derived>::VisitDeviceClause(
1194111941
template <typename Derived>
1194211942
void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
1194311943
const OpenACCFirstPrivateClause &C) {
11944-
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11944+
llvm::SmallVector<Expr *> InstantiatedVarList;
11945+
llvm::SmallVector<VarDecl *> InitRecipes;
11946+
11947+
for (const auto [RefExpr, InitRecipe] :
11948+
llvm::zip(C.getVarList(), C.getInitRecipes())) {
11949+
ExprResult VarRef = VisitVar(RefExpr);
11950+
11951+
if (VarRef.isUsable()) {
11952+
InstantiatedVarList.push_back(VarRef.get());
11953+
11954+
// We only have to create a new one if it is dependent, and Sema won't
11955+
// make one of these unless the type is non-dependent.
11956+
if (InitRecipe)
11957+
InitRecipes.push_back(InitRecipe);
11958+
else
11959+
InitRecipes.push_back(Self.getSema().OpenACC().CreateInitRecipe(
11960+
OpenACCClauseKind::FirstPrivate, VarRef.get()));
11961+
}
11962+
}
11963+
ParsedClause.setVarListDetails(InstantiatedVarList,
1194511964
OpenACCModifierKind::Invalid);
1194611965

1194711966
NewClause = OpenACCFirstPrivateClause::Create(
1194811967
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11949-
ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11968+
ParsedClause.getLParenLoc(), ParsedClause.getVarList(), InitRecipes,
1195011969
ParsedClause.getEndLoc());
1195111970
}
1195211971

clang/lib/Serialization/ASTReader.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12877,8 +12877,12 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
1287712877
case OpenACCClauseKind::FirstPrivate: {
1287812878
SourceLocation LParenLoc = readSourceLocation();
1287912879
llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
12880+
llvm::SmallVector<VarDecl *> RecipeList;
12881+
for (unsigned I = 0; I < VarList.size(); ++I)
12882+
RecipeList.push_back(readDeclAs<VarDecl>());
12883+
1288012884
return OpenACCFirstPrivateClause::Create(getContext(), BeginLoc, LParenLoc,
12881-
VarList, EndLoc);
12885+
VarList, RecipeList, EndLoc);
1288212886
}
1288312887
case OpenACCClauseKind::Attach: {
1288412888
SourceLocation LParenLoc = readSourceLocation();

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8761,6 +8761,9 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
87618761
const auto *FPC = cast<OpenACCFirstPrivateClause>(C);
87628762
writeSourceLocation(FPC->getLParenLoc());
87638763
writeOpenACCVarList(FPC);
8764+
8765+
for (VarDecl *VD : FPC->getInitRecipes())
8766+
AddDeclRef(VD);
87648767
return;
87658768
}
87668769
case OpenACCClauseKind::Attach: {

clang/tools/libclang/CIndex.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2895,6 +2895,8 @@ void OpenACCClauseEnqueue::VisitDeviceClause(const OpenACCDeviceClause &C) {
28952895
void OpenACCClauseEnqueue::VisitFirstPrivateClause(
28962896
const OpenACCFirstPrivateClause &C) {
28972897
VisitVarList(C);
2898+
for (VarDecl *V : C.getInitRecipes())
2899+
Visitor.AddDecl(V);
28982900
}
28992901

29002902
void OpenACCClauseEnqueue::VisitPresentClause(const OpenACCPresentClause &C) {

0 commit comments

Comments
 (0)