Skip to content

Commit 435e584

Browse files
authored
[clang][OpenMP] Add 'allocator' modifier for 'allocate' clause. (llvm#114883)
The 'allocator' modifier is now accepted in the 'allocate' clause. Added LIT tests covering codegen, PCH, template handling, and serialization for 'allocator' modifier. Added support for allocator-modifier to release notes. Testing - New allocate modifier LIT tests. - OpenMP LIT tests. - check-all - relevant sollve_vv test cases tests/5.2/scope/test_scope_allocate_construct.c
1 parent d047488 commit 435e584

15 files changed

+574
-28
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -888,6 +888,7 @@ OpenMP Support
888888
--------------
889889
- Added support for 'omp assume' directive.
890890
- Added support for 'omp scope' directive.
891+
- Added support for allocator-modifier in 'allocate' clause.
891892

892893
Improvements
893894
^^^^^^^^^^^^

clang/include/clang/AST/OpenMPClause.h

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,8 @@ class OMPAlignClause final
486486
/// #pragma omp parallel private(a) allocate(omp_default_mem_alloc :a)
487487
/// \endcode
488488
/// In this example directive '#pragma omp parallel' has clause 'private'
489-
/// and clause 'allocate' for the variable 'a'.
489+
/// and clause 'allocate' for the variable 'a', which specifies an explicit
490+
/// memory allocator.
490491
class OMPAllocateClause final
491492
: public OMPVarListClause<OMPAllocateClause>,
492493
private llvm::TrailingObjects<OMPAllocateClause, Expr *> {
@@ -499,6 +500,10 @@ class OMPAllocateClause final
499500
Expr *Allocator = nullptr;
500501
/// Position of the ':' delimiter in the clause;
501502
SourceLocation ColonLoc;
503+
/// Modifier of 'allocate' clause.
504+
OpenMPAllocateClauseModifier AllocatorModifier = OMPC_ALLOCATE_unknown;
505+
/// Location of allocator modifier if any.
506+
SourceLocation AllocatorModifierLoc;
502507

503508
/// Build clause with number of variables \a N.
504509
///
@@ -510,10 +515,14 @@ class OMPAllocateClause final
510515
/// \param N Number of the variables in the clause.
511516
OMPAllocateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
512517
Expr *Allocator, SourceLocation ColonLoc,
513-
SourceLocation EndLoc, unsigned N)
518+
OpenMPAllocateClauseModifier AllocatorModifier,
519+
SourceLocation AllocatorModifierLoc, SourceLocation EndLoc,
520+
unsigned N)
514521
: OMPVarListClause<OMPAllocateClause>(llvm::omp::OMPC_allocate, StartLoc,
515522
LParenLoc, EndLoc, N),
516-
Allocator(Allocator), ColonLoc(ColonLoc) {}
523+
Allocator(Allocator), ColonLoc(ColonLoc),
524+
AllocatorModifier(AllocatorModifier),
525+
AllocatorModifierLoc(AllocatorModifierLoc) {}
517526

518527
/// Build an empty clause.
519528
///
@@ -527,6 +536,9 @@ class OMPAllocateClause final
527536
void setColonLoc(SourceLocation CL) { ColonLoc = CL; }
528537

529538
void setAllocator(Expr *A) { Allocator = A; }
539+
void setAllocatorModifier(OpenMPAllocateClauseModifier AM) {
540+
AllocatorModifier = AM;
541+
}
530542

531543
public:
532544
/// Creates clause with a list of variables \a VL.
@@ -536,18 +548,31 @@ class OMPAllocateClause final
536548
/// \param LParenLoc Location of '('.
537549
/// \param Allocator Allocator expression.
538550
/// \param ColonLoc Location of ':' delimiter.
551+
/// \param AllocatorModifier Allocator modifier.
552+
/// \param SourceLocation Allocator modifier location.
539553
/// \param EndLoc Ending location of the clause.
540554
/// \param VL List of references to the variables.
541-
static OMPAllocateClause *Create(const ASTContext &C, SourceLocation StartLoc,
542-
SourceLocation LParenLoc, Expr *Allocator,
543-
SourceLocation ColonLoc,
544-
SourceLocation EndLoc, ArrayRef<Expr *> VL);
555+
static OMPAllocateClause *
556+
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
557+
Expr *Allocator, SourceLocation ColonLoc,
558+
OpenMPAllocateClauseModifier AllocatorModifier,
559+
SourceLocation AllocatorModifierLoc, SourceLocation EndLoc,
560+
ArrayRef<Expr *> VL);
545561

546562
/// Returns the allocator expression or nullptr, if no allocator is specified.
547563
Expr *getAllocator() const { return Allocator; }
548564

