[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.
This commit is contained in:
parent
50a3368f22
commit
d0dc3799b7
@ -1250,19 +1250,32 @@ public:
|
||||
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 @@ public:
|
||||
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
|
||||
|
@ -947,12 +947,12 @@ public:
|
||||
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);
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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(
|
||||
|
Loading…
x
Reference in New Issue
Block a user