Skip to content

Commit 2e499ee

Browse files
committed
[OPENMP50]Add initial support for 'affinity' clause.
Summary: Added parsing/sema/serialization support for affinity clause in task directives. Reviewers: jdoerfert Subscribers: yaxunl, guansong, arphaman, llvm-commits, cfe-commits, caomhin Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D80148
1 parent c1ae72d commit 2e499ee

File tree

16 files changed

+379
-15
lines changed

16 files changed

+379
-15
lines changed

clang/include/clang/AST/OpenMPClause.h

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7252,6 +7252,107 @@ class OMPUsesAllocatorsClause final
72527252
}
72537253
};
72547254

7255+
/// This represents clause 'affinity' in the '#pragma omp task'-based
7256+
/// directives.
7257+
///
7258+
/// \code
7259+
/// #pragma omp task affinity(iterator(i = 0:n) : ([3][n])a, b[:n], c[i])
7260+
/// \endcode
7261+
/// In this example directive '#pragma omp task' has clause 'affinity' with the
7262+
/// affinity modifer 'iterator(i = 0:n)' and locator items '([3][n])a', 'b[:n]'
7263+
/// and 'c[i]'.
7264+
class OMPAffinityClause final
7265+
: public OMPVarListClause<OMPAffinityClause>,
7266+
private llvm::TrailingObjects<OMPAffinityClause, Expr *> {
7267+
friend class OMPClauseReader;
7268+
friend OMPVarListClause;
7269+
friend TrailingObjects;
7270+
7271+
/// Location of ':' symbol.
7272+
SourceLocation ColonLoc;
7273+
7274+
/// Build clause.
7275+
///
7276+
/// \param StartLoc Starting location of the clause.
7277+
/// \param LParenLoc Location of '('.
7278+
/// \param ColonLoc Location of ':'.
7279+
/// \param EndLoc Ending location of the clause.
7280+
/// \param N Number of locators asssociated with the clause.
7281+
OMPAffinityClause(SourceLocation StartLoc, SourceLocation LParenLoc,
7282+
SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N)
7283+
: OMPVarListClause<OMPAffinityClause>(llvm::omp::OMPC_affinity, StartLoc,
7284+
LParenLoc, EndLoc, N) {}
7285+
7286+
/// Build an empty clause.
7287+
/// \param N Number of locators asssociated with the clause.
7288+
///
7289+
explicit OMPAffinityClause(unsigned N)
7290+
: OMPVarListClause<OMPAffinityClause>(llvm::omp::OMPC_affinity,
7291+
SourceLocation(), SourceLocation(),
7292+
SourceLocation(), N) {}
7293+
7294+
/// Sets the affinity modifier for the clause, if any.
7295+
void setModifier(Expr *E) {
7296+
getTrailingObjects<Expr *>()[varlist_size()] = E;
7297+
}
7298+
7299+
/// Sets the location of ':' symbol.
7300+
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
7301+
7302+
public:
7303+
/// Creates clause with a modifier a list of locator items.
7304+
///
7305+
/// \param C AST context.
7306+
/// \param StartLoc Starting location of the clause.
7307+
/// \param LParenLoc Location of '('.
7308+
/// \param ColonLoc Location of ':'.
7309+
/// \param EndLoc Ending location of the clause.
7310+
/// \param Locators List of locator items.
7311+
static OMPAffinityClause *Create(const ASTContext &C, SourceLocation StartLoc,
7312+
SourceLocation LParenLoc,
7313+
SourceLocation ColonLoc,
7314+
SourceLocation EndLoc, Expr *Modifier,
7315+
ArrayRef<Expr *> Locators);
7316+
7317+
/// Creates an empty clause with the place for \p N locator items.
7318+
///
7319+
/// \param C AST context.
7320+
/// \param N The number of locator items.
7321+
static OMPAffinityClause *CreateEmpty(const ASTContext &C, unsigned N);
7322+
7323+
/// Gets affinity modifier.
7324+
Expr *getModifier() { return getTrailingObjects<Expr *>()[varlist_size()]; }
7325+
Expr *getModifier() const {
7326+
return getTrailingObjects<Expr *>()[varlist_size()];
7327+
}
7328+
7329+
/// Gets the location of ':' symbol.
7330+
SourceLocation getColonLoc() const { return ColonLoc; }
7331+
7332+
// Iterators
7333+
child_range children() {
7334+
int Offset = getModifier() ? 1 : 0;
7335+
return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
7336+
reinterpret_cast<Stmt **>(varlist_end() + Offset));
7337+
}
7338+
7339+
const_child_range children() const {
7340+
auto Children = const_cast<OMPAffinityClause *>(this)->children();
7341+
return const_child_range(Children.begin(), Children.end());
7342+
}
7343+
7344+
child_range used_children() {
7345+
return child_range(child_iterator(), child_iterator());
7346+
}
7347+
const_child_range used_children() const {
7348+
return const_child_range(const_child_iterator(), const_child_iterator());
7349+
}
7350+
7351+
static bool classof(const OMPClause *T) {
7352+
return T->getClauseKind() == llvm::omp::OMPC_affinity;
7353+
}
7354+
};
7355+
72557356
/// This class implements a simple visitor for OMPClause
72567357
/// subclasses.
72577358
template<class ImplClass, template <typename> class Ptr, typename RetTy>

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3560,6 +3560,15 @@ bool RecursiveASTVisitor<Derived>::VisitOMPUsesAllocatorsClause(
35603560
return true;
35613561
}
35623562