565+
/// Return 'allocate' modifier.
566+
OpenMPAllocateClauseModifier getAllocatorModifier() const {
567+
return AllocatorModifier;
568+
}
569+
549570
/// Returns the location of the ':' delimiter.
550571
SourceLocation getColonLoc() const { return ColonLoc; }
572+
/// Return the location of the modifier.
573+
SourceLocation getAllocatorModifierLoc() const {
574+
return AllocatorModifierLoc;
575+
}
551576

552577
/// Creates an empty clause with the place for \a N variables.
553578
///

clang/include/clang/Basic/OpenMPKinds.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@
8686
#ifndef OPENMP_DOACROSS_MODIFIER
8787
#define OPENMP_DOACROSS_MODIFIER(Name)
8888
#endif
89+
#ifndef OPENMP_ALLOCATE_MODIFIER
90+
#define OPENMP_ALLOCATE_MODIFIER(Name)
91+
#endif
8992

9093
// Static attributes for 'schedule' clause.
9194
OPENMP_SCHEDULE_KIND(static)
@@ -214,6 +217,9 @@ OPENMP_GRAINSIZE_MODIFIER(strict)
214217
// Modifiers for the 'num_tasks' clause.
215218
OPENMP_NUMTASKS_MODIFIER(strict)
216219

220+
// Modifiers for 'allocate' clause.
221+
OPENMP_ALLOCATE_MODIFIER(allocator)
222+
217223
// Modifiers for the 'doacross' clause.
218224
OPENMP_DOACROSS_MODIFIER(source)
219225
OPENMP_DOACROSS_MODIFIER(sink)
@@ -245,4 +251,5 @@ OPENMP_DOACROSS_MODIFIER(source_omp_cur_iteration)
245251
#undef OPENMP_DEFAULTMAP_KIND
246252
#undef OPENMP_DEFAULTMAP_MODIFIER
247253
#undef OPENMP_DOACROSS_MODIFIER
254+
#undef OPENMP_ALLOCATE_MODIFIER
248255

clang/include/clang/Basic/OpenMPKinds.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,13 @@ enum OpenMPDoacrossClauseModifier {
223223
OMPC_DOACROSS_unknown
224224
};
225225

226+
/// OpenMP modifiers for 'allocate' clause.
227+
enum OpenMPAllocateClauseModifier {
228+
#define OPENMP_ALLOCATE_MODIFIER(Name) OMPC_ALLOCATE_##Name,
229+
#include "clang/Basic/OpenMPKinds.def"
230+
OMPC_ALLOCATE_unknown
231+
};
232+
226233
/// Contains 'interop' data for 'append_args' and 'init' clauses.
227234
class Expr;
228235
struct OMPInteropInfo final {

clang/include/clang/Sema/SemaOpenMP.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,6 +1148,7 @@ class SemaOpenMP : public SemaBase {
11481148
SourceLocation OmpAllMemoryLoc;
11491149
SourceLocation
11501150
StepModifierLoc; /// 'step' modifier location for linear clause
1151+
OpenMPAllocateClauseModifier AllocClauseModifier = OMPC_ALLOCATE_unknown;
11511152
};
11521153

11531154
OMPClause *ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
@@ -1165,10 +1166,10 @@ class SemaOpenMP : public SemaBase {
11651166
SourceLocation LParenLoc,
11661167
SourceLocation EndLoc);
11671168
/// Called on well-formed 'allocate' clause.
1168-
OMPClause *
1169-
ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef<Expr *> VarList,
1170-
SourceLocation StartLoc, SourceLocation ColonLoc,
1171-
SourceLocation LParenLoc, SourceLocation EndLoc);
1169+
OMPClause *ActOnOpenMPAllocateClause(
1170+
Expr *Allocator, OpenMPAllocateClauseModifier ACModifier,
1171+
ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1172+
SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc);
11721173
/// Called on well-formed 'private' clause.
11731174
OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
11741175
SourceLocation StartLoc,

