Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,7 @@ OpenMP Support
--------------
- Added support for 'omp assume' directive.
- Added support for 'omp scope' directive.
- Added support for allocator-modifier in 'allocate' clause.

Improvements
^^^^^^^^^^^^
Expand Down
39 changes: 32 additions & 7 deletions clang/include/clang/AST/OpenMPClause.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,8 @@ class OMPAlignClause final
/// #pragma omp parallel private(a) allocate(omp_default_mem_alloc :a)
/// \endcode
/// In this example directive '#pragma omp parallel' has clause 'private'
/// and clause 'allocate' for the variable 'a'.
/// and clause 'allocate' for the variable 'a', which specifies an explicit
/// memory allocator.
class OMPAllocateClause final
: public OMPVarListClause<OMPAllocateClause>,
private llvm::TrailingObjects<OMPAllocateClause, Expr *> {
Expand All @@ -499,6 +500,10 @@ class OMPAllocateClause final
Expr *Allocator = nullptr;
/// Position of the ':' delimiter in the clause;
SourceLocation ColonLoc;
/// Modifier of 'allocate' clause.
OpenMPAllocateClauseModifier AllocatorModifier = OMPC_ALLOCATE_unknown;
/// Location of allocator modifier if any.
SourceLocation AllocatorModifierLoc;

/// Build clause with number of variables \a N.
///
Expand All @@ -510,10 +515,14 @@ class OMPAllocateClause final
/// \param N Number of the variables in the clause.
OMPAllocateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
Expr *Allocator, SourceLocation ColonLoc,
SourceLocation EndLoc, unsigned N)
OpenMPAllocateClauseModifier AllocatorModifier,
SourceLocation AllocatorModifierLoc, SourceLocation EndLoc,
unsigned N)
: OMPVarListClause<OMPAllocateClause>(llvm::omp::OMPC_allocate, StartLoc,
LParenLoc, EndLoc, N),
Allocator(Allocator), ColonLoc(ColonLoc) {}
Allocator(Allocator), ColonLoc(ColonLoc),
AllocatorModifier(AllocatorModifier),
AllocatorModifierLoc(AllocatorModifierLoc) {}

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

void setAllocator(Expr *A) { Allocator = A; }
void setAllocatorModifier(OpenMPAllocateClauseModifier AM) {
AllocatorModifier = AM;
}

public:
/// Creates clause with a list of variables \a VL.
Expand All @@ -536,18 +548,31 @@ class OMPAllocateClause final
/// \param LParenLoc Location of '('.
/// \param Allocator Allocator expression.
/// \param ColonLoc Location of ':' delimiter.
/// \param AllocatorModifier Allocator modifier.
/// \param SourceLocation Allocator modifier location.
/// \param EndLoc Ending location of the clause.
/// \param VL List of references to the variables.
static OMPAllocateClause *Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation LParenLoc, Expr *Allocator,
SourceLocation ColonLoc,
SourceLocation EndLoc, ArrayRef<Expr *> VL);
static OMPAllocateClause *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
Expr *Allocator, SourceLocation ColonLoc,
OpenMPAllocateClauseModifier AllocatorModifier,
SourceLocation AllocatorModifierLoc, SourceLocation EndLoc,
ArrayRef<Expr *> VL);

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

/// Return 'allocate' modifier.
OpenMPAllocateClauseModifier getAllocatorModifier() const {
return AllocatorModifier;
}

/// Returns the location of the ':' delimiter.
SourceLocation getColonLoc() const { return ColonLoc; }
/// Return the location of the modifier.
SourceLocation getAllocatorModifierLoc() const {
return AllocatorModifierLoc;
}

/// Creates an empty clause with the place for \a N variables.
///
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Basic/OpenMPKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@
#ifndef OPENMP_DOACROSS_MODIFIER
#define OPENMP_DOACROSS_MODIFIER(Name)
#endif
#ifndef OPENMP_ALLOCATE_MODIFIER
#define OPENMP_ALLOCATE_MODIFIER(Name)
#endif