3563+
template <typename Derived>
3564+
bool RecursiveASTVisitor<Derived>::VisitOMPAffinityClause(
3565+
OMPAffinityClause *C) {
3566+
TRY_TO(TraverseStmt(C->getModifier()));
3567+
for (Expr *E : C->varlists())
3568+
TRY_TO(TraverseStmt(E));
3569+
return true;
3570+
}
3571+
35633572
// FIXME: look at the following tricky-seeming exprs to see if we
35643573
// need to recurse on anything. These are ones that have methods
35653574
// returning decls or qualtypes or nestednamespecifier -- though I'm

clang/include/clang/Sema/Sema.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10799,6 +10799,12 @@ class Sema final {
1079910799
SourceLocation LParenLoc,
1080010800
SourceLocation EndLoc,
1080110801
ArrayRef<UsesAllocatorsData> Data);
10802+
/// Called on well-formed 'affinity' clause.
10803+
OMPClause *ActOnOpenMPAffinityClause(SourceLocation StartLoc,
10804+
SourceLocation LParenLoc,
10805+
SourceLocation ColonLoc,
10806+
SourceLocation EndLoc, Expr *Modifier,
10807+
ArrayRef<Expr *> Locators);
1080210808

1080310809
/// The kind of conversion being performed.
1080410810
enum CheckedConversionKind {

clang/lib/AST/OpenMPClause.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
151151
case OMPC_inclusive:
152152
case OMPC_exclusive:
153153
case OMPC_uses_allocators:
154+
case OMPC_affinity:
154155
break;
155156
}
156157

@@ -241,6 +242,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
241242
case OMPC_inclusive:
242243
case OMPC_exclusive:
243244
case OMPC_uses_allocators:
245+
case OMPC_affinity:
244246
break;
245247
}
246248

@@ -1368,6 +1370,25 @@ OMPUsesAllocatorsClause::CreateEmpty(const ASTContext &C, unsigned N) {
13681370
return new (Mem) OMPUsesAllocatorsClause(N);
13691371
}
13701372

1373+
OMPAffinityClause *
1374+
OMPAffinityClause::Create(const ASTContext &C, SourceLocation StartLoc,
1375+
SourceLocation LParenLoc, SourceLocation ColonLoc,
1376+
SourceLocation EndLoc, Expr *Modifier,
1377+
ArrayRef<Expr *> Locators) {
1378+
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Locators.size() + 1));
1379+
auto *Clause = new (Mem)
1380+
OMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, Locators.size());
1381+
Clause->setModifier(Modifier);
1382+
Clause->setVarRefs(Locators);
1383+
return Clause;
1384+
}
1385+
1386+
OMPAffinityClause *OMPAffinityClause::CreateEmpty(const ASTContext &C,
1387+
unsigned N) {
1388+
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N + 1));
1389+
return new (Mem) OMPAffinityClause(N);
1390+
}
1391+
13711392
//===----------------------------------------------------------------------===//
13721393
// OpenMP clauses printing methods
13731394
//===----------------------------------------------------------------------===//
@@ -1969,6 +1990,21 @@ void OMPClausePrinter::VisitOMPUsesAllocatorsClause(
19691990
OS << ")";
19701991
}
19711992

1993+
void OMPClausePrinter::VisitOMPAffinityClause(OMPAffinityClause *Node) {
1994+
if (Node->varlist_empty())
1995+
return;
1996+
OS << "affinity";
1997+
char StartSym = '(';
1998+
if (Expr *Modifier = Node->getModifier()) {
1999+
OS << "(";
2000+
Modifier->printPretty(OS, nullptr, Policy);
2001+
OS << " :";
2002+
StartSym = ' ';
2003+
}
2004+
VisitOMPClauseList(Node, StartSym);
2005+
OS << ")";
2006+
}
2007+
19722008
void OMPTraitInfo::getAsVariantMatchInfo(ASTContext &ASTCtx,
19732009
VariantMatchInfo &VMI) const {
19742010
for (const OMPTraitSet &Set : Sets) {

clang/lib/AST/StmtProfile.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,12 @@ void OMPClauseProfiler::VisitOMPUsesAllocatorsClause(
809809
Profiler->VisitStmt(D.AllocatorTraits);
810810
}
811811
}
812+
void OMPClauseProfiler::VisitOMPAffinityClause(const OMPAffinityClause *C) {
813+
if (const Expr *Modifier = C->getModifier())
814+
Profiler->VisitStmt(Modifier);
815+
for (const Expr *E : C->varlists())
816+
Profiler->VisitStmt(E);
817+
}
812818
void OMPClauseProfiler::VisitOMPOrderClause(const OMPOrderClause *C) {}
813819
} // namespace
814820