clang/lib/AST/OpenMPClause.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,12 +1023,17 @@ OMPPartialClause *OMPPartialClause::CreateEmpty(const ASTContext &C) {
10231023
OMPAllocateClause *
10241024
OMPAllocateClause::Create(const ASTContext &C, SourceLocation StartLoc,
10251025
SourceLocation LParenLoc, Expr *Allocator,
1026-
SourceLocation ColonLoc, SourceLocation EndLoc,
1027-
ArrayRef<Expr *> VL) {
1026+
SourceLocation ColonLoc,
1027+
OpenMPAllocateClauseModifier AllocatorModifier,
1028+
SourceLocation AllocatorModifierLoc,
1029+
SourceLocation EndLoc, ArrayRef<Expr *> VL) {
1030+
10281031
// Allocate space for private variables and initializer expressions.
10291032
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
1030-
auto *Clause = new (Mem) OMPAllocateClause(StartLoc, LParenLoc, Allocator,
1031-
ColonLoc, EndLoc, VL.size());
1033+
auto *Clause = new (Mem) OMPAllocateClause(
1034+
StartLoc, LParenLoc, Allocator, ColonLoc, AllocatorModifier,
1035+
AllocatorModifierLoc, EndLoc, VL.size());
1036+
10321037
Clause->setVarRefs(VL);
10331038
return Clause;
10341039
}
@@ -2242,9 +2247,17 @@ void OMPClausePrinter::VisitOMPAllocateClause(OMPAllocateClause *Node) {
22422247
if (Node->varlist_empty())
22432248
return;
22442249
OS << "allocate";
2250+
OpenMPAllocateClauseModifier Modifier = Node->getAllocatorModifier();
22452251
if (Expr *Allocator = Node->getAllocator()) {
22462252
OS << "(";
2247-
Allocator->printPretty(OS, nullptr, Policy, 0);
2253+
if (Modifier == OMPC_ALLOCATE_allocator) {
2254+
OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier);
2255+
OS << "(";
2256+
Allocator->printPretty(OS, nullptr, Policy, 0);
2257+
OS << ")";
2258+
} else {
2259+
Allocator->printPretty(OS, nullptr, Policy, 0);
2260+
}
22482261
OS << ":";
22492262
VisitOMPClauseList(Node, ' ');
22502263
} else {

clang/lib/Basic/OpenMPKinds.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,11 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
180180
return OMPC_NUMTASKS_unknown;
181181
return Type;
182182
}
183+
case OMPC_allocate:
184+
return llvm::StringSwitch<OpenMPAllocateClauseModifier>(Str)
185+
#define OPENMP_ALLOCATE_MODIFIER(Name) .Case(#Name, OMPC_ALLOCATE_##Name)
186+
#include "clang/Basic/OpenMPKinds.def"
187+
.Default(OMPC_ALLOCATE_unknown);
183188
case OMPC_unknown:
184189
case OMPC_threadprivate:
185190
case OMPC_if:
@@ -190,7 +195,6 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
190195
case OMPC_sizes:
191196
case OMPC_permutation:
192197
case OMPC_allocator:
193-
case OMPC_allocate:
194198
case OMPC_collapse:
195199
case OMPC_private:
196200
case OMPC_firstprivate:
@@ -505,6 +509,16 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
505509
#include "clang/Basic/OpenMPKinds.def"
506510
}
507511
llvm_unreachable("Invalid OpenMP 'num_tasks' clause modifier");
512+
case OMPC_allocate:
513+
switch (Type) {
514+
case OMPC_ALLOCATE_unknown:
515+
return "unknown";
516+
#define OPENMP_ALLOCATE_MODIFIER(Name) \
517+
case OMPC_ALLOCATE_##Name: \
518+
return #Name;
519+
#include "clang/Basic/OpenMPKinds.def"
520+
}
521+
llvm_unreachable("Invalid OpenMP 'allocate' clause modifier");
508522
case OMPC_unknown:
509523
case OMPC_threadprivate:
510524
case OMPC_if:
@@ -515,7 +529,6 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
515529
case OMPC_sizes:
516530
case OMPC_permutation:
517531
case OMPC_allocator:
518-
case OMPC_allocate:
519532
case OMPC_collapse:
520533
case OMPC_private:
521534
case OMPC_firstprivate:

clang/lib/Parse/ParseOpenMP.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4800,7 +4800,23 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
48004800
// iterator(iterators-definition)
48014801
ExprResult Tail;
48024802
if (Kind == OMPC_allocate) {
4803-
Tail = ParseAssignmentExpression();
4803+
auto Modifier = static_cast<OpenMPAllocateClauseModifier>(
4804+
getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok), getLangOpts()));
4805+
if (Modifier == OMPC_ALLOCATE_allocator) {
4806+
Data.AllocClauseModifier = Modifier;
4807+
ConsumeToken();
4808+
BalancedDelimiterTracker AllocateT(*this, tok::l_paren,
4809+
tok::annot_pragma_openmp_end);
4810+
if (Tok.is(tok::l_paren)) {
4811+
AllocateT.consumeOpen();
4812+
Tail = ParseAssignmentExpression();
4813+
AllocateT.consumeClose();
4814+
} else {
4815+
Diag(Tok, diag::err_expected) << tok::l_paren;
4816+
}
4817+
} else {
4818+
Tail = ParseAssignmentExpression();
4819+
}
48044820
} else {
48054821
HasIterator = true;
48064822
EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
@@ -4817,6 +4833,12 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
48174833
} else {
48184834
// Colon not found, parse only list of variables.
48194835
TPA.Revert();
4836+
if (Kind == OMPC_allocate &&
4837+
Data.AllocClauseModifier == OMPC_ALLOCATE_allocator) {
4838+
SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
4839+
StopBeforeMatch);
4840+
Diag(Tok, diag::err_modifier_expected_colon) << "allocator";
4841+
}
48204842
}
48214843
} else {
48224844
// Parsing was unsuccessfull, revert and skip to the end of clause or
@@ -4886,7 +4908,6 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
48864908
// Parse ')' for linear clause with modifier.
48874909
if (NeedRParenForLinear)
48884910
LinearT.consumeClose();
4889-
48904911
// Parse ':' linear modifiers (val, uval, ref or step(step-size))
48914912
// or parse ':' alignment.
48924913
const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
@@ -5018,6 +5039,9 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
50185039
/// 'has_device_addr' '(' list ')'
50195040
/// allocate-clause:
50205041
/// 'allocate' '(' [ allocator ':' ] list ')'
5042+
/// As of OpenMP 5.1 there's also
5043+
/// 'allocate' '(' allocate-modifier: list ')'
5044+
/// where allocate-modifier is: 'allocator' '(' allocator ')'
50215045
/// nontemporal-clause:
50225046
/// 'nontemporal' '(' list ')'
50235047
/// inclusive-clause:

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17156,7 +17156,8 @@ OMPClause *SemaOpenMP::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
1715617156
Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
1715717157
break;
1715817158
case OMPC_allocate:
17159-
Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr, VarList, StartLoc,
17159+
Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr,
17160+
Data.AllocClauseModifier, VarList, StartLoc,
1716017161
LParenLoc, ColonLoc, EndLoc);
1716117162
break;
1716217163
case OMPC_nontemporal:
@@ -23162,9 +23163,17 @@ SemaOpenMP::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
2316223163
}
2316323164

2316423165
OMPClause *SemaOpenMP::ActOnOpenMPAllocateClause(
23165-
Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
23166-
SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
23166+
Expr *Allocator, OpenMPAllocateClauseModifier AllocClauseModifier,
23167+
ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
23168+
SourceLocation ColonLoc, SourceLocation EndLoc) {
23169+
2316723170
if (Allocator) {
23171+
// Allocator expression is dependent - skip it for now and build the
23172+
// allocator when instantiated.
23173+
if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
23174+
Allocator->isInstantiationDependent() ||
23175+
Allocator->containsUnexpandedParameterPack())
23176+
return nullptr;
2316823177
// OpenMP [2.11.4 allocate Clause, Description]
2316923178
// allocator is an expression of omp_allocator_handle_t type.
2317023179
if (!findOMPAllocatorHandleT(SemaRef, Allocator->getExprLoc(), DSAStack))
@@ -23220,8 +23229,12 @@ OMPClause *SemaOpenMP::ActOnOpenMPAllocateClause(
2322023229

2322123230
if (Allocator)
2322223231
DSAStack->addInnerAllocatorExpr(Allocator);
23232+
23233+
OpenMPAllocateClauseModifier AllocatorModifier = AllocClauseModifier;
23234+
SourceLocation AllocatorModifierLoc;
2322323235
return OMPAllocateClause::Create(getASTContext(), StartLoc, LParenLoc,
23224-
Allocator, ColonLoc, EndLoc, Vars);
23236+
Allocator, ColonLoc, AllocatorModifier,
23237+
AllocatorModifierLoc, EndLoc, Vars);
2322523238
}
2322623239

2322723240
OMPClause *SemaOpenMP::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,

clang/lib/Sema/TreeTransform.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2075,13 +2075,15 @@ class TreeTransform {
20752075
///
20762076
/// By default, performs semantic analysis to build the new OpenMP clause.
20772077
/// Subclasses may override this routine to provide different behavior.
2078-
OMPClause *RebuildOMPAllocateClause(Expr *Allocate, ArrayRef<Expr *> VarList,
2078+
OMPClause *RebuildOMPAllocateClause(Expr *Allocate,
2079+
OpenMPAllocateClauseModifier ACModifier,
2080+
ArrayRef<Expr *> VarList,
20792081
SourceLocation StartLoc,
20802082
SourceLocation LParenLoc,
20812083
SourceLocation ColonLoc,
20822084
SourceLocation EndLoc) {
20832085
return getSema().OpenMP().ActOnOpenMPAllocateClause(
2084-
Allocate, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
2086+
Allocate, ACModifier, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
20852087
}
20862088

20872089
/// Build a new OpenMP 'num_teams' clause.
@@ -11128,8 +11130,8 @@ TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
1112811130
Vars.push_back(EVar.get());
1112911131
}
1113011132
return getDerived().RebuildOMPAllocateClause(
11131-
Allocator, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11132-
C->getEndLoc());
11133+
Allocator, C->getAllocatorModifier(), Vars, C->getBeginLoc(),
11134+
C->getLParenLoc(), C->getColonLoc(), C->getEndLoc());
1113311135
}
1113411136

1113511137
template <typename Derived>

0 commit comments

Comments
 (0)