// Static attributes for 'schedule' clause.
OPENMP_SCHEDULE_KIND(static)
Expand Down Expand Up @@ -214,6 +217,9 @@ OPENMP_GRAINSIZE_MODIFIER(strict)
// Modifiers for the 'num_tasks' clause.
OPENMP_NUMTASKS_MODIFIER(strict)

// Modifiers for 'allocate' clause.
OPENMP_ALLOCATE_MODIFIER(allocator)

// Modifiers for the 'doacross' clause.
OPENMP_DOACROSS_MODIFIER(source)
OPENMP_DOACROSS_MODIFIER(sink)
Expand Down Expand Up @@ -245,4 +251,5 @@ OPENMP_DOACROSS_MODIFIER(source_omp_cur_iteration)
#undef OPENMP_DEFAULTMAP_KIND
#undef OPENMP_DEFAULTMAP_MODIFIER
#undef OPENMP_DOACROSS_MODIFIER
#undef OPENMP_ALLOCATE_MODIFIER

7 changes: 7 additions & 0 deletions clang/include/clang/Basic/OpenMPKinds.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,13 @@ enum OpenMPDoacrossClauseModifier {
OMPC_DOACROSS_unknown
};

/// OpenMP modifiers for 'allocate' clause.
enum OpenMPAllocateClauseModifier {
#define OPENMP_ALLOCATE_MODIFIER(Name) OMPC_ALLOCATE_##Name,
#include "clang/Basic/OpenMPKinds.def"
OMPC_ALLOCATE_unknown
};