clang/lib/Basic/OpenMPKinds.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
175175
case OMPC_inclusive:
176176
case OMPC_exclusive:
177177
case OMPC_uses_allocators:
178+
case OMPC_affinity:
178179
break;
179180
}
180181
llvm_unreachable("Invalid OpenMP simple clause kind");
@@ -422,6 +423,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
422423
case OMPC_inclusive:
423424
case OMPC_exclusive:
424425
case OMPC_uses_allocators:
426+
case OMPC_affinity:
425427
break;
426428
}
427429
llvm_unreachable("Invalid OpenMP simple clause kind");

clang/lib/CodeGen/CGStmtOpenMP.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4734,6 +4734,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
47344734
case OMPC_inclusive:
47354735
case OMPC_exclusive:
47364736
case OMPC_uses_allocators:
4737+
case OMPC_affinity:
47374738
llvm_unreachable("Clause is not allowed in 'omp atomic'.");
47384739
}
47394740
}

clang/lib/Parse/ParseOpenMP.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2668,6 +2668,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
26682668
case OMPC_nontemporal:
26692669
case OMPC_inclusive:
26702670
case OMPC_exclusive:
2671+
case OMPC_affinity:
26712672
Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
26722673
break;
26732674
case OMPC_uses_allocators:
@@ -3275,7 +3276,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
32753276
getOpenMPClauseName(Kind).data()))
32763277
return true;
32773278

3278-
bool DependWithIterator = false;
3279+
bool HasIterator = false;
32793280
bool NeedRParenForLinear = false;
32803281
BalancedDelimiterTracker LinearT(*this, tok::l_paren,
32813282
tok::annot_pragma_openmp_end);
@@ -3321,7 +3322,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
33213322
// iterators-definition ]
33223323
// where iterator-specifier is [ iterator-type ] identifier =
33233324
// range-specification
3324-
DependWithIterator = true;
3325+
HasIterator = true;
33253326
EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
33263327
ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
33273328
Data.DepModOrTailExpr = IteratorRes.get();
@@ -3440,12 +3441,24 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
34403441
ConsumeToken();
34413442
}
34423443
}
3443-
} else if (Kind == OMPC_allocate) {
3444+
} else if (Kind == OMPC_allocate ||
3445+
(Kind == OMPC_affinity && Tok.is(tok::identifier) &&
3446+
PP.getSpelling(Tok) == "iterator")) {
34443447
// Handle optional allocator expression followed by colon delimiter.
34453448
ColonProtectionRAIIObject ColonRAII(*this);
34463449
TentativeParsingAction TPA(*this);
3447-
ExprResult Tail =
3448-
Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
3450+
// OpenMP 5.0, 2.10.1, task Construct.
3451+
// where aff-modifier is one of the following:
3452+
// iterator(iterators-definition)
3453+
ExprResult Tail;
3454+
if (Kind == OMPC_allocate) {
3455+
Tail = ParseAssignmentExpression();
3456+
} else {
3457+
HasIterator = true;
3458+
EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
3459+
Tail = ParseOpenMPIteratorsExpr();
3460+
}
3461+
Tail = Actions.CorrectDelayedTyposInExpr(Tail);
34493462
Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(),
34503463
/*DiscardedValue=*/false);
34513464
if (Tail.isUsable()) {
@@ -3454,8 +3467,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
34543467
Data.ColonLoc = ConsumeToken();
34553468
TPA.Commit();
34563469
} else {
3457-
// colon not found, no allocator specified, parse only list of
3458-
// variables.
3470+
// Colon not found, parse only list of variables.
34593471
TPA.Revert();
34603472
}
34613473
} else {
@@ -3524,7 +3536,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
35243536
if (!T.consumeClose())
35253537
Data.RLoc = T.getCloseLocation();
35263538
// Exit from scope when the iterator is used in depend clause.
3527-
if (DependWithIterator)
3539+
if (HasIterator)
35283540
ExitScope();
35293541
return (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
35303542
(MustHaveTail && !Data.DepModOrTailExpr) || InvalidReductionId ||

0 commit comments

Comments
 (0)