/// Contains 'interop' data for 'append_args' and 'init' clauses.
class Expr;
struct OMPInteropInfo final {
Expand Down
9 changes: 5 additions & 4 deletions clang/include/clang/Sema/SemaOpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -1148,6 +1148,7 @@ class SemaOpenMP : public SemaBase {
SourceLocation OmpAllMemoryLoc;
SourceLocation
StepModifierLoc; /// 'step' modifier location for linear clause
OpenMPAllocateClauseModifier AllocClauseModifier = OMPC_ALLOCATE_unknown;
};

OMPClause *ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
Expand All @@ -1165,10 +1166,10 @@ class SemaOpenMP : public SemaBase {
SourceLocation LParenLoc,
SourceLocation EndLoc);
/// Called on well-formed 'allocate' clause.
OMPClause *
ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef<Expr *> VarList,
SourceLocation StartLoc, SourceLocation ColonLoc,
SourceLocation LParenLoc, SourceLocation EndLoc);
OMPClause *ActOnOpenMPAllocateClause(
Expr *Allocator, OpenMPAllocateClauseModifier ACModifier,
ArrayRef<Expr *> VarList, SourceLocation StartLoc,
SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc);
/// Called on well-formed 'private' clause.
OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
Expand Down
23 changes: 18 additions & 5 deletions clang/lib/AST/OpenMPClause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1023,12 +1023,17 @@ OMPPartialClause *OMPPartialClause::CreateEmpty(const ASTContext &C) {
OMPAllocateClause *
OMPAllocateClause::Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation LParenLoc, Expr *Allocator,
SourceLocation ColonLoc, SourceLocation EndLoc,
ArrayRef<Expr *> VL) {
SourceLocation ColonLoc,
OpenMPAllocateClauseModifier AllocatorModifier,
SourceLocation AllocatorModifierLoc,
SourceLocation EndLoc, ArrayRef<Expr *> VL) {

// Allocate space for private variables and initializer expressions.
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
auto *Clause = new (Mem) OMPAllocateClause(StartLoc, LParenLoc, Allocator,
ColonLoc, EndLoc, VL.size());
auto *Clause = new (Mem) OMPAllocateClause(
StartLoc, LParenLoc, Allocator, ColonLoc, AllocatorModifier,
AllocatorModifierLoc, EndLoc, VL.size());

Clause->setVarRefs(VL);
return Clause;
}
Expand Down Expand Up @@ -2242,9 +2247,17 @@ void OMPClausePrinter::VisitOMPAllocateClause(OMPAllocateClause *Node) {
if (Node->varlist_empty())
return;
OS << "allocate";
OpenMPAllocateClauseModifier Modifier = Node->getAllocatorModifier();
if (Expr *Allocator = Node->getAllocator()) {
OS << "(";
Allocator->printPretty(OS, nullptr, Policy, 0);
if (Modifier == OMPC_ALLOCATE_allocator) {
OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier);
OS << "(";
Allocator->printPretty(OS, nullptr, Policy, 0);
OS << ")";
} else {
Allocator->printPretty(OS, nullptr, Policy, 0);
}
OS << ":";
VisitOMPClauseList(Node, ' ');
} else {
Expand Down
17 changes: 15 additions & 2 deletions clang/lib/Basic/OpenMPKinds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,11 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
return OMPC_NUMTASKS_unknown;
return Type;
}
case OMPC_allocate:
return llvm::StringSwitch<OpenMPAllocateClauseModifier>(Str)
#define OPENMP_ALLOCATE_MODIFIER(Name) .Case(#Name, OMPC_ALLOCATE_##Name)
#include "clang/Basic/OpenMPKinds.def"
.Default(OMPC_ALLOCATE_unknown);
case OMPC_unknown:
case OMPC_threadprivate:
case OMPC_if:
Expand All @@ -190,7 +195,6 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
case OMPC_sizes:
case OMPC_permutation:
case OMPC_allocator:
case OMPC_allocate:
case OMPC_collapse:
case OMPC_private:
case OMPC_firstprivate:
Expand Down Expand Up @@ -505,6 +509,16 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
#include "clang/Basic/OpenMPKinds.def"
}
llvm_unreachable("Invalid OpenMP 'num_tasks' clause modifier");
case OMPC_allocate:
switch (Type) {
case OMPC_ALLOCATE_unknown:
return "unknown";
#define OPENMP_ALLOCATE_MODIFIER(Name) \
case OMPC_ALLOCATE_##Name: \
return #Name;
#include "clang/Basic/OpenMPKinds.def"
}
llvm_unreachable("Invalid OpenMP 'allocate' clause modifier");
case OMPC_unknown:
case OMPC_threadprivate:
case OMPC_if:
Expand All @@ -515,7 +529,6 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
case OMPC_sizes:
case OMPC_permutation:
case OMPC_allocator:
case OMPC_allocate:
case OMPC_collapse:
case OMPC_private:
case OMPC_firstprivate:
Expand Down
28 changes: 26 additions & 2 deletions clang/lib/Parse/ParseOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4800,7 +4800,23 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
// iterator(iterators-definition)
ExprResult Tail;
if (Kind == OMPC_allocate) {
Tail = ParseAssignmentExpression();
auto Modifier = static_cast<OpenMPAllocateClauseModifier>(
getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok), getLangOpts()));
if (Modifier == OMPC_ALLOCATE_allocator) {
Data.AllocClauseModifier = Modifier;
ConsumeToken();
BalancedDelimiterTracker AllocateT(*this, tok::l_paren,
tok::annot_pragma_openmp_end);
if (Tok.is(tok::l_paren)) {
AllocateT.consumeOpen();
Tail = ParseAssignmentExpression();
AllocateT.consumeClose();
} else {
Diag(Tok, diag::err_expected) << tok::l_paren;
}
} else {
Tail = ParseAssignmentExpression();
}
} else {
HasIterator = true;
EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
Expand All @@ -4817,6 +4833,12 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
} else {
// Colon not found, parse only list of variables.
TPA.Revert();
if (Kind == OMPC_allocate &&
Data.AllocClauseModifier == OMPC_ALLOCATE_allocator) {
SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
StopBeforeMatch);
Diag(Tok, diag::err_modifier_expected_colon) << "allocator";
}
}
} else {
// Parsing was unsuccessfull, revert and skip to the end of clause or
Expand Down Expand Up @@ -4886,7 +4908,6 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
// Parse ')' for linear clause with modifier.
if (NeedRParenForLinear)
LinearT.consumeClose();

// Parse ':' linear modifiers (val, uval, ref or step(step-size))
// or parse ':' alignment.
const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
Expand Down Expand Up @@ -5018,6 +5039,9 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
/// 'has_device_addr' '(' list ')'
/// allocate-clause:
/// 'allocate' '(' [ allocator ':' ] list ')'
/// As of OpenMP 5.1 there's also
/// 'allocate' '(' allocate-modifier: list ')'
/// where allocate-modifier is: 'allocator' '(' allocator ')'
/// nontemporal-clause:
/// 'nontemporal' '(' list ')'
/// inclusive-clause:
Expand Down
21 changes: 17 additions & 4 deletions clang/lib/Sema/SemaOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17156,7 +17156,8 @@ OMPClause *SemaOpenMP::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
break;
case OMPC_allocate:
Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr, VarList, StartLoc,
Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr,
Data.AllocClauseModifier, VarList, StartLoc,
LParenLoc, ColonLoc, EndLoc);
break;
case OMPC_nontemporal:
Expand Down Expand Up @@ -23162,9 +23163,17 @@ SemaOpenMP::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
}

OMPClause *SemaOpenMP::ActOnOpenMPAllocateClause(
Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
Expr *Allocator, OpenMPAllocateClauseModifier AllocClauseModifier,
ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation ColonLoc, SourceLocation EndLoc) {

if (Allocator) {
// Allocator expression is dependent - skip it for now and build the
// allocator when instantiated.
if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
Allocator->isInstantiationDependent() ||
Allocator->containsUnexpandedParameterPack())
return nullptr;
// OpenMP [2.11.4 allocate Clause, Description]
// allocator is an expression of omp_allocator_handle_t type.
if (!findOMPAllocatorHandleT(SemaRef, Allocator->getExprLoc(), DSAStack))
Expand Down Expand Up @@ -23220,8 +23229,12 @@ OMPClause *SemaOpenMP::ActOnOpenMPAllocateClause(

if (Allocator)
DSAStack->addInnerAllocatorExpr(Allocator);

OpenMPAllocateClauseModifier AllocatorModifier = AllocClauseModifier;
SourceLocation AllocatorModifierLoc;
return OMPAllocateClause::Create(getASTContext(), StartLoc, LParenLoc,
Allocator, ColonLoc, EndLoc, Vars);
Allocator, ColonLoc, AllocatorModifier,
AllocatorModifierLoc, EndLoc, Vars);
}

OMPClause *SemaOpenMP::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
Expand Down
10 changes: 6 additions & 4 deletions clang/lib/Sema/TreeTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -2075,13 +2075,15 @@ class TreeTransform {
///
/// By default, performs semantic analysis to build the new OpenMP clause.
/// Subclasses may override this routine to provide different behavior.
OMPClause *RebuildOMPAllocateClause(Expr *Allocate, ArrayRef<Expr *> VarList,
OMPClause *RebuildOMPAllocateClause(Expr *Allocate,
OpenMPAllocateClauseModifier ACModifier,
ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation ColonLoc,
SourceLocation EndLoc) {
return getSema().OpenMP().ActOnOpenMPAllocateClause(
Allocate, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
Allocate, ACModifier, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
}

/// Build a new OpenMP 'num_teams' clause.
Expand Down Expand Up @@ -11128,8 +11130,8 @@ TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
Vars.push_back(EVar.get());
}
return getDerived().RebuildOMPAllocateClause(
Allocator, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
C->getEndLoc());
Allocator, C->getAllocatorModifier(), Vars, C->getBeginLoc(),
C->getLParenLoc(), C->getColonLoc(), C->getEndLoc());
}

template <typename Derived>
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11598,6 +11598,7 @@ void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) {
}

void OMPClauseReader::VisitOMPAllocateClause(OMPAllocateClause *C) {
C->setAllocatorModifier(Record.readEnum<OpenMPAllocateClauseModifier>());
C->setLParenLoc(Record.readSourceLocation());
C->setColonLoc(Record.readSourceLocation());
C->setAllocator(Record.readSubExpr());
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7619,6 +7619,7 @@ void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) {

void OMPClauseWriter::VisitOMPAllocateClause(OMPAllocateClause *C) {
Record.push_back(C->varlist_size());
Record.writeEnum(C->getAllocatorModifier());
Record.AddSourceLocation(C->getLParenLoc());
Record.AddSourceLocation(C->getColonLoc());
Record.AddStmt(C->getAllocator());
Expand Down
Loading
Loading